From 36d4ebfafa094b5b71b1392f9922dbdf6a5ea9a4 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 10 Apr 2018 01:51:16 +0000 Subject: [PATCH 001/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2986 98333e67-4a24-44d7-a75c-e53540dd3050 --- .../xmlrpc_wininet_transport.c | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c b/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c index f990afb7b..858a7b461 100644 --- a/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c +++ b/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c @@ -3,7 +3,7 @@ =============================================================================== WinInet-based client transport for Xmlrpc-c. Copyright information at the bottom of this file. - + =============================================================================*/ #include "xmlrpc_config.h" @@ -55,14 +55,14 @@ struct xmlrpc_client_transport { struct lock * listLockP; struct list_head rpcList; /* List of all RPCs that exist for this transport. An RPC exists - from the time the user requests it until the time the user + from the time the user requests it until the time the user acknowledges it is done. */ int allowInvalidSSLCerts; /* Flag to specify if we ignore invalid SSL Certificates. If this is set to zero, calling a XMLRPC server with an invalid SSL certificate will fail. This is the default behavior of the other - transports, but invalid certificates were allowed in pre 1.2 + transports, but invalid certificates were allowed in pre 1.2 wininet xmlrpc-c transports. */ }; @@ -72,7 +72,7 @@ typedef struct { HINTERNET hHttpRequest; HINTERNET hURL; INTERNET_PORT nPort; - char szHostName[255]; + char szHostName[255]; char szUrlPath[255]; BOOL bUseSSL; char * headerList; @@ -115,7 +115,7 @@ createWinInetHeaderList(xmlrpc_env * const envP, /* NOTE: A newline is required between each added header */ szHeaderList = malloc(strlen(szContentType) + 17 + strlen(serverP->basicAuthHdrValue) + 1); - + if (szHeaderList == NULL) xmlrpc_faultf(envP, "Couldn't allocate memory for authorization header"); @@ -130,11 +130,11 @@ createWinInetHeaderList(xmlrpc_env * const envP, } else { /* Just the content type header is needed */ szHeaderList = malloc(strlen(szContentType) + 1); - + if (szHeaderList == NULL) xmlrpc_faultf(envP, "Couldn't allocate memory for standard header"); - else + else memcpy(szHeaderList, szContentType, strlen(szContentType) + 1); } *headerListP = szHeaderList; @@ -201,7 +201,7 @@ createWinInetTransaction(xmlrpc_env * const envP, XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP); } } - + if (envP->fault_occurred) free(winInetTransactionP); } @@ -236,7 +236,7 @@ get_wininet_response(xmlrpc_env * const envP, unsigned long dwLen; INTERNET_BUFFERS inetBuffer; unsigned long dwFlags; - unsigned long dwErr; + unsigned long dwErr; unsigned long nExpected; void * body; BOOL bOK; @@ -260,14 +260,14 @@ get_wininet_response(xmlrpc_env * const envP, required by XML-RPC. Following fails if server didn't send it. */ - bOK = HttpQueryInfo(winInetTransactionP->hHttpRequest, - HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, + bOK = HttpQueryInfo(winInetTransactionP->hHttpRequest, + HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, &inetBuffer.dwBufferTotal, &dwLen, NULL); if (!bOK) { LPTSTR pMsg; dwErr = GetLastError (); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -288,7 +288,7 @@ get_wininet_response(xmlrpc_env * const envP, inetBuffer.dwBufferLength = nExpected; InternetQueryDataAvailable(winInetTransactionP->hHttpRequest, &inetBuffer.dwBufferLength, 0, 0); - + /* Read Response from InternetFile */ do { if (inetBuffer.dwBufferLength != 0) @@ -306,8 +306,8 @@ get_wininet_response(xmlrpc_env * const envP, dwErr = 0; } else { LPTSTR pMsg; - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -318,7 +318,7 @@ get_wininet_response(xmlrpc_env * const envP, XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); } } - + if (inetBuffer.dwBufferLength) { TCHAR * const oldBufptr = inetBuffer.lpvBuffer; @@ -327,14 +327,14 @@ get_wininet_response(xmlrpc_env * const envP, /* Adjust inetBuffer.dwBufferLength when it is greater than the */ /* expected end of file */ if (inetBuffer.dwBufferLength > nExpected) - inetBuffer.dwBufferLength = nExpected; + inetBuffer.dwBufferLength = nExpected; } else inetBuffer.dwBufferLength = nExpected; dwErr = 0; } while (nExpected != 0); - /* Add to the response buffer. */ + /* Add to the response buffer. */ xmlrpc_mem_block_append(envP, winInetTransactionP->pResponseData, body, inetBuffer.dwBufferTotal); XMLRPC_FAIL_IF_FAULT(envP); @@ -369,11 +369,11 @@ performWinInetTransaction( pMsgMem = NULL; /* initial value */ reqFlags = INTERNET_FLAG_NO_UI; /* initial value */ - + winInetTransactionP->hURL = - InternetConnect(hSyncInternetSession, + InternetConnect(hSyncInternetSession, winInetTransactionP->szHostName, - winInetTransactionP->nPort, + winInetTransactionP->nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); /* Start our request running. */ @@ -386,14 +386,14 @@ performWinInetTransaction( winInetTransactionP->szUrlPath, "HTTP/1.1", NULL, (const char **)&acceptTypes, reqFlags, 1); - + XMLRPC_FAIL_IF_NULL(winInetTransactionP->hHttpRequest, envP, XMLRPC_INTERNAL_ERROR, "Unable to open the requested URL."); succeeded = HttpAddRequestHeaders(winInetTransactionP->hHttpRequest, - winInetTransactionP->headerList, + winInetTransactionP->headerList, strlen (winInetTransactionP->headerList), HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); @@ -411,9 +411,9 @@ performWinInetTransaction( &dwTimeOut, sizeof(dwTimeOut)); } Again: - /* Send the requested XML remote procedure command */ - succeeded = HttpSendRequest(winInetTransactionP->hHttpRequest, NULL, 0, - winInetTransactionP->pSendData, + /* Send the requested XML remote procedure command */ + succeeded = HttpSendRequest(winInetTransactionP->hHttpRequest, NULL, 0, + winInetTransactionP->pSendData, strlen(winInetTransactionP->pSendData)); if (!succeeded) { LPTSTR pMsg; @@ -422,7 +422,7 @@ performWinInetTransaction( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS, + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -473,13 +473,13 @@ performWinInetTransaction( "for example, if you entered www.server.com " "and the common name " "on the certificate says www.different.com. "); - + reqFlags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID; InternetSetOption(winInetTransactionP->hHttpRequest, INTERNET_OPTION_SECURITY_FLAGS, &reqFlags, sizeof(reqFlags)); - + goto Again; } else pMsg = "The SSL certificate common name " @@ -533,14 +533,14 @@ performWinInetTransaction( } } else - pMsg = (LPTSTR)pMsgMem; + pMsg = (LPTSTR)pMsgMem; XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); } queryLen = sizeof(unsigned long); /* initial value */ - succeeded = HttpQueryInfo(winInetTransactionP->hHttpRequest, + succeeded = HttpQueryInfo(winInetTransactionP->hHttpRequest, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, &winInetTransactionP->http_status, &queryLen, NULL); @@ -548,8 +548,8 @@ performWinInetTransaction( LPTSTR pMsg; lastErr = GetLastError(); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -576,7 +576,7 @@ performWinInetTransaction( winInetTransactionP->http_status, errMsg); goto cleanup; } - /* Read the response. */ + /* Read the response. */ get_wininet_response(envP, winInetTransactionP); XMLRPC_FAIL_IF_FAULT(envP); @@ -618,7 +618,7 @@ createRpcThread(xmlrpc_env * const envP, rc = pthread_create(threadP, NULL, doAsyncRpc, rpcP); switch (rc) { - case 0: + case 0: break; case EAGAIN: xmlrpc_faultf(envP, "pthread_create() failed: " @@ -647,7 +647,7 @@ rpcCreate(xmlrpc_env * const envP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, xmlrpc_mem_block * const responseXmlP, - xmlrpc_transport_asynch_complete complete, + xmlrpc_transport_asynch_complete complete, struct xmlrpc_call_info * const callInfoP, rpc ** const rpcPP) { @@ -662,7 +662,7 @@ rpcCreate(xmlrpc_env * const envP, rpcP->responseXmlP = responseXmlP; rpcP->threadExists = FALSE; - createWinInetTransaction(envP, serverP, callXmlP, responseXmlP, + createWinInetTransaction(envP, serverP, callXmlP, responseXmlP, &rpcP->winInetTransactionP); if (!envP->fault_occurred) { if (complete) { @@ -689,7 +689,7 @@ rpcCreate(xmlrpc_env * const envP, -static void +static void rpcDestroy(rpc * const rpcP) { XMLRPC_ASSERT_PTR_OK(rpcP); @@ -704,10 +704,10 @@ rpcDestroy(rpc * const rpcP) { -static void * -finishRpc(struct list_head * const headerP, +static void * +finishRpc(struct list_head * const headerP, void * const context ATTR_UNUSED) { - + rpc * const rpcP = headerP->itemP; if (rpcP->threadExists) { @@ -715,7 +715,7 @@ finishRpc(struct list_head * const headerP, int result; result = pthread_join(rpcP->thread, &status); - + rpcP->threadExists = FALSE; } @@ -807,7 +807,7 @@ statusCallback (HINTERNET const hInternet, -static void +static void create(xmlrpc_env * const envP, int const flags ATTR_UNUSED, const char * const appname ATTR_UNUSED, @@ -818,7 +818,7 @@ create(xmlrpc_env * const envP, /*---------------------------------------------------------------------------- This does the 'create' operation for a WinInet client transport. -----------------------------------------------------------------------------*/ - const struct xmlrpc_wininet_xportparms * const wininetXportParmsP = + const struct xmlrpc_wininet_xportparms * const wininetXportParmsP = transportparmsP; struct xmlrpc_client_transport * transportP; @@ -828,7 +828,7 @@ create(xmlrpc_env * const envP, xmlrpc_faultf(envP, "Unable to allocate transport descriptor."); else { transportP->listLockP = xmlrpc_lock_create(); - + list_make_empty(&transportP->rpcList); if (hSyncInternetSession == NULL) @@ -849,7 +849,7 @@ create(xmlrpc_env * const envP, -static void +static void destroy(struct xmlrpc_client_transport * const clientTransportP) { /*---------------------------------------------------------------------------- This does the 'destroy' operation for a WinInet client transport. @@ -869,8 +869,8 @@ destroy(struct xmlrpc_client_transport * const clientTransportP) { -static void -sendRequest(xmlrpc_env * const envP, +static void +sendRequest(xmlrpc_env * const envP, struct xmlrpc_client_transport * const clientTransportP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, @@ -905,7 +905,7 @@ sendRequest(xmlrpc_env * const envP, -static void +static void finishAsynch(struct xmlrpc_client_transport * const clientTransportP, xmlrpc_timeoutType const timeoutType ATTR_UNUSED, xmlrpc_timeout const timeout ATTR_UNUSED) { @@ -950,9 +950,9 @@ call(xmlrpc_env * const envP, if (!envP->fault_occurred) { performWinInetTransaction(envP, rpcP->winInetTransactionP, clientTransportP); - + *responsePP = responseXmlP; - + rpcDestroy(rpcP); } if (envP->fault_occurred) @@ -986,8 +986,8 @@ struct xmlrpc_client_transport_ops xmlrpc_wininet_transport_ops = { ** 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. -** +** 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 From a8215ed395049ab8ffdc4fc467dd6199a739ec58 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 10 Apr 2018 02:12:45 +0000 Subject: [PATCH 002/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2987 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/src/cpp/client_simple.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/trunk/src/cpp/client_simple.cpp b/trunk/src/cpp/client_simple.cpp index 2bb2ec6ed..abd198452 100644 --- a/trunk/src/cpp/client_simple.cpp +++ b/trunk/src/cpp/client_simple.cpp @@ -36,7 +36,7 @@ class cValueWrapper { clientSimple::clientSimple() { - + clientXmlTransportPtr const transportP(clientXmlTransport_http::create()); this->clientP = clientPtr(new client_xml(transportP)); @@ -54,7 +54,7 @@ clientSimple::call(string const serverUrl, rpcPtr rpcPtr(methodName, paramList()); rpcPtr->call(this->clientP.get(), &carriageParm); - + *resultP = rpcPtr->getResult(); } @@ -65,7 +65,7 @@ void makeParamArray(string const format, xmlrpc_value ** const paramArrayPP, va_list args) { - + env_wrap env; /* The format is a sequence of parameter specifications, such as @@ -120,10 +120,10 @@ clientSimple::call(string const serverUrl, cValueWrapper paramArrayWrapper(paramArrayP); // ensure destruction unsigned int const paramCount( xmlrpc_array_size(&env.env_c, paramArrayP)); - + if (env.env_c.fault_occurred) throw(error(env.env_c.fault_string)); - + paramList paramList; for (unsigned int i = 0; i < paramCount; ++i) { xmlrpc_value * paramP; @@ -148,13 +148,13 @@ clientSimple::call(string const serverUrl, string const methodName, paramList const& paramList, value * const resultP) { - + carriageParm_http0 carriageParm(serverUrl); - + rpcPtr rpcPtr(methodName, paramList); rpcPtr->call(this->clientP.get(), &carriageParm); - + *resultP = rpcPtr->getResult(); } From 5a24df0f9e4bbd233ca268c0a65cca3e123ba2ba Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 10 Apr 2018 02:14:47 +0000 Subject: [PATCH 003/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2988 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/src/cpp/client.cpp | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/trunk/src/cpp/client.cpp b/trunk/src/cpp/client.cpp index 6b7d27a50..0e8184c14 100644 --- a/trunk/src/cpp/client.cpp +++ b/trunk/src/cpp/client.cpp @@ -48,7 +48,7 @@ throwIfError(env_wrap const& env) { class memblockStringWrapper { -public: +public: memblockStringWrapper(string const value) { env_wrap env; @@ -60,7 +60,7 @@ class memblockStringWrapper { value.c_str(), value.size()); throwIfError(env); } - + memblockStringWrapper(xmlrpc_mem_block * const memblockP) : memblockP(memblockP) {}; @@ -96,7 +96,7 @@ struct client_xml_impl { transportPtr(transportPtr), dialect(dialect) {} }; - + carriageParm::carriageParm() {} @@ -160,7 +160,7 @@ carriageParm_http0::instantiate(string const serverUrl) { if (c_serverInfoP) throw(error("object already instantiated")); - + env_wrap env; this->c_serverInfoP = @@ -323,7 +323,7 @@ carriageParm_http0::setBasicAuth(string const username, if (!this->c_serverInfoP) throw(error("object not instantiated")); - + env_wrap env; xmlrpc_server_info_set_basic_auth( @@ -388,7 +388,7 @@ xmlTransactionPtr::xmlTransactionPtr() {} xmlTransactionPtr::xmlTransactionPtr(xmlTransaction * xmlTransP) : autoObjectPtr(xmlTransP) {} - + xmlTransaction * @@ -428,7 +428,7 @@ struct xmlTranCtl { callXml.c_str(), callXml.size()); throwIfError(env); } - + ~xmlTranCtl() { XMLRPC_MEMBLOCK_FREE(char, this->callXmlP); } @@ -455,7 +455,7 @@ clientXmlTransport::start(carriageParm * const carriageParmP, // Note: derived class clientXmlTransport_http overrides this, // so it doesn't normally get used. - + string responseXml; this->call(carriageParmP, callXml, &responseXml); @@ -593,7 +593,7 @@ clientXmlTransport_http::call( memblockStringWrapper responseHolder(responseXmlMP); // Makes responseXmlMP get freed at end of scope - + *responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlMP), XMLRPC_MEMBLOCK_SIZE(char, responseXmlMP)); } @@ -869,7 +869,7 @@ client_xml::call(carriageParm * const carriageParmP, string responseXml; xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); - + xml::trace("XML-RPC CALL", callXml); try { @@ -879,7 +879,7 @@ client_xml::call(carriageParm * const carriageParmP, "get XML response back. %s", e.what()); } xml::trace("XML-RPC RESPONSE", responseXml); - + try { xml::parseResponse(responseXml, outcomeP); } catch (exception const& e) { @@ -887,7 +887,7 @@ client_xml::call(carriageParm * const carriageParmP, e.what()); } } - + void @@ -899,14 +899,14 @@ client_xml::start(carriageParm * const carriageParmP, string callXml; xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); - + xml::trace("XML-RPC CALL", callXml); xmlTransaction_clientPtr const xmlTranP(tranP); this->implP->transportP->start(carriageParmP, callXml, xmlTranP); } - + void @@ -1008,14 +1008,14 @@ struct rpc_impl { rpc::rpc(string const methodName, paramList const& paramList) { - + this->implP = new rpc_impl(methodName, paramList); } rpc::~rpc() { - + if (this->implP->state == rpc_impl::STATE_ERROR) delete(this->implP->errorP); @@ -1051,11 +1051,11 @@ rpc::call(connection const& connection) { } - + void rpc::start(client * const clientP, carriageParm * const carriageParmP) { - + if (this->implP->state != rpc_impl::STATE_UNFINISHED) throw(error("Attempt to execute an RPC that has already been " "executed")); @@ -1067,10 +1067,10 @@ rpc::start(client * const clientP, } - + void rpc::start(xmlrpc_c::connection const& connection) { - + this->start(connection.clientP, connection.carriageParmP); } @@ -1129,7 +1129,7 @@ rpc::progress(struct xmlrpc_progress_data const&) const { -----------------------------------------------------------------------------*/ } - + value @@ -1230,7 +1230,7 @@ xmlTransaction_client::finish(string const& responseXml) const { try { rpcOutcome outcome; - + xml::parseResponse(responseXml, &outcome); this->tranP->finish(outcome); From e3834a201173d052a76d41baf82a34a61f762768 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 10 Apr 2018 02:16:51 +0000 Subject: [PATCH 004/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2989 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/include/xmlrpc-c/client_transport.hpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/trunk/include/xmlrpc-c/client_transport.hpp b/trunk/include/xmlrpc-c/client_transport.hpp index 4c6c87e1f..9b1bdd9e4 100644 --- a/trunk/include/xmlrpc-c/client_transport.hpp +++ b/trunk/include/xmlrpc-c/client_transport.hpp @@ -86,7 +86,7 @@ class XMLRPC_CLIENTPP_EXPORTED xmlTransactionPtr : public girmem::autoObjectPtr xmlTransactionPtr(); xmlTransactionPtr(xmlTransaction * xmlTransP); - + xmlrpc_c::xmlTransaction * operator->() const; }; @@ -133,7 +133,7 @@ class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport : public girmem::autoObject { }; class XMLRPC_CLIENTPP_EXPORTED clientXmlTransportPtr : public girmem::autoObjectPtr { - + public: clientXmlTransportPtr(); @@ -166,25 +166,25 @@ class XMLRPC_CLIENTPP_EXPORTED carriageParm_http0 : public xmlrpc_c::carriagePar void disallowAuthBasic(); - + void allowAuthDigest(); void disallowAuthDigest(); - + void allowAuthNegotiate(); void disallowAuthNegotiate(); - + void allowAuthNtlm(); void disallowAuthNtlm(); - + void setBasicAuth(std::string const userid, std::string const password); @@ -219,17 +219,17 @@ class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_http : public xmlrpc_c::client -----------------------------------------------------------------------------*/ 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); @@ -350,7 +350,7 @@ class XMLRPC_CLIENTPP_EXPORTED carriageParm_libwww0Ptr : public xmlrpc_c::carria }; class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_libwww : public xmlrpc_c::clientXmlTransport_http { - + public: clientXmlTransport_libwww(std::string const appname = "", std::string const appversion = ""); From dab6c9f4abf8e9033c11a52eca07b5c68875ad82 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 15 Apr 2018 17:58:31 +0000 Subject: [PATCH 005/154] Fix make distclean: remove autom4te.conf git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2990 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/GNUmakefile | 1 + 1 file changed, 1 insertion(+) diff --git a/trunk/GNUmakefile b/trunk/GNUmakefile index 7d3aff019..ea6ef12c9 100644 --- a/trunk/GNUmakefile +++ b/trunk/GNUmakefile @@ -148,6 +148,7 @@ distclean-local: clean-local rm -f config.log config.status config.mk srcdir.mk rm -f xmlrpc_config.h xmlrpc_amconfig.h stamp-h rm -f shell_config xmlrpc-c-config xmlrpc-c-config.test + rm -rf autom4te.cache # gets created by 'autoconf' rm -f TAGS check: $(SUBDIRS:%=%/check) From 9b73c7b64786e2dc8f7813f659889de94ecbfb2b Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 8 Jun 2018 15:23:50 +0000 Subject: [PATCH 006/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2991 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/src/cpp/packetsocket.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/trunk/src/cpp/packetsocket.cpp b/trunk/src/cpp/packetsocket.cpp index 328e2c477..478764b34 100644 --- a/trunk/src/cpp/packetsocket.cpp +++ b/trunk/src/cpp/packetsocket.cpp @@ -33,7 +33,7 @@ A stream is all the data transmitted during a single socket connection. - End of stream in the middle of a packet is a protocol error. + End of stream in the middle of a packet is a protocol error. All bytes not part of a control word are literal bytes of a packet. @@ -119,7 +119,7 @@ class XMLRPC_DLLEXPORT socketx { */ socketx::socketx(int const sockFd) { -#if MSVCRT +#if MSVCRT // We don't have any way to duplicate; we'll just have to borrow. this->fdIsBorrowed = true; this->fd = sockFd; @@ -196,10 +196,10 @@ socketx::waitForWritable() const { select(this->fd + 1, 0, &wr_set, 0, 0); #else struct pollfd pollfds[1]; - + pollfds[0].fd = this->fd; pollfds[0].events = POLLOUT; - + poll(pollfds, ARRAY_SIZE(pollfds), -1); #endif } @@ -302,7 +302,7 @@ socketx::read(unsigned char * const buffer, arrive later. Return as *bytesReadP the number of bytes put into 'buffer'. - + Throw a BrokenConnectionEx exception if the connection has been broken. -----------------------------------------------------------------------------*/ int rc; @@ -410,7 +410,7 @@ namespace xmlrpc_c { packet::packet() : bytes(NULL), length(0), allocSize(0) {} - + void @@ -673,7 +673,7 @@ packetSocket_impl::writeWait(packetPtr const& packetP) const { if (this->mustTrace) traceWrite(packetP->getBytes(), packetP->getLength()); - + this->sock.writeWait(packetStart, 4); const unsigned char * const end( @@ -769,7 +769,7 @@ packetSocket_impl::takeSomeEscapeSeq(const unsigned char * const buffer, this->escAccum.bytes[0], this->escAccum.bytes[1], this->escAccum.bytes[2]); - + this->inEscapeSeq = false; this->escAccum.len = 0; } @@ -822,7 +822,7 @@ packetSocket_impl::verifyNothingAccumulated() { if (this->inEscapeSeq) throwf("Streams socket closed in the middle of an " "escape sequence"); - + if (this->inPacket) throwf("Stream socket closed in the middle of a packet " "(%u bytes of packet received; no END marker to mark " @@ -855,7 +855,7 @@ packetSocket_impl::processBytesRead(const unsigned char * const buffer, throwf("Byte 0x%02x is not in a packet or escape sequence. " "Sender is probably not using packet socket protocol", buffer[cursor]); - + cursor += bytesTaken; } } From 0296457b1f0c668dc4068c85508e67f5696ac40a Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 8 Jun 2018 15:43:04 +0000 Subject: [PATCH 007/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2992 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/expat/xmltok/xmltok_impl.c | 982 +++++++++++++-------------- 1 file changed, 491 insertions(+), 491 deletions(-) diff --git a/trunk/lib/expat/xmltok/xmltok_impl.c b/trunk/lib/expat/xmltok/xmltok_impl.c index d0355275f..e566a58bd 100644 --- a/trunk/lib/expat/xmltok/xmltok_impl.c +++ b/trunk/lib/expat/xmltok/xmltok_impl.c @@ -21,7 +21,7 @@ See the file copying.txt for copying permission. #define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ case BT_LEAD ## n: \ if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ + return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n)) { \ *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; \ @@ -100,7 +100,7 @@ See the file copying.txt for copying permission. static int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr != end) { if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { @@ -110,24 +110,24 @@ int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); case BT_MINUS: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_COMMENT; - } - break; + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_COMMENT; + } + break; default: - ptr += MINBPC(enc); - break; + ptr += MINBPC(enc); + break; } } } @@ -138,7 +138,7 @@ int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; @@ -160,12 +160,12 @@ int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, switch (BYTE_TYPE(enc, ptr)) { case BT_PERCNT: if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; /* don't allow */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } /* fall through */ case BT_S: case BT_CR: case BT_LF: @@ -184,9 +184,9 @@ int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, } static -int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, - const char * end, +int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, + const char * end, int * tokPtr) { int upper = 0; @@ -232,56 +232,56 @@ int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, static int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int tok; const char *target = ptr; if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } ptr += MINBPC(enc); while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); - case BT_QUEST: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr + MINBPC(enc); - return tok; - } - break; - default: - ptr += MINBPC(enc); - break; - } + INVALID_CASES(ptr, nextTokPtr); + case BT_QUEST: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + *nextTokPtr = ptr + MINBPC(enc); + return tok; + } + break; + default: + ptr += MINBPC(enc); + break; + } } return XML_TOK_PARTIAL; case BT_QUEST: if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr + MINBPC(enc); - return tok; + *nextTokPtr = ptr + MINBPC(enc); + return tok; } /* fall through */ default: @@ -294,8 +294,8 @@ int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end, static -int PREFIX(scanCdataSection)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, +int PREFIX(scanCdataSection)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, const char * end, const char ** nextTokPtr) { @@ -316,7 +316,7 @@ int PREFIX(scanCdataSection)(const ENCODING * enc ATTR_UNUSED, static int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_NONE; @@ -325,7 +325,7 @@ int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *en if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; end = ptr + n; } } @@ -356,22 +356,22 @@ int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *en case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); default: ptr += MINBPC(enc); break; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NONXML: case BT_MALFORM: @@ -394,35 +394,35 @@ int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *en static int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_CR: case BT_LF: - break; - case BT_GT: - *nextTokPtr = ptr + MINBPC(enc); + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: case BT_CR: case BT_LF: + break; + case BT_GT: + *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_END_TAG; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } } return XML_TOK_PARTIAL; case BT_COLON: - /* no need to check qname syntax here, since end-tag must match exactly */ + /* no need to check qname syntax here, since end-tag must match exactly*/ ptr += MINBPC(enc); break; case BT_GT: @@ -440,7 +440,7 @@ int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { @@ -455,13 +455,13 @@ int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: - break; + break; case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CHAR_REF; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CHAR_REF; default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } } } @@ -472,7 +472,7 @@ int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end static int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr != end) { if (CHAR_MATCHES(enc, ptr, ASCII_x)) @@ -487,13 +487,13 @@ int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: - break; + break; case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CHAR_REF; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CHAR_REF; default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } } } @@ -504,12 +504,12 @@ int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_NUM: return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); default: @@ -518,7 +518,7 @@ int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_ENTITY_REF; @@ -534,148 +534,148 @@ int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int hadColon = 0; while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_COLON: if (hadColon) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } hadColon = 1; ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } break; case BT_S: case BT_CR: case BT_LF: for (;;) { - int t; - - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - t = BYTE_TYPE(enc, ptr); - if (t == BT_EQUALS) - break; - switch (t) { - case BT_S: - case BT_LF: - case BT_CR: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } + int t; + + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + t = BYTE_TYPE(enc, ptr); + if (t == BT_EQUALS) + break; + switch (t) { + case BT_S: + case BT_LF: + case BT_CR: + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } } - /* fall through */ + /* fall through */ case BT_EQUALS: - { - int open; - hadColon = 0; - for (;;) { - - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - open = BYTE_TYPE(enc, ptr); - if (open == BT_QUOT || open == BT_APOS) - break; - switch (open) { - case BT_S: - case BT_LF: - case BT_CR: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - ptr += MINBPC(enc); - /* in attribute value */ - for (;;) { - int t; - if (ptr == end) - return XML_TOK_PARTIAL; - t = BYTE_TYPE(enc, ptr); - if (t == open) - break; - switch (t) { - INVALID_CASES(ptr, nextTokPtr); - case BT_AMP: - { - int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr); - if (tok <= 0) { - if (tok == XML_TOK_INVALID) - *nextTokPtr = ptr; - return tok; - } - break; - } - case BT_LT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - default: - ptr += MINBPC(enc); - break; - } - } - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: - case BT_CR: - case BT_LF: - break; - case BT_SOL: - goto sol; - case BT_GT: - goto gt; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - /* ptr points to closing quote */ - for (;;) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_CR: case BT_LF: - continue; - case BT_GT: - gt: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_START_TAG_WITH_ATTS; - case BT_SOL: - sol: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - break; - } - break; + { + int open; + hadColon = 0; + for (;;) { + + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + open = BYTE_TYPE(enc, ptr); + if (open == BT_QUOT || open == BT_APOS) + break; + switch (open) { + case BT_S: + case BT_LF: + case BT_CR: + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + ptr += MINBPC(enc); + /* in attribute value */ + for (;;) { + int t; + if (ptr == end) + return XML_TOK_PARTIAL; + t = BYTE_TYPE(enc, ptr); + if (t == open) + break; + switch (t) { + INVALID_CASES(ptr, nextTokPtr); + case BT_AMP: + { + int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr); + if (tok <= 0) { + if (tok == XML_TOK_INVALID) + *nextTokPtr = ptr; + return tok; + } + break; + } + case BT_LT: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + default: + ptr += MINBPC(enc); + break; + } + } + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: + case BT_CR: + case BT_LF: + break; + case BT_SOL: + goto sol; + case BT_GT: + goto gt; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + /* ptr points to closing quote */ + for (;;) { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_S: case BT_CR: case BT_LF: + continue; + case BT_GT: + gt: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_START_TAG_WITH_ATTS; + case BT_SOL: + sol: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + break; } + break; + } default: *nextTokPtr = ptr; return XML_TOK_INVALID; @@ -688,13 +688,13 @@ int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int hadColon; if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_EXCL: if ((ptr += MINBPC(enc)) == end) return XML_TOK_PARTIAL; @@ -718,44 +718,44 @@ int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, /* we have a start-tag */ while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_COLON: if (hadColon) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } hadColon = 1; ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } break; case BT_S: case BT_CR: case BT_LF: - { - ptr += MINBPC(enc); - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: - goto gt; - case BT_SOL: - goto sol; - case BT_S: case BT_CR: case BT_LF: - ptr += MINBPC(enc); - continue; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); - } - return XML_TOK_PARTIAL; + { + ptr += MINBPC(enc); + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: + goto gt; + case BT_SOL: + goto sol; + case BT_S: case BT_CR: case BT_LF: + ptr += MINBPC(enc); + continue; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); } + return XML_TOK_PARTIAL; + } case BT_GT: gt: *nextTokPtr = ptr + MINBPC(enc); @@ -764,10 +764,10 @@ int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, sol: ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_EMPTY_ELEMENT_NO_ATTS; @@ -956,12 +956,12 @@ PREFIX(contentTok)(const ENCODING * const enc, static int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_PERCENT; @@ -971,7 +971,7 @@ int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_PARAM_ENTITY_REF; @@ -985,19 +985,19 @@ int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_CR: case BT_LF: case BT_S: case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: *nextTokPtr = ptr; @@ -1012,27 +1012,27 @@ int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanLit)(int open, const ENCODING *enc, - const char *ptr, const char *end, - const char **nextTokPtr) + const char *ptr, const char *end, + const char **nextTokPtr) { while (ptr != end) { int t = BYTE_TYPE(enc, ptr); switch (t) { - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); case BT_QUOT: case BT_APOS: ptr += MINBPC(enc); if (t != open) - break; + break; if (ptr == end) - return -XML_TOK_LITERAL; + return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: case BT_GT: case BT_PERCNT: case BT_LSQB: - return XML_TOK_LITERAL; + return XML_TOK_LITERAL; default: - return XML_TOK_INVALID; + return XML_TOK_INVALID; } default: ptr += MINBPC(enc); @@ -1044,7 +1044,7 @@ int PREFIX(scanLit)(int open, const ENCODING *enc, static int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int tok; if (ptr == end) @@ -1054,7 +1054,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; end = ptr + n; } } @@ -1064,27 +1064,27 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_APOS: return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_LT: - { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_EXCL: - return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_QUEST: - return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_NMSTRT: - case BT_HEX: - case BT_NONASCII: - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - *nextTokPtr = ptr - MINBPC(enc); - return XML_TOK_INSTANCE_START; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; + { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_EXCL: + return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_QUEST: + return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_NMSTRT: + case BT_HEX: + case BT_NONASCII: + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + *nextTokPtr = ptr - MINBPC(enc); + return XML_TOK_INSTANCE_START; } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } case BT_CR: if (ptr + MINBPC(enc) == end) return -XML_TOK_PROLOG_S; @@ -1093,18 +1093,18 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, for (;;) { ptr += MINBPC(enc); if (ptr == end) - break; + break; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_LF: - break; + break; case BT_CR: - /* don't split CR/LF pair */ - if (ptr + MINBPC(enc) != end) - break; - /* fall through */ + /* don't split CR/LF pair */ + if (ptr + MINBPC(enc) != end) + break; + /* fall through */ default: - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; } } *nextTokPtr = ptr; @@ -1123,10 +1123,10 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { - *nextTokPtr = ptr + 2*MINBPC(enc); - return XML_TOK_COND_SECT_CLOSE; + *nextTokPtr = ptr + 2*MINBPC(enc); + return XML_TOK_COND_SECT_CLOSE; } } *nextTokPtr = ptr; @@ -1164,22 +1164,22 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_DECL_CLOSE; case BT_NUM: return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NAME; \ - break; \ - } \ - if (IS_NAME_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NMTOKEN; \ - break; \ - } \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ + break; \ + } \ + if (IS_NAME_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NMTOKEN; \ + break; \ + } \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NMSTRT: @@ -1196,79 +1196,79 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, break; case BT_NONASCII: if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NAME; - break; - } + ptr += MINBPC(enc); + tok = XML_TOK_NAME; + break; + } if (IS_NAME_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NMTOKEN; - break; - } + ptr += MINBPC(enc); + tok = XML_TOK_NMTOKEN; + break; + } /* fall through */ default: *nextTokPtr = ptr; return XML_TOK_INVALID; } - while (ptr != end) { + while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: case BT_RPAR: case BT_COMMA: - case BT_VERBAR: case BT_LSQB: case BT_PERCNT: - case BT_S: case BT_CR: case BT_LF: - *nextTokPtr = ptr; - return tok; - case BT_COLON: - ptr += MINBPC(enc); - switch (tok) { - case XML_TOK_NAME: - if (ptr == end) - return XML_TOK_PARTIAL; - tok = XML_TOK_PREFIXED_NAME; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - default: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case XML_TOK_PREFIXED_NAME: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case BT_PLUS: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_PLUS; - case BT_AST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_ASTERISK; - case BT_QUEST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_QUESTION; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } + case BT_GT: case BT_RPAR: case BT_COMMA: + case BT_VERBAR: case BT_LSQB: case BT_PERCNT: + case BT_S: case BT_CR: case BT_LF: + *nextTokPtr = ptr; + return tok; + case BT_COLON: + ptr += MINBPC(enc); + switch (tok) { + case XML_TOK_NAME: + if (ptr == end) + return XML_TOK_PARTIAL; + tok = XML_TOK_PREFIXED_NAME; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + default: + tok = XML_TOK_NMTOKEN; + break; + } + break; + case XML_TOK_PREFIXED_NAME: + tok = XML_TOK_NMTOKEN; + break; + } + break; + case BT_PLUS: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_PLUS; + case BT_AST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; } - return -tok; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_ASTERISK; + case BT_QUEST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_QUESTION; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -tok; } static int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { const char *start; if (ptr == end) @@ -1282,7 +1282,7 @@ int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char * #undef LEAD_CASE case BT_AMP: if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LT: @@ -1291,27 +1291,27 @@ int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char * return XML_TOK_INVALID; case BT_LF: if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_S: if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_ATTRIBUTE_VALUE_S; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_ATTRIBUTE_VALUE_S; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; @@ -1326,7 +1326,7 @@ int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char * static int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { const char *start; if (ptr == end) @@ -1340,30 +1340,30 @@ int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end #undef LEAD_CASE case BT_AMP: if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_PERCNT: if (ptr == start) - return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LF: if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; @@ -1380,7 +1380,7 @@ int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end static int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int level = 0; if (MINBPC(enc) > 1) { @@ -1392,33 +1392,33 @@ int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *e } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); case BT_LT: if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { - ++level; - ptr += MINBPC(enc); - } + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { + ++level; + ptr += MINBPC(enc); + } } break; case BT_RSQB: if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr += MINBPC(enc); - if (level == 0) { - *nextTokPtr = ptr; - return XML_TOK_IGNORE_SECT; - } - --level; - } + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr += MINBPC(enc); + if (level == 0) { + *nextTokPtr = ptr; + return XML_TOK_IGNORE_SECT; + } + --level; + } } break; default: @@ -1433,7 +1433,7 @@ int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *e static int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, - const char **badPtr) + const char **badPtr) { ptr += MINBPC(enc); end -= MINBPC(enc); @@ -1461,22 +1461,22 @@ int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, break; case BT_S: if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { - *badPtr = ptr; - return 0; + *badPtr = ptr; + return 0; } break; case BT_NAME: case BT_NMSTRT: if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) - break; + break; default: switch (BYTE_TO_ASCII(enc, ptr)) { case 0x24: /* $ */ case 0x40: /* @ */ - break; + break; default: - *badPtr = ptr; - return 0; + *badPtr = ptr; + return 0; } break; } @@ -1485,27 +1485,27 @@ int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, } /* This must only be called for a well-formed start-tag or empty element tag. -Returns the number of attributes. Pointers to the first attsMax attributes +Returns the number of attributes. Pointers to the first attsMax attributes are stored in atts. */ static int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, - int attsMax, ATTRIBUTE *atts) + int attsMax, ATTRIBUTE *atts) { enum { other, inName, inValue } state = inName; int nAtts = 0; int open = 0; /* defined when state == inValue; - initialization just to shut up compilers */ + initialization just to shut up compilers */ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { #define START_NAME \ if (state == other) { \ - if (nAtts < attsMax) { \ - atts[nAtts].name = ptr; \ - atts[nAtts].normalized = 1; \ - } \ - state = inName; \ + if (nAtts < attsMax) { \ + atts[nAtts].name = ptr; \ + atts[nAtts].normalized = 1; \ + } \ + state = inName; \ } #define LEAD_CASE(n) \ case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; @@ -1519,47 +1519,47 @@ int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, #undef START_NAME case BT_QUOT: if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_QUOT; } else if (open == BT_QUOT) { state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; } break; case BT_APOS: if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_APOS; } else if (open == BT_APOS) { state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; } break; case BT_AMP: if (nAtts < attsMax) - atts[nAtts].normalized = 0; + atts[nAtts].normalized = 0; break; case BT_S: if (state == inName) state = other; else if (state == inValue - && nAtts < attsMax - && atts[nAtts].normalized - && (ptr == atts[nAtts].valuePtr - || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE - || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE - || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) - atts[nAtts].normalized = 0; + && nAtts < attsMax + && atts[nAtts].normalized + && (ptr == atts[nAtts].valuePtr + || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE + || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE + || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) + atts[nAtts].normalized = 0; break; case BT_CR: case BT_LF: /* This case ensures that the first attribute name is counted @@ -1567,12 +1567,12 @@ int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, if (state == inName) state = other; else if (state == inValue && nAtts < attsMax) - atts[nAtts].normalized = 0; + atts[nAtts].normalized = 0; break; case BT_GT: case BT_SOL: if (state != inValue) - return nAtts; + return nAtts; break; default: break; @@ -1593,20 +1593,20 @@ int PREFIX(charRefNumber)(const ENCODING *enc ATTR_UNUSED, const char *ptr) switch (c) { case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: - result <<= 4; - result |= (c - ASCII_0); - break; + result <<= 4; + result |= (c - ASCII_0); + break; case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F: - result <<= 4; - result += 10 + (c - ASCII_A); - break; + result <<= 4; + result += 10 + (c - ASCII_A); + break; case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f: - result <<= 4; - result += 10 + (c - ASCII_a); - break; + result <<= 4; + result += 10 + (c - ASCII_a); + break; } if (result >= 0x110000) - return -1; + return -1; } } else { @@ -1615,15 +1615,15 @@ int PREFIX(charRefNumber)(const ENCODING *enc ATTR_UNUSED, const char *ptr) result *= 10; result += (c - ASCII_0); if (result >= 0x110000) - return -1; + return -1; } } return checkCharRefNumber(result); } static -int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, +int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, const char * end) { switch ((end - ptr)/MINBPC(enc)) { @@ -1631,9 +1631,9 @@ int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_l: - return ASCII_LT; + return ASCII_LT; case ASCII_g: - return ASCII_GT; + return ASCII_GT; } } break; @@ -1641,9 +1641,9 @@ int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, if (CHAR_MATCHES(enc, ptr, ASCII_a)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_m)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_p)) - return ASCII_AMP; + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) + return ASCII_AMP; } } break; @@ -1652,23 +1652,23 @@ int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, case ASCII_q: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_u)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_t)) - return ASCII_QUOT; - } + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_t)) + return ASCII_QUOT; + } } break; case ASCII_a: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_p)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_s)) - return ASCII_APOS; - } + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_s)) + return ASCII_APOS; + } } break; } @@ -1684,12 +1684,12 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) #define LEAD_CASE(n) \ case BT_LEAD ## n: \ if (*ptr1++ != *ptr2++) \ - return 0; + return 0; LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) #undef LEAD_CASE /* fall through */ if (*ptr1++ != *ptr2++) - return 0; + return 0; break; case BT_NONASCII: case BT_NMSTRT: @@ -1699,23 +1699,23 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) case BT_NAME: case BT_MINUS: if (*ptr2++ != *ptr1++) - return 0; + return 0; if (MINBPC(enc) > 1) { - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 2) { - if (*ptr2++ != *ptr1++) - return 0; + if (*ptr2++ != *ptr1++) + return 0; + if (MINBPC(enc) > 2) { + if (*ptr2++ != *ptr1++) + return 0; if (MINBPC(enc) > 3) { - if (*ptr2++ != *ptr1++) - return 0; - } - } + if (*ptr2++ != *ptr1++) + return 0; + } + } } break; default: if (MINBPC(enc) == 1 && *ptr1 == *ptr2) - return 1; + return 1; switch (BYTE_TYPE(enc, ptr2)) { case BT_LEAD2: case BT_LEAD3: @@ -1727,9 +1727,9 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) case BT_DIGIT: case BT_NAME: case BT_MINUS: - return 0; + return 0; default: - return 1; + return 1; } } } @@ -1737,9 +1737,9 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) } static -int PREFIX(nameMatchesAscii)(const ENCODING * enc ATTR_UNUSED, +int PREFIX(nameMatchesAscii)(const ENCODING * enc ATTR_UNUSED, const char * ptr1, - const char * end1, + const char * end1, const char * ptr2) { for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { From 2a3aa348dcdf6676bef2de5f0b6230e97391540d Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 9 Jun 2018 20:50:24 +0000 Subject: [PATCH 008/154] cleanup git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2993 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/expat/xmltok/xmltok_impl.c | 58 +++++++++++++++++++++------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/trunk/lib/expat/xmltok/xmltok_impl.c b/trunk/lib/expat/xmltok/xmltok_impl.c index e566a58bd..7a294b2d4 100644 --- a/trunk/lib/expat/xmltok/xmltok_impl.c +++ b/trunk/lib/expat/xmltok/xmltok_impl.c @@ -1431,6 +1431,20 @@ int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *e +static bool +PREFIX(isSpecialChar)(char const c) { + + switch (c) { + case 0x24: /* $ */ + case 0x40: /* @ */ + return true; + default: + return false; + } +} + + + static int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, const char **badPtr) @@ -1467,18 +1481,18 @@ int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, break; case BT_NAME: case BT_NMSTRT: - if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) - break; + if (BYTE_TO_ASCII(enc, ptr) & ~0x7f) { + if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { + *badPtr = ptr; + return 0; + } + } + break; default: - switch (BYTE_TO_ASCII(enc, ptr)) { - case 0x24: /* $ */ - case 0x40: /* @ */ - break; - default: + if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { *badPtr = ptr; return 0; } - break; } } return 1; @@ -1681,13 +1695,27 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) { for (;;) { switch (BYTE_TYPE(enc, ptr1)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (*ptr1++ != *ptr2++) \ - return 0; - LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) -#undef LEAD_CASE - /* fall through */ + case BT_LEAD4: + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_LEAD3: + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_LEAD2: + if (*ptr1++ != *ptr2++) + return 0; if (*ptr1++ != *ptr2++) return 0; break; From fd888d5c36b04080099f1a5e5017eed6d9e0994b Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 9 Jun 2018 20:57:27 +0000 Subject: [PATCH 009/154] cleanup git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2994 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/src/cpp/packetsocket.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/trunk/src/cpp/packetsocket.cpp b/trunk/src/cpp/packetsocket.cpp index 478764b34..3719357a2 100644 --- a/trunk/src/cpp/packetsocket.cpp +++ b/trunk/src/cpp/packetsocket.cpp @@ -909,10 +909,11 @@ packetSocket_impl::readFromFile() { fprintf(stderr, "EOF on read\n"); this->eof = true; this->verifyNothingAccumulated(); - } else + } else { if (this->mustTrace) traceBytesRead(buffer, bytesRead); this->processBytesRead(buffer, bytesRead); + } } } } From c16f5cb9a01a33b4c7c639cabc4d806bf746186e Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 9 Jun 2018 20:57:50 +0000 Subject: [PATCH 010/154] cleanup git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2995 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/expat/xmltok/xmltok_impl.c | 39 +++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/trunk/lib/expat/xmltok/xmltok_impl.c b/trunk/lib/expat/xmltok/xmltok_impl.c index 7a294b2d4..cf0091d1d 100644 --- a/trunk/lib/expat/xmltok/xmltok_impl.c +++ b/trunk/lib/expat/xmltok/xmltok_impl.c @@ -167,7 +167,9 @@ int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, *nextTokPtr = ptr; return XML_TOK_INVALID; } - /* fall through */ + *nextTokPtr = ptr; + return XML_TOK_DECL_OPEN; + break; case BT_S: case BT_CR: case BT_LF: *nextTokPtr = ptr; return XML_TOK_DECL_OPEN; @@ -283,7 +285,9 @@ int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end, *nextTokPtr = ptr + MINBPC(enc); return tok; } - /* fall through */ + *nextTokPtr = ptr; + return XML_TOK_INVALID; + break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; @@ -927,8 +931,9 @@ PREFIX(contentTok)(const ENCODING * const enc, *nextTokPtr = ptr; return XML_TOK_INVALID; } - } - /* fall through */ + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + } break; case BT_AMP: case BT_LT: case BT_NONXML: @@ -1099,9 +1104,11 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, break; case BT_CR: /* don't split CR/LF pair */ - if (ptr + MINBPC(enc) != end) - break; - /* fall through */ + if (ptr + MINBPC(enc) == end) { + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + } + break; default: *nextTokPtr = ptr; return XML_TOK_PROLOG_S; @@ -1196,16 +1203,18 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, break; case BT_NONASCII: if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NAME; - break; - } + ptr += MINBPC(enc); + tok = XML_TOK_NAME; + break; + } if (IS_NAME_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NMTOKEN; + ptr += MINBPC(enc); + tok = XML_TOK_NMTOKEN; + } else { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } break; - } - /* fall through */ default: *nextTokPtr = ptr; return XML_TOK_INVALID; From 25fa6a6f3468ba81f6c0936eb58ef335f3aedfa2 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 01:34:37 +0000 Subject: [PATCH 011/154] Release 1.39.13 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2996 98333e67-4a24-44d7-a75c-e53540dd3050 From fd0cce9528694a6378518d0a4787d99ff752544a Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 01:42:14 +0000 Subject: [PATCH 012/154] Last 1.39 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2997 98333e67-4a24-44d7-a75c-e53540dd3050 From 34dee7a704ed311e1031a0712a5313df6cf38f4a Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 01:43:17 +0000 Subject: [PATCH 013/154] purge unnecessary mid-series release 1.39.06 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2998 98333e67-4a24-44d7-a75c-e53540dd3050 From c3e5b3cada8a0b614338276de40908b89ffd104f Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 01:45:02 +0000 Subject: [PATCH 014/154] Last 1.43 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@2999 98333e67-4a24-44d7-a75c-e53540dd3050 From 6144f54805d8d20c4d936996aa2955e4dfedc608 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 01:47:58 +0000 Subject: [PATCH 015/154] Promote Stable series to Super Stable git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3000 98333e67-4a24-44d7-a75c-e53540dd3050 From 7dcf6cc02da9fdc870e24200b586397560f2e358 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 01:51:12 +0000 Subject: [PATCH 016/154] Delete 1.43.07 - it's Not the last 1.43 release because 1.43 is now Super Stable git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3001 98333e67-4a24-44d7-a75c-e53540dd3050 From b77330a110292759c4ce05d4193a3216a43193a2 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 01:57:13 +0000 Subject: [PATCH 017/154] Promote Advanced series to Stable git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3002 98333e67-4a24-44d7-a75c-e53540dd3050 --- stable/GNUmakefile | 10 +- stable/README | 4 + .../project/vs2010express/cpptest.vcproj | 851 ++++++ .../project/vs2010express/cpptest.vcxproj | 533 ++++ .../vs2010express/cpptest.vcxproj.filters | 78 + .../vs2010express/cpptest.vcxproj.user | 4 + .../project/vs2010express/gennmtab.vcproj | 851 ++++++ .../project/vs2010express/gennmtab.vcxproj | 515 ++++ .../vs2010express/gennmtab.vcxproj.filters | 22 + .../vs2010express/gennmtab.vcxproj.user | 3 + .../project/vs2010express/rpctest.vcproj | 979 +++++++ .../project/vs2010express/rpctest.vcxproj | 587 ++++ .../vs2010express/rpctest.vcxproj.filters | 127 + .../vs2010express/rpctest.vcxproj.user | 3 + .../sample_add_asynch_client.vcproj | 839 ++++++ .../sample_add_asynch_client.vcxproj | 501 ++++ .../sample_add_asynch_client.vcxproj.filters | 22 + .../sample_add_asynch_client.vcxproj.user | 3 + .../vs2010express/sample_add_server.vcproj | 823 ++++++ .../vs2010express/sample_add_server.vcxproj | 481 ++++ .../sample_add_server.vcxproj.filters | 22 + .../sample_add_server.vcxproj.user | 3 + .../sample_add_server_w32httpsys.vcproj | 823 ++++++ .../sample_add_server_w32httpsys.vcxproj | 481 ++++ ...mple_add_server_w32httpsys.vcxproj.filters | 22 + .../sample_add_server_w32httpsys.vcxproj.user | 3 + .../sample_add_sync_client.vcproj | 827 ++++++ .../sample_add_sync_client.vcxproj | 481 ++++ .../sample_add_sync_client.vcxproj.filters | 22 + .../sample_add_sync_client.vcxproj.user | 3 + .../vs2010express/sample_auth_client.vcproj | 827 ++++++ .../vs2010express/sample_auth_client.vcxproj | 481 ++++ .../sample_auth_client.vcxproj.filters | 22 + .../sample_auth_client.vcxproj.user | 3 + .../tool_xmlrpc-transport.vcproj | 790 ++++++ .../tool_xmlrpc-transport.vcxproj | 519 ++++ .../tool_xmlrpc-transport.vcxproj.filters | 40 + .../tool_xmlrpc-transport.vcxproj.user | 3 + .../project/vs2010express/tool_xmlrpc.vcproj | 790 ++++++ .../project/vs2010express/tool_xmlrpc.vcxproj | 515 ++++ .../vs2010express/tool_xmlrpc.vcxproj.filters | 40 + .../vs2010express/tool_xmlrpc.vcxproj.user | 3 + .../project/vs2010express/vs2010express.sln | 399 +++ .../project/vs2010express/vs2010express.suo | Bin 0 -> 34304 bytes .../vs2010express/vs2010express.vcxproj | 90 + .../vs2010express.vcxproj.filters | 36 + .../vs2010express/vs2010express.vcxproj.user | 3 + .../project/vs2010express/xmlrpc.vcproj | 770 ++++++ .../project/vs2010express/xmlrpc.vcxproj | 438 +++ .../vs2010express/xmlrpc.vcxproj.filters | 98 + .../project/vs2010express/xmlrpc.vcxproj.user | 3 + .../project/vs2010express/xmlrpc__.vcproj | 2430 +++++++++++++++++ .../project/vs2010express/xmlrpc__.vcxproj | 482 ++++ .../vs2010express/xmlrpc__.vcxproj.filters | 140 + .../vs2010express/xmlrpc__.vcxproj.user | 3 + .../project/vs2010express/xmlrpc_abyss.vcproj | 2276 +++++++++++++++ .../vs2010express/xmlrpc_abyss.vcxproj | 472 ++++ .../xmlrpc_abyss.vcxproj.filters | 140 + .../vs2010express/xmlrpc_abyss.vcxproj.user | 4 + .../vs2010express/xmlrpc_client.vcproj | 724 +++++ .../vs2010express/xmlrpc_client.vcxproj | 428 +++ .../xmlrpc_client.vcxproj.filters | 62 + .../vs2010express/xmlrpc_client.vcxproj.user | 3 + .../vs2010express/xmlrpc_server.vcproj | 708 +++++ .../vs2010express/xmlrpc_server.vcxproj | 421 +++ .../xmlrpc_server.vcxproj.filters | 53 + .../vs2010express/xmlrpc_server.vcxproj.user | 3 + .../vs2010express/xmlrpc_server_abyss.vcproj | 704 +++++ .../vs2010express/xmlrpc_server_abyss.vcxproj | 428 +++ .../xmlrpc_server_abyss.vcxproj.filters | 50 + .../xmlrpc_server_abyss.vcxproj.user | 3 + .../vs2010express/xmlrpc_server_cgi.vcproj | 696 +++++ .../vs2010express/xmlrpc_server_cgi.vcxproj | 422 +++ .../xmlrpc_server_cgi.vcxproj.filters | 44 + .../xmlrpc_server_cgi.vcxproj.user | 3 + .../xmlrpc_server_w32httpsys.vcproj | 700 +++++ .../xmlrpc_server_w32httpsys.vcxproj | 423 +++ .../xmlrpc_server_w32httpsys.vcxproj.filters | 47 + .../xmlrpc_server_w32httpsys.vcxproj.user | 3 + .../project/vs2010express/xmlrpc_util.vcproj | 764 ++++++ .../project/vs2010express/xmlrpc_util.vcxproj | 438 +++ .../vs2010express/xmlrpc_util.vcxproj.filters | 86 + .../vs2010express/xmlrpc_util.vcxproj.user | 6 + .../vs2010express/xmlrpc_xmlparse.vcproj | 747 +++++ .../vs2010express/xmlrpc_xmlparse.vcxproj | 413 +++ .../xmlrpc_xmlparse.vcxproj.filters | 27 + .../xmlrpc_xmlparse.vcxproj.user | 6 + .../vs2010express/xmlrpc_xmltok.vcproj | 849 ++++++ .../vs2010express/xmlrpc_xmltok.vcxproj | 415 +++ .../xmlrpc_xmltok.vcxproj.filters | 51 + .../vs2010express/xmlrpc_xmltok.vcxproj.user | 3 + stable/Windows/project/vs2017/cpptest.vcxproj | 562 ++++ .../Windows/project/vs2017/gennmtab.vcxproj | 539 ++++ stable/Windows/project/vs2017/rpctest.vcxproj | 614 +++++ .../vs2017/sample_add_asynch_client.vcxproj | 525 ++++ .../project/vs2017/sample_add_server.vcxproj | 505 ++++ .../sample_add_server_w32httpsys.vcxproj | 505 ++++ .../vs2017/sample_add_sync_client.vcxproj | 505 ++++ .../project/vs2017/sample_auth_client.vcxproj | 505 ++++ .../vs2017/tool_xmlrpc-transport.vcxproj | 543 ++++ .../project/vs2017/tool_xmlrpc.vcxproj | 539 ++++ stable/Windows/project/vs2017/xmlrpc.sln | 442 +++ stable/Windows/project/vs2017/xmlrpc.vcxproj | 462 ++++ .../Windows/project/vs2017/xmlrpc__.vcxproj | 505 ++++ .../project/vs2017/xmlrpc_abyss.vcxproj | 494 ++++ .../project/vs2017/xmlrpc_abyss__.vcxproj | 479 ++++ .../project/vs2017/xmlrpc_client.vcxproj | 452 +++ .../project/vs2017/xmlrpc_server.vcxproj | 445 +++ .../vs2017/xmlrpc_server_abyss.vcxproj | 452 +++ .../project/vs2017/xmlrpc_server_cgi.vcxproj | 446 +++ .../vs2017/xmlrpc_server_w32httpsys.vcxproj | 447 +++ .../project/vs2017/xmlrpc_util.vcxproj | 462 ++++ .../project/vs2017/xmlrpc_util__.vcxproj | 475 ++++ .../project/vs2017/xmlrpc_xmlparse.vcxproj | 437 +++ .../project/vs2017/xmlrpc_xmltok.vcxproj | 439 +++ stable/Windows/xmlrpc_win32_config.h | 12 + stable/common.mk | 125 +- stable/config.mk.in | 24 +- stable/configure | 692 +++-- stable/configure.in | 189 +- stable/doc/INSTALL | 70 +- stable/examples/Makefile | 40 +- stable/examples/compound_value_client.c | 1 - stable/examples/cpp/Makefile | 8 +- stable/examples/curl_client.c | 29 +- stable/examples/json.c | 25 +- stable/examples/ssl_secure_server.c | 242 ++ stable/examples/ssl_server.c | 230 ++ stable/examples/xmlrpc_loop_server.c | 6 +- stable/examples/xmlrpc_sample_add_client.c | 14 +- stable/examples/xmlrpc_sample_add_server.c | 7 +- stable/include/Makefile | 16 + stable/include/xmlrpc-c/AbyssChanSwitch.hpp | 8 +- .../xmlrpc-c/AbyssChanSwitchOpenSsl.hpp | 35 + .../include/xmlrpc-c/AbyssChanSwitchWin.hpp | 8 +- stable/include/xmlrpc-c/AbyssEnvironment.hpp | 8 +- stable/include/xmlrpc-c/AbyssServer.hpp | 15 +- stable/include/xmlrpc-c/abyss.h | 12 +- stable/include/xmlrpc-c/abyss_openssl.h | 82 + stable/include/xmlrpc-c/abyss_opensslsock.h | 28 - stable/include/xmlrpc-c/abyss_unixsock.h | 6 + stable/include/xmlrpc-c/abyss_winsock.h | 7 + stable/include/xmlrpc-c/base.hpp | 10 + stable/include/xmlrpc-c/base64.hpp | 18 +- stable/include/xmlrpc-c/base_int.h | 2 +- stable/include/xmlrpc-c/client_transport.hpp | 5 +- stable/include/xmlrpc-c/env_wrap.hpp | 8 +- stable/include/xmlrpc-c/girerr.hpp | 18 +- stable/include/xmlrpc-c/girmem.hpp | 20 +- stable/include/xmlrpc-c/openssl_thread.h | 10 + stable/include/xmlrpc-c/packetsocket.hpp | 7 + stable/include/xmlrpc-c/registry.hpp | 2 +- stable/include/xmlrpc-c/server_abyss.h | 1 + stable/include/xmlrpc-c/server_abyss.hpp | 5 + stable/include/xmlrpc-c/string_int.h | 6 + stable/include/xmlrpc-c/util.h | 25 +- stable/include/xmlrpc-c/util_int.h | 61 + stable/include/xmlrpc-c/xmlparser.h | 106 - stable/lib/Makefile | 6 + stable/lib/abyss++/AbyssChanSwitch.cpp | 2 +- stable/lib/abyss++/AbyssChanSwitchOpenSsl.cpp | 59 + stable/lib/abyss++/AbyssChanSwitchUnix.cpp | 2 +- stable/lib/abyss++/AbyssChanSwitchWin.cpp | 2 +- stable/lib/abyss++/AbyssEnvironment.cpp | 6 +- stable/lib/abyss++/AbyssServer.cpp | 1 + stable/lib/abyss++/Makefile | 10 +- stable/lib/abyss/Makefile | 3 + stable/lib/abyss/src/Makefile | 23 +- stable/lib/abyss/src/chanswitch.c | 86 +- stable/lib/abyss/src/file.h | 24 +- stable/lib/abyss/src/handler.c | 46 +- stable/lib/abyss/src/http.c | 1281 +-------- stable/lib/abyss/src/http.h | 33 +- stable/lib/abyss/src/server.c | 152 +- stable/lib/abyss/src/server.h | 15 +- stable/lib/abyss/src/session.c | 99 + stable/lib/abyss/src/session.h | 29 + stable/lib/abyss/src/sessionReadRequest.c | 1210 ++++++++ stable/lib/abyss/src/sessionReadRequest.h | 12 + stable/lib/abyss/src/socket_openssl.c | 783 ++++-- stable/lib/abyss/src/socket_openssl.h | 14 + stable/lib/abyss/src/socket_unix.c | 517 +--- stable/lib/abyss/src/socket_win.c | 19 + stable/lib/abyss/src/sockutil.c | 490 ++++ stable/lib/abyss/src/sockutil.h | 72 + stable/lib/abyss/src/thread.h | 2 +- stable/lib/abyss/src/thread_fork.c | 3 +- stable/lib/curl_transport/Makefile | 3 + stable/lib/curl_transport/curltransaction.c | 31 +- .../curl_transport/xmlrpc_curl_transport.c | 4 +- stable/lib/expat/Makefile | 3 + stable/lib/expat/gennmtab/Makefile | 7 +- stable/lib/expat/xmlparse/Makefile | 3 + stable/lib/expat/xmlparse/xmlparse.c | 605 ++-- stable/lib/expat/xmlparse/xmlparse.h | 3 +- stable/lib/expat/xmltok/Makefile | 3 + stable/lib/libutil++/Makefile | 3 + stable/lib/libutil++/base64.cpp | 4 +- stable/lib/libutil++/girmem.cpp | 3 +- stable/lib/libutil/Makefile | 6 +- stable/lib/libutil/base64.c | 2 +- stable/lib/libutil/lock_windows.c | 4 +- stable/lib/libutil/memblock.c | 170 +- stable/lib/libutil/mempool.c | 98 + stable/lib/libutil/utf8.c | 1 + stable/lib/libwww_transport/Makefile | 3 + stable/lib/openssl/Makefile | 121 + stable/lib/openssl/xmlrpc_openssl_thread.c | 124 + stable/lib/util/Makefile | 6 +- stable/lib/wininet_transport/Makefile | 3 + .../xmlrpc_wininet_transport.c | 2 +- stable/src/Makefile | 3 + stable/src/abyss_handler.c | 10 + stable/src/base_global.c | 4 +- stable/src/cpp/Makefile | 3 + stable/src/cpp/XmlRpcCpp.cpp | 2 + stable/src/cpp/client.cpp | 1 + stable/src/cpp/packetsocket.cpp | 162 +- stable/src/cpp/pstream.cpp | 146 +- stable/src/cpp/registry.cpp | 1 + stable/src/cpp/server_abyss.cpp | 50 +- stable/src/cpp/value.cpp | 142 +- stable/src/double.c | 4 +- stable/src/json.c | 28 +- stable/src/parse_datetime.c | 4 +- stable/src/parse_value.c | 6 +- stable/src/parse_value.h | 2 +- stable/{examples => src}/parse_xml.c | 6 + stable/src/xmlparser.h | 131 + stable/src/xmlrpc_array.c | 30 +- stable/src/xmlrpc_authcookie.c | 1 + stable/src/xmlrpc_client.c | 6 + stable/src/xmlrpc_data.c | 65 +- stable/src/xmlrpc_decompose.c | 2 +- stable/src/xmlrpc_expat.c | 284 +- stable/src/xmlrpc_libxml2.c | 25 +- stable/src/xmlrpc_parse.c | 186 +- stable/src/xmlrpc_parse.h | 42 + stable/src/xmlrpc_serialize.c | 10 +- stable/src/xmlrpc_server_abyss.c | 25 +- stable/src/xmlrpc_server_cgi.c | 9 +- stable/src/xmlrpc_server_w32httpsys.c | 9 +- stable/src/xmlrpc_string.c | 193 +- stable/src/xmlrpc_struct.c | 52 +- stable/test/Makefile | 4 + stable/test/cpp/Makefile | 3 + stable/test/cpp/abyss.cpp | 14 +- stable/test/cpp/testclient.cpp | 13 +- stable/test/cpp/value.cpp | 8 + stable/test/memblock.c | 237 ++ stable/test/memblock.h | 7 + stable/test/parse_xml.c | 78 +- stable/test/server_abyss.c | 3 + stable/test/test.c | 98 +- stable/test/value.c | 38 +- stable/test/value_datetime.c | 3 +- stable/tools/Makefile | 8 +- stable/tools/binmode-rpc-kit/Makefile | 1 + stable/tools/common.mk | 17 + stable/tools/turbocharger/Makefile | 1 + stable/tools/xml-rpc-api2cpp/Makefile | 6 + stable/tools/xml-rpc-api2txt/Makefile | 6 + stable/tools/xml/Makefile | 6 + stable/tools/xml/xmlrpc_parsecall.c | 1 + stable/tools/xmlrpc/Makefile | 6 + stable/tools/xmlrpc/xmlrpc.c | 75 +- stable/tools/xmlrpc_cpp_proxy/Makefile | 6 + stable/tools/xmlrpc_dumpserver/Makefile | 72 + .../xmlrpc_dumpserver/xmlrpc_dumpserver.c | 269 ++ stable/tools/xmlrpc_pstream/Makefile | 6 + stable/tools/xmlrpc_transport/Makefile | 6 + .../tools/xmlrpc_transport/xmlrpc_transport.c | 1 + stable/unix-common.mk | 22 +- stable/version.mk | 4 +- stable/xmlrpc-c-config.main | 9 + stable/xmlrpc-c-config.test.main | 8 + stable/xmlrpc_amconfig.h.in | 37 - stable/xmlrpc_config.h.in | 101 +- 278 files changed, 50857 insertions(+), 3666 deletions(-) create mode 100644 stable/Windows/project/vs2010express/cpptest.vcproj create mode 100644 stable/Windows/project/vs2010express/cpptest.vcxproj create mode 100644 stable/Windows/project/vs2010express/cpptest.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/cpptest.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/gennmtab.vcproj create mode 100644 stable/Windows/project/vs2010express/gennmtab.vcxproj create mode 100644 stable/Windows/project/vs2010express/gennmtab.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/gennmtab.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/rpctest.vcproj create mode 100644 stable/Windows/project/vs2010express/rpctest.vcxproj create mode 100644 stable/Windows/project/vs2010express/rpctest.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/rpctest.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/sample_add_asynch_client.vcproj create mode 100644 stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj create mode 100644 stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/sample_add_server.vcproj create mode 100644 stable/Windows/project/vs2010express/sample_add_server.vcxproj create mode 100644 stable/Windows/project/vs2010express/sample_add_server.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/sample_add_server.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcproj create mode 100644 stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj create mode 100644 stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/sample_add_sync_client.vcproj create mode 100644 stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj create mode 100644 stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/sample_auth_client.vcproj create mode 100644 stable/Windows/project/vs2010express/sample_auth_client.vcxproj create mode 100644 stable/Windows/project/vs2010express/sample_auth_client.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/sample_auth_client.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcproj create mode 100644 stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj create mode 100644 stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/tool_xmlrpc.vcproj create mode 100644 stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj create mode 100644 stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/vs2010express.sln create mode 100644 stable/Windows/project/vs2010express/vs2010express.suo create mode 100644 stable/Windows/project/vs2010express/vs2010express.vcxproj create mode 100644 stable/Windows/project/vs2010express/vs2010express.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/vs2010express.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc__.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc__.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc__.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc__.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc_abyss.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc_client.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_client.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_client.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc_client.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc_util.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_util.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_util.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc_util.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.user create mode 100644 stable/Windows/project/vs2010express/xmlrpc_xmltok.vcproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj create mode 100644 stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.filters create mode 100644 stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.user create mode 100644 stable/Windows/project/vs2017/cpptest.vcxproj create mode 100644 stable/Windows/project/vs2017/gennmtab.vcxproj create mode 100644 stable/Windows/project/vs2017/rpctest.vcxproj create mode 100644 stable/Windows/project/vs2017/sample_add_asynch_client.vcxproj create mode 100644 stable/Windows/project/vs2017/sample_add_server.vcxproj create mode 100644 stable/Windows/project/vs2017/sample_add_server_w32httpsys.vcxproj create mode 100644 stable/Windows/project/vs2017/sample_add_sync_client.vcxproj create mode 100644 stable/Windows/project/vs2017/sample_auth_client.vcxproj create mode 100644 stable/Windows/project/vs2017/tool_xmlrpc-transport.vcxproj create mode 100644 stable/Windows/project/vs2017/tool_xmlrpc.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc.sln create mode 100644 stable/Windows/project/vs2017/xmlrpc.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc__.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_abyss.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_abyss__.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_client.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_server.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_server_abyss.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_server_cgi.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_server_w32httpsys.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_util.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_util__.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_xmlparse.vcxproj create mode 100644 stable/Windows/project/vs2017/xmlrpc_xmltok.vcxproj create mode 100644 stable/examples/ssl_secure_server.c create mode 100644 stable/examples/ssl_server.c create mode 100644 stable/include/xmlrpc-c/AbyssChanSwitchOpenSsl.hpp create mode 100644 stable/include/xmlrpc-c/abyss_openssl.h delete mode 100644 stable/include/xmlrpc-c/abyss_opensslsock.h create mode 100644 stable/include/xmlrpc-c/openssl_thread.h delete mode 100644 stable/include/xmlrpc-c/xmlparser.h create mode 100644 stable/lib/abyss++/AbyssChanSwitchOpenSsl.cpp create mode 100644 stable/lib/abyss/src/sessionReadRequest.c create mode 100644 stable/lib/abyss/src/sessionReadRequest.h create mode 100644 stable/lib/abyss/src/socket_openssl.h create mode 100644 stable/lib/abyss/src/sockutil.c create mode 100644 stable/lib/abyss/src/sockutil.h create mode 100644 stable/lib/libutil/mempool.c create mode 100644 stable/lib/openssl/Makefile create mode 100644 stable/lib/openssl/xmlrpc_openssl_thread.c rename stable/{examples => src}/parse_xml.c (93%) create mode 100644 stable/src/xmlparser.h create mode 100644 stable/src/xmlrpc_parse.h create mode 100644 stable/test/memblock.c create mode 100644 stable/test/memblock.h create mode 100644 stable/tools/xmlrpc_dumpserver/Makefile create mode 100644 stable/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c delete mode 100644 stable/xmlrpc_amconfig.h.in diff --git a/stable/GNUmakefile b/stable/GNUmakefile index d59937107..7d3aff019 100644 --- a/stable/GNUmakefile +++ b/stable/GNUmakefile @@ -120,6 +120,8 @@ shell_config: $(BLDDIR)/config.mk @echo 'LIBINST_DIR="$(LIBINST_DIR)"' >>$@ @echo 'BLDDIR="$(BLDDIR)"' >>$@ @echo 'ABS_SRCDIR="$(ABS_SRCDIR)"' >>$@ + @echo 'ABYSS_DOES_OPENSSL="$(MUST_BUILD_ABYSS_OPENSSL)"' >>$@ + @echo 'OPENSSL_LDADD="$(OPENSSL_LDADD)"' >>$@ @echo '#######################################################' >>$@ xmlrpc-c-config xmlrpc-c-config.test:%: %.main shell_config @@ -159,10 +161,16 @@ distdir: distdir-common .PHONY: install install: $(DEFAULT_SUBDIRS:%=%/install) install-common +HEADERDESTDIR = $(DESTDIR)$(HEADERINST_DIR) + +.PHONY: uninstall +uninstall: $(DEFAULT_SUBDIRS:%=%/uninstall) uninstall-common + -rmdir $(HEADERDESTDIR)/xmlrpc-c + .PHONY: dep dep: version.h $(BLDDIR)/include/xmlrpc-c/config.h $(SUBDIRS:%=%/dep) -xmlrpc_config.h xmlrpc_amconfig.h \ +xmlrpc_config.h \ :%:%.in $(SRCDIR)/configure $(SRCDIR)/configure diff --git a/stable/README b/stable/README index efd105c82..eb06fddb0 100644 --- a/stable/README +++ b/stable/README @@ -48,6 +48,10 @@ In the simplest case, it's just a conventional $ make $ make install +And then, if Linux: + + $ ldconfig + ADDITIONAL INFORMATION ---------------------- diff --git a/stable/Windows/project/vs2010express/cpptest.vcproj b/stable/Windows/project/vs2010express/cpptest.vcproj new file mode 100644 index 000000000..97458c8bf --- /dev/null +++ b/stable/Windows/project/vs2010express/cpptest.vcproj @@ -0,0 +1,851 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/cpptest.vcxproj b/stable/Windows/project/vs2010express/cpptest.vcxproj new file mode 100644 index 000000000..274542659 --- /dev/null +++ b/stable/Windows/project/vs2010express/cpptest.vcxproj @@ -0,0 +1,533 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856} + cpptest + + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + + /D INTERNAL_EXPAT %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + /D INTERNAL_EXPAT %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + /D INTERNAL_EXPAT %(AdditionalOptions) + Disabled + ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILDING_LIBPP;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + /D INTERNAL_EXPAT %(AdditionalOptions) + Disabled + ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + /D INTERNAL_EXPAT %(AdditionalOptions) + Disabled + ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + /D INTERNAL_EXPAT %(AdditionalOptions) + Disabled + ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + /D INTERNAL_EXPAT %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + /D INTERNAL_EXPAT %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {3e7064f3-6200-4c39-85be-775931d21828} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/cpptest.vcxproj.filters b/stable/Windows/project/vs2010express/cpptest.vcxproj.filters new file mode 100644 index 000000000..c16994a4a --- /dev/null +++ b/stable/Windows/project/vs2010express/cpptest.vcxproj.filters @@ -0,0 +1,78 @@ + + + + + {f5252a96-d4c6-445e-8c35-ca0248ffbb90} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {03ef63c2-410d-4c91-b5ad-640704d05a21} + h;hpp;hxx;hm;inl + + + {0619edec-58a6-46c4-bd19-cc5c1d85d0a5} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/cpptest.vcxproj.user b/stable/Windows/project/vs2010express/cpptest.vcxproj.user new file mode 100644 index 000000000..7cbb3216a --- /dev/null +++ b/stable/Windows/project/vs2010express/cpptest.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/gennmtab.vcproj b/stable/Windows/project/vs2010express/gennmtab.vcproj new file mode 100644 index 000000000..02b6420aa --- /dev/null +++ b/stable/Windows/project/vs2010express/gennmtab.vcproj @@ -0,0 +1,851 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/gennmtab.vcxproj b/stable/Windows/project/vs2010express/gennmtab.vcxproj new file mode 100644 index 000000000..1b5dc5e45 --- /dev/null +++ b/stable/Windows/project/vs2010express/gennmtab.vcxproj @@ -0,0 +1,515 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412} + gennmtab + + + + Application + v100 + false + + + Application + v100 + false + + + Application + v100 + false + + + Application + v100 + false + + + Application + v100 + false + + + Application + v100 + false + + + Application + v100 + false + + + Application + v100 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + + + + $(OutDir)$(ProjectName).tlb + + + + Disabled + ../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + (D) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + X64 + $(OutDir)$(ProjectName).tlb + + + + Disabled + ../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + (D) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + $(OutDir)$(ProjectName).tlb + + + + MaxSpeed + OnlyExplicitInline + ../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + (R) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + X64 + $(OutDir)$(ProjectName).tlb + + + + MaxSpeed + OnlyExplicitInline + ../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + (R) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + $(OutDir)$(ProjectName).tlb + + + + Disabled + ../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + (D) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + X64 + $(OutDir)$(ProjectName).tlb + + + + Disabled + ../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + (D) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + $(OutDir)$(ProjectName).tlb + + + + MaxSpeed + OnlyExplicitInline + ../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + (R) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + X64 + $(OutDir)$(ProjectName).tlb + + + + MaxSpeed + OnlyExplicitInline + ../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + (R) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/gennmtab.vcxproj.filters b/stable/Windows/project/vs2010express/gennmtab.vcxproj.filters new file mode 100644 index 000000000..316180282 --- /dev/null +++ b/stable/Windows/project/vs2010express/gennmtab.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {5d8a7041-77b6-4734-af85-85cf63011a8b} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90 + + + {0c293b56-e683-47a1-844d-ac211aa2c2c7} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + {2716887d-8a6c-4d92-b804-f03db0b67175} + h;hpp;hxx;hm;inl;fi;fd + + + + + Source Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/gennmtab.vcxproj.user b/stable/Windows/project/vs2010express/gennmtab.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/gennmtab.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/rpctest.vcproj b/stable/Windows/project/vs2010express/rpctest.vcproj new file mode 100644 index 000000000..ac7d0314f --- /dev/null +++ b/stable/Windows/project/vs2010express/rpctest.vcproj @@ -0,0 +1,979 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/rpctest.vcxproj b/stable/Windows/project/vs2010express/rpctest.vcxproj new file mode 100644 index 000000000..bd9f069df --- /dev/null +++ b/stable/Windows/project/vs2010express/rpctest.vcxproj @@ -0,0 +1,587 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722} + rpctest + + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $OutDir)\data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $OutDir)\data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $(OutDir)data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $(OutDir)data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $OutDir)\data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $OutDir)\data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $(OutDir)data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $(OutDir)data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {e98186cb-f1b0-40a6-87a5-77b13a3f1600} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {40b0756d-afee-4a38-9f38-a372ce431404} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/rpctest.vcxproj.filters b/stable/Windows/project/vs2010express/rpctest.vcxproj.filters new file mode 100644 index 000000000..14cbe16ae --- /dev/null +++ b/stable/Windows/project/vs2010express/rpctest.vcxproj.filters @@ -0,0 +1,127 @@ + + + + + {1c8c37ff-1b10-4421-8a91-f19e6247b6f9} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {6b698982-c603-4655-9359-13b6b0059aaf} + h;hpp;hxx;hm;inl + + + {f5cd24c3-8ff7-45eb-9198-80c9a81b9b79} + + + {a0d0e69f-fd5e-407b-8b8c-ade4c1768ee2} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + TestFiles + + + + + TestFiles + + + TestFiles + + + TestFiles + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/rpctest.vcxproj.user b/stable/Windows/project/vs2010express/rpctest.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/rpctest.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_asynch_client.vcproj b/stable/Windows/project/vs2010express/sample_add_asynch_client.vcproj new file mode 100644 index 000000000..ed1102437 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_asynch_client.vcproj @@ -0,0 +1,839 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj b/stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj new file mode 100644 index 000000000..54fe1d820 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj @@ -0,0 +1,501 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652} + sample_add_asynch_client + + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + odbc32.lib;odbccp32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + odbc32.lib;odbccp32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.filters b/stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.filters new file mode 100644 index 000000000..fcb4b4c46 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {9d1d1ca2-e002-4e95-960a-68ce98d812d6} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {cccace1e-db4f-4da4-95c2-ed2230affe3e} + h;hpp;hxx;hm;inl + + + {878cc7dc-a7e7-4255-8a4f-209a757107a7} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.user b/stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_server.vcproj b/stable/Windows/project/vs2010express/sample_add_server.vcproj new file mode 100644 index 000000000..2d2cbaf46 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_server.vcproj @@ -0,0 +1,823 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/sample_add_server.vcxproj b/stable/Windows/project/vs2010express/sample_add_server.vcxproj new file mode 100644 index 000000000..9bdfe26e8 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_server.vcxproj @@ -0,0 +1,481 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {BEEB1B9C-BAF4-4B54-AB51-891156301702} + sample_add_server + + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {e98186cb-f1b0-40a6-87a5-77b13a3f1600} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_server.vcxproj.filters b/stable/Windows/project/vs2010express/sample_add_server.vcxproj.filters new file mode 100644 index 000000000..1fff72dc5 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_server.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {78f7e7a1-21a8-403e-96c5-4490959577fe} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {d52a357e-0a48-4f06-aad1-5fd5e922b6eb} + h;hpp;hxx;hm;inl + + + {d7b48ffa-20c8-4d45-81f9-56d6e5bdc8c3} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_server.vcxproj.user b/stable/Windows/project/vs2010express/sample_add_server.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_server.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcproj b/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcproj new file mode 100644 index 000000000..25233507e --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcproj @@ -0,0 +1,823 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj b/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj new file mode 100644 index 000000000..48387784e --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj @@ -0,0 +1,481 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {B6887828-9480-4D4D-9CFC-AE4980D41707} + sample_add_server_w32httpsys + + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {0eecb080-fc8f-4c46-9fb7-5db22f9d1622} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.filters b/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.filters new file mode 100644 index 000000000..c973d393d --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {d850a83b-706b-4478-8141-956e906663bd} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {9e5db171-0efd-4c2f-9d85-9dbb14d0f96c} + h;hpp;hxx;hm;inl + + + {6070c286-d300-47f6-b001-efebf8190759} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.user b/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_sync_client.vcproj b/stable/Windows/project/vs2010express/sample_add_sync_client.vcproj new file mode 100644 index 000000000..5f23a6a12 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_sync_client.vcproj @@ -0,0 +1,827 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj b/stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj new file mode 100644 index 000000000..aac62116d --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj @@ -0,0 +1,481 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710} + sample_add_sync_client + + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj.filters b/stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj.filters new file mode 100644 index 000000000..9198d1fe5 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {27eac376-bbcc-46ec-bbcb-f9bac54d664e} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {e0b59389-fbfc-4db6-abca-73c84a9326d5} + h;hpp;hxx;hm;inl + + + {f418327e-7416-493b-a34f-66bc7e2ba523} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj.user b/stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_add_sync_client.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_auth_client.vcproj b/stable/Windows/project/vs2010express/sample_auth_client.vcproj new file mode 100644 index 000000000..31ea15c1c --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_auth_client.vcproj @@ -0,0 +1,827 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/sample_auth_client.vcxproj b/stable/Windows/project/vs2010express/sample_auth_client.vcxproj new file mode 100644 index 000000000..765a663c5 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_auth_client.vcxproj @@ -0,0 +1,481 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714} + sample_auth_client + + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_auth_client.vcxproj.filters b/stable/Windows/project/vs2010express/sample_auth_client.vcxproj.filters new file mode 100644 index 000000000..675e9e788 --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_auth_client.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {51df2750-29e7-46f9-a1dd-26d18780f433} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {af693b21-170c-437e-8084-2bd3883deadf} + h;hpp;hxx;hm;inl + + + {185dcef2-b402-4b32-b59b-f992f113d086} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/sample_auth_client.vcxproj.user b/stable/Windows/project/vs2010express/sample_auth_client.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/sample_auth_client.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcproj b/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcproj new file mode 100644 index 000000000..014d2747d --- /dev/null +++ b/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcproj @@ -0,0 +1,790 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj b/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj new file mode 100644 index 000000000..de11f0cdf --- /dev/null +++ b/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj @@ -0,0 +1,519 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + xmlrpc_transport + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942} + + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.filters b/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.filters new file mode 100644 index 000000000..d7049523a --- /dev/null +++ b/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.filters @@ -0,0 +1,40 @@ + + + + + {95618a07-efd6-4963-ad2e-3f963cde6816} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {e5a752dc-fcf4-4e81-81b9-d856d1c6d892} + h;hpp;hxx;hm;inl + + + {b0f90688-1d56-49c9-a6d6-2471a08f07fa} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.user b/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/tool_xmlrpc.vcproj b/stable/Windows/project/vs2010express/tool_xmlrpc.vcproj new file mode 100644 index 000000000..d85bda710 --- /dev/null +++ b/stable/Windows/project/vs2010express/tool_xmlrpc.vcproj @@ -0,0 +1,790 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj b/stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj new file mode 100644 index 000000000..9d6280625 --- /dev/null +++ b/stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj @@ -0,0 +1,515 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + xmlrpc + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940} + + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + Application + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj.filters b/stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj.filters new file mode 100644 index 000000000..d83dd8fb4 --- /dev/null +++ b/stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj.filters @@ -0,0 +1,40 @@ + + + + + {13c7b6bf-db0d-4f32-b15d-ed7499cca73c} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {1327ed33-278c-4453-9d06-be01f5c61f76} + h;hpp;hxx;hm;inl + + + {53663fed-de9a-42f2-9022-ee40672d92f6} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj.user b/stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/tool_xmlrpc.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/vs2010express.sln b/stable/Windows/project/vs2010express/vs2010express.sln new file mode 100644 index 000000000..412aa432a --- /dev/null +++ b/stable/Windows/project/vs2010express/vs2010express.sln @@ -0,0 +1,399 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpptest", "cpptest.vcxproj", "{26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}" + ProjectSection(ProjectDependencies) = postProject + {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} + {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} + {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + {3E7064F3-6200-4C39-85BE-775931D21828} = {3E7064F3-6200-4C39-85BE-775931D21828} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennmtab", "gennmtab.vcxproj", "{99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpctest", "rpctest.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}" + ProjectSection(ProjectDependencies) = postProject + {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} + {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} + {40B0756D-AFEE-4A38-9F38-A372CE431404} = {40B0756D-AFEE-4A38-9F38-A372CE431404} + {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600} + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_asynch_client", "sample_add_asynch_client.vcxproj", "{2D4A179E-E2BA-4ED9-934E-7E54C08F1652}" + ProjectSection(ProjectDependencies) = postProject + {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server", "sample_add_server.vcxproj", "{BEEB1B9C-BAF4-4B54-AB51-891156301702}" + ProjectSection(ProjectDependencies) = postProject + {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} + {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server_w32httpsys", "sample_add_server_w32httpsys.vcxproj", "{B6887828-9480-4D4D-9CFC-AE4980D41707}" + ProjectSection(ProjectDependencies) = postProject + {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} + {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} = {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_sync_client", "sample_add_sync_client.vcxproj", "{A7A81BBD-C84D-479A-A9BD-194ADA3B1710}" + ProjectSection(ProjectDependencies) = postProject + {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_auth_client", "sample_auth_client.vcxproj", "{29A2BBC4-9ED9-4162-817C-FEEB36FB1714}" + ProjectSection(ProjectDependencies) = postProject + {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "tool_xmlrpc.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}" + ProjectSection(ProjectDependencies) = postProject + {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc_transport", "tool_xmlrpc-transport.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}" + ProjectSection(ProjectDependencies) = postProject + {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} + {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc", "xmlrpc.vcxproj", "{226AB06F-60CA-4B21-9040-C6ECC0581522}" + ProjectSection(ProjectDependencies) = postProject + {40B0756D-AFEE-4A38-9F38-A372CE431404} = {40B0756D-AFEE-4A38-9F38-A372CE431404} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc++", "xmlrpc__.vcxproj", "{3E7064F3-6200-4C39-85BE-775931D21828}" + ProjectSection(ProjectDependencies) = postProject + {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} + {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600} + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_abyss", "xmlrpc_abyss.vcxproj", "{20A8F64B-F738-4D32-A798-A65AD8291541}" + ProjectSection(ProjectDependencies) = postProject + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_client", "xmlrpc_client.vcxproj", "{28BB53D9-D487-41DF-BBB3-FDB5846D1630}" + ProjectSection(ProjectDependencies) = postProject + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_abyss", "xmlrpc_server_abyss.vcxproj", "{E98186CB-F1B0-40A6-87A5-77B13A3F1600}" + ProjectSection(ProjectDependencies) = postProject + {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_cgi", "xmlrpc_server_cgi.vcxproj", "{A2AAAF37-F382-4A11-8D86-53B589921616}" + ProjectSection(ProjectDependencies) = postProject + {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_w32httpsys", "xmlrpc_server_w32httpsys.vcxproj", "{0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}" + ProjectSection(ProjectDependencies) = postProject + {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_util", "xmlrpc_util.vcxproj", "{29FBABB6-E36A-4559-9514-B3DAF6AE1416}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmlparse", "xmlrpc_xmlparse.vcxproj", "{40B0756D-AFEE-4A38-9F38-A372CE431404}" + ProjectSection(ProjectDependencies) = postProject + {BD9F6041-A272-462D-8C41-87CEF1F11408} = {BD9F6041-A272-462D-8C41-87CEF1F11408} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmltok", "xmlrpc_xmltok.vcxproj", "{BD9F6041-A272-462D-8C41-87CEF1F11408}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server", "xmlrpc_server.vcxproj", "{74B67128-BC84-4BCB-A256-9286B6371552}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug-DLL|Win32 = Debug-DLL|Win32 + Debug-Static|Win32 = Debug-Static|Win32 + Release|Win32 = Release|Win32 + Release-DLL|Win32 = Release-DLL|Win32 + Release-Static|Win32 = Release-Static|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug|Win32.Build.0 = Debug-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release|Win32.ActiveCfg = Release-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release|Win32.Build.0 = Release-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug|Win32.Build.0 = Debug-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release|Win32.ActiveCfg = Release-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release|Win32.Build.0 = Release-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug|Win32.Build.0 = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release|Win32.ActiveCfg = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release|Win32.Build.0 = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug|Win32.Build.0 = Debug-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release|Win32.ActiveCfg = Release-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release|Win32.Build.0 = Release-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug|Win32.Build.0 = Debug-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release|Win32.ActiveCfg = Release-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release|Win32.Build.0 = Release-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug|Win32.Build.0 = Debug-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release|Win32.ActiveCfg = Release-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release|Win32.Build.0 = Release-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug|Win32.Build.0 = Debug-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release|Win32.ActiveCfg = Release-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release|Win32.Build.0 = Release-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug|Win32.Build.0 = Debug-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release|Win32.ActiveCfg = Release-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release|Win32.Build.0 = Release-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug|Win32.Build.0 = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release|Win32.ActiveCfg = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release|Win32.Build.0 = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug|Win32.Build.0 = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release|Win32.ActiveCfg = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release|Win32.Build.0 = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug|Win32.Build.0 = Debug-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release|Win32.ActiveCfg = Release-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release|Win32.Build.0 = Release-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug|Win32.Build.0 = Debug-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release|Win32.ActiveCfg = Release-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release|Win32.Build.0 = Release-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug|Win32.Build.0 = Debug-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release|Win32.ActiveCfg = Release-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release|Win32.Build.0 = Release-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug|Win32.Build.0 = Debug-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release|Win32.ActiveCfg = Release-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release|Win32.Build.0 = Release-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug|Win32.Build.0 = Debug-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release|Win32.ActiveCfg = Release-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release|Win32.Build.0 = Release-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug|Win32.Build.0 = Debug-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release|Win32.ActiveCfg = Release-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release|Win32.Build.0 = Release-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug|Win32.Build.0 = Debug-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release|Win32.ActiveCfg = Release-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release|Win32.Build.0 = Release-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug|Win32.Build.0 = Debug-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release|Win32.ActiveCfg = Release-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release|Win32.Build.0 = Release-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug|Win32.Build.0 = Debug-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release|Win32.ActiveCfg = Release-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release|Win32.Build.0 = Release-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug|Win32.Build.0 = Debug-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release|Win32.ActiveCfg = Release-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release|Win32.Build.0 = Release-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug|Win32.ActiveCfg = Debug-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug|Win32.Build.0 = Debug-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release|Win32.ActiveCfg = Release-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release|Win32.Build.0 = Release-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.Build.0 = Release-Static|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/stable/Windows/project/vs2010express/vs2010express.suo b/stable/Windows/project/vs2010express/vs2010express.suo new file mode 100644 index 0000000000000000000000000000000000000000..24315f40c508561bf01d63d5cf5d0e6b4e3b4ba8 GIT binary patch literal 34304 zcmeHQeUMyLmG6N>AYvpqOu&RV30XI2dg!m|nF%JQzXp=bBttR`1V)CQnVv}}o$j%_ zXOfr@gGN3gZdeo+BP0+NP<9C}YjD9(ShclUx(k-ZD)FCn)v}h=+S=$A{sF@Ne)smB zdGn?}-krWLVCn5T{l4yd=iGaL_uO;Od+)p-zP#Y)kACC*|LL)%HJ)=lZ@zVb=UtZl z4Ol0Mbdkq%4pvBSzV+5ya;L|G)xV@ap&IxjWSxt~YXi*zvAxd&T>v^CbRlRS=-r_A zfaZhH^q%*ER)ekrT?~33s1bAts0p+Xv=nq1=>4EYpv9oeK}$d%05yXafR=%-04)do z73hPYzXq)UT?zUS=)<6uATOu|M9lfH^n(JRASeWC1%*NFAm-`7auw)m&__UPKoQVK zL2E(GL;7<~n>{)FifD_3CyQm?vj?@}JT-adPWE}WbG3BQzhD0Cm;66&I2V~-WFsQ= zfMd?H-LnqdN3fRg?3M={{x?AbS=-LxX#&H{+v`bs3Z5OFE>9ZEqUU=2ry!HsU#M}x z<={^&v)@pT8rj9+2K=*cG4+D)7;1q$3ndv+sEZ-&agvsJ&S_wOW8ZbkpE`Rk|Bw{^ z*(SUOb%D|Wl#zOX{a@vy4p8gV1MI)5|8qb4zdC-rv|g?MFGZeZAl?2?y~F-b9mM{> z1;qY;3yA%n`s^S`$)fr{x2XeE|EDg9f?}XJC;{pOT?4unv<|c$v;ouw>IQ8DZ36Xx zt^;ibeIC>cx*pUAx&d?}Xe;O@(9NKJ(8oY`f(Aghf|8&?&=6=C#8w{xje@p;(xC02 z9iR+oCnyWbfyO`|2jxM;X%RFIngHzru_v)Ne*&}@v=4L}Xg}zapaYw9L%J|Mq+m{l`W(P)0uQ}PfHIaEnv@3>cd@PC6(uSTZ*}S zisgK_u&2&;@#nJSS#yQ96jK$sR3WikCX*Us>yhOgR*_IV7o3aDi}=Sx+hVp!HDW#I zv%kh*CG?}m>_jiiqh}4l(ip;?8_)x@=$Se6r~a!udR& z!anA8lIA$cQ1GhXzYSc9x<5iev8}w8kiY9D{Da z8ATl5CUVzi+>G&u_<|x-UY`%4r4ov+U%}R5|C= z5!$qarA<43+8-Qy$G|rY39?nW(^fsFfn_-lTb^!U4 zFR$m6|9g@5L#2*0f^s%v#G>^xj<(NWYYX;`Lk5<=Ss=Rw=4Yf!7?XBV4_6?1V6;p*`%S2`T?LkWp zqOEClR8GL(WZ!d&KiXjGigy0p=zByM=ONQ|uR3G;awYiFW@Vpp%AftUw{#gh|ML3B zDoN?Y(jtWZM}5LE%qjmSEj`lcu}Z&viaDNU_rMslQK-=i+%+`y_4SJhqrIrP?X z)VaK}wWK}Z$vH_iP3S}Un^7Lx{Z7kI-@t#BfFB2sO8nJaEG{%l5@*d!E#OZJl)RZ{ z=9sz1ia+Yv49c&{DC>Cyr5?pzj-Tqt%M7kbYo?N9)8=f5Vq}5ez<|)s|_&aHP%%=R;0+GW)pJq|!45aB47Kzlb z?(?7WcMO!QpiD&!9xQ`Fm~rzO*S!A03-@2R;mIX0|LUI(T}pR~@FC}(-oEVnw=Ugq z@7jO;?Ta^FvTVa^Pc*mxA<+H!gOAkG^sM)-eh@|&qUukX<6n6YWW$LAV?~&CC7=R4Z?bPYMs+q@IASLZ5X(#Qj zC}9-k8-llm_9s0K^gVQy`a?Cl8y6O7HuFE;vs=uY3`nZ~%l_62DaKLO;^h6HJZ!LP zHaO-Vb@jhK)J(HY3MrYhf82j+AO>kuJMI5L+ZIQM!P-&!+CbZNYfRF@Qcu z&dO?OK#o7MBg5! zK(3sn>X8XI4E4%Rd8HN?FM8=a>rXHD{BGdpA6_-`$ZPBkstVPzs@&?JX+1Bs{+Q^E z9Cs?&gQjLU9T@ezpbp?5jx|5lLfDRjf?}L(!#*EI#1@AmVgNZuaHhJC5XC4ujOv>5 zA;hq?7uRnCwd3m167LwcLPClVj@2Vs9Aj9QWt6ThQ{1>rQ=Y|2wnJ^HBCblMUrQk& zPe8OyK(t#7E#}2`0`1m;wGi4f46W%EE!&3C)hleQ1ab#UUL!wRm)03EHH;aD9CN7i z>2=x!qThZBFT5X5+m47Z!_}E>SG#>AlHHU{zl|i4P0C~r$!fmK%mA?2 zDrN+<{v%?Ivw}{6o2xGo{k6C1qXk?h<`8K4C9-@lOv9 z?NsXI0JJVG4xiAx^x=e|pJVv>pp$7&wjz&|$GJ}C8K$_JMY5Zc>9>)xF3i=IIV78` zDXUcawIq=o1TNbIibJp!f1*7e-~t=G@$Yz9CN$MjjkbiW~I3+IdX22A>ZuSTnx^(vd5Lr>j@ufHAaT1y}G zN;jxy1L~K_+6$Fua=QP$_8d*lp-tA5RVw{jlDeS-{hS^bsSnuuBhU$P^ndCG&ZgzO zI$qKj5ivS(zL5YbWzG6=w%#1tBv(6LX4^h;4(+C7`fVhUY*HpGW@cMc63K2!rC&>? zW*%+8u`ZJ9pLtAiHH&07CDU&sQ!|gL+A@b^lQm_PO23xW%tQKi=%1vX^@8Yclrs=4K432w_=?$4|;~^`Q+R~PbUY2uIIhy`nj4#vYV3Ww~?|g%(amfGxh0YlQm_P zO23vQk~yEC$DQ|9I)G2FKyjzADL98FYH4wBjkD=?e zNN&^A$x-wJQ(R3W**(eh+ejhVoJ=N>?2c6WwIq>j@_x5-zh*72)xAz;v8(5q(vwWT zRU~#z%480^Zb_wIOUg3#!CIh=8-`AeLgRKqBL}gE-ikQZc*mbuqvqurEnz-ILaj~P zf)SWIMq-9K95C(pU>LpEcC8E=+PYi)1$? z({Ce*WRo&kF;kzN?3PsewIq?u=Y@z<&fBP6iR6I5Dv``*3yJP_VP{B-neX55c_F_b ziDcd92~Bb}i)1$?({Ce*WRo(PL$X^^>DQ7(avShUtAg)=(XT>}n|%9^Nai~I8ALaA zHth`N3X5~7o#{{3f6~GvSF=cVQ!@QFl1MfwlQ|^2C6#_H@xA8=-qB`!Fh<{r;jLFj z?d6lmjaWKGNGT8)&Uic0^oXU?V@}AeqKFSr={;n3;%`ltW1!+&&_&d``S@Eh{%fts zWA4NYD&W28op=M5kw+LsiLqh0WON`#1>c4(Cy}SziLO*$I&0*oN;o;{N=wz2X8`XP zJCCw--&vJXwy3lAJakqhW5f-o2y-VQ6}1f`-3%c1##C&g@~EN&Kl#e(jSqVsd-Uj= zjSPV((k)lK-t|=9?>4+JdieB-frZPslks`$jYsr@J8pmV=`)Y5z4NQPzOm|~O&)uE zqMhSUul=7B?dy-Ve>wkBtZ~lKh3mb~{o<94pWnE@_r=3an<)q5DB9()$3e1R_n}3< zdEx(_>)r6=b$2i5^DPvSTjrFxjy---EqPb$zU$0a+F7K&DPdwiJy(8Cr?bK!Ke|GgkhDVuIx&P()<5#|N zbTD%JzBhjpetjVa)mdFI+L%G`7PPGeV1@izA) zwmxrj&(7-eHutpSYf2#| zdpEdLI46!b;V z5fJ0uJp_6f#JtC_e5ADg4_JN~^aSXurG1Z=mS4m2>!2q=e_z_i^PQw`mGVDVS~@xB z&n=Jr9+y7$%=wn}dDrg^w0`eE_xnDz!wkwe`&||1?nNN8zQnk=_W2sG$VsAgp22+f z`KdjgF3)3FR{QmI}^VlwovuyRV*vrR!PTGa}tf^ewXzTHr>odPUQLpz`-AB^VJ^UsVzfQ%7 zh4SkZ{qV^$+HyaR$mp&7pB@EY#bcg}Vy&&B5$snS6yDzy?tX>f2Ul02AE~$ERTxir z5YnXJTVO0veyL3Q)21Se$~`l`TISRPCtK&N_YA)Cq*7S6 z`!+M8efaH9#(Ld`Y;?oLE7s~v#N}}&ziUtswX?^95$ZfX$5OtJOkHULb;@txP=X`LQAIP(MFR)sGKU^%qk4 ziBx_dIk=}#Xu*zs`}W3t34f$D7WPJitsUM_BINgWM8iIBFc@y_2n1q*NFZ=qgGYqq zW+BpRYkU}MjdS_Sb;LOje0O8^g)`r}`M;O=K6~KAcgWLjLULcl6m`zOQbV7)d;FID z55}%NwrWju+x-naE5OXL47K84Ggf)EG@JO_U%>^5Gp1VnLo!>%f5zWljH63HEOf<; zmIIGreYCV)i$7zfS4*=g|D(8Iu5{5_{M)KA$1#?l#VJ+6R6`$S~vgO?AUX#B&$tv~%GZ$epn z2-nrc9W2%NT4qMp(|@8T4t^%%2e!bDQ(xDuHwL_0@#|`hKj9i}!13pD + + + + Debug + Win32 + + + Release + Win32 + + + + {3B52A2DE-8AF9-40F2-8CB3-9A91129FA2E7} + Win32Proj + vs2010express + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/vs2010express.vcxproj.filters b/stable/Windows/project/vs2010express/vs2010express.vcxproj.filters new file mode 100644 index 000000000..37c27d537 --- /dev/null +++ b/stable/Windows/project/vs2010express/vs2010express.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Заголовочные файлы + + + Заголовочные файлы + + + + + Файлы иÑходного кода + + + Файлы иÑходного кода + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/vs2010express.vcxproj.user b/stable/Windows/project/vs2010express/vs2010express.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/vs2010express.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc.vcproj b/stable/Windows/project/vs2010express/xmlrpc.vcproj new file mode 100644 index 000000000..b5804cf41 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc.vcproj @@ -0,0 +1,770 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc.vcxproj b/stable/Windows/project/vs2010express/xmlrpc.vcxproj new file mode 100644 index 000000000..350056b19 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc.vcxproj @@ -0,0 +1,438 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc + {226AB06F-60CA-4B21-9040-C6ECC0581522} + libxmlrpc + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + NotSet + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + NotSet + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {40b0756d-afee-4a38-9f38-a372ce431404} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc.vcxproj.filters new file mode 100644 index 000000000..426f4daf9 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc.vcxproj.filters @@ -0,0 +1,98 @@ + + + + + {7ba6ba0b-5e14-4a4e-a655-a2117da5f14c} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc + + + {ace2259f-e281-4bac-a92d-05106c0956b7} + h;hpp;hxx;hm;inl + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc__.vcproj b/stable/Windows/project/vs2010express/xmlrpc__.vcproj new file mode 100644 index 000000000..4206b032a --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc__.vcproj @@ -0,0 +1,2430 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc__.vcxproj b/stable/Windows/project/vs2010express/xmlrpc__.vcxproj new file mode 100644 index 000000000..70c37263d --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc__.vcxproj @@ -0,0 +1,482 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc++ + {3E7064F3-6200-4C39-85BE-775931D21828} + xmlrpc++ + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {e98186cb-f1b0-40a6-87a5-77b13a3f1600} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc__.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc__.vcxproj.filters new file mode 100644 index 000000000..a2bf2a8fb --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc__.vcxproj.filters @@ -0,0 +1,140 @@ + + + + + {e0ec1689-aae9-4f03-9c1a-d6af7b5e4786} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc + + + {1b40cc94-4f18-4dae-a340-9064f2748356} + h;hpp;hxx;hm;inl + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc__.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc__.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc__.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_abyss.vcproj b/stable/Windows/project/vs2010express/xmlrpc_abyss.vcproj new file mode 100644 index 000000000..6e281ef78 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_abyss.vcproj @@ -0,0 +1,2276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj b/stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj new file mode 100644 index 000000000..316cf96e2 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj @@ -0,0 +1,472 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_abyss + {20A8F64B-F738-4D32-A798-A65AD8291541} + xmlrpc_abyss + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib %(AdditionalOptions) + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib %(AdditionalOptions) + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib %(AdditionalOptions) + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib %(AdditionalOptions) + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.filters new file mode 100644 index 000000000..bee0fab2d --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.filters @@ -0,0 +1,140 @@ + + + + + {2fe8d434-30aa-44b1-9cab-5a05e3fd9da6} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {c891c99d-77cb-41ea-9015-c88ecce64065} + h;hpp;hxx;hm;inl + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.user new file mode 100644 index 000000000..6e2aec7ae --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_client.vcproj b/stable/Windows/project/vs2010express/xmlrpc_client.vcproj new file mode 100644 index 000000000..e35fdb5dd --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_client.vcproj @@ -0,0 +1,724 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_client.vcxproj b/stable/Windows/project/vs2010express/xmlrpc_client.vcxproj new file mode 100644 index 000000000..08844cb0c --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_client.vcxproj @@ -0,0 +1,428 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_client + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + libxmlrpc_client + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wininet.lib;%(AdditionalDependencies) + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wininet.lib;%(AdditionalDependencies) + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_client.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc_client.vcxproj.filters new file mode 100644 index 000000000..4432089b6 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_client.vcxproj.filters @@ -0,0 +1,62 @@ + + + + + {da1113f6-bb68-4b77-bf28-50f90042f5ba} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc + + + {9379c908-e99b-4868-b75b-caa13139f18e} + h;hpp;hxx;hm;inl + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_client.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc_client.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_client.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server.vcproj b/stable/Windows/project/vs2010express/xmlrpc_server.vcproj new file mode 100644 index 000000000..05e35f0d6 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server.vcproj @@ -0,0 +1,708 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_server.vcxproj b/stable/Windows/project/vs2010express/xmlrpc_server.vcxproj new file mode 100644 index 000000000..c82deea29 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server.vcxproj @@ -0,0 +1,421 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_server + {74B67128-BC84-4BCB-A256-9286B6371552} + libxmlrpc_server + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc_server.vcxproj.filters new file mode 100644 index 000000000..8685df386 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server.vcxproj.filters @@ -0,0 +1,53 @@ + + + + + {98f0c562-c723-44d4-8265-509fc4d0793f} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc + + + {e560ea87-f609-4ffe-b12d-9048ef152de6} + h;hpp;hxx;hm;inl + + + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc_server.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcproj b/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcproj new file mode 100644 index 000000000..ce02c2943 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcproj @@ -0,0 +1,704 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj b/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj new file mode 100644 index 000000000..5b1ceb9a2 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj @@ -0,0 +1,428 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_server_abyss + {E98186CB-F1B0-40A6-87A5-77B13A3F1600} + libxmlrpc_server_abyss + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.filters new file mode 100644 index 000000000..164423cfa --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.filters @@ -0,0 +1,50 @@ + + + + + {c6beca11-dace-4a60-9e79-68a2573517f8} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc + + + {a05de9d2-31db-4777-9b4a-22d71cca26b2} + h;hpp;hxx;hm;inl + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcproj b/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcproj new file mode 100644 index 000000000..39e4ff289 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcproj @@ -0,0 +1,696 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj b/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj new file mode 100644 index 000000000..2bc73f722 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj @@ -0,0 +1,422 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_server_cgi + {A2AAAF37-F382-4A11-8D86-53B589921616} + libxmlrpc_server_cgi + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.filters new file mode 100644 index 000000000..6a577d5a3 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + {eedbc6b9-1776-449c-b523-0272aadada5e} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc + + + {a3db0447-e924-4ba9-88e0-e957f7d46f12} + h;hpp;hxx;hm;inl + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcproj b/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcproj new file mode 100644 index 000000000..3029a8919 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcproj @@ -0,0 +1,700 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj b/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj new file mode 100644 index 000000000..5081386ba --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj @@ -0,0 +1,423 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_server_w32httpsys + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} + libxmlrpc_server_w32httpsys + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.filters new file mode 100644 index 000000000..fb2577652 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {c8071e7f-a99b-4320-9b1a-7c6cc15eed44} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc + + + {c61ba18d-d4b1-4a4d-bd76-49583e5fb2d0} + h;hpp;hxx;hm;inl + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_util.vcproj b/stable/Windows/project/vs2010express/xmlrpc_util.vcproj new file mode 100644 index 000000000..259740242 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_util.vcproj @@ -0,0 +1,764 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_util.vcxproj b/stable/Windows/project/vs2010express/xmlrpc_util.vcxproj new file mode 100644 index 000000000..ab913a907 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_util.vcxproj @@ -0,0 +1,438 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_util + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + libxmlrpc_util + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + NotSet + true + $(OutDir)$(ProjectName).pdb + true + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + NotSet + true + $(OutDir)$(ProjectName).pdb + true + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + NotSet + true + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + NotSet + true + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_util.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc_util.vcxproj.filters new file mode 100644 index 000000000..0d8d717c6 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_util.vcxproj.filters @@ -0,0 +1,86 @@ + + + + + {891eb28b-6895-4b33-8ddb-51d5c9a8be5f} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc + + + {deb57323-308f-49f5-b527-1760d95ab89f} + h;hpp;hxx;hm;inl + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_util.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc_util.vcxproj.user new file mode 100644 index 000000000..f5e1823bd --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_util.vcxproj.user @@ -0,0 +1,6 @@ + + + + false + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcproj b/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcproj new file mode 100644 index 000000000..a7048291d --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcproj @@ -0,0 +1,747 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj b/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj new file mode 100644 index 000000000..fe888b734 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj @@ -0,0 +1,413 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_xmlparse + {40B0756D-AFEE-4A38-9F38-A372CE431404} + xmlparse + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + false + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + false + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib/util/include;../../../include;../../../lib/expat/xmltok;../../../lib/expat/xmlwf;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {bd9f6041-a272-462d-8c41-87cef1f11408} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.filters new file mode 100644 index 000000000..5125369c5 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {28aa86ac-4de8-468e-91f0-423092a981ef} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90 + + + {2c49a70c-181b-438a-b095-9edd602e690f} + h;hpp;hxx;hm;inl;fi;fd + + + {2afaacc0-9676-41dc-aba3-fe726ab15dfb} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.user new file mode 100644 index 000000000..2c48fb598 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.user @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcproj b/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcproj new file mode 100644 index 000000000..b6227a153 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcproj @@ -0,0 +1,849 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj b/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj new file mode 100644 index 000000000..9986e3a88 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj @@ -0,0 +1,415 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_xmltok + {BD9F6041-A272-462D-8C41-87CEF1F11408} + xmltok + + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + StaticLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + DynamicLibrary + v100 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26730.3 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + + + + Disabled + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + {99bd200e-a4d5-4ed4-9d00-a6a19efe1412} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.filters b/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.filters new file mode 100644 index 000000000..364e94ba7 --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.filters @@ -0,0 +1,51 @@ + + + + + {1cad20ff-e903-4647-bb2c-fa93de37be3c} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90 + + + {0de6fd22-54e7-4338-82ac-f4fec07bde99} + h;hpp;hxx;hm;inl;fi;fd + + + {356469e0-2d7e-42fd-b712-57e23c58124c} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.user b/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/stable/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/cpptest.vcxproj b/stable/Windows/project/vs2017/cpptest.vcxproj new file mode 100644 index 000000000..21119857f --- /dev/null +++ b/stable/Windows/project/vs2017/cpptest.vcxproj @@ -0,0 +1,562 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856} + cpptest + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + + /D INTERNAL_EXPAT %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + /D INTERNAL_EXPAT %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + /D INTERNAL_EXPAT %(AdditionalOptions) + Disabled + ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + /D INTERNAL_EXPAT %(AdditionalOptions) + Disabled + ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + /D INTERNAL_EXPAT %(AdditionalOptions) + Disabled + ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + /D INTERNAL_EXPAT %(AdditionalOptions) + Disabled + ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + /D INTERNAL_EXPAT %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + /D INTERNAL_EXPAT %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {08cc5327-8e78-4768-9edb-c17649092ae1} + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {08cc5327-8e78-4768-9edb-c07649092ae1} + + + {3e7064f3-6200-4c39-85be-775931d21828} + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/gennmtab.vcxproj b/stable/Windows/project/vs2017/gennmtab.vcxproj new file mode 100644 index 000000000..211ef60c5 --- /dev/null +++ b/stable/Windows/project/vs2017/gennmtab.vcxproj @@ -0,0 +1,539 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412} + gennmtab + + + + Application + v141 + false + + + Application + v141 + false + + + Application + v141 + false + + + Application + v141 + false + + + Application + v141 + false + + + Application + v141 + false + + + Application + v141 + false + + + Application + v141 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + true + MinimumRecommendedRules.ruleset + + + + + + $(OutDir)$(ProjectName).tlb + + + + Disabled + ../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + (D) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + X64 + $(OutDir)$(ProjectName).tlb + + + + Disabled + ../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + (D) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + $(OutDir)$(ProjectName).tlb + + + + MaxSpeed + OnlyExplicitInline + ../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + (R) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + X64 + $(OutDir)$(ProjectName).tlb + + + + MaxSpeed + OnlyExplicitInline + ../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + (R) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + $(OutDir)$(ProjectName).tlb + + + + Disabled + ../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + (D) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + X64 + $(OutDir)$(ProjectName).tlb + + + + Disabled + ../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + (D) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + $(OutDir)$(ProjectName).tlb + + + + MaxSpeed + OnlyExplicitInline + ../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + (R) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + X64 + $(OutDir)$(ProjectName).tlb + + + + MaxSpeed + OnlyExplicitInline + ../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + (R) Generating nametab.h ... + $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h + + + + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/rpctest.vcxproj b/stable/Windows/project/vs2017/rpctest.vcxproj new file mode 100644 index 000000000..2d49e5544 --- /dev/null +++ b/stable/Windows/project/vs2017/rpctest.vcxproj @@ -0,0 +1,614 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722} + rpctest + 10.0.14393.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $OutDir)\data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $OutDir)\data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $(OutDir)data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $(OutDir)data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $OutDir)\data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $OutDir)\data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $(OutDir)data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + Copy test files + if not exist $(OutDir)data md $(OutDir)data +copy ..\..\..\test\data\*.* $(OutDir)data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {e98186cb-f1b0-40a6-87a5-77b13a3f1600} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {40b0756d-afee-4a38-9f38-a372ce431404} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/sample_add_asynch_client.vcxproj b/stable/Windows/project/vs2017/sample_add_asynch_client.vcxproj new file mode 100644 index 000000000..fc4edec5a --- /dev/null +++ b/stable/Windows/project/vs2017/sample_add_asynch_client.vcxproj @@ -0,0 +1,525 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652} + sample_add_asynch_client + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + odbc32.lib;odbccp32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + odbc32.lib;odbccp32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/sample_add_server.vcxproj b/stable/Windows/project/vs2017/sample_add_server.vcxproj new file mode 100644 index 000000000..517d109f5 --- /dev/null +++ b/stable/Windows/project/vs2017/sample_add_server.vcxproj @@ -0,0 +1,505 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {BEEB1B9C-BAF4-4B54-AB51-891156301702} + sample_add_server + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {e98186cb-f1b0-40a6-87a5-77b13a3f1600} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/sample_add_server_w32httpsys.vcxproj b/stable/Windows/project/vs2017/sample_add_server_w32httpsys.vcxproj new file mode 100644 index 000000000..61fdc3e31 --- /dev/null +++ b/stable/Windows/project/vs2017/sample_add_server_w32httpsys.vcxproj @@ -0,0 +1,505 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {B6887828-9480-4D4D-9CFC-AE4980D41707} + sample_add_server_w32httpsys + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {0eecb080-fc8f-4c46-9fb7-5db22f9d1622} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/sample_add_sync_client.vcxproj b/stable/Windows/project/vs2017/sample_add_sync_client.vcxproj new file mode 100644 index 000000000..ca2c0d857 --- /dev/null +++ b/stable/Windows/project/vs2017/sample_add_sync_client.vcxproj @@ -0,0 +1,505 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710} + sample_add_sync_client + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/sample_auth_client.vcxproj b/stable/Windows/project/vs2017/sample_auth_client.vcxproj new file mode 100644 index 000000000..9c364159f --- /dev/null +++ b/stable/Windows/project/vs2017/sample_auth_client.vcxproj @@ -0,0 +1,505 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714} + sample_auth_client + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/tool_xmlrpc-transport.vcxproj b/stable/Windows/project/vs2017/tool_xmlrpc-transport.vcxproj new file mode 100644 index 000000000..a9270c6a3 --- /dev/null +++ b/stable/Windows/project/vs2017/tool_xmlrpc-transport.vcxproj @@ -0,0 +1,543 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + xmlrpc_transport + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942} + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/tool_xmlrpc.vcxproj b/stable/Windows/project/vs2017/tool_xmlrpc.vcxproj new file mode 100644 index 000000000..7eb710d07 --- /dev/null +++ b/stable/Windows/project/vs2017/tool_xmlrpc.vcxproj @@ -0,0 +1,539 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + xmlrpc + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940} + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + Disabled + ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + true + $(OutDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).exe + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc.sln b/stable/Windows/project/vs2017/xmlrpc.sln new file mode 100644 index 000000000..1ddb5c19a --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc.sln @@ -0,0 +1,442 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmlparse", "xmlrpc_xmlparse.vcxproj", "{40B0756D-AFEE-4A38-9F38-A372CE431404}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmltok", "xmlrpc_xmltok.vcxproj", "{BD9F6041-A272-462D-8C41-87CEF1F11408}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennmtab", "gennmtab.vcxproj", "{99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_util", "xmlrpc_util.vcxproj", "{29FBABB6-E36A-4559-9514-B3DAF6AE1416}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc", "xmlrpc.vcxproj", "{226AB06F-60CA-4B21-9040-C6ECC0581522}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_abyss", "xmlrpc_abyss.vcxproj", "{20A8F64B-F738-4D32-A798-A65AD8291541}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server", "xmlrpc_server.vcxproj", "{74B67128-BC84-4BCB-A256-9286B6371552}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_abyss", "xmlrpc_server_abyss.vcxproj", "{E98186CB-F1B0-40A6-87A5-77B13A3F1600}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_cgi", "xmlrpc_server_cgi.vcxproj", "{A2AAAF37-F382-4A11-8D86-53B589921616}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_w32httpsys", "xmlrpc_server_w32httpsys.vcxproj", "{0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_client", "xmlrpc_client.vcxproj", "{28BB53D9-D487-41DF-BBB3-FDB5846D1630}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_asynch_client", "sample_add_asynch_client.vcxproj", "{2D4A179E-E2BA-4ED9-934E-7E54C08F1652}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server", "sample_add_server.vcxproj", "{BEEB1B9C-BAF4-4B54-AB51-891156301702}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server_w32httpsys", "sample_add_server_w32httpsys.vcxproj", "{B6887828-9480-4D4D-9CFC-AE4980D41707}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_sync_client", "sample_add_sync_client.vcxproj", "{A7A81BBD-C84D-479A-A9BD-194ADA3B1710}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_auth_client", "sample_auth_client.vcxproj", "{29A2BBC4-9ED9-4162-817C-FEEB36FB1714}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpctest", "rpctest.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc++", "xmlrpc__.vcxproj", "{3E7064F3-6200-4C39-85BE-775931D21828}" + ProjectSection(ProjectDependencies) = postProject + {08CC5327-8E78-4768-9EDB-C07649092AE1} = {08CC5327-8E78-4768-9EDB-C07649092AE1} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpptest", "cpptest.vcxproj", "{26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}" + ProjectSection(ProjectDependencies) = postProject + {08CC5327-8E78-4768-9EDB-C07649092AE1} = {08CC5327-8E78-4768-9EDB-C07649092AE1} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "tool_xmlrpc.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc_transport", "tool_xmlrpc-transport.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_util++", "xmlrpc_util__.vcxproj", "{08CC5327-8E78-4768-9EDB-C07649092AE1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_abyss++", "xmlrpc_abyss__.vcxproj", "{08CC5327-8E78-4768-9EDB-C17649092AE1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug-DLL|Win32 = Debug-DLL|Win32 + Debug-DLL|x64 = Debug-DLL|x64 + Debug-Static|Win32 = Debug-Static|Win32 + Debug-Static|x64 = Debug-Static|x64 + Release-DLL|Win32 = Release-DLL|Win32 + Release-DLL|x64 = Release-DLL|x64 + Release-Static|Win32 = Release-Static|Win32 + Release-Static|x64 = Release-Static|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|x64.Build.0 = Release-Static|x64 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|x64.Build.0 = Release-Static|x64 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|x64.Build.0 = Release-Static|x64 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|x64.Build.0 = Release-Static|x64 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|x64.Build.0 = Release-Static|x64 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|x64.Build.0 = Release-Static|x64 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|x64.Build.0 = Release-Static|x64 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|x64.Build.0 = Release-Static|x64 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|x64.Build.0 = Release-Static|x64 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|x64.Build.0 = Release-Static|x64 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|x64.Build.0 = Release-Static|x64 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|x64.Build.0 = Release-Static|x64 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|x64.Build.0 = Release-Static|x64 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|x64.Build.0 = Release-Static|x64 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|x64.Build.0 = Release-Static|x64 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|x64.Build.0 = Release-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|x64.Build.0 = Release-Static|x64 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|x64.Build.0 = Release-Static|x64 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|x64.Build.0 = Release-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|x64.Build.0 = Release-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|x64.Build.0 = Release-Static|x64 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-Static|x64.Build.0 = Release-Static|x64 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-Static|x64.Build.0 = Debug-Static|x64 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-Static|Win32.Build.0 = Release-Static|Win32 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-Static|x64.ActiveCfg = Release-Static|x64 + {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-Static|x64.Build.0 = Release-Static|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/stable/Windows/project/vs2017/xmlrpc.vcxproj b/stable/Windows/project/vs2017/xmlrpc.vcxproj new file mode 100644 index 000000000..441a4d8f8 --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc.vcxproj @@ -0,0 +1,462 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc + {226AB06F-60CA-4B21-9040-C6ECC0581522} + libxmlrpc + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + NotSet + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + NotSet + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {40b0756d-afee-4a38-9f38-a372ce431404} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc__.vcxproj b/stable/Windows/project/vs2017/xmlrpc__.vcxproj new file mode 100644 index 000000000..fcbdbd4ee --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc__.vcxproj @@ -0,0 +1,505 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc++ + {3E7064F3-6200-4C39-85BE-775931D21828} + xmlrpc++ + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {e98186cb-f1b0-40a6-87a5-77b13a3f1600} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {08cc5327-8e78-4768-9edb-c07649092ae1} + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_abyss.vcxproj b/stable/Windows/project/vs2017/xmlrpc_abyss.vcxproj new file mode 100644 index 000000000..c746bbdf9 --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_abyss.vcxproj @@ -0,0 +1,494 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_abyss + {20A8F64B-F738-4D32-A798-A65AD8291541} + xmlrpc_abyss + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib %(AdditionalOptions) + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib %(AdditionalOptions) + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib %(AdditionalOptions) + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib %(AdditionalOptions) + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_abyss__.vcxproj b/stable/Windows/project/vs2017/xmlrpc_abyss__.vcxproj new file mode 100644 index 000000000..06bf5ed7f --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_abyss__.vcxproj @@ -0,0 +1,479 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_abyss++ + {08CC5327-8E78-4768-9EDB-C17649092AE1} + libxmlrpc_abyss++ + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSSPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSSPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSSPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSSPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {e98186cb-f1b0-40a6-87a5-77b13a3f1600} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {08cc5327-8e78-4768-9edb-c07649092ae1} + + + {3e7064f3-6200-4c39-85be-775931d21828} + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_client.vcxproj b/stable/Windows/project/vs2017/xmlrpc_client.vcxproj new file mode 100644 index 000000000..25d549a5c --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_client.vcxproj @@ -0,0 +1,452 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_client + {28BB53D9-D487-41DF-BBB3-FDB5846D1630} + libxmlrpc_client + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wininet.lib;%(AdditionalDependencies) + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wininet.lib;%(AdditionalDependencies) + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_server.vcxproj b/stable/Windows/project/vs2017/xmlrpc_server.vcxproj new file mode 100644 index 000000000..1ad6427ad --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_server.vcxproj @@ -0,0 +1,445 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_server + {74B67128-BC84-4BCB-A256-9286B6371552} + libxmlrpc_server + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_server_abyss.vcxproj b/stable/Windows/project/vs2017/xmlrpc_server_abyss.vcxproj new file mode 100644 index 000000000..664a313b5 --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_server_abyss.vcxproj @@ -0,0 +1,452 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_server_abyss + {E98186CB-F1B0-40A6-87A5-77B13A3F1600} + libxmlrpc_server_abyss + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_server_cgi.vcxproj b/stable/Windows/project/vs2017/xmlrpc_server_cgi.vcxproj new file mode 100644 index 000000000..84599bc52 --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_server_cgi.vcxproj @@ -0,0 +1,446 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_server_cgi + {A2AAAF37-F382-4A11-8D86-53B589921616} + libxmlrpc_server_cgi + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_server_w32httpsys.vcxproj b/stable/Windows/project/vs2017/xmlrpc_server_w32httpsys.vcxproj new file mode 100644 index 000000000..d192c9613 --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_server_w32httpsys.vcxproj @@ -0,0 +1,447 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_server_w32httpsys + {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} + libxmlrpc_server_w32httpsys + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_util.vcxproj b/stable/Windows/project/vs2017/xmlrpc_util.vcxproj new file mode 100644 index 000000000..aae0bd3d4 --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_util.vcxproj @@ -0,0 +1,462 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_util + {29FBABB6-E36A-4559-9514-B3DAF6AE1416} + libxmlrpc_util + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + false + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + NotSet + true + $(OutDir)$(ProjectName).pdb + true + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + NotSet + true + $(OutDir)$(ProjectName).pdb + true + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + NotSet + true + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;%(AdditionalDependencies) + NotSet + true + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_util__.vcxproj b/stable/Windows/project/vs2017/xmlrpc_util__.vcxproj new file mode 100644 index 000000000..a9b497592 --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_util__.vcxproj @@ -0,0 +1,475 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_util++ + {08CC5327-8E78-4768-9EDB-C07649092AE1} + xmlrpc++ + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBUTILPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBUTILPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBUTILPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBUTILPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB + true + MultiThreadedDLL + true + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + {226ab06f-60ca-4b21-9040-c6ecc0581522} + false + + + {20a8f64b-f738-4d32-a798-a65ad8291541} + false + + + {28bb53d9-d487-41df-bbb3-fdb5846d1630} + false + + + {74b67128-bc84-4bcb-a256-9286b6371552} + false + + + {e98186cb-f1b0-40a6-87a5-77b13a3f1600} + false + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + + + + + + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_xmlparse.vcxproj b/stable/Windows/project/vs2017/xmlrpc_xmlparse.vcxproj new file mode 100644 index 000000000..9cb49d836 --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_xmlparse.vcxproj @@ -0,0 +1,437 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_xmlparse + {40B0756D-AFEE-4A38-9F38-A372CE431404} + xmlparse + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + false + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + false + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib/util/include;../../../include;../../../lib/expat/xmltok;../../../lib/expat/xmlwf;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + {29fbabb6-e36a-4559-9514-b3daf6ae1416} + false + + + {bd9f6041-a272-462d-8c41-87cef1f11408} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/project/vs2017/xmlrpc_xmltok.vcxproj b/stable/Windows/project/vs2017/xmlrpc_xmltok.vcxproj new file mode 100644 index 000000000..8399e9b80 --- /dev/null +++ b/stable/Windows/project/vs2017/xmlrpc_xmltok.vcxproj @@ -0,0 +1,439 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug-Static + Win32 + + + Debug-Static + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release-Static + Win32 + + + Release-Static + x64 + + + + libxmlrpc_xmltok + {BD9F6041-A272-462D-8C41-87CEF1F11408} + xmltok + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + DynamicLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.26228.10 + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + ..\..\..\bin\$(Configuration)-$(Platform)\ + ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ + MinimumRecommendedRules.ruleset + + + + + + Disabled + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(OutDir)$(ProjectName).pdb + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + $(OutDir)$(ProjectName).lib + MachineX64 + + + true + $(IntDir)$(ProjectName).bsc + + + + + Disabled + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + Disabled + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) + NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + + + {99bd200e-a4d5-4ed4-9d00-a6a19efe1412} + false + + + + + + \ No newline at end of file diff --git a/stable/Windows/xmlrpc_win32_config.h b/stable/Windows/xmlrpc_win32_config.h index a7a667d76..9a9ecb18d 100644 --- a/stable/Windows/xmlrpc_win32_config.h +++ b/stable/Windows/xmlrpc_win32_config.h @@ -260,4 +260,16 @@ #define XMLRPC_CHDIR chdir #endif +#if MSVCRT + #define XMLRPC_FINITE _finite +#else + #define XMLRPC_FINITE finite +#endif + +#if MSVCRT + #define XMLRPC_GETPID _getpid +#else + #define XMLRPC_GETPID getpid +#endif + #endif diff --git a/stable/common.mk b/stable/common.mk index db6f8bfcb..68dcfdf52 100644 --- a/stable/common.mk +++ b/stable/common.mk @@ -20,7 +20,7 @@ $(XMLRPC_MAJOR_RELEASE).$(XMLRPC_MINOR_RELEASE).$(XMLRPC_POINT_RELEASE) # fully made. .DELETE_ON_ERROR: -GCC_WARNINGS = -Wall -W -Wno-uninitialized -Wundef -Wimplicit \ +GCC_WARNINGS = -Wall -W -Wno-uninitialized -Wundef \ -Wno-unknown-pragmas # We need -Wwrite-strings after we fix all the missing consts # @@ -30,7 +30,7 @@ GCC_WARNINGS = -Wall -W -Wno-uninitialized -Wundef -Wimplicit \ # on -Wuninitialized for all the others. GCC_C_WARNINGS = $(GCC_WARNINGS) \ - -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes + -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wimplicit GCC_CXX_WARNINGS = $(GCC_WARNINGS) -Wsynth @@ -42,7 +42,7 @@ GCC_CXX_WARNINGS = $(GCC_WARNINGS) -Wsynth # execute() methods and not the other (as cpp/test/registry.cpp does), but the # code works fine. -# The NDEBUG macro says not to build code that assumes there are no bugs. +# The NDEBUG macro says not build the code to assume there are no bugs. # This makes the code go faster. The main thing it does is tell the C library # to make assert() a no-op as opposed to generating code to check the # assertion and crash the program if it isn't really true. You can add @@ -96,6 +96,9 @@ endif LDFLAGS_ALL = $(LDFLAGS_PTHREAD) $(LDFLAGS_PERSONAL) $(LDFLAGS) +LDFLAGS_FOR_BUILD_ALL = \ + $(LDFLAGS_PTHREAD) $(LDFLAGS_PERSONAL) $(LDFLAGS_FOR_BUILD) + ############################################################################## # STATIC LINK LIBRARY RULES # ############################################################################## @@ -325,10 +328,13 @@ ifneq ($(CADD),) CXXFLAGS := $(CADD) endif -CFLAGS_ALL = $(CFLAGS_COMMON) $(CFLAGS_LOCAL) \ +CFLAGS_ALL = $(CFLAGS_COMMON) $(CFLAGS_LOCAL) $(CFLAGS_TARGET) \ $(INCLUDES) $(CFLAGS_PERSONAL) $(CFLAGS) -CXXFLAGS_ALL = $(CXXFLAGS_COMMON) $(CFLAGS_LOCAL) \ +CFLAGS_ALL_FOR_BUILD = $(CFLAGS_COMMON) $(CFLAGS_LOCAL) $(CFLAGS_TARGET) \ + $(INCLUDES) $(CFLAGS_PERSONAL) $(CFLAGS_FOR_BUILD) + +CXXFLAGS_ALL = $(CXXFLAGS_COMMON) $(CFLAGS_LOCAL) $(CFLAGS_TARGET) \ $(INCLUDES) $(CFLAGS_PERSONAL) $(CXXFLAGS) @@ -380,6 +386,11 @@ $(SUBDIRS:%=%/install): %/install: $(CURDIR)/% $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ $(notdir $@) +.PHONY: $(SUBDIRS:%=%/uninstall) +$(SUBDIRS:%=%/uninstall): %/uninstall: $(CURDIR)/% + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + $(notdir $@) + .PHONY: $(SUBDIRS:%=%/clean) $(SUBDIRS:%=%/clean): %/clean: $(CURDIR)/% $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ @@ -567,6 +578,13 @@ $(SUBDIRS:%=$(CURDIR)/%): mkdir $@ +LIBDESTDIR = $(DESTDIR)$(LIBINST_DIR) +HEADERDESTDIR = $(DESTDIR)$(HEADERINST_DIR) +PROGRAMDESTDIR = $(DESTDIR)$(PROGRAMINST_DIR) +MANDESTDIR = $(DESTDIR)$(MANINST_DIR) +PKGCONFIGDESTDIR = $(DESTDIR)$(PKGCONFIGINST_DIR) + + ############################################################################## # INSTALL RULES # # (except shared libraries) # @@ -583,40 +601,35 @@ install-common: \ install-man \ install-pkgconfig \ -LIBDESTDIR = $(DESTDIR)$(LIBINST_DIR) INSTALL_LIB_CMD = $(INSTALL_DATA) $$p $(LIBDESTDIR)/$$p RANLIB_CMD = $(RANLIB) $(DESTDIR)$(LIBINST_DIR)/$$p install-static-libraries: $(STATIC_LIBRARIES_TO_INSTALL) $(MKINSTALLDIRS) $(LIBDESTDIR) - @list='$(STATIC_LIBRARIES_TO_INSTALL)'; for p in $$list; do \ - if test -f $$p; then \ + @list='$(STATIC_LIBRARIES_TO_INSTALL)'; \ + for p in $$list; do \ echo " $(INSTALL_LIB_CMD)"; \ $(INSTALL_LIB_CMD); \ - else :; fi; \ - done + done @$(POST_INSTALL) - @list='$(STATIC_LIBRARIES_TO_INSTALL)'; for p in $$list; do \ - if test -f $$p; then \ + @list='$(STATIC_LIBRARIES_TO_INSTALL)'; \ + for p in $$list; do \ echo " $(RANLIB_CMD)"; \ $(RANLIB_CMD); \ - else :; fi; \ - done + done -HEADERDESTDIR = $(DESTDIR)$(HEADERINST_DIR) -INSTALL_HDR_CMD = $(INSTALL_DATA) $$d$$p $(HEADERDESTDIR)/$$p +INSTALL_HDR_CMD = $(INSTALL_DATA) $$p $(HEADERDESTDIR)/$$p install-headers: $(HEADERS_TO_INSTALL) $(MKINSTALLDIRS) $(HEADERDESTDIR) $(MKINSTALLDIRS) $(HEADERDESTDIR)/xmlrpc-c - @list='$(HEADERS_TO_INSTALL)'; for p in $$list; do \ - if test -f "$$p"; then d= ; else d="$(SRCDIR)/$(SUBDIR)/"; fi; \ - echo " $(INSTALL_HDR_CMD)"; \ - $(INSTALL_HDR_CMD); \ - done - + @list='$(HEADERS_TO_INSTALL)'; \ + for p in $$list; do \ + echo " $(INSTALL_HDR_CMD)"; \ + $(INSTALL_HDR_CMD); \ + done -INSTALL_PROGRAM_CMD = $(INSTALL_PROGRAM) $$p $(DESTDIR)$(PROGRAMINST_DIR)/$$p +INSTALL_PROGRAM_CMD = $(INSTALL_PROGRAM) $$p $(PROGRAMDESTDIR)/$$p install-bin: $(PROGRAMS_TO_INSTALL) $(DESTDIR)$(PROGRAMINST_DIR) @list='$(PROGRAMS_TO_INSTALL)'; \ @@ -628,18 +641,16 @@ install-bin: $(PROGRAMS_TO_INSTALL) $(DESTDIR)$(PROGRAMINST_DIR) $(DESTDIR)$(PROGRAMINST_DIR): $(MKINSTALLDIRS) $@ -MANDESTDIR = $(DESTDIR)$(MANINST_DIR) INSTALL_MAN_CMD = $(INSTALL_DATA) $$p $(MANDESTDIR)/$$p install-man: $(MAN_FILES_TO_INSTALL) - $(MKINSTALLDIRS) $(MANDESTDIR) @list='$(MAN_FILES_TO_INSTALL)'; \ for p in $$list; do \ + $(MKINSTALLDIRS) $(MANDESTDIR) \ echo "$(INSTALL_MAN_CMD)"; \ $(INSTALL_MAN_CMD); \ done -PKGCONFIGDESTDIR = $(DESTDIR)$(PKGCONFIGINST_DIR) INSTALL_PKGCONFIG_CMD = $(INSTALL_DATA) $$p $(PKGCONFIGDESTDIR)/$$p install-pkgconfig: $(PKGCONFIG_FILES_TO_INSTALL) @@ -650,6 +661,68 @@ install-pkgconfig: $(PKGCONFIG_FILES_TO_INSTALL) $(INSTALL_PKGCONFIG_CMD); \ done + +############################################################################## +# UNINSTALL RULES # +############################################################################## + +RM = rm -f + +.PHONY: uninstall-common uninstall-headers uninstall-bin uninstall-man +uninstall-common: \ + uninstall-pkgconfig \ + uninstall-man \ + uninstall-bin \ + uninstall-headers \ + uninstall-shared-libraries \ + uninstall-static-libraries \ + +UNINSTALL_LIB_CMD = $(RM) $(LIBDESTDIR)/$$p + +uninstall-static-libraries: + @list='$(STATIC_LIBRARIES_TO_INSTALL)'; \ + for p in $$list; do \ + echo " $(UNINSTALL_LIB_CMD)"; \ + $(UNINSTALL_LIB_CMD); \ + done + +UNINSTALL_HDR_CMD = rm -f $(HEADERDESTDIR)/$$p + +uninstall-headers: + @list='$(HEADERS_TO_INSTALL)'; \ + for p in $$list; do \ + echo " $(UNINSTALL_HDR_CMD)"; \ + $(UNINSTALL_HDR_CMD); \ + done; + +UNINSTALL_PROGRAM_CMD = rm -f $(PROGRAMDESTDIR)/$$p + +uninstall-bin: + @list='$(PROGRAMS_TO_INSTALL)'; \ + for p in $$list; do \ + echo "$(UNINSTALL_PROGRAM_CMD)"; \ + $(UNINSTALL_PROGRAM_CMD); \ + done + +UNINSTALL_MAN_CMD = rm -f $(MANDESTDIR)/$$p + +uninstall-man: + @list='$(MAN_FILES_TO_INSTALL)'; \ + for p in $$list; do \ + echo "$(UNINSTALL_MAN_CMD)"; \ + $(UNINSTALL_MAN_CMD); \ + done + +UNINSTALL_PKGCONFIG_CMD = rm -f $(PKGCONFIGDESTDIR)/$$p + +uninstall-pkgconfig: + @list='$(PKGCONFIG_FILES_TO_INSTALL)'; \ + for p in $$list; do \ + echo "$(UNINSTALL_PKGCONFIG_CMD)"; \ + $(UNINSTALL_PKGCONFIG_CMD); \ + done + + ############################################################################## # MISCELLANEOUS RULES # ############################################################################## diff --git a/stable/config.mk.in b/stable/config.mk.in index 0d7c2f48b..f19ead43e 100644 --- a/stable/config.mk.in +++ b/stable/config.mk.in @@ -27,6 +27,7 @@ ENABLE_LIBXML2_BACKEND = @ENABLE_LIBXML2_BACKEND@ MUST_BUILD_WININET_CLIENT = @MUST_BUILD_WININET_CLIENT@ MUST_BUILD_CURL_CLIENT = @MUST_BUILD_CURL_CLIENT@ MUST_BUILD_LIBWWW_CLIENT = @MUST_BUILD_LIBWWW_CLIENT@ +MUST_BUILD_ABYSS_OPENSSL = @MUST_BUILD_ABYSS_OPENSSL@ BUILD_TOOLS = @BUILD_TOOLS@ BUILD_XMLRPC_PSTREAM = @BUILD_XMLRPC_PSTREAM@ WININET_LDADD = @WININET_LDADD@ @@ -356,17 +357,28 @@ endif # MISCELLANEOUS ############################################################################## -# BUILDTOOL_CC is the compiler to use to generate build tools, which we +# CC_FOR_BUILD is the compiler to use to generate build tools, which we # will then run to build the product. The typical reason this would be # different from CC is that you're cross-compiling: the product will run # in Environment A, but you're building in Environment B, so you must # build the build tools for Environment B. +# The build system uses CC_FOR_BUILD for linking as well. + +# The build system use CFLAGS_FOR_BUILD and LDFLAGS_FOR_BUILD when compiling +# and linking, respectively, build tools. + # The cross compiling user can update config.mk or override -# BUILDTOOL_CC on a make command. +# CC_FOR_BUILD on a make command. + +# LDFLAGS_FOR_BUILD is similar + +# These variable names are conventional. + +CC_FOR_BUILD = $(CC) +CFLAGS_FOR_BUILD = $(CFLAGS) +LDFLAGS_FOR_BUILD = $(LDFLAGS) -BUILDTOOL_CC = $(CC) -BUILDTOOL_CCLD = $(CCLD) ifeq ($(C_COMPILER_GNU),yes) CFLAGS_NO_INLINE_WARNING = -Wno-inline @@ -438,3 +450,7 @@ DESTDIR = # the read-only directory /usr/src/mypkg . VPATH := .:$(SRCDIR)/$(SUBDIR) + +HAVE_OPENSSL = @HAVE_OPENSSL@ +OPENSSL_LDADD = @OPENSSL_LDADD@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ diff --git a/stable/configure b/stable/configure index 86c47bf47..c1b3138d9 100755 --- a/stable/configure +++ b/stable/configure @@ -631,6 +631,10 @@ C_COMPILER_GNU ENABLE_LIBXML2_BACKEND have_xml2_config HAVE_LIBWWW_SSL_DEFINE +HAVE_ABYSS_OPENSSL_DEFINE +MUST_BUILD_ABYSS_OPENSSL +OPENSSL_CFLAGS +OPENSSL_LDADD CURL_LIBDIR CURL_LDADD CURL_CONFIG @@ -643,6 +647,24 @@ WININET_CFLAGS WININET_CONFIG ENABLE_ABYSS_THREADS DIRECTORY_SEPARATOR +HAVE__STRICMP_DEFINE +HAVE_STRICMP_DEFINE +HAVE_STRCASECMP_DEFINE +HAVE_GMTIME_R_DEFINE +HAVE_LOCALTIME_R_DEFINE +HAVE_GETTIMEOFDAY_DEFINE +HAVE_PSELECT_DEFINE +HAVE__STRTOUI64_DEFINE +HAVE___STRTOULL_DEFINE +HAVE___STRTOLL_DEFINE +HAVE_STRTOUQ_DEFINE +HAVE_STRTOQ_DEFINE +HAVE_STRTOULL_DEFINE +HAVE_STRTOLL_DEFINE +HAVE_SETENV_DEFINE +HAVE_ASPRINTF_DEFINE +HAVE_SETGROUPS_DEFINE +HAVE_WCSNCMP_DEFINE ATTR_UNUSED VA_LIST_IS_ARRAY_DEFINE HAVE_SYS_SELECT_H_DEFINE @@ -758,6 +780,7 @@ enable_abyss_server enable_cgi_server enable_cplusplus enable_abyss_threads +enable_abyss_openssl with_libwww_ssl enable_libxml2_backend ' @@ -1396,6 +1419,7 @@ Optional Features: --disable-cgi-server Don't build the CGI server module --disable-cplusplus Don't build the C++ wrapper classes or tools --disable-abyss-threads Use fork in Abyss instead of pthreads + --disable-abyss-openssl Don't build Abyss Openssl channel function --enable-libxml2-backend Use libxml2 instead of built-in expat Optional Packages: @@ -2288,11 +2312,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -ac_config_headers="$ac_config_headers xmlrpc_amconfig.h" - -ac_config_commands="$ac_config_commands default-1" - - ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -5344,6 +5363,12 @@ _ACEOF fi done +if test "x$ac_cv_func_wcsncmp" = x""yes; then + HAVE_WCSNCMP_DEFINE=1 +else + HAVE_WCSNCMP_DEFINE=0 +fi + for ac_func in setgroups do : @@ -5356,6 +5381,12 @@ _ACEOF fi done +if test "x$ac_cv_func_setgroups" = x""yes; then + HAVE_SETGROUPS_DEFINE=1 +else + HAVE_SETGROUPS_DEFINE=0 +fi + for ac_func in asprintf do : @@ -5368,19 +5399,156 @@ _ACEOF fi done +if test "x$ac_cv_func_asprintf" = x""yes; then + HAVE_ASPRINTF_DEFINE=1 +else + HAVE_ASPRINTF_DEFINE=0 +fi + + +for ac_func in setenv +do : + ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv" +if test "x$ac_cv_func_setenv" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SETENV 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_setenv" = x""yes; then + HAVE_SETENV_DEFINE=1 +else + HAVE_SETENV_DEFINE=0 +fi + + +for ac_func in strtoll +do : + ac_fn_c_check_func "$LINENO" "strtoll" "ac_cv_func_strtoll" +if test "x$ac_cv_func_strtoll" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRTOLL 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_strtoll" = x""yes; then + HAVE_STRTOLL_DEFINE=1 +else + HAVE_STRTOLL_DEFINE=0 +fi + -for ac_func in setenv strtoll strtoull strtoq strtouq __strtoll __strtoull +for ac_func in strtoull do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + ac_fn_c_check_func "$LINENO" "strtoull" "ac_cv_func_strtoull" +if test "x$ac_cv_func_strtoull" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define HAVE_STRTOULL 1 _ACEOF fi done +if test "x$ac_cv_func_strtoull" = x""yes; then + HAVE_STRTOULL_DEFINE=1 +else + HAVE_STRTOULL_DEFINE=0 +fi + + +for ac_func in strtoq +do : + ac_fn_c_check_func "$LINENO" "strtoq" "ac_cv_func_strtoq" +if test "x$ac_cv_func_strtoq" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRTOQ 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_strtoq" = x""yes; then + HAVE_STRTOQ_DEFINE=1 +else + HAVE_STRTOQ_DEFINE=0 +fi + + +for ac_func in strtouq +do : + ac_fn_c_check_func "$LINENO" "strtouq" "ac_cv_func_strtouq" +if test "x$ac_cv_func_strtouq" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRTOUQ 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_strtouq" = x""yes; then + HAVE_STRTOUQ_DEFINE=1 +else + HAVE_STRTOUQ_DEFINE=0 +fi + + +for ac_func in __strtoll +do : + ac_fn_c_check_func "$LINENO" "__strtoll" "ac_cv_func___strtoll" +if test "x$ac_cv_func___strtoll" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE___STRTOLL 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func___strtoll" = x""yes; then + HAVE___STRTOLL_DEFINE=1 +else + HAVE___STRTOLL_DEFINE=0 +fi + + +for ac_func in __strtoull +do : + ac_fn_c_check_func "$LINENO" "__strtoull" "ac_cv_func___strtoull" +if test "x$ac_cv_func___strtoull" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE___STRTOULL 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func___strtoull" = x""yes; then + HAVE___STRTOULL_DEFINE=1 +else + HAVE___STRTOULL_DEFINE=0 +fi + + +for ac_func in _strtoui64 +do : + ac_fn_c_check_func "$LINENO" "_strtoui64" "ac_cv_func__strtoui64" +if test "x$ac_cv_func__strtoui64" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE__STRTOUI64 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func__strtoui64" = x""yes; then + HAVE__STRTOUI64_DEFINE=1 +else + HAVE__STRTOUI64_DEFINE=0 +fi + for ac_func in pselect do : @@ -5393,6 +5561,12 @@ _ACEOF fi done +if test "x$ac_cv_func_pselect" = x""yes; then + HAVE_PSELECT_DEFINE=1 +else + HAVE_PSELECT_DEFINE=0 +fi + for ac_func in gettimeofday do : @@ -5405,6 +5579,13 @@ _ACEOF fi done +if test "x$ac_cv_func_gettimeofday" = x""yes; then + HAVE_GETTIMEOFDAY_DEFINE=1 +else + HAVE_GETTIMEOFDAY_DEFINE=0 +fi + + for ac_func in localtime_r do : ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r" @@ -5416,6 +5597,13 @@ _ACEOF fi done +if test "x$ac_cv_func_localtime_r" = x""yes; then + HAVE_LOCALTIME_R_DEFINE=1 +else + HAVE_LOCALTIME_R_DEFINE=0 +fi + + for ac_func in gmtime_r do : ac_fn_c_check_func "$LINENO" "gmtime_r" "ac_cv_func_gmtime_r" @@ -5427,6 +5615,12 @@ _ACEOF fi done +if test "x$ac_cv_func_gmtime_r" = x""yes; then + HAVE_GMTIME_R_DEFINE=1 +else + HAVE_GMTIME_R_DEFINE=0 +fi + for ac_func in strcasecmp do : @@ -5439,6 +5633,13 @@ _ACEOF fi done +if test "x$ac_cv_func_strcasecmp" = x""yes; then + HAVE_STRCASECMP_DEFINE=1 +else + HAVE_STRCASECMP_DEFINE=0 +fi + + for ac_func in stricmp do : ac_fn_c_check_func "$LINENO" "stricmp" "ac_cv_func_stricmp" @@ -5450,6 +5651,13 @@ _ACEOF fi done +if test "x$ac_cv_func_stricmp" = x""yes; then + HAVE_STRICMP_DEFINE=1 +else + HAVE_STRICMP_DEFINE=0 +fi + + for ac_func in _stricmp do : ac_fn_c_check_func "$LINENO" "_stricmp" "ac_cv_func__stricmp" @@ -5461,6 +5669,12 @@ _ACEOF fi done +if test "x$ac_cv_func__stricmp" = x""yes; then + HAVE__STRICMP_DEFINE=1 +else + HAVE__STRICMP_DEFINE=0 +fi + case "$host_os" in @@ -5757,6 +5971,65 @@ fi # MUST_BUILD_CURL_CLIENT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL library" >&5 +$as_echo_n "checking for OpenSSL library... " >&6; } + +if pkg-config openssl; then + HAVE_OPENSSL=yes + OPENSSL_LDADD=$(pkg-config openssl --libs) + + OPENSSL_CFLAGS=$(pkg-config openssl --cflags) + +else + HAVE_OPENSSL=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_OPENSSL" >&5 +$as_echo "$HAVE_OPENSSL" >&6; } + +# One really annoying case where the user needs to disable building of +# Openssl-based parts explicitly is where there is no Openssl for the target +# platform but there is for the native platform. In that case, Pkg-config +# finds the openssl.pc in /usr/lib, ignoring the fact that /usr/lib is not in +# the search path specified by the PKG_CONFIG environment variable. This is +# a major design flaw in Pkg-config. + +# Check whether --enable-abyss-openssl was given. +if test "${enable_abyss_openssl+set}" = set; then : + enableval=$enable_abyss_openssl; +else + enable_abyss_openssl=maybe +fi + + +if test $enable_abyss_openssl = maybe; then + if test $HAVE_OPENSSL = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: You don't appear to Openssl installed (no pkg-config file for it in your pkg-config search path), so we will not build the Abyss Openssl channel module" >&5 +$as_echo "$as_me: You don't appear to Openssl installed (no pkg-config file for it in your pkg-config search path), so we will not build the Abyss Openssl channel module" >&6;} + MUST_BUILD_ABYSS_OPENSSL=no + else + MUST_BUILD_ABYSS_OPENSSL=yes + fi +else + MUST_BUILD_ABYSS_OPENSSL=$enable_abyss_openssl +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Abyss Openssl channel module" >&5 +$as_echo_n "checking whether to build Abyss Openssl channel module... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MUST_BUILD_ABYSS_OPENSSL" >&5 +$as_echo "$MUST_BUILD_ABYSS_OPENSSL" >&6; } + + +if test $MUST_BUILD_ABYSS_OPENSSL = yes; then + HAVE_ABYSS_OPENSSL_DEFINE=1 +else + HAVE_ABYSS_OPENSSL_DEFINE=0 +fi + + + + + # Check whether --with-libwww-ssl was given. if test "${with_libwww_ssl+set}" = set; then : @@ -5853,9 +6126,189 @@ CPP_WARN_FLAGS= BUILDDIR=$(pwd) -AR=${ac_tool_prefix}ar +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS -RANLIB=${ac_tool_prefix}ranlib +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi @@ -5952,7 +6405,43 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -DEFS=-DHAVE_CONFIG_H +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + ac_libobjs= ac_ltlibobjs= @@ -6386,16 +6875,11 @@ case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" _ACEOF @@ -6416,18 +6900,10 @@ Usage: $0 [OPTION]... [TAG]... --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE Configuration files: $config_files -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - Report bugs to the package provider." _ACEOF @@ -6489,18 +6965,7 @@ do esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) + --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) @@ -6548,11 +7013,6 @@ _ASBOX _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# - - _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 @@ -6561,8 +7021,6 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in - "xmlrpc_amconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS xmlrpc_amconfig.h" ;; - "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; "srcdir.mk") CONFIG_FILES="$CONFIG_FILES srcdir.mk" ;; "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; "xmlrpc_config.h") CONFIG_FILES="$CONFIG_FILES xmlrpc_config.h" ;; @@ -6578,8 +7036,6 @@ done # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree @@ -6767,116 +7223,8 @@ fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +eval set X " :F $CONFIG_FILES " shift for ac_tag do @@ -7089,41 +7437,11 @@ which seems to be undefined. Please make sure it is defined" >&2;} esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi - ;; - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - case $ac_file$ac_mode in - "default-1":C) test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h ;; - esac + done # for ac_tag diff --git a/stable/configure.in b/stable/configure.in index 30a84c014..bb0e6432e 100644 --- a/stable/configure.in +++ b/stable/configure.in @@ -1,7 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(include/xmlrpc-c/base.h) -AM_CONFIG_HEADER(xmlrpc_amconfig.h) dnl ======================================================================= dnl Define PACKAGE, VERSION, @PACKAGE@, @VERSION@ @@ -359,26 +358,152 @@ AC_MSG_ERROR(your C library does not provide vsnprintf) dnl Unicode function needed by test suites. AC_CHECK_FUNCS(wcsncmp) +if test "x$ac_cv_func_wcsncmp" = x""yes; then + HAVE_WCSNCMP_DEFINE=1 +else + HAVE_WCSNCMP_DEFINE=0 +fi +AC_SUBST(HAVE_WCSNCMP_DEFINE) dnl CygWin doesn't provide setgroups. AC_CHECK_FUNCS(setgroups) +if test "x$ac_cv_func_setgroups" = x""yes; then + HAVE_SETGROUPS_DEFINE=1 +else + HAVE_SETGROUPS_DEFINE=0 +fi +AC_SUBST(HAVE_SETGROUPS_DEFINE) AC_CHECK_FUNCS(asprintf) +if test "x$ac_cv_func_asprintf" = x""yes; then + HAVE_ASPRINTF_DEFINE=1 +else + HAVE_ASPRINTF_DEFINE=0 +fi +AC_SUBST(HAVE_ASPRINTF_DEFINE) + +AC_CHECK_FUNCS(setenv) +if test "x$ac_cv_func_setenv" = x""yes; then + HAVE_SETENV_DEFINE=1 +else + HAVE_SETENV_DEFINE=0 +fi +AC_SUBST(HAVE_SETENV_DEFINE) + +AC_CHECK_FUNCS(strtoll) +if test "x$ac_cv_func_strtoll" = x""yes; then + HAVE_STRTOLL_DEFINE=1 +else + HAVE_STRTOLL_DEFINE=0 +fi +AC_SUBST(HAVE_STRTOLL_DEFINE) + +AC_CHECK_FUNCS(strtoull) +if test "x$ac_cv_func_strtoull" = x""yes; then + HAVE_STRTOULL_DEFINE=1 +else + HAVE_STRTOULL_DEFINE=0 +fi +AC_SUBST(HAVE_STRTOULL_DEFINE) + +AC_CHECK_FUNCS(strtoq) +if test "x$ac_cv_func_strtoq" = x""yes; then + HAVE_STRTOQ_DEFINE=1 +else + HAVE_STRTOQ_DEFINE=0 +fi +AC_SUBST(HAVE_STRTOQ_DEFINE) -AC_CHECK_FUNCS(setenv strtoll strtoull strtoq strtouq __strtoll __strtoull) +AC_CHECK_FUNCS(strtouq) +if test "x$ac_cv_func_strtouq" = x""yes; then + HAVE_STRTOUQ_DEFINE=1 +else + HAVE_STRTOUQ_DEFINE=0 +fi +AC_SUBST(HAVE_STRTOUQ_DEFINE) + +AC_CHECK_FUNCS(__strtoll) +if test "x$ac_cv_func___strtoll" = x""yes; then + HAVE___STRTOLL_DEFINE=1 +else + HAVE___STRTOLL_DEFINE=0 +fi +AC_SUBST(HAVE___STRTOLL_DEFINE) + +AC_CHECK_FUNCS(__strtoull) +if test "x$ac_cv_func___strtoull" = x""yes; then + HAVE___STRTOULL_DEFINE=1 +else + HAVE___STRTOULL_DEFINE=0 +fi +AC_SUBST(HAVE___STRTOULL_DEFINE) + +AC_CHECK_FUNCS(_strtoui64) +if test "x$ac_cv_func__strtoui64" = x""yes; then + HAVE__STRTOUI64_DEFINE=1 +else + HAVE__STRTOUI64_DEFINE=0 +fi +AC_SUBST(HAVE__STRTOUI64_DEFINE) dnl uclib doesn't have pselect AC_CHECK_FUNCS(pselect) +if test "x$ac_cv_func_pselect" = x""yes; then + HAVE_PSELECT_DEFINE=1 +else + HAVE_PSELECT_DEFINE=0 +fi +AC_SUBST(HAVE_PSELECT_DEFINE) dnl Windows doesn't have gettimeofday, localtime_r, or gmtime_r AC_CHECK_FUNCS(gettimeofday) +if test "x$ac_cv_func_gettimeofday" = x""yes; then + HAVE_GETTIMEOFDAY_DEFINE=1 +else + HAVE_GETTIMEOFDAY_DEFINE=0 +fi +AC_SUBST(HAVE_GETTIMEOFDAY_DEFINE) + AC_CHECK_FUNCS(localtime_r) +if test "x$ac_cv_func_localtime_r" = x""yes; then + HAVE_LOCALTIME_R_DEFINE=1 +else + HAVE_LOCALTIME_R_DEFINE=0 +fi +AC_SUBST(HAVE_LOCALTIME_R_DEFINE) + AC_CHECK_FUNCS(gmtime_r) +if test "x$ac_cv_func_gmtime_r" = x""yes; then + HAVE_GMTIME_R_DEFINE=1 +else + HAVE_GMTIME_R_DEFINE=0 +fi +AC_SUBST(HAVE_GMTIME_R_DEFINE) dnl Windows doesn't have strcasecmp; AC_CHECK_FUNCS(strcasecmp) +if test "x$ac_cv_func_strcasecmp" = x""yes; then + HAVE_STRCASECMP_DEFINE=1 +else + HAVE_STRCASECMP_DEFINE=0 +fi +AC_SUBST(HAVE_STRCASECMP_DEFINE) + AC_CHECK_FUNCS(stricmp) +if test "x$ac_cv_func_stricmp" = x""yes; then + HAVE_STRICMP_DEFINE=1 +else + HAVE_STRICMP_DEFINE=0 +fi +AC_SUBST(HAVE_STRICMP_DEFINE) + AC_CHECK_FUNCS(_stricmp) +if test "x$ac_cv_func__stricmp" = x""yes; then + HAVE__STRICMP_DEFINE=1 +else + HAVE__STRICMP_DEFINE=0 +fi +AC_SUBST(HAVE__STRICMP_DEFINE) dnl ======================================================================= dnl Checks for operating system features. @@ -563,6 +688,60 @@ if test $MUST_BUILD_CURL_CLIENT = yes; then fi # MUST_BUILD_CURL_CLIENT +dnl ======================================================================= +dnl Finding OpenSSL +dnl ======================================================================= + +AC_MSG_CHECKING(for OpenSSL library) + +if pkg-config openssl; then + HAVE_OPENSSL=yes + OPENSSL_LDADD=$(pkg-config openssl --libs) + AC_SUBST(OPENSSL_LDADD) + OPENSSL_CFLAGS=$(pkg-config openssl --cflags) + AC_SUBST(OPENSSL_CFLAGS) +else + HAVE_OPENSSL=no +fi + +AC_MSG_RESULT($HAVE_OPENSSL) + +# One really annoying case where the user needs to disable building of +# Openssl-based parts explicitly is where there is no Openssl for the target +# platform but there is for the native platform. In that case, Pkg-config +# finds the openssl.pc in /usr/lib, ignoring the fact that /usr/lib is not in +# the search path specified by the PKG_CONFIG environment variable. This is +# a major design flaw in Pkg-config. + +AC_ARG_ENABLE(abyss-openssl, + [ --disable-abyss-openssl Don't build Abyss Openssl channel function], + , + enable_abyss_openssl=maybe) + +if test $enable_abyss_openssl = maybe; then + if test $HAVE_OPENSSL = no; then + AC_MSG_NOTICE([You don't appear to Openssl installed (no pkg-config file for it in your pkg-config search path), so we will not build the Abyss Openssl channel module]) + MUST_BUILD_ABYSS_OPENSSL=no + else + MUST_BUILD_ABYSS_OPENSSL=yes + fi +else + MUST_BUILD_ABYSS_OPENSSL=$enable_abyss_openssl +fi + +AC_MSG_CHECKING(whether to build Abyss Openssl channel module) +AC_MSG_RESULT($MUST_BUILD_ABYSS_OPENSSL) +AC_SUBST(MUST_BUILD_ABYSS_OPENSSL) + +if test $MUST_BUILD_ABYSS_OPENSSL = yes; then + HAVE_ABYSS_OPENSSL_DEFINE=1 +else + HAVE_ABYSS_OPENSSL_DEFINE=0 +fi + +AC_SUBST(HAVE_ABYSS_OPENSSL_DEFINE) + + dnl ======================================================================= dnl Checks for build options. dnl ======================================================================= @@ -619,10 +798,8 @@ AC_SUBST(CPP_WARN_FLAGS) BUILDDIR=$(pwd) AC_SUBST(BUILDDIR) -AR=${ac_tool_prefix}ar -AC_SUBST([AR]) -RANLIB=${ac_tool_prefix}ranlib -AC_SUBST([RANLIB]) +AC_CHECK_TOOL([AR], [ar]) +AC_PROG_RANLIB dnl ======================================================================= dnl Output our results. diff --git a/stable/doc/INSTALL b/stable/doc/INSTALL index b6ad44682..2779b3aea 100644 --- a/stable/doc/INSTALL +++ b/stable/doc/INSTALL @@ -11,6 +11,10 @@ Essentially, it's just the conventional $ make $ make install +And on Linux systems, you'll usually also need: + + $ ldconfig + To build handy tools such as the 'xmlrpc' command line XML-RPC client: $ cd tools @@ -52,6 +56,36 @@ a significant amount of time. See './configure --help' for the options that disable certain transports. +LDCONFIG +-------- + +On systems that use the GNU C Library (usually Linux), you often have to run +the program 'ldconfig' after installing the shared libraries of Xmlrpc-c. If +you don't, when you try to run a program that uses an Xmlrpc-c library, you +get an error message telling you it can't find the library. + +This is because the usual way that the dynamic (shared) library loader finds +libraries is through the file /etc/ld.so.cache, which is a directory of most +of the shared libraries on the system. 'ldconfig' is what updates that +directory. It searches various places that shared libraries might be, +including the place you probably installed the Xmlrpc-c shared libraries, and +records all their locations, indexed by the library's soname. + +If you suspect a problem with your shared library lookup, you can use the +command + + $ ldconfig -p + +to list out the directory (i.e. the information in /etc/ld.so.cache). + +But this directory is not the only way the OS can find a shared library, so +'ldconfig' may not be required or helpful in your circumstance. Another way +to tell the OS how to find shared libraries is through the environment +variable LD_LIBRARY_PATH. If that value includes the directory in which you +installed the Xmlrpc-c libraries, the OS should be able to find them +regardless of what is in the directory. + + SEPARATE BUILD TREE ------------------- @@ -108,24 +142,44 @@ code and running that program as part of the build. That compile, unlike all the regular ones, must be done for the build machine, not the target machine. -To facilitate that, there are the BUILDTOOL_CC and BUILDTOOL_CCLD make -variables. BUILDTOOL_CC is the command name for the appropriate compiler -with which to build a build tool, i.e. a compiler that generates code to run -on the build system. BUILDTOOL_CCLD is similarly for the linker, and should -be the kind of linker command that invokes a combined compiler/linker, +To facilitate that, there are the make variables CC_FOR_BUILD, +CFLAGS_FOR_BUILD, and LDFLAGS_FOR_BUILD. + +CC_FOR_BUILD is the command name for the appropriate compiler with which to +build a build tool, i.e. a compiler that generates code to run on the build +system. It is also the command name for the linker, which obviously has to be +the the kind of linker command that invokes a combined compiler/linker, e.g. "gcc" instead of "ld". +CFLAGS_FOR_BUILD and LD_FLAGS_FOR_BUILD are options for the compile and +link commands, respectively, used to build build tools. + You can set these make variables on the Make command line, or if you prefer, by modifying the file 'config.mk' after 'configure' creates it. The default -value of these variables (as set in 'config.mk') is the same compile and link -commands as for building target code. +value of these variables (as set in 'config.mk') are the same as for building +target code. (There is probably a way to do this with GNU Autoconf facilities, using -'configure --build=XXX' and avoid the BUILDTOOL_CC complication. If you know +'configure --build=XXX' and avoid the CC_FOR_BUILD complication. If you know how (without using Automake), tell the Xmlrpc-c maintainer and he will change the build system to use it). +SKIPPING SHARED LIBRARY BUILD/INSTALL +------------------------------------- + +To build just the static libraries, not the shared (dynamically linked) +libraries, set make variable MUST_BUILD_SHLIB to "N": + + $ make MUST_BUILD_SHLIB=N + +You can add this setting to the bottom of the 'config.mk' file that +'configure' generates if that is more convenient. + +Alternatively, you could just build and install normally and delete the shared +libraries afterward. That normally works. + + COMMON PROBLEMS --------------- diff --git a/stable/examples/Makefile b/stable/examples/Makefile index 415ae7e37..9221491c8 100644 --- a/stable/examples/Makefile +++ b/stable/examples/Makefile @@ -52,10 +52,13 @@ ifneq ($(MSVCRT),yes) SERVERPROGS_ABYSS += interrupted_server endif +ifeq ($(MUST_BUILD_ABYSS_OPENSSL),yes) + SERVERPROGS_ABYSS += ssl_server ssl_secure_server +endif + BASIC_PROGS = \ json \ gen_sample_add_xml \ - parse_xml \ # Build up PROGS: PROGS = @@ -120,44 +123,29 @@ OBJECTS = $(patsubst %,%.o,$(patsubst %.cgi,%_cgi,$(PROGS))) $(OBJECTS):%.o:%.c $(CC) -c $(INCLUDES) $(CFLAGS_ALL) $< -# config.h and xmlrpc_amconfig.h just describe the build environment. -# We use them so that the example programs will build in users' -# various environments. If you're copying these examples, you can -# just remove these headers from the programs and hardcode whatever is -# right for your build environment. +# config.h just describes the build environment. We use it so that the +# example programs will build in users' various environments. If you're +# copying these examples, you can just remove this header from the programs +# and hardcode whatever is right for your build environment. -$(OBJECTS): config.h xmlrpc_amconfig.h +$(OBJECTS): config.h config.h: $(LN_S) $(BLDDIR)/xmlrpc_config.h $@ -xmlrpc_amconfig.h: - $(LN_S) $(BLDDIR)/$@ . .PHONY: clean clean: - rm -f $(PROGS) *.o config.h xmlrpc_amconfig.h + rm -f $(PROGS) *.o config.h $(MAKE) -C cpp clean .PHONY: distclean distclean: clean -BINDIR=$(DESTDIR)$(bindir) - -FILENAME_GENERATOR = "echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'" - -INSTCMD = "$(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p \ - $(BINDIR)/`$(FILENAME_GENERATOR)`" - .PHONY: install -install: $(PROGS) - @$(NORMAL_INSTALL) - $(MKINSTALLDIRS) $(BINDIR) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - if test -f $$p; then \ - echo "$(INSTCMD)"; $(INSTCMD); \ - else :; \ - fi; \ - done +install: + +.PHONY: uninstall +uninstall: .PHONY: check check: diff --git a/stable/examples/compound_value_client.c b/stable/examples/compound_value_client.c index 92baad1e4..057517d5d 100644 --- a/stable/examples/compound_value_client.c +++ b/stable/examples/compound_value_client.c @@ -20,7 +20,6 @@ Argument 0: Integer. Version number of this argument protocol. Must be 1. - Argument 1: Array. One element for each pair of numbers you want the server to divide. Each element is structure, with these members: diff --git a/stable/examples/cpp/Makefile b/stable/examples/cpp/Makefile index 1b1441b24..172a899a3 100644 --- a/stable/examples/cpp/Makefile +++ b/stable/examples/cpp/Makefile @@ -102,18 +102,16 @@ OBJECTS = $(patsubst %,%.o,$(patsubst %.cgi,%_cgi,$(PROGS))) $(OBJECTS):%.o:%.cpp $(CXX) -c $(INCLUDES) $(CXXFLAGS_ALL) $< -# See example/Makefile for an explanation of config.h and xmlrpc_amconfig.h +# See example/Makefile for an explanation of config.h -$(OBJECTS): config.h xmlrpc_amconfig.h +$(OBJECTS): config.h config.h: $(LN_S) $(BLDDIR)/xmlrpc_config.h $@ -xmlrpc_amconfig.h: - $(LN_S) $(BLDDIR)/$@ . .PHONY: clean clean: - rm -f $(PROGS) *.o config.h xmlrpc_amconfig.h + rm -f $(PROGS) *.o config.h .PHONY: distclean distclean: clean diff --git a/stable/examples/curl_client.c b/stable/examples/curl_client.c index 54dfc627d..691afc046 100644 --- a/stable/examples/curl_client.c +++ b/stable/examples/curl_client.c @@ -1,5 +1,17 @@ /* Same as xmlrpc_sample_add_client.c, except it demonstrates use of Curl - transport parameters, including timeout. + transport parameters, including timeout and SSL stuff. + + You specify the server URL as an argument, which can be an "http:" URL for + true XML-RPC or "https:" for the secure SSL/TLS variation of XML-RPC. + + Example that works with 'xmlrpc_sample_add_server' example server: + + $ ./curl_client http::/localhost:8080/RPC2 + + Example that works with 'ssl_server' example server: + + $ ./curl_client https::/localhost:8080/RPC2 + */ #define _XOPEN_SOURCE 600 @@ -66,16 +78,19 @@ int main(int const argc, const char ** const argv) { - const char * const serverUrl = "http://localhost:8080/RPC2"; + const char * serverUrl; xmlrpc_env env; struct xmlrpc_curl_xportparms transportParms; struct xmlrpc_clientparms clientParms; xmlrpc_client * clientP; - if (argc-1 > 0) { - fprintf(stderr, "This program has no arguments\n"); + if (argc-1 < 1) { + fprintf(stderr, "You must specify the server URL as an argument. " + "Example: http://localhost:8080/RPC2\n"); exit(1); + } else { + serverUrl = argv[1]; } /* Initialize our error-handling environment. */ @@ -86,8 +101,8 @@ main(int const argc, die_if_fault_occurred(&env); transportParms.network_interface = NULL; - transportParms.no_ssl_verifypeer = 0; - transportParms.no_ssl_verifyhost = 0; + transportParms.no_ssl_verifypeer = 1; + transportParms.no_ssl_verifyhost = 1; transportParms.user_agent = NULL; transportParms.ssl_cert = NULL; transportParms.sslcerttype = NULL; @@ -101,7 +116,7 @@ main(int const argc, transportParms.capath = NULL; transportParms.randomfile = NULL; transportParms.egdsocket= NULL; - transportParms.ssl_cipher_list= NULL; + transportParms.ssl_cipher_list= "ALL:eNULL:aNULL"; transportParms.timeout = 2000; /* milliseconds */ clientParms.transport = "curl"; diff --git a/stable/examples/json.c b/stable/examples/json.c index 7e70814c5..a3b6f90f9 100644 --- a/stable/examples/json.c +++ b/stable/examples/json.c @@ -10,6 +10,7 @@ #include #include +#include @@ -28,23 +29,23 @@ void printAsXml(xmlrpc_value * const valP) { xmlrpc_env env; - xmlrpc_mem_block out; + xmlrpc_mem_block * outP; xmlrpc_env_init(&env); - XMLRPC_MEMBLOCK_INIT(char, &env, &out, 0); + outP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); dieIfFaultOccurred(&env); - xmlrpc_serialize_value(&env, &out, valP); + xmlrpc_serialize_value(&env, outP, valP); printf("XML-RPC XML:\n"); printf("%.*s\n", - XMLRPC_MEMBLOCK_SIZE(char, &out), - XMLRPC_MEMBLOCK_CONTENTS(char, &out)); + XMLRPC_MEMBLOCK_SIZE(char, outP), + XMLRPC_MEMBLOCK_CONTENTS(char, outP)); - XMLRPC_MEMBLOCK_CLEAN(char, &out); + XMLRPC_MEMBLOCK_FREE(char, outP); xmlrpc_env_clean(&env); } @@ -54,26 +55,26 @@ void printAsJson(xmlrpc_value * const valP) { xmlrpc_env env; - xmlrpc_mem_block out; + xmlrpc_mem_block * outP; xmlrpc_value * val2P; xmlrpc_env_init(&env); - XMLRPC_MEMBLOCK_INIT(char, &env, &out, 0); + outP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); dieIfFaultOccurred(&env); - xmlrpc_serialize_json(&env, valP, &out); + xmlrpc_serialize_json(&env, valP, outP); dieIfFaultOccurred(&env); printf("JSON:\n"); printf("%.*s\n", - XMLRPC_MEMBLOCK_SIZE(char, &out), - XMLRPC_MEMBLOCK_CONTENTS(char, &out)); + XMLRPC_MEMBLOCK_SIZE(char, outP), + XMLRPC_MEMBLOCK_CONTENTS(char, outP)); - XMLRPC_MEMBLOCK_CLEAN(char, &out); + XMLRPC_MEMBLOCK_FREE(char, outP); xmlrpc_env_clean(&env); } diff --git a/stable/examples/ssl_secure_server.c b/stable/examples/ssl_secure_server.c new file mode 100644 index 000000000..0ef533cb8 --- /dev/null +++ b/stable/examples/ssl_secure_server.c @@ -0,0 +1,242 @@ +/* A simple standalone XML-RPC server program based on Abyss that uses SSL + (Secure Sockets Layer) via OpenSSL, with authentication. + + This is like the 'ssl_server' example, except that it requires + authentication, which means it is much harder to use - you have to set up a + certificate, private key, DSA parameters, and Diffie-Hellman parameters. + + Example: + + $ ./ssl_secure_server 8080 & + $ ./curl_client https://localhost:8080/RPC2 + + Before the above will work, you have to create a variety of files and put + them where this program expects to find them. Example: + + $ mkdir /tmp/ssltest + $ cd /tmp/ssltest + $ openssl genpkey -genparam -algorithm DSA >dsap.pem + $ openssl genpkey -paramfile dsap.pem >dsakey.pem + $ openssl req -new dsakey.pem >csr.csr + $ openssl x509 -req -in csr.csr -signkey dsakey.pem >certificate.pem + $ openssl dhparam -in dsap.pem -dsaparam -outform PEM >dhparam.pem + + + You can drive the most difficult part of this example (initial SSL + handshake) with the 'openssl' program that comes with OpenSSL, as follows. + + $ ./ssl_secure_server 8080 & + $ openssl -connect localhost:8080 -state + + The 'openssl' command connects and handshakes with the server, then waits + for you to type stuff to send to the server. You would have to type a + complete HTTP header followed by a valid XML-RPC call to complete the + demonstration. + + This uses the "provide your own Abyss server" mode of operation, + as opposed to other Xmlrpc-c facilities that create an Abyss server under + the covers, because this is the only way to get SSL. + + NOTE: We deliberately don't check error indications here to make the code + easier to read. If you're having trouble getting this code to run, by all + means add checks of the "error" and "env" variables! +*/ + +#define _XOPEN_SOURCE 600 +#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ + +#include +#include +#include +#ifndef _WIN32 +#include +#include +#endif + +#include + +#include +#include +#include +#include +#include + +#include "config.h" /* information about this build environment */ + + +static void +sslInfoCallback(const SSL * const sslP, + int const where, + int const ret) { + + const char * str; + int const w = where & ~SSL_ST_MASK; + + if (w & SSL_ST_CONNECT) + str = "SSL_connect"; + else if (w & SSL_ST_ACCEPT) + str = "SSL_accept"; + else + str = "undefined"; + + if (where & SSL_CB_LOOP) { + fprintf(stderr, "%s:%s\n", str, SSL_state_string_long(sslP)); + } else if (where & SSL_CB_ALERT) { + str = (where & SSL_CB_READ) ? "read" : "write"; + fprintf(stderr, "SSL3 alert %s:%s:%s\n", + str, + SSL_alert_type_string_long(ret), + SSL_alert_desc_string_long(ret)); + } else if (where & SSL_CB_EXIT) { + if (ret == 0) + fprintf(stderr, "%s:failed in %s\n", + str, SSL_state_string_long(sslP)); + else if (ret < 0) { + fprintf(stderr, "%s:error in %s\n", + str, SSL_state_string_long(sslP)); + } + } +} + + + +static void +printPeerIpAddr(TSession * const abyssSessionP) { + +#ifdef _WIN32 + struct abyss_win_chaninfo * channelInfoP; +#else + struct abyss_unix_chaninfo * channelInfoP; +#endif + struct sockaddr_in * sockAddrInP; + unsigned char * ipAddr; /* 4 byte array */ + + SessionGetChannelInfo(abyssSessionP, (void*)&channelInfoP); + + sockAddrInP = (struct sockaddr_in *) &channelInfoP->peerAddr; + + ipAddr = (unsigned char *)&sockAddrInP->sin_addr.s_addr; + + printf("RPC is from IP address %u.%u.%u.%u\n", + ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]); +} + + + +static xmlrpc_server_shutdown_fn requestShutdown; + +static void +shutdownAbyss(xmlrpc_env * const faultP, + void * const context, + const char * const comment, + void * const callInfo) { + + TServer * const abyssServerP = context; + + xmlrpc_env_init(faultP); + + ServerTerminate(abyssServerP); +} + + + +static xmlrpc_value * +sample_add(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const channelInfo) { + + xmlrpc_int x, y, z; + + printPeerIpAddr(channelInfo); + + /* Parse our argument array. */ + xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); + if (envP->fault_occurred) + return NULL; + + /* Add our two numbers. */ + z = x + y; + + /* Return our result. */ + return xmlrpc_build_value(envP, "i", z); +} + + + +int +main(int const argc, + const char ** const argv) { + + struct xmlrpc_method_info3 const methodInfo = { + .methodName = "sample.add", + .methodFunction = &sample_add, + .serverInfo = NULL + }; + + SSL_CTX * sslCtxP; + FILE * certFileP; + TChanSwitch * chanSwitchP; + TServer abyssServer; + xmlrpc_registry * registryP; + xmlrpc_env env; + const char * error; + + if (argc-1 != 1) { + fprintf(stderr, "You must specify 1 argument: The TCP port number " + "on which to listen for XML-RPC calls. " + "You specified %d.\n", argc-1); + exit(1); + } + + AbyssInit(&error); + + xmlrpc_env_init(&env); + + sslCtxP = SSL_CTX_new(SSLv23_server_method()); + + SSL_CTX_set_cipher_list(sslCtxP, "ALL:!aNULL"); + + SSL_CTX_use_certificate_chain_file(sslCtxP, + "/tmp/ssltest/certificate.pem"); + + SSL_CTX_use_PrivateKey_file(sslCtxP, "/tmp/ssltest/dsakey.pem", + SSL_FILETYPE_PEM); + + certFileP = fopen("/tmp/ssltest/dhparam.pem", "r"); + + DH * const dhP = PEM_read_DHparams(certFileP, NULL, NULL, NULL); + + SSL_CTX_set_tmp_dh(sslCtxP, dhP); + + SSL_CTX_set_info_callback(sslCtxP, sslInfoCallback); + + ChanSwitchOpenSslCreateIpV4Port(atoi(argv[1]), sslCtxP, + &chanSwitchP, &error); + + ServerCreateSwitch(&abyssServer, chanSwitchP, &error); + + registryP = xmlrpc_registry_new(&env); + + xmlrpc_registry_add_method3(&env, registryP, &methodInfo); + + xmlrpc_registry_set_shutdown(registryP, &shutdownAbyss, &abyssServer); + + xmlrpc_server_abyss_set_handlers2(&abyssServer, "/RPC2", registryP); + + ServerInit(&abyssServer); + + printf("Running server...\n"); + + ServerRun(&abyssServer); + /* This waits for TCP connections and processes them as XML-RPC + RPCs indefinitely (until system.shutdown method performed). + */ + + ServerFree(&abyssServer); + ChanSwitchDestroy(chanSwitchP); + SSL_CTX_free(sslCtxP); + AbyssTerm(); + + return 0; +} diff --git a/stable/examples/ssl_server.c b/stable/examples/ssl_server.c new file mode 100644 index 000000000..cfadfd983 --- /dev/null +++ b/stable/examples/ssl_server.c @@ -0,0 +1,230 @@ +/* A simple standalone XML-RPC server program based on Abyss that uses SSL + (Secure Sockets Layer) via OpenSSL. + + This server is not sophisticated enough to do any actual verification of + client or server, but it works with a client that is willing to do an + HTTPS connection using a non-authenticating cipher. The 'curl_client' + example program is one way to run such a client. + + Example: + + $ ./ssl_server 8080 & + $ ./curl_client https://localhost:8080/RPC2 + + You can drive the most difficult part of this example (initial SSL + handshake) with the 'openssl' program that comes with OpenSSL, as follows. + + $ ./ssl_server 8080 & + $ openssl -connect localhost:8080 -cipher ALL:aNULL:eNULL -state + + The 'openssl' command connects and handshakes with the server, then waits + for you to type stuff to send to the server. You would have to type a + complete HTTP header followed by a valid XML-RPC call to complete the + demonstration. + + Note that the examples above do no authentication, so you don't have to + supply certificates and keys to the server. See the 'ssl_secure_server' + example for that. + + This uses the "provide your own Abyss server" mode of operation, + as opposed to other Xmlrpc-c facilities that create an Abyss server under + the covers, because this is the only way to get SSL. + + NOTE: We deliberately don't check error indications here to make the code + easier to read. If you're having trouble getting this code to run, by all + means add checks of the "error" and "env" variables! +*/ + +#define _XOPEN_SOURCE 600 +#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ + +#include +#include +#include +#ifndef _WIN32 +#include +#include +#endif + +#include + +#include +#include +#include +#include +#include + +#include "config.h" /* information about this build environment */ + + +static void +sslInfoCallback(const SSL * const sslP, + int const where, + int const ret) { + + const char * str; + int const w = where & ~SSL_ST_MASK; + + if (w & SSL_ST_CONNECT) + str = "SSL_connect"; + else if (w & SSL_ST_ACCEPT) + str = "SSL_accept"; + else + str = "undefined"; + + if (where & SSL_CB_LOOP) { + fprintf(stderr, "%s:%s\n", str, SSL_state_string_long(sslP)); + } else if (where & SSL_CB_ALERT) { + str = (where & SSL_CB_READ) ? "read" : "write"; + fprintf(stderr, "SSL3 alert %s:%s:%s\n", + str, + SSL_alert_type_string_long(ret), + SSL_alert_desc_string_long(ret)); + } else if (where & SSL_CB_EXIT) { + if (ret == 0) + fprintf(stderr, "%s:failed in %s\n", + str, SSL_state_string_long(sslP)); + else if (ret < 0) { + fprintf(stderr, "%s:error in %s\n", + str, SSL_state_string_long(sslP)); + } + } +} + + + +static void +printPeerIpAddr(TSession * const abyssSessionP) { + +#ifdef _WIN32 + struct abyss_win_chaninfo * channelInfoP; +#else + struct abyss_unix_chaninfo * channelInfoP; +#endif + struct sockaddr_in * sockAddrInP; + unsigned char * ipAddr; /* 4 byte array */ + + SessionGetChannelInfo(abyssSessionP, (void*)&channelInfoP); + + sockAddrInP = (struct sockaddr_in *) &channelInfoP->peerAddr; + + ipAddr = (unsigned char *)&sockAddrInP->sin_addr.s_addr; + + printf("RPC is from IP address %u.%u.%u.%u\n", + ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]); +} + + + +static xmlrpc_server_shutdown_fn requestShutdown; + +static void +shutdownAbyss(xmlrpc_env * const faultP, + void * const context, + const char * const comment, + void * const callInfo) { + + TServer * const abyssServerP = context; + + xmlrpc_env_init(faultP); + + ServerTerminate(abyssServerP); +} + + + +static xmlrpc_value * +sample_add(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const channelInfo) { + + xmlrpc_int x, y, z; + + printPeerIpAddr(channelInfo); + + /* Parse our argument array. */ + xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); + if (envP->fault_occurred) + return NULL; + + /* Add our two numbers. */ + z = x + y; + + /* Return our result. */ + return xmlrpc_build_value(envP, "i", z); +} + + + +int +main(int const argc, + const char ** const argv) { + + struct xmlrpc_method_info3 const methodInfo = { + .methodName = "sample.add", + .methodFunction = &sample_add, + .serverInfo = NULL + }; + + SSL_CTX * sslCtxP; + TChanSwitch * chanSwitchP; + TServer abyssServer; + xmlrpc_registry * registryP; + xmlrpc_env env; + const char * error; + + if (argc-1 != 1) { + fprintf(stderr, "You must specify 1 argument: The TCP port number " + "on which to listen for XML-RPC calls. " + "You specified %d.\n", argc-1); + exit(1); + } + + AbyssInit(&error); + + xmlrpc_env_init(&env); + + sslCtxP = SSL_CTX_new(SSLv23_server_method()); + + SSL_CTX_set_cipher_list(sslCtxP, "ALL:aNULL:eNULL"); + + EC_KEY * const ecdhP = EC_KEY_new_by_curve_name(NID_sect163r2); + + // The following makes ECDH ciphers available. Without it (or some + // alternative), no ciphers are available + SSL_CTX_set_tmp_ecdh(sslCtxP, ecdhP); + EC_KEY_free(ecdhP); + + // Provide handy tracing to Standard Error of the SSL handshake + SSL_CTX_set_info_callback(sslCtxP, sslInfoCallback); + + ChanSwitchOpenSslCreateIpV4Port(atoi(argv[1]), sslCtxP, + &chanSwitchP, &error); + + ServerCreateSwitch(&abyssServer, chanSwitchP, &error); + + registryP = xmlrpc_registry_new(&env); + + xmlrpc_registry_add_method3(&env, registryP, &methodInfo); + + xmlrpc_registry_set_shutdown(registryP, &shutdownAbyss, &abyssServer); + + xmlrpc_server_abyss_set_handlers2(&abyssServer, "/RPC2", registryP); + + ServerInit(&abyssServer); + + printf("Running server...\n"); + + ServerRun(&abyssServer); + /* This waits for TCP connections and processes them as XML-RPC + RPCs indefinitely (until system.shutdown method performed). + */ + + ServerFree(&abyssServer); + ChanSwitchDestroy(chanSwitchP); + SSL_CTX_free(sslCtxP); + AbyssTerm(); + + return 0; +} diff --git a/stable/examples/xmlrpc_loop_server.c b/stable/examples/xmlrpc_loop_server.c index d76868d59..742fc3bab 100644 --- a/stable/examples/xmlrpc_loop_server.c +++ b/stable/examples/xmlrpc_loop_server.c @@ -106,9 +106,9 @@ requestShutdown(xmlrpc_env * const faultP, const char * const comment, void * const callInfo) { - /* You make this run by executing the system method - 'system.shutdown'. This function is registered in the method - registry as the thing to call for that. + /* You make this run by executing the system method 'system.shutdown'. + This function is registered in the method registry as the thing to call + for that. */ int * const terminationRequestedP = context; TSession * const abyssSessionP = callInfo; diff --git a/stable/examples/xmlrpc_sample_add_client.c b/stable/examples/xmlrpc_sample_add_client.c index 34472e636..d80a44e5c 100644 --- a/stable/examples/xmlrpc_sample_add_client.c +++ b/stable/examples/xmlrpc_sample_add_client.c @@ -21,7 +21,7 @@ #define NAME "Xmlrpc-c Test Client" #define VERSION "1.0" -static void +static void dieIfFaultOccurred (xmlrpc_env * const envP) { if (envP->fault_occurred) { fprintf(stderr, "ERROR: %s (%d)\n", @@ -32,8 +32,8 @@ dieIfFaultOccurred (xmlrpc_env * const envP) { -int -main(int const argc, +int +main(int const argc, const char ** const argv) { xmlrpc_env env; @@ -62,21 +62,23 @@ main(int const argc, resultP = xmlrpc_client_call(&env, serverUrl, methodName, "(ii)", (xmlrpc_int32) 5, (xmlrpc_int32) 7); dieIfFaultOccurred(&env); - + /* Get our sum and print it out. */ xmlrpc_read_int(&env, resultP, &sum); dieIfFaultOccurred(&env); printf("The sum is %d\n", sum); - + /* Dispose of our result value. */ xmlrpc_DECREF(resultP); /* Clean up our error-handling environment. */ xmlrpc_env_clean(&env); - + /* Shutdown our XML-RPC client library. */ xmlrpc_client_cleanup(); return 0; } + + diff --git a/stable/examples/xmlrpc_sample_add_server.c b/stable/examples/xmlrpc_sample_add_server.c index 4595266c1..d0edd29df 100644 --- a/stable/examples/xmlrpc_sample_add_server.c +++ b/stable/examples/xmlrpc_sample_add_server.c @@ -73,8 +73,8 @@ sample_add(xmlrpc_env * const envP, -int -main(int const argc, +int +main(int const argc, const char ** const argv) { struct xmlrpc_method_info3 const methodInfo = { @@ -92,7 +92,7 @@ main(int const argc, "You specified %d arguments.\n", argc-1); exit(1); } - + xmlrpc_env_init(&env); registryP = xmlrpc_registry_new(&env); @@ -126,4 +126,3 @@ main(int const argc, } - diff --git a/stable/include/Makefile b/stable/include/Makefile index 1fb9149a1..3b4a37b81 100644 --- a/stable/include/Makefile +++ b/stable/include/Makefile @@ -122,11 +122,16 @@ ifeq ($(MUST_BUILD_CLIENT),yes) endif endif + ifeq ($(ENABLE_CGI_SERVER),yes) HEADERS_TO_INSTALL += xmlrpc-c/server_cgi.h COMPAT_LINK_CMDS += $(LN_S) xmlrpc-c/server_cgi.h xmlrpc_cgi.h; endif +ifeq ($(MUST_BUILD_OPENSSL),Y) + HEADERS_TO_INSTALL += xmlrpc-c/openssl_thread.h +endif + default: all all: @@ -141,9 +146,20 @@ install-compat-hdr: install-headers XmlRpcCpp.h; \ $(COMPAT_LINK_CMDS) +.PHONY: uninstall-compat-hdr +uninstall-compat-hdr: + cd $(DESTDIR)$(HEADERINST_DIR); \ + rm -f xmlrpc.h xmlrpc_client.h xmlrpc_server.h xmlrpc_cgi.h \ + xmlrpc_server_abyss.h xmlrpc_abyss.h \ + xmlrpc_server_w32httpsys.h \ + XmlRpcCpp.h; \ + .PHONY: install install: install-common install-compat-hdr +.PHONY: uninstall +uninstall: uninstall-common uninstall-compat-hdr + .PHONY: clean clean: rm -f xmlrpc-c/config.h diff --git a/stable/include/xmlrpc-c/AbyssChanSwitch.hpp b/stable/include/xmlrpc-c/AbyssChanSwitch.hpp index 25857ec06..baf047001 100644 --- a/stable/include/xmlrpc-c/AbyssChanSwitch.hpp +++ b/stable/include/xmlrpc-c/AbyssChanSwitch.hpp @@ -13,7 +13,13 @@ namespace xmlrpc_c { -class AbyssChanSwitch { +#ifdef XMLRPC_BUILDING_ABYSSPP +#define XMLRPC_ABYSSPP_EXPORTED XMLRPC_DLLEXPORT +#else +#define XMLRPC_ABYSSPP_EXPORTED +#endif + +class XMLRPC_ABYSSPP_EXPORTED AbyssChanSwitch { /*---------------------------------------------------------------------------- An object of this class is a channel switch for use with an AbyssServer object, which means it listens for and accepts requests from clients to diff --git a/stable/include/xmlrpc-c/AbyssChanSwitchOpenSsl.hpp b/stable/include/xmlrpc-c/AbyssChanSwitchOpenSsl.hpp new file mode 100644 index 000000000..95e3d1c98 --- /dev/null +++ b/stable/include/xmlrpc-c/AbyssChanSwitchOpenSsl.hpp @@ -0,0 +1,35 @@ +/*============================================================================ + AbyssChanSwitchOpenSsl.hpp +============================================================================== + + This declares class AbyssChanSwitchOpenSsl, which provides communication + facilities for use with an AbyssServer object that uses Unix sockets. + +============================================================================*/ +#ifndef ABYSS_CHAN_SWITCH_OPEN_SSL_HPP_INCLUDED +#define ABYSS_CHAN_SWITCH_OPEN_SSL_HPP_INCLUDED + +#include +#include + +#include + +namespace xmlrpc_c { + +class AbyssChanSwitchOpenSsl : public AbyssChanSwitch { + +public: + + AbyssChanSwitchOpenSsl( + int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + SSL_CTX * const sslCtxP); + + AbyssChanSwitchOpenSsl( + unsigned short const listenPortNum, + SSL_CTX * const sslCtxP); +}; + +} // namespace +#endif diff --git a/stable/include/xmlrpc-c/AbyssChanSwitchWin.hpp b/stable/include/xmlrpc-c/AbyssChanSwitchWin.hpp index ee5987d2b..e357d84fc 100644 --- a/stable/include/xmlrpc-c/AbyssChanSwitchWin.hpp +++ b/stable/include/xmlrpc-c/AbyssChanSwitchWin.hpp @@ -14,7 +14,13 @@ namespace xmlrpc_c { -class AbyssChanSwitchWin : public AbyssChanSwitch { +#ifdef XMLRPC_BUILDING_ABYSSPP +#define XMLRPC_ABYSSPP_EXPORTED XMLRPC_DLLEXPORT +#else +#define XMLRPC_ABYSSPP_EXPORTED +#endif + +class XMLRPC_ABYSSPP_EXPORTED AbyssChanSwitchWin : public AbyssChanSwitch { public: AbyssChanSwitchWin(unsigned short const listenPortNum); diff --git a/stable/include/xmlrpc-c/AbyssEnvironment.hpp b/stable/include/xmlrpc-c/AbyssEnvironment.hpp index 266d68adb..1e41a8269 100644 --- a/stable/include/xmlrpc-c/AbyssEnvironment.hpp +++ b/stable/include/xmlrpc-c/AbyssEnvironment.hpp @@ -9,7 +9,13 @@ namespace xmlrpc_c { -class AbyssEnvironment { +#ifdef XMLRPC_BUILDING_ABYSSPP +#define XMLRPC_ABYSSPP_EXPORTED XMLRPC_DLLEXPORT +#else +#define XMLRPC_ABYSSPP_EXPORTED +#endif + +class XMLRPC_ABYSSPP_EXPORTED AbyssEnvironment { /*---------------------------------------------------------------------------- A program that uses libxmlrpc_abyss++ should contain exactly one object of this class, as a global static object. diff --git a/stable/include/xmlrpc-c/AbyssServer.hpp b/stable/include/xmlrpc-c/AbyssServer.hpp index 08711e231..08e9fddf9 100644 --- a/stable/include/xmlrpc-c/AbyssServer.hpp +++ b/stable/include/xmlrpc-c/AbyssServer.hpp @@ -22,7 +22,13 @@ namespace xmlrpc_c { -class AbyssServer { +#ifdef XMLRPC_BUILDING_ABYSSPP +#define XMLRPC_ABYSSPP_EXPORTED XMLRPC_DLLEXPORT +#else +#define XMLRPC_ABYSSPP_EXPORTED +#endif + +class XMLRPC_ABYSSPP_EXPORTED AbyssServer { /*---------------------------------------------------------------------------- An object of this class represents an Abyss HTTP server. @@ -34,7 +40,7 @@ class AbyssServer { -----------------------------------------------------------------------------*/ public: - class Exception : public std::runtime_error { + class XMLRPC_ABYSSPP_EXPORTED Exception : public std::runtime_error { public: Exception(unsigned short const httpStatusCode, std::string const& explanation); @@ -46,7 +52,7 @@ class AbyssServer { unsigned short _httpStatusCode; }; - class Session { + class XMLRPC_ABYSSPP_EXPORTED Session { public: class Impl; @@ -182,7 +188,7 @@ class AbyssServer { Impl * const implP; }; - class ReqHandler { + class XMLRPC_ABYSSPP_EXPORTED ReqHandler { /*------------------------------------------------------------------------ An object of this class handles HTTP requests, which essentially means it provides responses to them. An AbyssServer object calls methods of @@ -239,6 +245,7 @@ class AbyssServer { } // namespace +XMLRPC_ABYSSPP_EXPORTED std::ostream& operator<<(std::ostream & out, xmlrpc_c::AbyssServer::Session::Method const& method); diff --git a/stable/include/xmlrpc-c/abyss.h b/stable/include/xmlrpc-c/abyss.h index e87381a60..0011c5c6f 100644 --- a/stable/include/xmlrpc-c/abyss.h +++ b/stable/include/xmlrpc-c/abyss.h @@ -252,6 +252,12 @@ void ServerSetMaxConnBacklog(TServer * const serverP, unsigned int const maxConnBacklog); +#define HAVE_SERVER_SET_MAX_SESSION_MEM 1 +XMLRPC_ABYSS_EXPORTED +void +ServerSetMaxSessionMem(TServer * const serverP, + size_t const size); + XMLRPC_ABYSS_EXPORTED void ServerInit2(TServer * const serverP, @@ -431,6 +437,7 @@ typedef struct { abyss_bool keepalive; } TRequestInfo; +XMLRPC_ABYSS_EXPORTED void SessionGetBody(TSession * const sessionP, size_t const max, @@ -651,11 +658,8 @@ abyss_bool DateInit(void); XMLRPC_ABYSS_EXPORTED abyss_bool SessionLog(TSession * const s); - #ifdef __cplusplus } - - #endif /***************************************************************************** @@ -689,4 +693,4 @@ abyss_bool SessionLog(TSession * const s); ** SUCH DAMAGE. ** ******************************************************************************/ -#endif /* _ABYSS_H_ */ +#endif diff --git a/stable/include/xmlrpc-c/abyss_openssl.h b/stable/include/xmlrpc-c/abyss_openssl.h new file mode 100644 index 000000000..cb4bc12d2 --- /dev/null +++ b/stable/include/xmlrpc-c/abyss_openssl.h @@ -0,0 +1,82 @@ +#ifndef ABYSS_OPENSSL_H_INCLUDED +#define ABYSS_OPENSSL_H_INCLUDED +/*============================================================================= + abyss_openssl.h +=============================================================================== + Declarations to be used with an Abyss server that can server HTTPS URLs + via OpenSSL. + + Note that there is no equivalent of this file for the original two Abyss + channel types, "Unix" and "Windows". Those are built into + , for historical reasons. +=============================================================================*/ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +struct abyss_openSsl_chaninfo { + size_t peerAddrLen; + /* Length of 'peerAddr' (which is effectively polymorphic, so could + have any of various lengths depending upon the type of socket + address + */ + struct sockaddr peerAddr; + + SSL * sslP; + /* The handle of the OpenSSL connection object underlying this channel. + + You can use this to get all sort of neat information about the + connection, such as the verified certification the client + presented, using the OpenSSL library. (For example, to find out + the authenticated name of the client, use + SSL_get_peer_certificate(), and use X509_get_subject name() with + the result of that). + + This is kind of a modularity violation, which we don't mind because + it is so easy and flexible. But note that it is the Abyss design + intent that you use the SSL object _only_ to get information about + the channel. + */ +}; + +void +ChanSwitchOpenSslCreate(int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP); + +void +ChanSwitchOpenSslCreateIpV4Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP); + +void +ChanSwitchOpenSslCreateIpV6Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP); + +void +ChanSwitchOpenSslCreateFd(int const fd, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP); + +void +ChannelOpenSslCreateSsl(SSL * const sslP, + TChannel ** const channelPP, + struct abyss_openSsl_chaninfo ** const channelInfoPP, + const char ** const errorP); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stable/include/xmlrpc-c/abyss_opensslsock.h b/stable/include/xmlrpc-c/abyss_opensslsock.h deleted file mode 100644 index dea25313d..000000000 --- a/stable/include/xmlrpc-c/abyss_opensslsock.h +++ /dev/null @@ -1,28 +0,0 @@ -/* This is just a sub-file for abyss.h */ - -#include - -struct abyss_openssl_chaninfo { - /* TODO: figure out useful information to put in here. - Maybe client IP address and port. Maybe authenticated host name. - Maybe authentication level. - Maybe a certificate. - */ - int dummy; -}; - -void -ChanSwitchOpensslCreate(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChanSwitchOpensslCreateFd(int const fd, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChannelOpensslCreateSsl(SSL * const sslP, - TChannel ** const channelPP, - struct abyss_openssl_chaninfo ** const channelInfoPP, - const char ** const errorP); diff --git a/stable/include/xmlrpc-c/abyss_unixsock.h b/stable/include/xmlrpc-c/abyss_unixsock.h index c92b279ac..5ffe924b6 100644 --- a/stable/include/xmlrpc-c/abyss_unixsock.h +++ b/stable/include/xmlrpc-c/abyss_unixsock.h @@ -30,6 +30,12 @@ ChanSwitchUnixCreateFd(int const fd, TChanSwitch ** const chanSwitchPP, const char ** const errorP); +void +ChanSwitchUnixGetListenName(TChanSwitch * const chanSwitchP, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP); + void ChannelUnixCreateFd(int const fd, TChannel ** const channelPP, diff --git a/stable/include/xmlrpc-c/abyss_winsock.h b/stable/include/xmlrpc-c/abyss_winsock.h index eb0351da7..6c069d8ac 100644 --- a/stable/include/xmlrpc-c/abyss_winsock.h +++ b/stable/include/xmlrpc-c/abyss_winsock.h @@ -38,4 +38,11 @@ ChannelWinCreateWinsock(SOCKET const fd, struct abyss_win_chaninfo ** const channelInfoPP, const char ** const errorP); +XMLRPC_ABYSS_EXPORTED +void +ChanSwitchWinGetListenName(TChanSwitch * const chanSwitchP, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP); + typedef SOCKET TOsSocket; diff --git a/stable/include/xmlrpc-c/base.hpp b/stable/include/xmlrpc-c/base.hpp index 8f2e490db..0a1923e57 100644 --- a/stable/include/xmlrpc-c/base.hpp +++ b/stable/include/xmlrpc-c/base.hpp @@ -290,6 +290,11 @@ toValue(int const x) { return xmlrpc_c::value_int(x); } +inline xmlrpc_c::value_i8 +toValue(xmlrpc_int64 const x) { + return xmlrpc_c::value_i8(x); +} + inline xmlrpc_c::value_boolean toValue(bool const x) { return xmlrpc_c::value_boolean(x); @@ -364,6 +369,11 @@ fromValue(int & y, xmlrpc_c::value const& x) { y = xmlrpc_c::value_int(x); } +inline void +fromValue(xmlrpc_int64 & y, xmlrpc_c::value const& x) { + y = xmlrpc_c::value_i8(x); +} + inline void fromValue(bool & y, xmlrpc_c::value const& x) { y = xmlrpc_c::value_boolean(x); diff --git a/stable/include/xmlrpc-c/base64.hpp b/stable/include/xmlrpc-c/base64.hpp index 5eb5cd70e..85684214b 100644 --- a/stable/include/xmlrpc-c/base64.hpp +++ b/stable/include/xmlrpc-c/base64.hpp @@ -7,16 +7,16 @@ #include /* - XMLRPC_LIBPP_EXPORTED marks a symbol in this file that is exported from - libxmlrpc++. +XMLRPC_LIBUTILPP_EXPORTED marks a symbol in this file that is exported from +libxmlrpc_util++. - XMLRPC_BUILDING_LIBPP says this compilation is part of libxmlrpc++, as - opposed to something that _uses_ libxmlrpc++. +XMLRPC_BUILDING_LIBUTILPP says this compilation is part of libxmlrpc_util++, as +opposed to something that _uses_ libxmlrpc_util++. */ -#ifdef XMLRPC_BUILDING_LIBPP -#define XMLRPC_LIBPP_EXPORTED XMLRPC_DLLEXPORT +#ifdef XMLRPC_BUILDING_LIBUTILPP +#define XMLRPC_LIBUTILPP_EXPORTED XMLRPC_DLLEXPORT #else -#define XMLRPC_LIBPP_EXPORTED +#define XMLRPC_LIBUTILPP_EXPORTED #endif namespace xmlrpc_c { @@ -24,14 +24,14 @@ namespace xmlrpc_c { enum newlineCtl {NEWLINE_NO, NEWLINE_YES}; -XMLRPC_LIBPP_EXPORTED +XMLRPC_LIBUTILPP_EXPORTED std::string base64FromBytes( std::vector const& bytes, xmlrpc_c::newlineCtl const newlineCtl = xmlrpc_c::NEWLINE_YES); -XMLRPC_LIBPP_EXPORTED +XMLRPC_LIBUTILPP_EXPORTED std::vector bytesFromBase64(std::string const& base64); diff --git a/stable/include/xmlrpc-c/base_int.h b/stable/include/xmlrpc-c/base_int.h index 0ff15e4fa..17d2d6cf9 100644 --- a/stable/include/xmlrpc-c/base_int.h +++ b/stable/include/xmlrpc-c/base_int.h @@ -77,7 +77,7 @@ struct _xmlrpc_value { For base64, this is bytes of the byte string, directly. */ - xmlrpc_mem_block _block; + xmlrpc_mem_block * blockP; xmlrpc_mem_block *_wcs_block; /* This is a copy of the string value in _block, but in UTF-16 diff --git a/stable/include/xmlrpc-c/client_transport.hpp b/stable/include/xmlrpc-c/client_transport.hpp index 02cefe0b7..4c6c87e1f 100644 --- a/stable/include/xmlrpc-c/client_transport.hpp +++ b/stable/include/xmlrpc-c/client_transport.hpp @@ -422,6 +422,7 @@ class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_pstream : public xmlrpc_c::cli constrOpt(constrOpt&); constrOpt & fd (int const& arg); + constrOpt & useBrokenConnEx (bool const& arg); private: struct constrOpt_impl * implP; @@ -437,8 +438,10 @@ class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_pstream : public xmlrpc_c::cli std::string const& callXml, std::string * const responseXmlP); + class BrokenConnectionEx {}; + private: - packetSocket * packetSocketP; + class clientXmlTransport_pstream_impl * const implP; }; diff --git a/stable/include/xmlrpc-c/env_wrap.hpp b/stable/include/xmlrpc-c/env_wrap.hpp index f31cb0e55..7c405c667 100644 --- a/stable/include/xmlrpc-c/env_wrap.hpp +++ b/stable/include/xmlrpc-c/env_wrap.hpp @@ -4,9 +4,15 @@ #include "xmlrpc-c/c_util.h" #include "xmlrpc-c/util.h" +#ifdef XMLRPC_BUILDING_LIBUTILPP +#define XMLRPC_LIBUTILPP_EXPORTED XMLRPC_DLLEXPORT +#else +#define XMLRPC_LIBUTILPP_EXPORTED +#endif + namespace xmlrpc_c { -class XMLRPC_DLLEXPORT env_wrap { +class XMLRPC_LIBUTILPP_EXPORTED env_wrap { /*---------------------------------------------------------------------------- A wrapper to assist in using the Xmlrpc-c C libraries in Xmlrpc-c C++ code. diff --git a/stable/include/xmlrpc-c/girerr.hpp b/stable/include/xmlrpc-c/girerr.hpp index 79024fe03..ee499c6d1 100644 --- a/stable/include/xmlrpc-c/girerr.hpp +++ b/stable/include/xmlrpc-c/girerr.hpp @@ -7,23 +7,23 @@ #include /* - XMLRPC_LIBPP_EXPORTED marks a symbol in this file that is exported from - libxmlrpc++. +XMLRPC_LIBUTILPP_EXPORTED marks a symbol in this file that is exported from +libxmlrpc_util++. - XMLRPC_BUILDING_LIBPP says this compilation is part of libxmlrpc++, as - opposed to something that _uses_ libxmlrpc++. +XMLRPC_BUILDING_LIBUTILPP says this compilation is part of libxmlrpc_util++, as +opposed to something that _uses_ libxmlrpc_util++. */ -#ifdef XMLRPC_BUILDING_LIBPP -#define XMLRPC_LIBPP_EXPORTED XMLRPC_DLLEXPORT +#ifdef XMLRPC_BUILDING_LIBUTILPP +#define XMLRPC_LIBUTILPP_EXPORTED XMLRPC_DLLEXPORT #else -#define XMLRPC_LIBPP_EXPORTED +#define XMLRPC_LIBUTILPP_EXPORTED #endif #define HAVE_GIRERR_ERROR namespace girerr { -class XMLRPC_LIBPP_EXPORTED error : public std::exception { +class XMLRPC_LIBUTILPP_EXPORTED error : public std::exception { public: error(std::string const& what_arg) : _what(what_arg) {} @@ -38,7 +38,7 @@ class XMLRPC_LIBPP_EXPORTED error : public std::exception { // throwf() always throws a girerr::error . -XMLRPC_LIBPP_EXPORTED +XMLRPC_LIBUTILPP_EXPORTED void throwf(const char * const format, ...) XMLRPC_PRINTF_ATTR(1,2) diff --git a/stable/include/xmlrpc-c/girmem.hpp b/stable/include/xmlrpc-c/girmem.hpp index b8fe71bb8..014464196 100644 --- a/stable/include/xmlrpc-c/girmem.hpp +++ b/stable/include/xmlrpc-c/girmem.hpp @@ -12,23 +12,23 @@ #include /* - XMLRPC_LIBPP_EXPORTED marks a symbol in this file that is exported from - libxmlrpc++. +XMLRPC_LIBUTILPP_EXPORTED marks a symbol in this file that is exported from +libxmlrpc_util++. - XMLRPC_BUILDING_LIBPP says this compilation is part of libxmlrpc++, as - opposed to something that _uses_ libxmlrpc++. +XMLRPC_BUILDING_LIBUTILPP says this compilation is part of libxmlrpc_util++, as +opposed to something that _uses_ libxmlrpc_util++. */ -#ifdef XMLRPC_BUILDING_LIBPP -#define XMLRPC_LIBPP_EXPORTED XMLRPC_DLLEXPORT +#ifdef XMLRPC_BUILDING_LIBUTILPP +#define XMLRPC_LIBUTILPP_EXPORTED XMLRPC_DLLEXPORT #else -#define XMLRPC_LIBPP_EXPORTED +#define XMLRPC_LIBUTILPP_EXPORTED #endif namespace girmem { -class XMLRPC_LIBPP_EXPORTED autoObjectPtr; +class XMLRPC_LIBUTILPP_EXPORTED autoObjectPtr; -class XMLRPC_LIBPP_EXPORTED autoObject { +class XMLRPC_LIBUTILPP_EXPORTED autoObject { friend class autoObjectPtr; public: @@ -49,7 +49,7 @@ class XMLRPC_LIBPP_EXPORTED autoObject { autoObject(autoObject const&); }; -class XMLRPC_LIBPP_EXPORTED autoObjectPtr { +class XMLRPC_LIBUTILPP_EXPORTED autoObjectPtr { public: autoObjectPtr(); autoObjectPtr(girmem::autoObject * objectP); diff --git a/stable/include/xmlrpc-c/openssl_thread.h b/stable/include/xmlrpc-c/openssl_thread.h new file mode 100644 index 000000000..e751aed0f --- /dev/null +++ b/stable/include/xmlrpc-c/openssl_thread.h @@ -0,0 +1,10 @@ +#ifndef XMLRPC_OPENSS_THREAD_H_INCLUDED +#define XMLRPC_OPENSS_THREAD_H_INCLUDED + +void +xmlrpc_openssl_thread_setup(const char ** const errorP); + +void +xmlrpc_openssl_thread_cleanup(void); + +#endif diff --git a/stable/include/xmlrpc-c/packetsocket.hpp b/stable/include/xmlrpc-c/packetsocket.hpp index e6fabafed..2f715ac0d 100644 --- a/stable/include/xmlrpc-c/packetsocket.hpp +++ b/stable/include/xmlrpc-c/packetsocket.hpp @@ -102,6 +102,10 @@ class XMLRPC_PACKETSOCKET_EXPORTED packetSocket { void writeWait(packetPtr const& packetPtr) const; + void + writeWait(packetPtr const& packetPtr, + bool * const brokenConnP) const; + void read(bool * const eofP, bool * const gotPacketP, @@ -122,6 +126,9 @@ class XMLRPC_PACKETSOCKET_EXPORTED packetSocket { readWait(bool * const eofP, packetPtr * const packetPP); + void + useBrokenConnEx(); + private: packetSocket_impl * implP; }; diff --git a/stable/include/xmlrpc-c/registry.hpp b/stable/include/xmlrpc-c/registry.hpp index 55118704a..0dc5e3f15 100644 --- a/stable/include/xmlrpc-c/registry.hpp +++ b/stable/include/xmlrpc-c/registry.hpp @@ -211,7 +211,7 @@ class XMLRPC_SERVERPP_EXPORTED registry : public girmem::autoObject { void processCall(std::string const& callXml, - const xmlrpc_c::callInfo * const callInfoP, + const xmlrpc_c::callInfo * const callInfoP, std::string * const responseXmlP) const; size_t diff --git a/stable/include/xmlrpc-c/server_abyss.h b/stable/include/xmlrpc-c/server_abyss.h index 6298f4dcb..49b1e5c02 100644 --- a/stable/include/xmlrpc-c/server_abyss.h +++ b/stable/include/xmlrpc-c/server_abyss.h @@ -100,6 +100,7 @@ typedef struct { socklen_t sockaddrlen; unsigned int max_conn; unsigned int max_conn_backlog; + size_t max_rpc_mem; } xmlrpc_server_abyss_parms; diff --git a/stable/include/xmlrpc-c/server_abyss.hpp b/stable/include/xmlrpc-c/server_abyss.hpp index 9847463a3..6171f807f 100644 --- a/stable/include/xmlrpc-c/server_abyss.hpp +++ b/stable/include/xmlrpc-c/server_abyss.hpp @@ -60,6 +60,7 @@ class XMLRPC_SERVER_ABYSSPP_EXPORTED serverAbyss { constrOpt & portNumber (unsigned int const& arg); constrOpt & maxConn (unsigned int const& arg); constrOpt & maxConnBacklog (unsigned int const& arg); + constrOpt & maxRpcMem (size_t const& arg); constrOpt & keepaliveTimeout (unsigned int const& arg); constrOpt & keepaliveMaxConn (unsigned int const& arg); constrOpt & timeout (unsigned int const& arg); @@ -94,6 +95,10 @@ class XMLRPC_SERVER_ABYSSPP_EXPORTED serverAbyss { ); ~serverAbyss(); + void + getListenName(struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP); + void run(); diff --git a/stable/include/xmlrpc-c/string_int.h b/stable/include/xmlrpc-c/string_int.h index ab68fe085..8d27f663d 100644 --- a/stable/include/xmlrpc-c/string_int.h +++ b/stable/include/xmlrpc-c/string_int.h @@ -124,6 +124,12 @@ xmlrpc_makePrintableChar(char const input); #define STRSCAT(A,B) \ (strncat((A), (B), sizeof(A)-strlen(A)-1)) +#define MEMSSET(a,b) (memset(a, b, sizeof(*a))) + +#define MEMSCPY(a,b) (memcpy(a, b, sizeof(*a))) + +#define MEMSZERO(a) (MEMSSET(a, 0)) + /* We could do this, but it works only in GNU C #define SSPRINTF(TARGET, REST...) \ (snprintf(TARGET, sizeof(TARGET) , ## REST)) diff --git a/stable/include/xmlrpc-c/util.h b/stable/include/xmlrpc-c/util.h index 63fd6179e..cb04baa72 100644 --- a/stable/include/xmlrpc-c/util.h +++ b/stable/include/xmlrpc-c/util.h @@ -231,18 +231,13 @@ xmlrpc_faultf(xmlrpc_env * const envP, /*========================================================================= -** 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! -*/ + 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. +=========================================================================*/ -typedef struct _xmlrpc_mem_block { - size_t _size; - size_t _allocated; - void* _block; -} xmlrpc_mem_block; +typedef struct _xmlrpc_mem_block xmlrpc_mem_block; /* Allocate a new xmlrpc_mem_block. */ XMLRPC_UTIL_EXPORTED @@ -286,10 +281,6 @@ void xmlrpc_mem_block_append 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) \ @@ -307,10 +298,6 @@ void xmlrpc_mem_block_append 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) \ diff --git a/stable/include/xmlrpc-c/util_int.h b/stable/include/xmlrpc-c/util_int.h index db5c5e911..ce7d69da9 100644 --- a/stable/include/xmlrpc-c/util_int.h +++ b/stable/include/xmlrpc-c/util_int.h @@ -12,6 +12,23 @@ #include "util.h" +/* + XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from + libxmlrpc_util. + + XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as + opposed to something that _uses_ libxmlrpc_util. +*/ +#ifdef XMLRPC_BUILDING_UTIL +#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT +#else +#define XMLRPC_UTIL_EXPORTED +#endif + +#ifdef __cplusplus +extern "C" { +#endif + #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) @@ -19,4 +36,48 @@ ** this and throw in a few assertions here and there. */ #define XMLRPC_BAD_POINTER ((void*) 0xDEADBEEF) +/*============================================================================ + xmlrpc_mem_pool + + A memory pool from which you can allocate xmlrpc_mem_block's. + + This is a mechanism for limiting memory allocation. + + Since the xmlrpc_mem_block type is part of the API, we may want to make + xmlrpc_mem_pool external some day. For now, any xmlrpc_mem_block created + outside of Xmlrpc-c code goes in the default pool. +============================================================================*/ + +typedef struct _xmlrpc_mem_pool xmlrpc_mem_pool; + +XMLRPC_UTIL_EXPORTED +xmlrpc_mem_pool * +xmlrpc_mem_pool_new(xmlrpc_env * const envP, + size_t const size); + +XMLRPC_UTIL_EXPORTED +void +xmlrpc_mem_pool_free(xmlrpc_mem_pool * const poolP); + +XMLRPC_UTIL_EXPORTED +void +xmlrpc_mem_pool_alloc(xmlrpc_env * const envP, + xmlrpc_mem_pool * const poolP, + size_t const size); + +XMLRPC_UTIL_EXPORTED +void +xmlrpc_mem_pool_release(xmlrpc_mem_pool * const poolP, + size_t const size); + +XMLRPC_UTIL_EXPORTED +xmlrpc_mem_block * +xmlrpc_mem_block_new_pool(xmlrpc_env * const envP, + size_t const size, + xmlrpc_mem_pool * const poolP); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/stable/include/xmlrpc-c/xmlparser.h b/stable/include/xmlrpc-c/xmlparser.h deleted file mode 100644 index 985d19d6a..000000000 --- a/stable/include/xmlrpc-c/xmlparser.h +++ /dev/null @@ -1,106 +0,0 @@ -/* 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 * const 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. */ -const char * -xml_element_name(const xml_element * const elemP); - -/* 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(const xml_element * const elemP); - -xml_element ** -xml_element_children(const xml_element * const elemP); - - -/*========================================================================= -** 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. -*/ - -void -xml_parse(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xml_element ** const resultPP); - -/* Initialize and terminate static global parser state. This should be done - once per run of a program, and while the program is just one thread. -*/ -void -xml_init(xmlrpc_env * const envP); - -void -xml_term(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. */ - -#endif diff --git a/stable/lib/Makefile b/stable/lib/Makefile index ee0ea2f4d..c0e7889d6 100644 --- a/stable/lib/Makefile +++ b/stable/lib/Makefile @@ -32,6 +32,10 @@ ifneq ($(ENABLE_LIBXML2_BACKEND),yes) SUBDIRS += expat endif +ifeq ($(HAVE_OPENSSL),Y) + SUBDIRS += openssl +endif + default: all .PHONY: all clean distclean tags distdir install check dep @@ -56,6 +60,8 @@ distdir: distdir-common install: $(SUBDIRS:%=%/install) +uninstall: $(SUBDIRS:%=%/uninstall) + check: dep: $(SUBDIRS:%=%/dep) diff --git a/stable/lib/abyss++/AbyssChanSwitch.cpp b/stable/lib/abyss++/AbyssChanSwitch.cpp index a07ab0536..e505a3a84 100644 --- a/stable/lib/abyss++/AbyssChanSwitch.cpp +++ b/stable/lib/abyss++/AbyssChanSwitch.cpp @@ -2,7 +2,7 @@ using namespace std; -#include +#include "xmlrpc-c/abyss.h" #include "xmlrpc-c/AbyssChanSwitch.hpp" diff --git a/stable/lib/abyss++/AbyssChanSwitchOpenSsl.cpp b/stable/lib/abyss++/AbyssChanSwitchOpenSsl.cpp new file mode 100644 index 000000000..7a5ef5900 --- /dev/null +++ b/stable/lib/abyss++/AbyssChanSwitchOpenSsl.cpp @@ -0,0 +1,59 @@ +#include + +using namespace std; + +#ifdef _WIN32 + /* With _WIN32, does not declare + ChanSwitchOpenSslCreate */ + #error This module does not compile for a Windows target. +#endif + +#include +#include + +#include "xmlrpc-c/abyss.h" +#include "xmlrpc-c/abyss_openssl.h" + + +#include "xmlrpc-c/AbyssChanSwitchOpenSsl.hpp" + + + + +namespace xmlrpc_c { + + + +AbyssChanSwitchOpenSsl::AbyssChanSwitchOpenSsl( + int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + SSL_CTX * const sslCtxP) { + + const char * error; + + ChanSwitchOpenSslCreate(protocolFamily, sockAddrP, sockAddrLen, sslCtxP, + &this->_cChanSwitchP, &error); + + if (error) + throw runtime_error(error); +} + + + +AbyssChanSwitchOpenSsl::AbyssChanSwitchOpenSsl( + unsigned short const listenPortNum, + SSL_CTX * const sslCtxP) { + + const char * error; + + ChanSwitchOpenSslCreateIpV4Port(listenPortNum, sslCtxP, + &this->_cChanSwitchP, &error); + + if (error) + throw runtime_error(error); +} + + + +} // namespace diff --git a/stable/lib/abyss++/AbyssChanSwitchUnix.cpp b/stable/lib/abyss++/AbyssChanSwitchUnix.cpp index 3d5ed2b91..b16326106 100644 --- a/stable/lib/abyss++/AbyssChanSwitchUnix.cpp +++ b/stable/lib/abyss++/AbyssChanSwitchUnix.cpp @@ -7,7 +7,7 @@ using namespace std; #error This module does not compile for a Windows target. #endif -#include +#include "xmlrpc-c/abyss.h" #include "xmlrpc-c/AbyssChanSwitchUnix.hpp" diff --git a/stable/lib/abyss++/AbyssChanSwitchWin.cpp b/stable/lib/abyss++/AbyssChanSwitchWin.cpp index 160ab0c70..eb5277fce 100644 --- a/stable/lib/abyss++/AbyssChanSwitchWin.cpp +++ b/stable/lib/abyss++/AbyssChanSwitchWin.cpp @@ -7,7 +7,7 @@ using namespace std; #error This module compiles only for a Windows target. #endif -#include +#include "xmlrpc-c/abyss.h" #include "xmlrpc-c/AbyssChanSwitchWin.hpp" diff --git a/stable/lib/abyss++/AbyssEnvironment.cpp b/stable/lib/abyss++/AbyssEnvironment.cpp index 503df8168..e31a983ec 100644 --- a/stable/lib/abyss++/AbyssEnvironment.cpp +++ b/stable/lib/abyss++/AbyssEnvironment.cpp @@ -2,10 +2,10 @@ using namespace std; -#include +#include "xmlrpc-c/girerr.hpp" using girerr::throwf; -#include -#include +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/abyss.h" #include "xmlrpc-c/AbyssEnvironment.hpp" diff --git a/stable/lib/abyss++/AbyssServer.cpp b/stable/lib/abyss++/AbyssServer.cpp index 2936ef508..d9383bb35 100644 --- a/stable/lib/abyss++/AbyssServer.cpp +++ b/stable/lib/abyss++/AbyssServer.cpp @@ -460,6 +460,7 @@ AbyssServer::Session::method() const { case m_options: return METHOD_OPTIONS; } assert(false); // All values of TMethod are handled in switch. + return METHOD_UNKNOWN; /* Defeat bogus compiler warning */ } diff --git a/stable/lib/abyss++/Makefile b/stable/lib/abyss++/Makefile index a01986de0..f6538afc2 100644 --- a/stable/lib/abyss++/Makefile +++ b/stable/lib/abyss++/Makefile @@ -28,6 +28,9 @@ ifeq ($(findstring mingw,$(HOST_OS)),mingw) LIBXMLRPC_ABYSSPP_MODS += AbyssChanSwitchWin else LIBXMLRPC_ABYSSPP_MODS += AbyssChanSwitchUnix + ifeq ($(MUST_BUILD_OPENSSL),yes) + LIBXMLRPC_ABYSSPP_MODS += AbyssChanSwitchOpenSsl + endif endif TARGET_MODS_PP = \ @@ -65,10 +68,10 @@ all: \ #----------------------------------------------------------------------------- -# RULE TO LINK LIBRARIES +# RULES TO LINK LIBRARIES #----------------------------------------------------------------------------- -# The actual rules for this is in common.mk, courtesy of TARGET_LIB_NAMES_PP +# The actual rules for this are in common.mk, courtesy of TARGET_LIB_NAMES_PP # shlibfn generates e.g. libxmlrpc.so.3.1 # shliblefn generates e.g. libxmlrpc.so @@ -132,6 +135,9 @@ xmlrpc_abyss++.pc: .PHONY: install install: install-common +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean clean-local distclean distclean-local clean: clean-common clean-local clean-local: diff --git a/stable/lib/abyss/Makefile b/stable/lib/abyss/Makefile index a67562452..20b69a1e8 100644 --- a/stable/lib/abyss/Makefile +++ b/stable/lib/abyss/Makefile @@ -32,6 +32,9 @@ distdir: distdir-common .PHONY: install install: $(SUBDIRS:%=%/install) +.PHONY: uninstall +uninstall: $(SUBDIRS:%=%/uninstall) + .PHONY: dep dep: $(SUBDIRS:%=%/dep) diff --git a/stable/lib/abyss/src/Makefile b/stable/lib/abyss/src/Makefile index 18bc5a15c..1078f4e9b 100644 --- a/stable/lib/abyss/src/Makefile +++ b/stable/lib/abyss/src/Makefile @@ -20,9 +20,15 @@ SHARED_LIBS_TO_INSTALL := libxmlrpc_abyss ifeq ($(findstring mingw,$(HOST_OS)),mingw) THREAD_MODULE = thread_windows - SOCKET_MODULE = socket_win + SOCKET_MODS = socket_win else - SOCKET_MODULE = socket_unix + SOCKET_MODS = socket_unix + ifeq ($(MUST_BUILD_ABYSS_OPENSSL),yes) + SOCKET_MODS += socket_openssl + endif + + SOCKET_MODS += sockutil + ifeq ($(ENABLE_ABYSS_THREADS),yes) THREAD_MODULE = thread_pthread else @@ -44,12 +50,15 @@ TARGET_MODS = \ response \ server \ session \ + sessionReadRequest \ socket \ - $(SOCKET_MODULE) \ + $(SOCKET_MODS) \ token \ $(THREAD_MODULE) \ trace \ + + PKGCONFIG_FILES_TO_INSTALL := xmlrpc_abyss.pc OMIT_ABYSS_LIB_RULE = Y @@ -91,6 +100,9 @@ $(ABYSS_SHLIB): LIBDEP = $(LIBXMLRPC_UTIL_LIBDEP) $(SOCKETLIBOPT) ifeq ($(ENABLE_ABYSS_THREADS),yes) $(ABYSS_SHLIB): LIBDEP += $(THREAD_LIBS) endif +ifeq ($(MUST_BUILD_ABYSS_OPENSSL),yes) +$(ABYSS_SHLIB): LIBDEP += $(OPENSSL_LDADD) +endif # Rule for this is in common.mk, courtesy of TARGET_STATIC_LIBRARIES: @@ -104,6 +116,8 @@ libxmlrpc_abyss.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) # Rules to compile object modules from which to build the static and shared # Abyss library are in common.mk, courtesy of TARGET_MODS. +socket_openssl.o socket_openssl.osh: CFLAGS_TARGET=$(OPENSSL_CFLAGS) + #----------------------------------------------------------------------------- # RULES TO MAKE PKGCONFIG FILES @@ -144,6 +158,9 @@ distdir: .PHONY: install install: install-common +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: dep dep: dep-common diff --git a/stable/lib/abyss/src/chanswitch.c b/stable/lib/abyss/src/chanswitch.c index 0f544061e..a686aafa4 100644 --- a/stable/lib/abyss/src/chanswitch.c +++ b/stable/lib/abyss/src/chanswitch.c @@ -19,33 +19,105 @@ #include "xmlrpc-c/abyss.h" #if MSVCRT #include "socket_win.h" -#else +#endif +#if !MSVCRT #include "socket_unix.h" #endif +#if HAVE_ABYSS_OPENSSL + #include "socket_openssl.h" +#endif #include "chanswitch.h" -static void -socketOsInit(const char ** const errorP) { +static void +socketWinInit(const char ** const errorP) { #if MSVCRT SocketWinInit(errorP); #else - SocketUnixInit(errorP); + *errorP = NULL; #endif } static void -socketOsTerm(void) { - +socketWinTerm(void) { #if MSVCRT SocketWinTerm(); +#endif +} + + + +static void +socketUnixInit(const char ** const errorP) { +#if !MSVCRT + SocketUnixInit(errorP); #else + *errorP = NULL; +#endif +} + + + +static void +socketUnixTerm(void) { +#if !MSVCRT SocketUnixTerm(); #endif } + + + +static void +socketOpenSslTerm(void) { +#if HAVE_ABYSS_OPENSSL + SocketOpenSslTerm(); +#endif +} + + + +static void +socketOpenSslInit(const char ** const errorP) { +#if HAVE_ABYSS_OPENSSL + SocketOpenSslInit(errorP); +#else + *errorP = NULL; +#endif +} + + + +static void +socketOsInit(const char ** const errorP) { + + socketWinInit(errorP); + if (!*errorP) { + socketUnixInit(errorP); + if (!*errorP) { + socketOpenSslInit(errorP); + + if (*errorP) + socketUnixTerm(); + } + if (*errorP) + socketWinTerm(); + } +} + + + +static void +socketOsTerm(void) { + + socketOpenSslTerm(); + + socketUnixTerm(); + + socketWinTerm(); +} @@ -160,7 +232,7 @@ ChanSwitchAccept(TChanSwitch * const chanSwitchP, (*chanSwitchP->vtbl.accept)(chanSwitchP, channelPP, channelInfoPP, errorP); - if (SwitchTraceIsActive) + if (SwitchTraceIsActive && *errorP == NULL) fprintf(stderr, "Got connection from channel switch. " "Channel = %p\n", *channelPP); } diff --git a/stable/lib/abyss/src/file.h b/stable/lib/abyss/src/file.h index 57b1a75c5..d3840395a 100644 --- a/stable/lib/abyss/src/file.h +++ b/stable/lib/abyss/src/file.h @@ -14,7 +14,7 @@ #define NAME_MAX 1024 #endif -#ifdef WIN32 +#if MSVCRT #ifndef __BORLANDC__ #define O_APPEND _O_APPEND #define O_CREAT _O_CREAT @@ -35,28 +35,12 @@ #define A_SUBDIR 1 #define O_BINARY 0 #define O_TEXT 0 -#endif /* WIN32 */ - -#ifdef WIN32 +#endif /* MSVCRT */ #if MSVCRT typedef struct _stati64 TFileStat; typedef struct _finddatai64_t TFileInfo; - -#else /* MSVCRT */ - -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; - -#endif /* MSVCRT */ - -#else /* WIN32 */ +#else /* MSVCRT */ #include #include @@ -70,7 +54,7 @@ typedef struct finddata_t { time_t time_write; } TFileInfo; -#endif +#endif /* MSVCRT */ typedef struct TFileFind TFileFind; diff --git a/stable/lib/abyss/src/handler.c b/stable/lib/abyss/src/handler.c index c1beeef32..80a2914e7 100644 --- a/stable/lib/abyss/src/handler.c +++ b/stable/lib/abyss/src/handler.c @@ -8,20 +8,21 @@ #define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ +#include "xmlrpc_config.h" + #include #include #include #include #include #include -#ifdef _WIN32 +#if MSVCRT #include #else #include #endif #include -#include "xmlrpc_config.h" #include "bool.h" #include "int.h" #include "girmath.h" @@ -264,21 +265,16 @@ htmlTail(void) { static void -sendDirectoryDocument(TList * const listP, - bool const ascending, - uint16_t const sort, - bool const text, - const char * const uri, - MIMEType * const mimeTypeP, - TSession * const sessionP) { +sendDirectoryDocumentHeading(TSession * const sessionP, + const char * const uri, + bool const text) { char z[4096]; - char *p,z1[26],z2[20],z3[9],u; - const char * z4; - int16_t i; - uint32_t k; - + if (text) { + size_t i; + char * p; + sprintf(z, "Index of %s\r\n", uri); i = strlen(z)-2; p = z + i + 2; @@ -303,6 +299,26 @@ sendDirectoryDocument(TList * const listP, } HTTPWriteBodyChunk(sessionP, z, strlen(z)); +} + + + +static void +sendDirectoryDocument(TList * const listP, + bool const ascending, + uint16_t const sort, + bool const text, + const char * const uri, + MIMEType * const mimeTypeP, + TSession * const sessionP) { + + char z[4096]; + char *p,z1[26],z2[20],z3[9],u; + const char * z4; + int16_t i; + uint32_t k; + + sendDirectoryDocumentHeading(sessionP, uri, text); /* Sort the files */ qsort(listP->item, listP->size, sizeof(void *), @@ -702,7 +718,7 @@ HandlerDefaultBuiltin(TSession * const sessionP) { endingslash = false; /* initial value */ - if (!RequestValidURIPath(sessionP)) { + if (!HTTPRequestHasValidUriPath(sessionP)) { ResponseStatus(sessionP, 400); return true; } diff --git a/stable/lib/abyss/src/http.c b/stable/lib/abyss/src/http.c index 028e257b5..815906e45 100644 --- a/stable/lib/abyss/src/http.c +++ b/stable/lib/abyss/src/http.c @@ -28,1269 +28,38 @@ #include "http.h" -/********************************************************************* -** Request Parser -*********************************************************************/ - -/********************************************************************* -** Request -*********************************************************************/ - -static void -initRequestInfo(TRequestInfo * const requestInfoP, - httpVersion const httpVersion, - const char * const requestLine, - TMethod const httpMethod, - const char * const host, - unsigned int const port, - const char * const path, - const char * const query) { -/*---------------------------------------------------------------------------- - Set up the request info structure. For information that is - controlled by the header, use the defaults -- I.e. the value that - applies if the request contains no applicable header field. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_PTR_OK(requestLine); - XMLRPC_ASSERT_PTR_OK(path); - - requestInfoP->requestline = xmlrpc_strdupsol(requestLine); - requestInfoP->method = httpMethod; - requestInfoP->host = xmlrpc_strdupnull(host); - requestInfoP->port = port; - requestInfoP->uri = strdup(path); - requestInfoP->query = xmlrpc_strdupnull(query); - requestInfoP->from = NULL; - requestInfoP->useragent = NULL; - requestInfoP->referer = NULL; - requestInfoP->user = NULL; - - if (httpVersion.major > 1 || - (httpVersion.major == 1 && httpVersion.minor >= 1)) - requestInfoP->keepalive = true; - else - requestInfoP->keepalive = false; -} - - - -static void -freeRequestInfo(TRequestInfo * const requestInfoP) { - - xmlrpc_strfreenull(requestInfoP->host); - - xmlrpc_strfreenull(requestInfoP->user); - - xmlrpc_strfree(requestInfoP->uri); - - xmlrpc_strfree(requestInfoP->requestline); -} - - - -void -RequestInit(TSession * const sessionP, - TConn * const connectionP) { - - sessionP->validRequest = false; /* Don't have valid request yet */ - - sessionP->failureReason = NULL; - - time(&sessionP->date); - - sessionP->connP = connectionP; - - sessionP->responseStarted = false; - - sessionP->chunkedwrite = false; - sessionP->chunkedwritemode = false; - - sessionP->continueRequired = false; - - sessionP->requestIsChunked = false; - - sessionP->chunkState.position = CHUNK_ATHEADER; - - ListInit(&sessionP->cookies); - ListInit(&sessionP->ranges); - TableInit(&sessionP->requestHeaderFields); - TableInit(&sessionP->responseHeaderFields); - - sessionP->status = 0; /* No status from handler yet */ - - StringAlloc(&(sessionP->header)); -} - - - -void -RequestFree(TSession * const sessionP) { - - if (sessionP->validRequest) - freeRequestInfo(&sessionP->requestInfo); - - ListFree(&sessionP->cookies); - ListFree(&sessionP->ranges); - TableFree(&sessionP->requestHeaderFields); - TableFree(&sessionP->responseHeaderFields); - StringFree(&(sessionP->header)); -} - - - -static char * -firstLfPos(TConn * const connectionP, - char * const lineStart) { -/*---------------------------------------------------------------------------- - Return a pointer in the connection's receive buffer to the first - LF (linefeed aka newline) character in the buffer at or after 'lineStart'. - - If there is no LF in the buffer at or after 'lineStart', return NULL. ------------------------------------------------------------------------------*/ - const char * const bufferEnd = - connectionP->buffer.t + connectionP->buffersize; - - char * p; - - for (p = lineStart; p < bufferEnd && *p != '\n'; ++p); - - if (p < bufferEnd) - return p; - else - return NULL; -} - - - -static void -getLineInBuffer(TConn * const connectionP, - char * const lineStart, - time_t const deadline, - char ** const lineEndP, - bool * const timedOutP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Get a line into the connection's read buffer, starting at position - 'lineStart', if there isn't one already there. 'lineStart' is either - within the buffer or just after it. - - Read the channel until we get a full line, except fail if we don't get - one by 'deadline'. ------------------------------------------------------------------------------*/ - char * lfPos; - bool timedOut; - - assert(lineStart <= connectionP->buffer.t + connectionP->buffersize); - - for (*errorP = false, lfPos = NULL, timedOut = false; - !*errorP && !lfPos && !timedOut; - ) { - int const timeLeft = (int)(deadline - time(NULL)); - if (timeLeft <= 0) - timedOut = true; - else { - lfPos = firstLfPos(connectionP, lineStart); - if (!lfPos) { - if (ConnBufferSpace(connectionP) < 1) - xmlrpc_asprintf(errorP, "HTTP request header does not " - "fit in the server's connection buffer."); - else { - const char * readError; - ConnRead(connectionP, timeLeft, NULL, - &timedOut, &readError); - if (readError) { - xmlrpc_asprintf(errorP, "Failed to read from the " - "connection. %s", readError); - xmlrpc_strfree(readError); - } - } - } - } - } - *lineEndP = lfPos + 1; - *timedOutP = timedOut; -} - - - -static bool -isContinuationLine(const char * const line) { - - return (line[0] == ' ' || line[0] == '\t'); -} - - - -static bool -isEmptyLine(const char * const line) { - - return (line[0] == '\n' || (line[0] == '\r' && line[1] == '\n')); -} - - - -static void -convertLineEnd(char * const lineStart, - char * const prevLineStart, - char const newVal) { -/*---------------------------------------------------------------------------- - Assuming a line begins at 'lineStart' and the line before it (the - "previous line") begins at 'prevLineStart', replace the line - delimiter at the end of the previous line with the character 'newVal'. - - The line delimiter is either CRLF or LF. In the CRLF case, we replace - both CR and LF with 'newVal'. ------------------------------------------------------------------------------*/ - assert(lineStart >= prevLineStart + 1); - *(lineStart-1) = newVal; - if (prevLineStart + 1 < lineStart && - *(lineStart-2) == '\r') - *(lineStart-2) = newVal; -} +const char * +RequestHeaderValue(TSession * const sessionP, + const char * const name) { -static void -getRestOfField(TConn * const connectionP, - char * const lineEnd, - time_t const deadline, - const char ** const fieldEndP, - bool * const timedOutP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Given that the read buffer for connection *connectionP contains (at - its current read position) the first line of an HTTP header field, which - ends at position 'lineEnd', find or get the rest of it. - - Some or all of the rest of the field may be in the buffer already; - we read more from the connection as necessary, but not if it takes past - 'deadline'. In the latter case, we fail. - - We return the location of the end of the whole field as *headerEndP. - We do not remove the field from the buffer, but we do modify the - buffer so as to join the multiple lines of the field into a single - line, and to NUL-terminate the field. ------------------------------------------------------------------------------*/ - char * const fieldStart = connectionP->buffer.t + connectionP->bufferpos; - - char * fieldEnd; - /* End of the field lines we've seen at so far */ - bool gotWholeField; - bool timedOut; - - fieldEnd = lineEnd; /* initial value - end of 1st line */ - - for (gotWholeField = false, timedOut = false, *errorP = false; - !gotWholeField && !timedOut && !*errorP;) { - - char * nextLineEnd; - - /* Note that we are guaranteed, assuming the HTTP stream is - valid, that there is at least one more line in it. Worst - case, it's the empty line that marks the end of the headers. - */ - getLineInBuffer(connectionP, fieldEnd, deadline, - &nextLineEnd, &timedOut, errorP); - if (!*errorP) { - if (isContinuationLine(fieldEnd)) { - /* Join previous line to this one */ - convertLineEnd(fieldEnd, fieldStart, ' '); - /* Add this line to the header */ - fieldEnd = nextLineEnd; - } else { - gotWholeField = true; - - /* NUL-terminate the whole field */ - convertLineEnd(fieldEnd, fieldStart, '\0'); - } - } - } - *fieldEndP = fieldEnd; - *timedOutP = timedOut; -} - - - -static void -readField(TConn * const connectionP, - time_t const deadline, - bool * const endOfHeaderP, - char ** const fieldP, - bool * const timedOutP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Read an HTTP header field, or the end of header empty line, on connection - *connectionP. - - An HTTP header field is basically a line, except that if a line starts - with white space, it's a continuation of the previous line. A line - is delimited by either LF or CRLF. - - The first line of an HTTP header field is never empty; an empty line - signals the end of the HTTP header and beginning of the HTTP body. We - call that empty line the EOH mark. - - We assume the connection is positioned to a header or EOH mark. - - In the course of reading, we read at least one character past the - line delimiter at the end of the field or EOH mark; we may read - much more. But we leave everything after the field or EOH (and - its line delimiter) in the internal buffer, with the buffer pointer - pointing to it. - - We use stuff already in the internal buffer (perhaps left by a - previous call to this subroutine) before reading any more from from - the channel. - - We return as *fieldP the next field as an ASCIIZ string, with no - line delimiter. That string is stored in the "unused" portion of - the connection's internal buffer. Iff there is no next field, we - return *endOfHeaderP == true and nothing meaningful as *fieldP. ------------------------------------------------------------------------------*/ - char * const bufferStart = connectionP->buffer.t + connectionP->bufferpos; - - char * lineEnd; - const char * getLineError; - - getLineInBuffer(connectionP, bufferStart, deadline, &lineEnd, - timedOutP, &getLineError); - - if (getLineError) { - xmlrpc_asprintf(errorP, "Failed to get a line of HTTP header " - "from client. %s", getLineError); - xmlrpc_strfree(getLineError); - } else if (!*timedOutP) { - if (isContinuationLine(bufferStart)) - xmlrpc_asprintf(errorP, "Client sent continuation line when " - "we were expecting a new header"); - else if (isEmptyLine(bufferStart)) { - /* Consume the EOH mark from the buffer */ - connectionP->bufferpos = lineEnd - connectionP->buffer.t; - *endOfHeaderP = true; - *errorP = NULL; - } else { - /* We have the first line of a field; there may be more. */ - - const char * fieldEnd; - const char * error; - - *endOfHeaderP = false; - - getRestOfField(connectionP, lineEnd, deadline, - &fieldEnd, timedOutP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "After receiving the beginning of " - "an HTTP header field, failed to read " - "the rest of it. %s", error); - xmlrpc_strfree(error); - } else { - *errorP = NULL; - - if (!*timedOutP) { - *fieldP = bufferStart; - - /* Consume the header from the buffer (but be careful -- - you can't reuse that part of the buffer because the - string we will return is in it! - */ - connectionP->bufferpos = fieldEnd - connectionP->buffer.t; - } - } - } - } -} - - - -static void -skipToNonemptyLine(TConn * const connectionP, - time_t const deadline, - bool * const timedOutP, - const char ** const errorP) { - - char * const bufferStart = connectionP->buffer.t + connectionP->bufferpos; - - bool gotNonEmptyLine; - char * lineStart; - - for (lineStart = bufferStart, gotNonEmptyLine = false, *timedOutP = false, - *errorP = NULL; - !gotNonEmptyLine && !*timedOutP && !*errorP; ) { - - char * lineEnd; - - getLineInBuffer(connectionP, lineStart, deadline, &lineEnd, - timedOutP, errorP); - - if (!*errorP && !*timedOutP) { - if (!isEmptyLine(lineStart)) - gotNonEmptyLine = true; - else - lineStart = lineEnd; - } - } - if (!*errorP && !*timedOutP) { - /* Consume all the empty lines; advance buffer pointer to first - non-empty line. - */ - connectionP->bufferpos = lineStart - connectionP->buffer.t; - } -} - - - -static void -readRequestField(TSession * const sessionP, - time_t const deadline, - char ** const requestLineP, - bool * const timedOutP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Read the HTTP request field (POST, etc.) from session 'sessionP'. We read - through the session's internal buffer; i.e. we may get data that was - previously read from the network, or we may read more from the network. - - We assume the connection is presently positioned to the beginning of - the HTTP document. We leave it positioned after the request field. - - We ignore any empty lines at the beginning of the stream, per - RFC2616 Section 4.1. - - If we can't get the field before 'deadline', return *timedOutP = true. - - Return as *requestLineP the request field read. This ASCIIZ string is - in the session's internal buffer. ------------------------------------------------------------------------------*/ - char * line; - bool endOfHeader; - const char * skipError; - - skipToNonemptyLine(sessionP->connP, deadline, timedOutP, &skipError); - - if (skipError) { - xmlrpc_asprintf(errorP, "Failed to find the request field, " - "i.e. a non-empty line. %s", skipError); - xmlrpc_strfree(skipError); - } else if (!*timedOutP) { - const char * error; - - readField(sessionP->connP, deadline, &endOfHeader, &line, - timedOutP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Got beginning of the request field, " - "but failed to get the rest. %s", error); - xmlrpc_strfree(error); - } else { - *errorP = NULL; - - if (!*timedOutP) { - /* End of header is delimited by an empty line, and we skipped - all the empty lines above, so readField() could not have - encountered EOH: - */ - assert(!endOfHeader); - - *requestLineP = line; - } - } - } -} - - - -static void -hexDigitValue(char const digit, - unsigned int * const valueP, - const char ** const errorP) { - - if (digit == '\0') - xmlrpc_asprintf(errorP, "string ends in the middle of a " - "%% escape sequence"); - else { - char const digitLc = tolower(digit); - - if ((digitLc >= '0') && (digitLc <= '9')) { - *valueP = digitLc - '0'; - *errorP = NULL; - } else if ((digitLc >= 'a') && (digitLc <= 'f')) { - *valueP = 10 + digitLc - 'a'; - *errorP = NULL; - } else - xmlrpc_asprintf(errorP, "Non-hexadecimal digit '%c' in " - "%%HH escape sequence", digit); - } -} - - - -static void -parsePerCentEscape(const char ** const srcP, - char * const unescapedP, - const char ** const errorP) { -/*----------------------------------------------------------------------------- - With *srcP pointing to a supposed %HH escape sequence in a buffer, set - *unescapedP to the character that the sequence represents and advance *srcP - past it. ------------------------------------------------------------------------------*/ - unsigned int digit0; - - const char * src; - - src = *srcP; /* initial value */ - - ++src; /* Move past per cent sign */ - - if (!*src) - xmlrpc_asprintf(errorP, "URI ends after the %%"); - else { - *errorP = NULL; /* initial assumption */ - - hexDigitValue(*src++, &digit0, errorP); - - if (!*errorP) { - unsigned int digit1; - - if (!*src) - xmlrpc_asprintf(errorP, "URI ends after the first digit"); - else { - hexDigitValue(*src++, &digit1, errorP); - - if (!*errorP) - *unescapedP = ((digit0 << 4) | digit1); - } - } - } - *srcP = src; -} - - - -static void -unescapeUri(const char * const uriComponent, - const char ** const unescapedP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Unescape a component of a URI, e.g. the host name. That component may - have %HH encoding, especially of characters that are delimiters within - a URI like slash and colon. - - Return the unescaped version as *unescapedP in newly malloced storage. ------------------------------------------------------------------------------*/ - char * buffer; - - buffer = strdup(uriComponent); - - if (!buffer) - xmlrpc_asprintf(errorP, "Couldn't get memory for URI unescape buffer"); - else { - const char * src; - char * dst; - - src = dst = buffer; - - *errorP = NULL; /* initial value */ - - while (*src && !*errorP) { - switch (*src) { - case '%': { - char unescaped; - const char * error; - - parsePerCentEscape(&src, &unescaped, &error); - - if (error) { - xmlrpc_asprintf(errorP, - "Invalid %%HH escape sequence. %s", - error); - xmlrpc_strfree(error); - } else - *dst++ = unescaped; - } break; - - default: - *dst++ = *src++; - break; - } - } - *dst = '\0'; - - if (*errorP) - xmlrpc_strfree(buffer); - else - *unescapedP = buffer; - } -} - - - -static void -parseHostPort(const char * const hostport, - const char ** const hostP, - unsigned short * const portP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Parse a 'hostport', a string in the form www.acme.com:8080 . - - Return the host name part (www.acme.com) as *hostP (in newly - malloced storage), and the port part (8080) as *portP. - - Default the port to 80 if 'hostport' doesn't have the port part. ------------------------------------------------------------------------------*/ - char * buffer; - - buffer = strdup(hostport); - - if (!buffer) - xmlrpc_asprintf(errorP, "Couldn't get memory for host/port buffer"); - else { - /* Note that the host portion may contain colons. The old RFC says - it can't, but a newer one says the host may be an IPv6 address - in the form [x:x:x...]. But the port portion may contain only - digits, so we use the _last_ colon as the delimiter. - */ - char * const colonPos = strrchr(buffer, ':'); - - if (colonPos) { - const char * p; - uint32_t port; - - *colonPos = '\0'; /* Split hostport at the colon */ - - for (p = colonPos + 1, port = 0; - isdigit(*p) && port < 65535; - (port = port * 10 + (*p - '0')), ++p); - - if (*p || port == 0) { - xmlrpc_asprintf(errorP, "There is nothing, or something " - "non-numeric for the port number after the " - "colon in '%s'", hostport); - } else { - *hostP = xmlrpc_strdupsol(buffer); - *portP = port; - *errorP = NULL; - } - } else { - *hostP = xmlrpc_strdupsol(buffer); - *portP = 80; - *errorP = NULL; - } - free(buffer); - } -} - - - -static void -splitUriQuery(const char * const requestUri, - const char ** const queryP, - const char ** const noQueryP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Split 'requestUri' at the question mark, returning the stuff after - as *queryP and the stuff before as *noQueryP. ------------------------------------------------------------------------------*/ - char * buffer; - - buffer = strdup(requestUri); - - if (!buffer) - xmlrpc_asprintf(errorP, "Couldn't get memory for URI buffer"); - else { - char * const qmark = strchr(buffer, '?'); - - if (qmark) { - *qmark = '\0'; - *queryP = xmlrpc_strdupsol(qmark + 1); - } else - *queryP = NULL; - - *errorP = NULL; - *noQueryP = buffer; - } -} - - - -static void -parseHttpHostPortPath(const char * const hostportpath, - const char ** const hostP, - unsigned short* const portP, - const char ** const pathP, - const char ** const errorP) { - - const char * path; - - char * buffer; - - buffer = strdup(hostportpath); - - if (!buffer) - xmlrpc_asprintf(errorP, - "Couldn't get memory for host/port/path buffer"); - else { - char * const slashPos = strchr(buffer, '/'); - - char * hostport; - - if (slashPos) { - path = xmlrpc_strdupsol(slashPos); /* Includes the initial slash */ - - *slashPos = '\0'; /* NUL termination for hostport */ - } else - path = strdup("*"); - - hostport = buffer; - - /* The following interprets the port field without taking into account - any %HH encoding, as the RFC says may be there. We ignore that - remote possibility out of laziness. - */ - parseHostPort(hostport, hostP, portP, errorP); - - if (*errorP) - xmlrpc_strfree(path); - else - *pathP = path; - - free(buffer); - } -} - - - -static void -unescapeHostPathQuery(const char * const host, - const char * const path, - const char * const query, - const char ** const hostP, - const char ** const pathP, - const char ** const queryP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Unescape each of the four components of a URI. - - Each may be NULL, in which case we return NULL. ------------------------------------------------------------------------------*/ - if (host) - unescapeUri(host, hostP, errorP); - else - *hostP = NULL; - if (!*errorP) { - if (path) - unescapeUri(path, pathP, errorP); - else - *pathP = NULL; - if (!*errorP) { - if (query) - unescapeUri(query, queryP, errorP); - else - *queryP = NULL; - if (*errorP) - xmlrpc_strfree(*pathP); - } else { - if (*hostP) - xmlrpc_strfree(*hostP); - } - } -} - - - -static void -parseRequestUri(char * const requestUri, - const char ** const hostP, - unsigned short * const portP, - const char ** const pathP, - const char ** const queryP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Parse the request URI (in the request line - "GET http://www.myserver.com:8080/myfile.cgi?parm HTTP/1.1", - "http://www.myserver.com:8080/myfile.cgi?parm" is the request URI). - - Return as *hostP the "www.myserver.com" in the above example. If - that part of the URI doesn't exist, return *hostP == NULL. - - Return as *portP the 8080 in the above example. If it doesn't exist, - return 80. - - Return as *pathP the "/myfile.cgi" in the above example. If it - doesn't exist, return "*". - - Return as *queryP the "parm" in the above example. If it doesn't - exist, return *queryP == NULL. - - Return strings in newly malloc'ed storage. - - We can return syntactically invalid entities, e.g. a host name that - contains "<", if 'requestUri' is similarly invalid. We should fix that - some day. RFC 2396 lists a lot of characters as reserved for certain - use in the URI, such as colon, and totally disallowed, such as space. ------------------------------------------------------------------------------*/ - const char * requestUriNoQuery; - /* The request URI with any query (the stuff marked by a question - mark at the end of a request URI) chopped off. - */ - const char * query; - const char * path; - const char * host; - unsigned short port; - - splitUriQuery(requestUri, &query, &requestUriNoQuery, errorP); - if (!*errorP) { - if (requestUriNoQuery[0] == '/') { - host = NULL; - path = xmlrpc_strdupsol(requestUriNoQuery); - port = 80; - *errorP = NULL; - } else { - if (!xmlrpc_strneq(requestUriNoQuery, "http://", 7)) - xmlrpc_asprintf(errorP, "Scheme is not http://"); - else - parseHttpHostPortPath(&requestUriNoQuery[7], - &host, &port, &path, errorP); - } - - if (!*errorP) { - *portP = port; - unescapeHostPathQuery(host, path, query, - hostP, pathP, queryP, errorP); - - if (host) - xmlrpc_strfree(host); - if (path) - xmlrpc_strfree(path); - } - - if (query) - xmlrpc_strfree(query); - xmlrpc_strfree(requestUriNoQuery); - } -} - - - -static TMethod -methodFromMethodName(const char * const httpMethodName) { - - if (xmlrpc_streq(httpMethodName, "GET")) - return m_get; - else if (xmlrpc_streq(httpMethodName, "PUT")) - return m_put; - else if (xmlrpc_streq(httpMethodName, "OPTIONS")) - return m_options; - else if (xmlrpc_streq(httpMethodName, "DELETE")) - return m_delete; - else if (xmlrpc_streq(httpMethodName, "POST")) - return m_post; - else if (xmlrpc_streq(httpMethodName, "TRACE")) - return m_trace; - else if (xmlrpc_streq(httpMethodName, "HEAD")) - return m_head; - else - return m_unknown; -} - - - -static void -parseHttpVersion(const char * const textFromReqLine, - httpVersion * const httpVersionP, - const char ** const errorP) { - - uint32_t vmin, vmaj; - - if (sscanf(textFromReqLine, "HTTP/%d.%d", &vmaj, &vmin) != 2) - xmlrpc_asprintf(errorP, "Does not have the form HTTP/n.n"); - else { - *errorP = NULL; - httpVersionP->major = vmaj; - httpVersionP->minor = vmin; - } -} - - - -static void -parseRequestLine(char * const requestLine, - TMethod * const httpMethodP, - httpVersion * const httpVersionP, - const char ** const hostP, - unsigned short * const portP, - const char ** const pathP, - const char ** const queryP, - bool * const moreLinesP, - const char ** const errorP) { - - char * const requestBuffer = strdup(requestLine); - - const char * httpMethodName; - char * p; - - if (requestBuffer == NULL) - xmlrpc_asprintf(errorP, "Couldn't get memory for working buffer"); - else { - p = requestBuffer; - - /* Jump over spaces */ - NextToken((const char **)&p); - - httpMethodName = GetToken(&p); - if (!httpMethodName) - xmlrpc_asprintf(errorP, "No method name (e.g. \"GET\")"); - else { - char * requestUri; - - *httpMethodP = methodFromMethodName(httpMethodName); - - /* URI and Query Decoding */ - NextToken((const char **)&p); - - requestUri = GetToken(&p); - if (!requestUri) - xmlrpc_asprintf(errorP, "No URI after the method name ('%s')", - httpMethodName); - else { - const char * host; - unsigned short port; - const char * path; - const char * query; - const char * error; - - parseRequestUri(requestUri, - &host, &port, &path, &query, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Invalid URI ('%s'). %s", - requestUri, error); - xmlrpc_strfree(error); - } else { - const char * httpVersion; - - NextToken((const char **)&p); - - /* HTTP Version Decoding */ - - httpVersion = GetToken(&p); - if (httpVersion) { - const char * error; - parseHttpVersion(httpVersion, httpVersionP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Invalid HTTP version " - "token ('%s'). %s", - httpVersion, error); - xmlrpc_strfree(error); - } else { - *errorP = NULL; - *moreLinesP = true; - } - } else { - /* There is no HTTP version, so this is a single - line request. - */ - *errorP = NULL; - *moreLinesP = false; - } - if (*errorP) { - xmlrpc_strfree(host); - xmlrpc_strfree(path); - xmlrpc_strfree(query); - } - *hostP = host; - *portP = port; - *pathP = path; - *queryP = query; - } - } - } - xmlrpc_strfree(requestBuffer); - } -} - - - -static void -strtolower(char * const s) { - - char * t; - - t = &s[0]; - while (*t) { - *t = tolower(*t); - ++t; - } -} - - - -static void -getFieldNameToken(char ** const pP, - char ** const fieldNameP, - const char ** const errorP, - uint16_t * const httpErrorCodeP) { -/*---------------------------------------------------------------------------- - Assuming that *pP points to the place in an HTTP header where the field - name belongs, return the field name and advance *pP past that token. - - The field name is the lower case representation of the value of the - field name token. - - If the field name is invalid, return a text explanation as *errorP - and a suitable HTTP status code as *httpErrorCodeP. If not, return - *errorP == NULL and nothing as *httpErrorCodeP. ------------------------------------------------------------------------------*/ - char * fieldName; - - NextToken((const char **)pP); - - fieldName = GetToken(pP); - if (!fieldName) { - xmlrpc_asprintf(errorP, "The header has no field name token"); - *httpErrorCodeP = 400; /* Bad Request */ - } else { - if (fieldName[strlen(fieldName)-1] != ':') { - /* Not a valid field name */ - xmlrpc_asprintf(errorP, "The field name token '%s' " - "does not end with a colon (:)", fieldName); - *httpErrorCodeP = 400; /* Bad Request */ - } else { - fieldName[strlen(fieldName)-1] = '\0'; /* remove trailing colon */ - - strtolower(fieldName); - - *errorP = NULL; - } - } - *fieldNameP = fieldName; -} - - - -static void -processField(const char * const fieldName, - char * const fieldValue, - TSession * const sessionP, - const char ** const errorP, - uint16_t * const httpErrorCodeP) { -/*---------------------------------------------------------------------------- - We may modify *fieldValue, and we put pointers to *fieldValue and - *fieldName into *sessionP. - - We must fix this some day. *sessionP should point to individual - malloc'ed strings. ------------------------------------------------------------------------------*/ - *errorP = NULL; /* initial assumption */ - - if (xmlrpc_streq(fieldName, "connection")) { - if (xmlrpc_strcaseeq(fieldValue, "keep-alive")) - sessionP->requestInfo.keepalive = true; - else - sessionP->requestInfo.keepalive = false; - } else if (xmlrpc_streq(fieldName, "host")) { - if (sessionP->requestInfo.host) { - xmlrpc_strfree(sessionP->requestInfo.host); - sessionP->requestInfo.host = NULL; - } - parseHostPort(fieldValue, &sessionP->requestInfo.host, - &sessionP->requestInfo.port, errorP); - } else if (xmlrpc_streq(fieldName, "from")) - sessionP->requestInfo.from = fieldValue; - else if (xmlrpc_streq(fieldName, "user-agent")) - sessionP->requestInfo.useragent = fieldValue; - else if (xmlrpc_streq(fieldName, "referer")) - sessionP->requestInfo.referer = fieldValue; - else if (xmlrpc_streq(fieldName, "range")) { - if (xmlrpc_strneq(fieldValue, "bytes=", 6)) { - bool succeeded; - succeeded = ListAddFromString(&sessionP->ranges, &fieldValue[6]); - if (!succeeded) { - xmlrpc_asprintf(errorP, "ListAddFromString() failed for " - "\"range: bytes=...\" header value '%s'", - &fieldValue[6]); - *httpErrorCodeP = 400; - } - } - } else if (xmlrpc_streq(fieldName, "cookies")) { - bool succeeded; - succeeded = ListAddFromString(&sessionP->cookies, fieldValue); - if (!succeeded) { - xmlrpc_asprintf(errorP, "ListAddFromString() failed for " - "cookies: header value '%s'", fieldValue); - *httpErrorCodeP = 400; - } - } else if (xmlrpc_streq(fieldName, "expect")) { - if (xmlrpc_strcaseeq(fieldValue, "100-continue")) - sessionP->continueRequired = true; - } else if (xmlrpc_streq(fieldName, "transfer-encoding")) { - if (xmlrpc_strcaseeq(fieldValue, "chunked")) - sessionP->requestIsChunked = true; - else if (xmlrpc_strcaseeq(fieldValue, "identity")) { - // Same as no transfer-encoding specified - } else { - xmlrpc_asprintf(errorP, "Server does not know '%s' transfer " - "encoding. It knows only 'chunked' and " - "'identity'", fieldValue); - *httpErrorCodeP = 501; - } - } -} - - - -static void -readAndProcessHeaderFields(TSession * const sessionP, - time_t const deadline, - const char ** const errorP, - uint16_t * const httpErrorCodeP) { -/*---------------------------------------------------------------------------- - Read all the HTTP header fields from the session *sessionP, which has at - least one field coming. Update *sessionP to reflect the information in the - fields. - - If we find an error in the fields or while trying to read them, we return - a text explanation of the problem as *errorP and an appropriate HTTP error - code as *httpErrorCodeP. Otherwise, we return *errorP = NULL and nothing - as *httpErrorCodeP. ------------------------------------------------------------------------------*/ - bool endOfHeader; - bool timedOut; - - assert(!sessionP->validRequest); - /* Calling us doesn't make sense if there is already a valid request */ - - for (endOfHeader = false, *errorP = NULL, timedOut = false; - !endOfHeader && !*errorP && !timedOut; ) { - char * field; - const char * error; - readField(sessionP->connP, deadline, &endOfHeader, &field, - &timedOut, &error); - if (error) { - xmlrpc_asprintf(errorP, "Failed to read header from " - "client connection. %s", error); - *httpErrorCodeP = 500; /* Internal server error */ - xmlrpc_strfree(error); - } else if (timedOut) { - xmlrpc_asprintf(errorP, "Timed out wating for client to send " - "something"); - *httpErrorCodeP = 408; /* Request timed out */ - } else { - if (!endOfHeader) { - char * p; - char * fieldName; - - p = &field[0]; - getFieldNameToken(&p, &fieldName, errorP, httpErrorCodeP); - if (!*errorP) { - char * fieldValue; - - NextToken((const char **)&p); - - fieldValue = p; - - TableAdd(&sessionP->requestHeaderFields, - fieldName, fieldValue); - - processField(fieldName, fieldValue, sessionP, errorP, - httpErrorCodeP); - } - } - } - } -} - - - -void -RequestRead(TSession * const sessionP, - uint32_t const timeout, - const char ** const errorP, - uint16_t * const httpErrorCodeP) { -/*---------------------------------------------------------------------------- - Read the headers of a new HTTP request (assuming nothing has yet been - read on the session). - - Update *sessionP with the information from the headers. - - Leave the connection positioned to the body of the request, ready - to be read by an HTTP request handler (via SessionRefillBuffer() and - SessionGetReadData()). - - If we are unable to read the headers, we return a text description as - *errorP and a suitable HTTP status code as *httpErrorCodeP. - - If we successfully read the headers, we return *errorP == NULL and - nothing as *httpErrorCodeP. ------------------------------------------------------------------------------*/ - time_t const deadline = time(NULL) + timeout; - - bool timedOut; - const char * error; - char * requestLine; /* In connection's internal buffer */ - - readRequestField(sessionP, deadline, &requestLine, &timedOut, &error); - if (error) { - xmlrpc_asprintf(errorP, "Problem getting the request header. %s", - error); - *httpErrorCodeP = 500; /* Internal error */ - xmlrpc_strfree(error); - } else if (timedOut) { - xmlrpc_asprintf(errorP, "Timed out waiting for client to send " - "the request field"); - *httpErrorCodeP = 408; /* Request timed out */ - } else { - TMethod httpMethod; - const char * host; - const char * path; - const char * query; - unsigned short port; - bool moreFields; - const char * error; - - parseRequestLine(requestLine, &httpMethod, &sessionP->version, - &host, &port, &path, &query, - &moreFields, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Unable to parse the request header " - "'%s'. %s", requestLine, error); - *httpErrorCodeP = 400; /* Bad request */ - xmlrpc_strfree(error); - } else { - initRequestInfo(&sessionP->requestInfo, sessionP->version, - requestLine, - httpMethod, host, port, path, query); - - if (moreFields) { - readAndProcessHeaderFields(sessionP, deadline, - errorP, httpErrorCodeP); - } else - *errorP = NULL; - - if (!*errorP) - sessionP->validRequest = true; - - xmlrpc_strfreenull(host); - xmlrpc_strfree(path); - xmlrpc_strfreenull(query); - } - } + return TableValue(&sessionP->requestHeaderFields, name); } const char * -RequestHeaderValue(TSession * const sessionP, - const char * const name) { - - return TableValue(&sessionP->requestHeaderFields, name); +HTTPMethodName(TMethod const method) { + + switch (method) { + case m_unknown: return "UNKNOWN"; + case m_get: return "GET"; + case m_put: return "PUT"; + case m_head: return "HEAD"; + case m_post: return "POST"; + case m_delete: return "DELETE"; + case m_trace: return "TRACE"; + case m_options: return "OPTIONS"; + } + assert(false); /* Compiler ought to know this, but doesn't */ + return 0; /* quiet compiler warning */ } bool -RequestValidURI(TSession * const sessionP) { +HTTPRequestHasValidUri(TSession * const sessionP) { if (!sessionP->requestInfo.uri) return false; @@ -1307,7 +76,7 @@ RequestValidURI(TSession * const sessionP) { bool -RequestValidURIPath(TSession * const sessionP) { +HTTPRequestHasValidUriPath(TSession * const sessionP) { uint32_t i; const char * p; @@ -1530,16 +299,6 @@ HTTPReasonByStatus(uint16_t const code) { -int32_t -HTTPRead(TSession * const s ATTR_UNUSED, - const char * const buffer ATTR_UNUSED, - uint32_t const len ATTR_UNUSED) { - - return 0; -} - - - bool HTTPWriteBodyChunk(TSession * const sessionP, const char * const buffer, diff --git a/stable/lib/abyss/src/http.h b/stable/lib/abyss/src/http.h index 3883a8af0..e7fac458f 100644 --- a/stable/lib/abyss/src/http.h +++ b/stable/lib/abyss/src/http.h @@ -2,39 +2,20 @@ #define HTTP_H_INCLUDED #include +#include "xmlrpc-c/abyss.h" -#include "bool.h" -#include "conn.h" - -/********************************************************************* -** Request -*********************************************************************/ - -bool RequestValidURI(TSession * const r); -bool RequestValidURIPath(TSession * const r); -bool RequestUnescapeURI(TSession *r); - -void -RequestRead(TSession * const sessionP, - uint32_t const timeout, - const char ** const errorP, - uint16_t * const httpErrorCodeP); +const char * +HTTPMethodName(TMethod const method); -void RequestInit(TSession * const r,TConn * const c); -void RequestFree(TSession * const r); +bool +HTTPRequestHasValidUri(TSession * const sessionP); -/********************************************************************* -** HTTP -*********************************************************************/ +bool +HTTPRequestHasValidUriPath(TSession * const sessionP); const char * HTTPReasonByStatus(uint16_t const code); -int32_t -HTTPRead(TSession * const sessionP, - const char * const buffer, - uint32_t const len); - bool HTTPWriteBodyChunk(TSession * const sessionP, const char * const buffer, diff --git a/stable/lib/abyss/src/server.c b/stable/lib/abyss/src/server.c index 41c851719..13dbdf0ec 100644 --- a/stable/lib/abyss/src/server.c +++ b/stable/lib/abyss/src/server.c @@ -8,6 +8,11 @@ #include #include #include +#if MSVCRT + #include +#else + #include +#endif #include #include #include @@ -39,6 +44,7 @@ #endif #include "http.h" #include "handler.h" +#include "sessionReadRequest.h" #include "server.h" @@ -124,9 +130,9 @@ logClose(struct _TServer * const srvP) { static void setupTrace(struct _TServer * const srvP) { - srvP->traceIsActive = (getenv("ABYSS_TRACE_SERVER") != NULL); + srvP->tracer.traceIsActive = (getenv("ABYSS_TRACE_SERVER") != NULL); - if (srvP->traceIsActive) + if (srvP->tracer.traceIsActive) fprintf(stderr, "Abyss server will trace " "basic server activity " "because of ABYSS_TRACE_SERVER environment variable\n"); @@ -146,11 +152,11 @@ tracev(const char * const fmt, static void -trace(struct _TServer * const srvP, - const char * const fmt, +trace(struct Tracer * const tracerP, + const char * const fmt, ...) { - if (srvP->traceIsActive) { + if (tracerP->traceIsActive) { va_list argptr; va_start(argptr, fmt); @@ -199,7 +205,9 @@ createServer(struct _TServer ** const srvPP, bool const userChanSwitch, unsigned short const portNumber, const char ** const errorP) { - +/*---------------------------------------------------------------------------- + Create a server object and return it as *srvPP. +-----------------------------------------------------------------------------*/ struct _TServer * srvP; MALLOCVAR(srvP); @@ -234,7 +242,8 @@ createServer(struct _TServer ** const srvPP, srvP->uriHandlerStackSize = 0; srvP->maxConn = 15; srvP->maxConnBacklog = 15; - + srvP->maxSessionMem = 0; + initUnixStuff(srvP); ListInitAutoFree(&srvP->handlers); @@ -283,6 +292,12 @@ ServerCreate(TServer * const serverP, xmlrpc_uint16_t const portNumber, const char * const filesPath, const char * const logFileName) { +/*---------------------------------------------------------------------------- + Create a server that will listen for and accept client connections on TCP + port 'portNumber'. Those connections will be raw TCP connections. + + Set *serverP to represent that server. +-----------------------------------------------------------------------------*/ bool const noAcceptFalse = false; bool const userChanSwitchFalse = false; @@ -348,7 +363,12 @@ ServerCreateSocket(TServer * const serverP, TOsSocket const socketFd, const char * const filesPath, const char * const logFileName) { +/*---------------------------------------------------------------------------- + Create a server that will listen for and accept client connections on + socket 'socketFd'. Those connections will be raw TCP connections. + Set *serverP to represent that server. +-----------------------------------------------------------------------------*/ bool success; TChanSwitch * chanSwitchP; const char * error; @@ -392,7 +412,13 @@ ServerCreateNoAccept(TServer * const serverP, const char * const name, const char * const filesPath, const char * const logFileName) { +/*---------------------------------------------------------------------------- + Create a server that will not get client connections; the user will have to + get the client connections and use server methods that take an existing + connection as an argument. + Set *serverP to represent that server. +-----------------------------------------------------------------------------*/ bool const noAcceptTrue = true; bool const userChanSwitchFalse = false; @@ -421,7 +447,14 @@ void ServerCreateSwitch(TServer * const serverP, TChanSwitch * const chanSwitchP, const char ** const errorP) { - +/*---------------------------------------------------------------------------- + Create a server that will get client connections from channel switch + *chanSwitchP. Those connections would typically be raw TCP connections, + but could be anything that can be abstracted by a Channel object. For + example, an SSL encrypted TCP connection. + + Set *serverP to represent that server. +-----------------------------------------------------------------------------*/ bool const noAcceptFalse = false; bool const userChanSwitchTrue = true; @@ -600,6 +633,16 @@ ServerSetMaxConnBacklog(TServer * const serverP, +void +ServerSetMaxSessionMem(TServer * const serverP, + size_t const size) { + + if (size > 0) + serverP->srvP->maxSessionMem = size; +} + + + static URIHandler2 makeUriHandler2(const struct uriHandler * const handlerP) { @@ -674,10 +717,24 @@ handleReqInvalidURI(TSession * const sessionP) { static void -processRequestFromClient(TConn * const connectionP, - bool const lastReqOnConn, - uint32_t const timeout, - bool * const keepAliveP) { +traceRequestStart(struct Tracer * const tracerP, + TSession * const sessionP) { + + if (sessionP->requestInfo.uri) { + trace(tracerP, "Processing request with URI '%s', method %s", + sessionP->requestInfo.uri, + HTTPMethodName(sessionP->requestInfo.method)); + } +} + + + +static void +processRequestFromClient(TConn * const connectionP, + bool const lastReqOnConn, + uint32_t const timeout, + struct Tracer * const tracerP, + bool * const keepAliveP) { /*---------------------------------------------------------------------------- Get and execute one HTTP request from client connection *connectionP, through the connection buffer. I.e. Some of the request may already be in @@ -706,20 +763,21 @@ processRequestFromClient(TConn * const connectionP, const char * error; uint16_t httpErrorCode; - RequestInit(&session, connectionP); + SessionInit(&session, connectionP); session.serverDeniesKeepalive = lastReqOnConn; - RequestRead(&session, timeout, &error, &httpErrorCode); + SessionReadRequest(&session, timeout, &error, &httpErrorCode); if (error) { ResponseStatus(&session, httpErrorCode); ResponseError2(&session, error); xmlrpc_strfree(error); } else { + traceRequestStart(tracerP, &session); if (session.version.major >= 2) handleReqTooNewHttpVersion(&session); - else if (!RequestValidURI(&session)) + else if (!HTTPRequestHasValidUri(&session)) handleReqInvalidURI(&session); else runUserHandler(&session, connectionP->server->srvP); @@ -736,7 +794,7 @@ processRequestFromClient(TConn * const connectionP, SessionLog(&session); - RequestFree(&session); + SessionTerm(&session); } @@ -757,8 +815,9 @@ serverFunc(void * const userHandle) { bool connectionDone; /* No more need for this HTTP connection */ - trace(srvP, "Thread starting to handle requests on a new connection. " - "PID = %d", getpid()); + trace(&srvP->tracer, + "Thread starting to handle requests on a new connection. " + "PID = %d", XMLRPC_GETPID()); requestCount = 0; connectionDone = false; @@ -791,13 +850,15 @@ serverFunc(void * const userHandle) { bool keepalive; - trace(srvP, "HTTP request %u at least partially received. " + trace(&srvP->tracer, + "HTTP request %u at least partially received. " "Receiving the rest and processing", requestCount); processRequestFromClient(connectionP, lastReqOnConn, srvP->timeout, - &keepalive); + &srvP->tracer, &keepalive); - trace(srvP, "Done processing the HTTP request. Keepalive = %s", + trace(&srvP->tracer, + "Done processing the HTTP request. Keepalive = %s", keepalive ? "YES" : "NO"); ++requestCount; @@ -809,7 +870,7 @@ serverFunc(void * const userHandle) { ConnReadInit(connectionP); } } - trace(srvP, "PID %d done with connection", getpid()); + trace(&srvP->tracer, "PID %d done with connection", XMLRPC_GETPID()); } @@ -1144,7 +1205,7 @@ processNewChannel(TServer * const serverP, freeFinishedConns(outstandingConnListP); - trace(srvP, "Waiting for there to be fewer than the maximum " + trace(&srvP->tracer, "Waiting for there to be fewer than the maximum " "%u sessions in progress", srvP->maxConn); @@ -1184,7 +1245,7 @@ acceptAndProcessNextConnection( TChannel * channelP; void * channelInfoP; - trace(srvP, "Waiting for a new channel from channel switch"); + trace(&srvP->tracer, "Waiting for a new channel from channel switch"); assert(srvP->readyToAccept); assert(srvP->chanSwitchP); @@ -1200,7 +1261,7 @@ acceptAndProcessNextConnection( if (channelP) { const char * error; - trace(srvP, "Got a new channel from channel switch"); + trace(&srvP->tracer, "Got a new channel from channel switch"); processNewChannel(serverP, channelP, channelInfoP, outstandingConnListP, &error); @@ -1211,14 +1272,16 @@ acceptAndProcessNextConnection( ChannelDestroy(channelP); free(channelInfoP); } else { - trace(srvP, "successfully processed newly accepted channel"); + trace(&srvP->tracer, + "successfully processed newly accepted channel"); /* Connection created above will destroy *channelP and *channelInfoP as it terminates. */ } } else { /* Accept function was interrupted before it got a connection */ - trace(srvP, "Wait for new channel from switch was interrupted"); + trace(&srvP->tracer, + "Wait for new channel from switch was interrupted"); *errorP = NULL; } } @@ -1237,15 +1300,16 @@ serverRun2(TServer * const serverP, *errorP = NULL; /* initial value */ - trace(srvP, "Starting main connection accepting loop"); + trace(&srvP->tracer, "Starting main connection accepting loop"); while (!srvP->terminationRequested && !*errorP) acceptAndProcessNextConnection(serverP, outstandingConnListP, errorP); - trace(srvP, "Main connection accepting loop is done"); + trace(&srvP->tracer, "Main connection accepting loop is done"); if (!*errorP) { - trace(srvP, "Interrupting and waiting for %u existing connections " + trace(&srvP->tracer, + "Interrupting and waiting for %u existing connections " "to finish", outstandingConnListP->count); @@ -1253,7 +1317,7 @@ serverRun2(TServer * const serverP, waitForNoConnections(outstandingConnListP); - trace(srvP, "No connections left"); + trace(&srvP->tracer, "No connections left"); destroyOutstandingConnList(outstandingConnListP); } @@ -1266,7 +1330,7 @@ ServerRun(TServer * const serverP) { struct _TServer * const srvP = serverP->srvP; - trace(srvP, "%s entered", __FUNCTION__); + trace(&srvP->tracer, "%s entered", __FUNCTION__); if (!srvP->serverAcceptsConnections) TraceMsg("This server is not set up to accept connections " @@ -1286,7 +1350,7 @@ ServerRun(TServer * const serverP) { xmlrpc_strfree(error); } } - trace(srvP, "%s exiting", __FUNCTION__); + trace(&srvP->tracer, "%s exiting", __FUNCTION__); } @@ -1308,7 +1372,7 @@ serverRunChannel(TServer * const serverP, TConn * connectionP; const char * error; - trace(srvP, "%s entered", __FUNCTION__); + trace(&srvP->tracer, "%s entered", __FUNCTION__); srvP->keepalivemaxconn = 1; @@ -1328,7 +1392,7 @@ serverRunChannel(TServer * const serverP, ConnWaitAndRelease(connectionP); } - trace(srvP, "%s exiting", __FUNCTION__); + trace(&srvP->tracer, "%s exiting", __FUNCTION__); } @@ -1346,7 +1410,7 @@ ServerRunChannel(TServer * const serverP, -----------------------------------------------------------------------------*/ struct _TServer * const srvP = serverP->srvP; - trace(srvP, "%s entered", __FUNCTION__); + trace(&srvP->tracer, "%s entered", __FUNCTION__); if (srvP->serverAcceptsConnections) xmlrpc_asprintf(errorP, @@ -1356,7 +1420,7 @@ ServerRunChannel(TServer * const serverP, else serverRunChannel(serverP, channelP, channelInfoP, errorP); - trace(srvP, "%s exiting", __FUNCTION__); + trace(&srvP->tracer, "%s exiting", __FUNCTION__); } @@ -1418,15 +1482,15 @@ ServerRunConn(TServer * const serverP, void ServerRunOnce(TServer * const serverP) { /*---------------------------------------------------------------------------- - Accept a connection from the channel switch and do the HTTP - transaction that comes over it. + Accept a connection from the channel switch and do the HTTP transaction + that comes over it. - If no connection is presently waiting at the switch, wait for one. - But return immediately if we receive a signal during the wait. + If no connection is presently waiting at the switch, wait for one. But + return immediately if we receive a signal during the wait. -----------------------------------------------------------------------------*/ struct _TServer * const srvP = serverP->srvP; - trace(srvP, "%s entered", __FUNCTION__); + trace(&srvP->tracer, "%s entered", __FUNCTION__); if (!srvP->serverAcceptsConnections) TraceMsg("This server is not set up to accept connections " @@ -1468,7 +1532,7 @@ ServerRunOnce(TServer * const serverP) { } } } - trace(srvP, "%s exiting", __FUNCTION__); + trace(&srvP->tracer, "%s exiting", __FUNCTION__); } @@ -1560,7 +1624,7 @@ ServerDaemonize(TServer * const serverP) { if (srvP->pidfileP) { char z[16]; - sprintf(z, "%d", getpid()); + sprintf(z, "%d", XMLRPC_GETPID()); FileWrite(srvP->pidfileP, z, strlen(z)); FileClose(srvP->pidfileP); } diff --git a/stable/lib/abyss/src/server.h b/stable/lib/abyss/src/server.h index 2891a562b..0462e74c9 100644 --- a/stable/lib/abyss/src/server.h +++ b/stable/lib/abyss/src/server.h @@ -12,9 +12,13 @@ struct TFile; -struct _TServer { +struct Tracer { bool traceIsActive; /* We should report to Standard Error our internal activities */ +}; + +struct _TServer { + struct Tracer tracer; bool terminationRequested; /* User wants this server to terminate as soon as possible, @@ -68,6 +72,15 @@ struct _TServer { connections on the server's behalf and holds them waiting for the server to accept them from the OS. */ + size_t maxSessionMem; + /* The maximum memory the server can use for certain purposes for a + single session. These purposes consist of things where the size + of the memory is unpredictable, especially under the control of the + client. This limit stops clients from using too much memory and + consequently denying service to other clients. + + Zero means no limit. + */ TList handlers; /* Ordered list of HTTP request handlers. For each HTTP request, Server calls each one in order until one reports that it handled diff --git a/stable/lib/abyss/src/session.c b/stable/lib/abyss/src/session.c index 83ebbacb2..2fac2d970 100644 --- a/stable/lib/abyss/src/session.c +++ b/stable/lib/abyss/src/session.c @@ -625,3 +625,102 @@ SessionGetDefaultHandlerCtx(TSession * const sessionP) { return srvP->defaultHandlerContext; } + + + +void +SessionInit(TSession * const sessionP, + TConn * const connectionP) { + + sessionP->validRequest = false; /* Don't have valid request yet */ + + sessionP->failureReason = NULL; + + time(&sessionP->date); + + sessionP->connP = connectionP; + + sessionP->responseStarted = false; + + sessionP->chunkedwrite = false; + sessionP->chunkedwritemode = false; + + sessionP->continueRequired = false; + + sessionP->requestIsChunked = false; + + sessionP->chunkState.position = CHUNK_ATHEADER; + + sessionP->memPoolP = NULL; + + ListInit(&sessionP->cookies); + ListInit(&sessionP->ranges); + TableInit(&sessionP->requestHeaderFields); + TableInit(&sessionP->responseHeaderFields); + + sessionP->status = 0; /* No status from handler yet */ + + StringAlloc(&(sessionP->header)); +} + + + +static void +freeRequestInfo(TRequestInfo * const requestInfoP) { + + xmlrpc_strfreenull(requestInfoP->host); + + xmlrpc_strfreenull(requestInfoP->user); + + xmlrpc_strfree(requestInfoP->uri); + + xmlrpc_strfree(requestInfoP->requestline); +} + + + +void +SessionTerm(TSession * const sessionP) { + + if (sessionP->validRequest) + freeRequestInfo(&sessionP->requestInfo); + + ListFree(&sessionP->cookies); + ListFree(&sessionP->ranges); + TableFree(&sessionP->requestHeaderFields); + TableFree(&sessionP->responseHeaderFields); + StringFree(&(sessionP->header)); + + if (sessionP->memPoolP) + xmlrpc_mem_pool_free(sessionP->memPoolP); +} + + + +void +SessionMakeMemPool(TSession * const sessionP, + size_t const size, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Set up a memory pool for this session. All future allocations of memory + for certain purposes will come from this pool. + + The point of this is that the pool has limited size, so this puts a limit + on how much memory the session can use. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + + xmlrpc_env_init(&env); + + sessionP->memPoolP = xmlrpc_mem_pool_new(&env, size); + + if (env.fault_occurred) + *errorP = xmlrpc_strdupsol(env.fault_string); + else + *errorP = NULL; + + xmlrpc_env_clean(&env); +} + + + diff --git a/stable/lib/abyss/src/session.h b/stable/lib/abyss/src/session.h index 381e41220..bfbaaf645 100644 --- a/stable/lib/abyss/src/session.h +++ b/stable/lib/abyss/src/session.h @@ -2,9 +2,11 @@ #define SESSION_H_INCLUDED #include "xmlrpc-c/abyss.h" +#include "xmlrpc-c/util_int.h" #include "bool.h" #include "date.h" #include "data.h" +#include "conn.h" typedef struct { uint8_t major; @@ -28,6 +30,16 @@ struct _TSession { reads the request from the client and finds it to be valid HTTP, it becomes true. */ + xmlrpc_mem_pool * memPoolP; + /* The memory pool from which various memory needed for our processing + comes. We don't allocate all memory from here; just parts that + have unpredictable size that might allow a client to get more than + its share of system meomry if we didn't limit it. This pool has a + limited size. + + NULL means all memory comes from the general system pool and there + is therefore no protection of clients from each other. + */ const char * failureReason; /* This is non-null to indicate that we have encountered a protocol error or other problem in the session and the session cannot @@ -113,5 +125,22 @@ struct _TSession { } chunkState; }; +/*---------------------------------------------------------------------------- + Following are methods of a TSession object private to Abyss. Other + methods are for use by user Uri handlers and are declared in the + external abyss.h header file. +-----------------------------------------------------------------------------*/ + +void +SessionInit(TSession * const sessionP, + TConn * const c); + +void +SessionTerm(TSession * const sessionP); + +void +SessionMakeMemPool(TSession * const sessionP, + size_t const size, + const char ** const errorP); #endif diff --git a/stable/lib/abyss/src/sessionReadRequest.c b/stable/lib/abyss/src/sessionReadRequest.c new file mode 100644 index 000000000..0b77d3ff7 --- /dev/null +++ b/stable/lib/abyss/src/sessionReadRequest.c @@ -0,0 +1,1210 @@ +#define _XOPEN_SOURCE 600 /* For strdup() */ +#define _BSD_SOURCE /* For xmlrpc_strcaseeq() */ + +#include +#include +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "bool.h" +#include "mallocvar.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/base64_int.h" +#include "xmlrpc-c/abyss.h" + +#include "server.h" +#include "session.h" +#include "conn.h" +#include "token.h" +#include "date.h" +#include "data.h" + +#include "sessionReadRequest.h" + + + +static void +initRequestInfo(TRequestInfo * const requestInfoP, + httpVersion const httpVersion, + const char * const requestLine, + TMethod const httpMethod, + const char * const host, + unsigned int const port, + const char * const path, + const char * const query) { +/*---------------------------------------------------------------------------- + Set up the request info structure. For information that is + controlled by the header, use the defaults -- I.e. the value that + applies if the request contains no applicable header field. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_PTR_OK(requestLine); + XMLRPC_ASSERT_PTR_OK(path); + + requestInfoP->requestline = xmlrpc_strdupsol(requestLine); + requestInfoP->method = httpMethod; + requestInfoP->host = xmlrpc_strdupnull(host); + requestInfoP->port = port; + requestInfoP->uri = strdup(path); + requestInfoP->query = xmlrpc_strdupnull(query); + requestInfoP->from = NULL; + requestInfoP->useragent = NULL; + requestInfoP->referer = NULL; + requestInfoP->user = NULL; + + if (httpVersion.major > 1 || + (httpVersion.major == 1 && httpVersion.minor >= 1)) + requestInfoP->keepalive = true; + else + requestInfoP->keepalive = false; +} + + + +static char * +firstLfPos(TConn * const connectionP, + char * const lineStart) { +/*---------------------------------------------------------------------------- + Return a pointer in the connection's receive buffer to the first + LF (linefeed aka newline) character in the buffer at or after 'lineStart'. + + If there is no LF in the buffer at or after 'lineStart', return NULL. +-----------------------------------------------------------------------------*/ + const char * const bufferEnd = + connectionP->buffer.t + connectionP->buffersize; + + char * p; + + for (p = lineStart; p < bufferEnd && *p != '\n'; ++p); + + if (p < bufferEnd) + return p; + else + return NULL; +} + + + +static void +getLineInBuffer(TConn * const connectionP, + char * const lineStart, + time_t const deadline, + char ** const lineEndP, + bool * const timedOutP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Get a line into the connection's read buffer, starting at position + 'lineStart', if there isn't one already there. 'lineStart' is either + within the buffer or just after it. + + Read the channel until we get a full line, except fail if we don't get + one by 'deadline'. +-----------------------------------------------------------------------------*/ + char * lfPos; + bool timedOut; + + assert(lineStart <= connectionP->buffer.t + connectionP->buffersize); + + for (*errorP = NULL, lfPos = NULL, timedOut = false; + !*errorP && !lfPos && !timedOut; + ) { + int const timeLeft = (int)(deadline - time(NULL)); + if (timeLeft <= 0) + timedOut = true; + else { + lfPos = firstLfPos(connectionP, lineStart); + if (!lfPos) { + if (ConnBufferSpace(connectionP) < 1) + xmlrpc_asprintf(errorP, "HTTP request header does not " + "fit in the server's connection buffer."); + else { + const char * readError; + ConnRead(connectionP, timeLeft, NULL, + &timedOut, &readError); + if (readError) { + xmlrpc_asprintf(errorP, "Failed to read from the " + "connection. %s", readError); + xmlrpc_strfree(readError); + } + } + } + } + } + *lineEndP = lfPos + 1; + *timedOutP = timedOut; +} + + + +static bool +isContinuationLine(const char * const line) { + + return (line[0] == ' ' || line[0] == '\t'); +} + + + +static bool +isEmptyLine(const char * const line) { + + return (line[0] == '\n' || (line[0] == '\r' && line[1] == '\n')); +} + + + +static void +convertLineEnd(char * const lineStart, + char * const prevLineStart, + char const newVal) { +/*---------------------------------------------------------------------------- + Assuming a line begins at 'lineStart' and the line before it (the + "previous line") begins at 'prevLineStart', replace the line + delimiter at the end of the previous line with the character 'newVal'. + + The line delimiter is either CRLF or LF. In the CRLF case, we replace + both CR and LF with 'newVal'. +-----------------------------------------------------------------------------*/ + assert(lineStart >= prevLineStart + 1); + *(lineStart-1) = newVal; + if (prevLineStart + 1 < lineStart && + *(lineStart-2) == '\r') + *(lineStart-2) = newVal; +} + + + +static void +getRestOfField(TConn * const connectionP, + char * const lineEnd, + time_t const deadline, + const char ** const fieldEndP, + bool * const timedOutP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Given that the read buffer for connection *connectionP contains (at + its current read position) the first line of an HTTP header field, which + ends at position 'lineEnd', find or get the rest of it. + + Some or all of the rest of the field may be in the buffer already; + we read more from the connection as necessary, but not if it takes past + 'deadline'. In the latter case, we fail. + + We return the location of the end of the whole field as *headerEndP. + We do not remove the field from the buffer, but we do modify the + buffer so as to join the multiple lines of the field into a single + line, and to NUL-terminate the field. +-----------------------------------------------------------------------------*/ + char * const fieldStart = connectionP->buffer.t + connectionP->bufferpos; + + char * fieldEnd; + /* End of the field lines we've seen at so far */ + bool gotWholeField; + bool timedOut; + + fieldEnd = lineEnd; /* initial value - end of 1st line */ + + for (gotWholeField = false, timedOut = false, *errorP = NULL; + !gotWholeField && !timedOut && !*errorP;) { + + char * nextLineEnd; + + /* Note that we are guaranteed, assuming the HTTP stream is + valid, that there is at least one more line in it. Worst + case, it's the empty line that marks the end of the headers. + */ + getLineInBuffer(connectionP, fieldEnd, deadline, + &nextLineEnd, &timedOut, errorP); + if (!*errorP) { + if (isContinuationLine(fieldEnd)) { + /* Join previous line to this one */ + convertLineEnd(fieldEnd, fieldStart, ' '); + /* Add this line to the header */ + fieldEnd = nextLineEnd; + } else { + gotWholeField = true; + + /* NUL-terminate the whole field */ + convertLineEnd(fieldEnd, fieldStart, '\0'); + } + } + } + *fieldEndP = fieldEnd; + *timedOutP = timedOut; +} + + + +static void +readField(TConn * const connectionP, + time_t const deadline, + bool * const endOfHeaderP, + char ** const fieldP, + bool * const timedOutP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Read an HTTP header field, or the end of header empty line, on connection + *connectionP. + + An HTTP header field is basically a line, except that if a line starts + with white space, it's a continuation of the previous line. A line + is delimited by either LF or CRLF. + + The first line of an HTTP header field is never empty; an empty line + signals the end of the HTTP header and beginning of the HTTP body. We + call that empty line the EOH mark. + + We assume the connection is positioned to a header or EOH mark. + + In the course of reading, we read at least one character past the + line delimiter at the end of the field or EOH mark; we may read + much more. But we leave everything after the field or EOH (and + its line delimiter) in the internal buffer, with the buffer pointer + pointing to it. + + We use stuff already in the internal buffer (perhaps left by a + previous call to this subroutine) before reading any more from from + the channel. + + We return as *fieldP the next field as an ASCIIZ string, with no + line delimiter. That string is stored in the "unused" portion of + the connection's internal buffer. Iff there is no next field, we + return *endOfHeaderP == true and nothing meaningful as *fieldP. +-----------------------------------------------------------------------------*/ + char * const bufferStart = connectionP->buffer.t + connectionP->bufferpos; + + char * lineEnd; + const char * getLineError; + + getLineInBuffer(connectionP, bufferStart, deadline, &lineEnd, + timedOutP, &getLineError); + + if (getLineError) { + xmlrpc_asprintf(errorP, "Failed to get a line of HTTP header " + "from client. %s", getLineError); + xmlrpc_strfree(getLineError); + } else if (!*timedOutP) { + if (isContinuationLine(bufferStart)) + xmlrpc_asprintf(errorP, "Client sent continuation line when " + "we were expecting a new header"); + else if (isEmptyLine(bufferStart)) { + /* Consume the EOH mark from the buffer */ + connectionP->bufferpos = lineEnd - connectionP->buffer.t; + *endOfHeaderP = true; + *errorP = NULL; + } else { + /* We have the first line of a field; there may be more. */ + + const char * fieldEnd; + const char * error; + + *endOfHeaderP = false; + + getRestOfField(connectionP, lineEnd, deadline, + &fieldEnd, timedOutP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "After receiving the beginning of " + "an HTTP header field, failed to read " + "the rest of it. %s", error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + + if (!*timedOutP) { + *fieldP = bufferStart; + + /* Consume the header from the buffer (but be careful -- + you can't reuse that part of the buffer because the + string we will return is in it! + */ + connectionP->bufferpos = fieldEnd - connectionP->buffer.t; + } + } + } + } +} + + + +static void +skipToNonemptyLine(TConn * const connectionP, + time_t const deadline, + bool * const timedOutP, + const char ** const errorP) { + + char * const bufferStart = connectionP->buffer.t + connectionP->bufferpos; + + bool gotNonEmptyLine; + char * lineStart; + + for (lineStart = bufferStart, gotNonEmptyLine = false, *timedOutP = false, + *errorP = NULL; + !gotNonEmptyLine && !*timedOutP && !*errorP; ) { + + char * lineEnd; + + getLineInBuffer(connectionP, lineStart, deadline, &lineEnd, + timedOutP, errorP); + + if (!*errorP && !*timedOutP) { + if (!isEmptyLine(lineStart)) + gotNonEmptyLine = true; + else + lineStart = lineEnd; + } + } + if (!*errorP && !*timedOutP) { + /* Consume all the empty lines; advance buffer pointer to first + non-empty line. + */ + connectionP->bufferpos = lineStart - connectionP->buffer.t; + } +} + + + +static void +readRequestField(TSession * const sessionP, + time_t const deadline, + char ** const requestLineP, + bool * const timedOutP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Read the HTTP request field (POST, etc.) from session 'sessionP'. We read + through the session's internal buffer; i.e. we may get data that was + previously read from the network, or we may read more from the network. + + We assume the connection is presently positioned to the beginning of + the HTTP document. We leave it positioned after the request field. + + We ignore any empty lines at the beginning of the stream, per + RFC2616 Section 4.1. + + If we can't get the field before 'deadline', return *timedOutP = true. + + Return as *requestLineP the request field read. This ASCIIZ string is + in the session's internal buffer. +-----------------------------------------------------------------------------*/ + char * line; + bool endOfHeader; + const char * skipError; + + skipToNonemptyLine(sessionP->connP, deadline, timedOutP, &skipError); + + if (skipError) { + xmlrpc_asprintf(errorP, "Failed to find the request field, " + "i.e. a non-empty line. %s", skipError); + xmlrpc_strfree(skipError); + } else if (!*timedOutP) { + const char * error; + + readField(sessionP->connP, deadline, &endOfHeader, &line, + timedOutP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Got beginning of the request field, " + "but failed to get the rest. %s", error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + + if (!*timedOutP) { + /* End of header is delimited by an empty line, and we skipped + all the empty lines above, so readField() could not have + encountered EOH: + */ + assert(!endOfHeader); + + *requestLineP = line; + } + } + } +} + + + +static void +hexDigitValue(char const digit, + unsigned int * const valueP, + const char ** const errorP) { + + if (digit == '\0') + xmlrpc_asprintf(errorP, "string ends in the middle of a " + "%% escape sequence"); + else { + char const digitLc = tolower(digit); + + if ((digitLc >= '0') && (digitLc <= '9')) { + *valueP = digitLc - '0'; + *errorP = NULL; + } else if ((digitLc >= 'a') && (digitLc <= 'f')) { + *valueP = 10 + digitLc - 'a'; + *errorP = NULL; + } else + xmlrpc_asprintf(errorP, "Non-hexadecimal digit '%c' in " + "%%HH escape sequence", digit); + } +} + + + +static void +parsePerCentEscape(const char ** const srcP, + char * const unescapedP, + const char ** const errorP) { +/*----------------------------------------------------------------------------- + With *srcP pointing to a supposed %HH escape sequence in a buffer, set + *unescapedP to the character that the sequence represents and advance *srcP + past it. +-----------------------------------------------------------------------------*/ + unsigned int digit0; + + const char * src; + + src = *srcP; /* initial value */ + + ++src; /* Move past per cent sign */ + + if (!*src) + xmlrpc_asprintf(errorP, "URI ends after the %%"); + else { + *errorP = NULL; /* initial assumption */ + + hexDigitValue(*src++, &digit0, errorP); + + if (!*errorP) { + unsigned int digit1; + + if (!*src) + xmlrpc_asprintf(errorP, "URI ends after the first digit"); + else { + hexDigitValue(*src++, &digit1, errorP); + + if (!*errorP) + *unescapedP = ((digit0 << 4) | digit1); + } + } + } + *srcP = src; +} + + + +static void +unescapeUri(const char * const uriComponent, + const char ** const unescapedP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Unescape a component of a URI, e.g. the host name. That component may + have %HH encoding, especially of characters that are delimiters within + a URI like slash and colon. + + Return the unescaped version as *unescapedP in newly malloced storage. +-----------------------------------------------------------------------------*/ + char * buffer; + + buffer = strdup(uriComponent); + + if (!buffer) + xmlrpc_asprintf(errorP, "Couldn't get memory for URI unescape buffer"); + else { + const char * src; + char * dst; + + src = dst = buffer; + + *errorP = NULL; /* initial value */ + + while (*src && !*errorP) { + switch (*src) { + case '%': { + char unescaped; + const char * error; + + parsePerCentEscape(&src, &unescaped, &error); + + if (error) { + xmlrpc_asprintf(errorP, + "Invalid %%HH escape sequence. %s", + error); + xmlrpc_strfree(error); + } else + *dst++ = unescaped; + } break; + + default: + *dst++ = *src++; + break; + } + } + *dst = '\0'; + + if (*errorP) + xmlrpc_strfree(buffer); + else + *unescapedP = buffer; + } +} + + + +static void +parseHostPort(const char * const hostport, + const char ** const hostP, + unsigned short * const portP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Parse a 'hostport', a string in the form www.acme.com:8080 . + + Return the host name part (www.acme.com) as *hostP (in newly + malloced storage), and the port part (8080) as *portP. + + Default the port to 80 if 'hostport' doesn't have the port part. +-----------------------------------------------------------------------------*/ + char * buffer; + + buffer = strdup(hostport); + + if (!buffer) + xmlrpc_asprintf(errorP, "Couldn't get memory for host/port buffer"); + else { + /* Note that the host portion may contain colons. The old RFC says + it can't, but a newer one says the host may be an IPv6 address + in the form [x:x:x...]. But the port portion may contain only + digits, so we use the _last_ colon as the delimiter. + */ + char * const colonPos = strrchr(buffer, ':'); + + if (colonPos) { + const char * p; + uint32_t port; + + *colonPos = '\0'; /* Split hostport at the colon */ + + for (p = colonPos + 1, port = 0; + isdigit(*p) && port < 65535; + (port = port * 10 + (*p - '0')), ++p); + + if (*p || port == 0) { + xmlrpc_asprintf(errorP, "There is nothing, or something " + "non-numeric for the port number after the " + "colon in '%s'", hostport); + } else { + *hostP = xmlrpc_strdupsol(buffer); + *portP = port; + *errorP = NULL; + } + } else { + *hostP = xmlrpc_strdupsol(buffer); + *portP = 80; + *errorP = NULL; + } + free(buffer); + } +} + + + +static void +splitUriQuery(const char * const requestUri, + const char ** const queryP, + const char ** const noQueryP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Split 'requestUri' at the question mark, returning the stuff after + as *queryP and the stuff before as *noQueryP. +-----------------------------------------------------------------------------*/ + char * buffer; + + buffer = strdup(requestUri); + + if (!buffer) + xmlrpc_asprintf(errorP, "Couldn't get memory for URI buffer"); + else { + char * const qmark = strchr(buffer, '?'); + + if (qmark) { + *qmark = '\0'; + *queryP = xmlrpc_strdupsol(qmark + 1); + } else + *queryP = NULL; + + *errorP = NULL; + *noQueryP = buffer; + } +} + + + +static void +parseHttpHostPortPath(const char * const hostportpath, + const char ** const hostP, + unsigned short* const portP, + const char ** const pathP, + const char ** const errorP) { + + const char * path; + + char * buffer; + + buffer = strdup(hostportpath); + + if (!buffer) + xmlrpc_asprintf(errorP, + "Couldn't get memory for host/port/path buffer"); + else { + char * const slashPos = strchr(buffer, '/'); + + char * hostport; + + if (slashPos) { + path = xmlrpc_strdupsol(slashPos); /* Includes the initial slash */ + + *slashPos = '\0'; /* NUL termination for hostport */ + } else + path = strdup("*"); + + hostport = buffer; + + /* The following interprets the port field without taking into account + any %HH encoding, as the RFC says may be there. We ignore that + remote possibility out of laziness. + */ + parseHostPort(hostport, hostP, portP, errorP); + + if (*errorP) + xmlrpc_strfree(path); + else + *pathP = path; + + free(buffer); + } +} + + + +static void +unescapeHostPathQuery(const char * const host, + const char * const path, + const char * const query, + const char ** const hostP, + const char ** const pathP, + const char ** const queryP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Unescape each of the four components of a URI. + + Each may be NULL, in which case we return NULL. +-----------------------------------------------------------------------------*/ + if (host) + unescapeUri(host, hostP, errorP); + else + *hostP = NULL; + if (!*errorP) { + if (path) + unescapeUri(path, pathP, errorP); + else + *pathP = NULL; + if (!*errorP) { + if (query) + unescapeUri(query, queryP, errorP); + else + *queryP = NULL; + if (*errorP) + xmlrpc_strfree(*pathP); + } else { + if (*hostP) + xmlrpc_strfree(*hostP); + } + } +} + + + +static void +parseRequestUri(char * const requestUri, + const char ** const hostP, + unsigned short * const portP, + const char ** const pathP, + const char ** const queryP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Parse the request URI (in the request line + "GET http://www.myserver.com:8080/myfile.cgi?parm HTTP/1.1", + "http://www.myserver.com:8080/myfile.cgi?parm" is the request URI). + + Return as *hostP the "www.myserver.com" in the above example. If + that part of the URI doesn't exist, return *hostP == NULL. + + Return as *portP the 8080 in the above example. If it doesn't exist, + return 80. + + Return as *pathP the "/myfile.cgi" in the above example. If it + doesn't exist, return "*". + + Return as *queryP the "parm" in the above example. If it doesn't + exist, return *queryP == NULL. + + Return strings in newly malloc'ed storage. + + We can return syntactically invalid entities, e.g. a host name that + contains "<", if 'requestUri' is similarly invalid. We should fix that + some day. RFC 2396 lists a lot of characters as reserved for certain + use in the URI, such as colon, and totally disallowed, such as space. +-----------------------------------------------------------------------------*/ + const char * requestUriNoQuery; + /* The request URI with any query (the stuff marked by a question + mark at the end of a request URI) chopped off. + */ + const char * query; + const char * path; + const char * host; + unsigned short port; + + splitUriQuery(requestUri, &query, &requestUriNoQuery, errorP); + if (!*errorP) { + if (requestUriNoQuery[0] == '/') { + host = NULL; + path = xmlrpc_strdupsol(requestUriNoQuery); + port = 80; + *errorP = NULL; + } else { + if (!xmlrpc_strneq(requestUriNoQuery, "http://", 7)) + xmlrpc_asprintf(errorP, "Scheme is not http://"); + else + parseHttpHostPortPath(&requestUriNoQuery[7], + &host, &port, &path, errorP); + } + + if (!*errorP) { + *portP = port; + unescapeHostPathQuery(host, path, query, + hostP, pathP, queryP, errorP); + + if (host) + xmlrpc_strfree(host); + if (path) + xmlrpc_strfree(path); + } + + if (query) + xmlrpc_strfree(query); + xmlrpc_strfree(requestUriNoQuery); + } +} + + + +static TMethod +methodFromMethodName(const char * const httpMethodName) { + + if (xmlrpc_streq(httpMethodName, "GET")) + return m_get; + else if (xmlrpc_streq(httpMethodName, "PUT")) + return m_put; + else if (xmlrpc_streq(httpMethodName, "OPTIONS")) + return m_options; + else if (xmlrpc_streq(httpMethodName, "DELETE")) + return m_delete; + else if (xmlrpc_streq(httpMethodName, "POST")) + return m_post; + else if (xmlrpc_streq(httpMethodName, "TRACE")) + return m_trace; + else if (xmlrpc_streq(httpMethodName, "HEAD")) + return m_head; + else + return m_unknown; +} + + + +static void +parseHttpVersion(const char * const textFromReqLine, + httpVersion * const httpVersionP, + const char ** const errorP) { + + uint32_t vmin, vmaj; + + if (sscanf(textFromReqLine, "HTTP/%d.%d", &vmaj, &vmin) != 2) + xmlrpc_asprintf(errorP, "Does not have the form HTTP/n.n"); + else { + *errorP = NULL; + httpVersionP->major = vmaj; + httpVersionP->minor = vmin; + } +} + + + +static void +parseRequestLine(char * const requestLine, + TMethod * const httpMethodP, + httpVersion * const httpVersionP, + const char ** const hostP, + unsigned short * const portP, + const char ** const pathP, + const char ** const queryP, + bool * const moreLinesP, + const char ** const errorP) { + + char * const requestBuffer = strdup(requestLine); + + const char * httpMethodName; + char * p; + + if (requestBuffer == NULL) + xmlrpc_asprintf(errorP, "Couldn't get memory for working buffer"); + else { + p = requestBuffer; + + /* Jump over spaces */ + NextToken((const char **)&p); + + httpMethodName = GetToken(&p); + if (!httpMethodName) + xmlrpc_asprintf(errorP, "No method name (e.g. \"GET\")"); + else { + char * requestUri; + + *httpMethodP = methodFromMethodName(httpMethodName); + + /* URI and Query Decoding */ + NextToken((const char **)&p); + + requestUri = GetToken(&p); + if (!requestUri) + xmlrpc_asprintf(errorP, "No URI after the method name ('%s')", + httpMethodName); + else { + const char * host; + unsigned short port; + const char * path; + const char * query; + const char * error; + + parseRequestUri(requestUri, + &host, &port, &path, &query, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Invalid URI ('%s'). %s", + requestUri, error); + xmlrpc_strfree(error); + } else { + const char * httpVersion; + + NextToken((const char **)&p); + + /* HTTP Version Decoding */ + + httpVersion = GetToken(&p); + if (httpVersion) { + const char * error; + parseHttpVersion(httpVersion, httpVersionP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Invalid HTTP version " + "token ('%s'). %s", + httpVersion, error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + *moreLinesP = true; + } + } else { + /* There is no HTTP version, so this is a single + line request. + */ + *errorP = NULL; + *moreLinesP = false; + } + if (*errorP) { + xmlrpc_strfree(host); + xmlrpc_strfree(path); + xmlrpc_strfree(query); + } + *hostP = host; + *portP = port; + *pathP = path; + *queryP = query; + } + } + } + xmlrpc_strfree(requestBuffer); + } +} + + + +static void +strtolower(char * const s) { + + char * t; + + t = &s[0]; + while (*t) { + *t = tolower(*t); + ++t; + } +} + + + +static void +getFieldNameToken(char ** const pP, + char ** const fieldNameP, + const char ** const errorP, + uint16_t * const httpErrorCodeP) { +/*---------------------------------------------------------------------------- + Assuming that *pP points to the place in an HTTP header where the field + name belongs, return the field name and advance *pP past that token. + + The field name is the lower case representation of the value of the + field name token. + + If the field name is invalid, return a text explanation as *errorP + and a suitable HTTP status code as *httpErrorCodeP. If not, return + *errorP == NULL and nothing as *httpErrorCodeP. +-----------------------------------------------------------------------------*/ + char * fieldName; + + NextToken((const char **)pP); + + fieldName = GetToken(pP); + if (!fieldName) { + xmlrpc_asprintf(errorP, "The header has no field name token"); + *httpErrorCodeP = 400; /* Bad Request */ + } else { + if (fieldName[strlen(fieldName)-1] != ':') { + /* Not a valid field name */ + xmlrpc_asprintf(errorP, "The field name token '%s' " + "does not end with a colon (:)", fieldName); + *httpErrorCodeP = 400; /* Bad Request */ + } else { + fieldName[strlen(fieldName)-1] = '\0'; /* remove trailing colon */ + + strtolower(fieldName); + + *errorP = NULL; + } + } + *fieldNameP = fieldName; +} + + + +static void +processField(const char * const fieldName, + char * const fieldValue, + TSession * const sessionP, + const char ** const errorP, + uint16_t * const httpErrorCodeP) { +/*---------------------------------------------------------------------------- + We may modify *fieldValue, and we put pointers to *fieldValue and + *fieldName into *sessionP. + + We must fix this some day. *sessionP should point to individual + malloc'ed strings. +-----------------------------------------------------------------------------*/ + *errorP = NULL; /* initial assumption */ + + if (xmlrpc_streq(fieldName, "connection")) { + if (xmlrpc_strcaseeq(fieldValue, "keep-alive")) + sessionP->requestInfo.keepalive = true; + else + sessionP->requestInfo.keepalive = false; + } else if (xmlrpc_streq(fieldName, "host")) { + if (sessionP->requestInfo.host) { + xmlrpc_strfree(sessionP->requestInfo.host); + sessionP->requestInfo.host = NULL; + } + parseHostPort(fieldValue, &sessionP->requestInfo.host, + &sessionP->requestInfo.port, errorP); + } else if (xmlrpc_streq(fieldName, "from")) + sessionP->requestInfo.from = fieldValue; + else if (xmlrpc_streq(fieldName, "user-agent")) + sessionP->requestInfo.useragent = fieldValue; + else if (xmlrpc_streq(fieldName, "referer")) + sessionP->requestInfo.referer = fieldValue; + else if (xmlrpc_streq(fieldName, "range")) { + if (xmlrpc_strneq(fieldValue, "bytes=", 6)) { + bool succeeded; + succeeded = ListAddFromString(&sessionP->ranges, &fieldValue[6]); + if (!succeeded) { + xmlrpc_asprintf(errorP, "ListAddFromString() failed for " + "\"range: bytes=...\" header value '%s'", + &fieldValue[6]); + *httpErrorCodeP = 400; + } + } + } else if (xmlrpc_streq(fieldName, "cookies")) { + bool succeeded; + succeeded = ListAddFromString(&sessionP->cookies, fieldValue); + if (!succeeded) { + xmlrpc_asprintf(errorP, "ListAddFromString() failed for " + "cookies: header value '%s'", fieldValue); + *httpErrorCodeP = 400; + } + } else if (xmlrpc_streq(fieldName, "expect")) { + if (xmlrpc_strcaseeq(fieldValue, "100-continue")) + sessionP->continueRequired = true; + } else if (xmlrpc_streq(fieldName, "transfer-encoding")) { + if (xmlrpc_strcaseeq(fieldValue, "chunked")) + sessionP->requestIsChunked = true; + else if (xmlrpc_strcaseeq(fieldValue, "identity")) { + // Same as no transfer-encoding specified + } else { + xmlrpc_asprintf(errorP, "Server does not know '%s' transfer " + "encoding. It knows only 'chunked' and " + "'identity'", fieldValue); + *httpErrorCodeP = 501; + } + } +} + + + +static void +readAndProcessHeaderFields(TSession * const sessionP, + time_t const deadline, + const char ** const errorP, + uint16_t * const httpErrorCodeP) { +/*---------------------------------------------------------------------------- + Read all the HTTP header fields from the session *sessionP, which has at + least one field coming. Update *sessionP to reflect the information in the + fields. + + If we find an error in the fields or while trying to read them, we return + a text explanation of the problem as *errorP and an appropriate HTTP error + code as *httpErrorCodeP. Otherwise, we return *errorP = NULL and nothing + as *httpErrorCodeP. +-----------------------------------------------------------------------------*/ + bool endOfHeader; + bool timedOut; + + assert(!sessionP->validRequest); + /* Calling us doesn't make sense if there is already a valid request */ + + for (endOfHeader = false, *errorP = NULL, timedOut = false; + !endOfHeader && !*errorP && !timedOut; ) { + char * field; + const char * error; + readField(sessionP->connP, deadline, &endOfHeader, &field, + &timedOut, &error); + if (error) { + xmlrpc_asprintf(errorP, "Failed to read header from " + "client connection. %s", error); + *httpErrorCodeP = 500; /* Internal server error */ + xmlrpc_strfree(error); + } else if (timedOut) { + xmlrpc_asprintf(errorP, "Timed out wating for client to send " + "something"); + *httpErrorCodeP = 408; /* Request timed out */ + } else { + if (!endOfHeader) { + char * p; + char * fieldName; + + p = &field[0]; + getFieldNameToken(&p, &fieldName, errorP, httpErrorCodeP); + if (!*errorP) { + char * fieldValue; + + NextToken((const char **)&p); + + fieldValue = p; + + TableAdd(&sessionP->requestHeaderFields, + fieldName, fieldValue); + + processField(fieldName, fieldValue, sessionP, errorP, + httpErrorCodeP); + } + } + } + } +} + + + +void +SessionReadRequest(TSession * const sessionP, + uint32_t const timeout, + const char ** const errorP, + uint16_t * const httpErrorCodeP) { +/*---------------------------------------------------------------------------- + Read the headers of a new HTTP request (assuming nothing has yet been + read on the session). + + Update *sessionP with the information from the headers. + + Leave the connection positioned to the body of the request, ready + to be read by an HTTP request handler (via SessionRefillBuffer() and + SessionGetReadData()). + + If we are unable to read the headers, we return a text description as + *errorP and a suitable HTTP status code as *httpErrorCodeP. + + If we successfully read the headers, we return *errorP == NULL and + nothing as *httpErrorCodeP. +-----------------------------------------------------------------------------*/ + time_t const deadline = time(NULL) + timeout; + + bool timedOut; + const char * error; + char * requestLine; /* In connection's internal buffer */ + + readRequestField(sessionP, deadline, &requestLine, &timedOut, &error); + if (error) { + xmlrpc_asprintf(errorP, "Problem getting the request header. %s", + error); + *httpErrorCodeP = 500; /* Internal error */ + xmlrpc_strfree(error); + } else if (timedOut) { + xmlrpc_asprintf(errorP, "Timed out waiting for client to send " + "the request field"); + *httpErrorCodeP = 408; /* Request timed out */ + } else { + TMethod httpMethod; + const char * host; + const char * path; + const char * query; + unsigned short port; + bool moreFields; + const char * error; + + parseRequestLine(requestLine, &httpMethod, &sessionP->version, + &host, &port, &path, &query, + &moreFields, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Unable to parse the request header " + "'%s'. %s", requestLine, error); + *httpErrorCodeP = 400; /* Bad request */ + xmlrpc_strfree(error); + } else { + initRequestInfo(&sessionP->requestInfo, sessionP->version, + requestLine, + httpMethod, host, port, path, query); + + if (moreFields) { + readAndProcessHeaderFields(sessionP, deadline, + errorP, httpErrorCodeP); + } else + *errorP = NULL; + + if (!*errorP) + sessionP->validRequest = true; + + xmlrpc_strfreenull(host); + xmlrpc_strfree(path); + xmlrpc_strfreenull(query); + } + } +} + + + diff --git a/stable/lib/abyss/src/sessionReadRequest.h b/stable/lib/abyss/src/sessionReadRequest.h new file mode 100644 index 000000000..6b3107ef6 --- /dev/null +++ b/stable/lib/abyss/src/sessionReadRequest.h @@ -0,0 +1,12 @@ +#ifndef SESSION_READ_REQUEST_H_INCLUDED +#define SESSION_READ_REQUEST_H_INCLUDED + +#include "session.h" + +void +SessionReadRequest(TSession * const sessionP, + uint32_t const timeout, + const char ** const errorP, + uint16_t * const httpErrorCodeP); + +#endif diff --git a/stable/lib/abyss/src/socket_openssl.c b/stable/lib/abyss/src/socket_openssl.c index e90be0d03..1f35ec317 100644 --- a/stable/lib/abyss/src/socket_openssl.c +++ b/stable/lib/abyss/src/socket_openssl.c @@ -4,10 +4,6 @@ This is the implementation of TChanSwitch and TChannel for an SSL (Secure Sockets Layer) connection based on an OpenSSL connection object -- what you create with SSL_new(). - - This is just a template for future development. It does not function - (or even compile) today. - =============================================================================*/ #include "xmlrpc_config.h" @@ -39,64 +35,200 @@ #include "channel.h" #include "socket.h" #include "xmlrpc-c/abyss.h" +#include "xmlrpc-c/abyss_openssl.h" +#include "sockutil.h" #include "socket_openssl.h" -struct channelOpenSsl { +/* We've seen Openssl from the year 2002 not have SSL_ERROR_WANT_ACCEPT. + In 2016, it is defined as a macro. +*/ +#ifdef SSL_ERROR_WANT_ACCEPT +#define HAVE_SSL_ERROR_WANT_ACCEPT 1 +#else +#define HAVE_SSL_ERROR_WANT_ACCEPT 0 +#endif + + + +static const char * +sslErrorMsg(void) { /*---------------------------------------------------------------------------- - The properties/state of a TChannel unique to the OpenSSL variety. + The information on the OpenSSL error stack, in human-readable (barely) + form. -----------------------------------------------------------------------------*/ - SSL * sslP; - /* SSL connection handle (such as is created by SSL_new() in - the openssl library). - */ - bool userSuppliedConn; - /* The SSL connection belongs to the user; we did not create - it. - */ -}; + const char * retval; + bool eof; + retval = xmlrpc_strdupsol(""); + for (eof = false; !eof; ) { + const char * sourceFileName; + int lineNum; -static bool -connected(int const fd) { -/*---------------------------------------------------------------------------- - Return TRUE iff the socket on file descriptor 'fd' is in the connected - state. + int const errCode = ERR_get_error_line(&sourceFileName, &lineNum); + + if (errCode == 0) + eof = true; + else { + const char * newRetval; + + xmlrpc_asprintf(&newRetval, "%s %s (%s:%d); ", + retval, ERR_error_string(errCode, NULL), + sourceFileName, lineNum); - If 'fd' does not identify a stream socket or we are unable to determine - the state of the stream socket, the answer is "false". + xmlrpc_strfree(retval); + + retval = newRetval; + } + } + return retval; +} + + + +static const char * +sslResultMsg(int const resultCode) { +/*---------------------------------------------------------------------------- + English description of a result code such as OpenSSL's SSL_get_error + returns. -----------------------------------------------------------------------------*/ - bool connected; - struct sockaddr sockaddr; - socklen_t nameLen; + switch (resultCode) { + case SSL_ERROR_NONE: return "None"; + case SSL_ERROR_SSL: return "SSL"; + case SSL_ERROR_WANT_READ: return "Want Read"; + case SSL_ERROR_WANT_WRITE: return "Want Write"; + case SSL_ERROR_WANT_X509_LOOKUP: return "Want X509_LOOKUP"; + case SSL_ERROR_SYSCALL: return "Syscall"; + case SSL_ERROR_ZERO_RETURN: return "Zero Return"; + case SSL_ERROR_WANT_CONNECT: return "Want Connect"; +#if HAVE_SSL_ERROR_WANT_ACCEPT + case SSL_ERROR_WANT_ACCEPT: return "Want Accept"; +#endif + default: return "???"; + } +} + + + +static void +sslCreate(SSL_CTX * const sslCtxP, + SSL ** const sslPP, + const char ** const errorP) { + + *sslPP = SSL_new(sslCtxP); + + if (!*sslPP) { + const char * const sslMsg = sslErrorMsg(); + + xmlrpc_asprintf(errorP, "Failed to create SSL connection " + "object. SSL_new() failed. %s", sslMsg); + xmlrpc_strfree(sslMsg); + } else + *errorP = NULL; +} + + + +static void +sslSetFd(SSL * const sslP, + int const acceptedFd, + const char ** const errorP) { + + int succeeded; + + succeeded = SSL_set_fd(sslP, acceptedFd); + + if (!succeeded) { + const char * sslMsg; + + sslMsg = sslErrorMsg(); + + xmlrpc_asprintf(errorP, "SSL_set_fd(%d) failed. %s", + acceptedFd, sslMsg); + + xmlrpc_strfree(sslMsg); + } else + *errorP = NULL; +} + + + +static void +traceCipherList(SSL * const sslP) { + + int priority; + bool eof; + + fprintf(stderr, "SSL object will consider using the following " + "ciphers in priority order, if conditions are right to use " + "them and the client agrees: "); + + for (priority = 0, eof = false; !eof; ++priority) { + const char * const cipherName = SSL_get_cipher_list(sslP, priority); + + if (cipherName) + fprintf(stderr, "%s ", cipherName); + else + eof = true; + } + fprintf(stderr, "\n"); +} + + + +static void +sslAccept(SSL * const sslP, + const char ** const errorP) { + int rc; - nameLen = sizeof(sockaddr); + if (SwitchTraceIsActive) + traceCipherList(sslP); + + rc = SSL_accept(sslP); - rc = getpeername(fd, &sockaddr, &nameLen); + if (rc == 1) + *errorP = NULL; + else { + int const resultCode = SSL_get_error(sslP, rc); - if (rc == 0) - connected = TRUE; - else - connected = FALSE; + const char * const errorStack = sslErrorMsg(); - return connected; + xmlrpc_asprintf(errorP, "SSL_accept() failed. rc=%d/%d: %s. " + "OpenSSL error stack: %s\n", + rc, resultCode, sslResultMsg(resultCode), errorStack); + + xmlrpc_strfree(errorStack); + } } +struct ChannelOpenSsl { +/*---------------------------------------------------------------------------- + The properties/state of a TChannel unique to the OpenSSL variety. +-----------------------------------------------------------------------------*/ + int fd; + /* File descriptor of the TCP connection underlying the SSL connection + */ + SSL * sslP; + /* SSL connection handle */ + bool userSuppliedSsl; + /* The SSL connection belongs to the user; we did not create it. */ +}; + + + void -SocketOpensslInit(const char ** const errorP) { +SocketOpenSslInit(const char ** const errorP) { SSL_load_error_strings(); /* readable error messages, don't call this if memory is tight */ SSL_library_init(); /* initialize library */ - /* actions_to_seed_PRNG(); */ - *errorP = NULL; } @@ -105,7 +237,7 @@ SocketOpensslInit(const char ** const errorP) { void SocketOpenSslTerm(void) { - ERR_free_string(); + ERR_free_strings(); } @@ -120,12 +252,12 @@ static ChannelDestroyImpl channelDestroy; static void channelDestroy(TChannel * const channelP) { - struct channelOpenssl * const channelOpensslP = channelP->implP; + struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; - if (!socketUnixP->userSuppliedConn) - SSL_shutdown(channelOpensslP->sslP); + if (!channelOpenSslP->userSuppliedSsl) + SSL_shutdown(channelOpenSslP->sslP); - free(channelOpensslP); + free(channelOpenSslP); } @@ -138,35 +270,33 @@ channelWrite(TChannel * const channelP, uint32_t const len, bool * const failedP) { - struct channelOpenssl * const channelOpensslP = channelP->implP; + struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; - int bytesLeft; + unsigned int bytesLeft; bool error; assert(sizeof(int) >= sizeof(len)); - for (bytesLeft = len, error = FALSE; - bytesLeft > 0 && !error; - ) { - int const maxSend = (int)(-1) >> 1; + for (bytesLeft = len, error = false; bytesLeft > 0 && !error; ) { + uint32_t const maxSend = (uint32_t)(-1) >> 1; int rc; - rc = SSL_write(channelOpensslP->ssl, &buffer[len-bytesLeft], + rc = SSL_write(channelOpenSslP->sslP, &buffer[len-bytesLeft], MIN(maxSend, bytesLeft)); if (ChannelTraceIsActive) { if (rc <= 0) fprintf(stderr, - "Abyss socket: SSL_write() failed. rc=%d (%s)", - rc, SSL_get_error(rc)); + "Abyss socket: SSL_write() failed. rc=%d/%d", + rc, SSL_get_error(channelOpenSslP->sslP, rc)); else fprintf(stderr, "Abyss socket: sent %u bytes: '%.*s'\n", rc, rc, &buffer[len-bytesLeft]); } if (rc <= 0) /* 0 means connection closed; < 0 means severe error */ - error = TRUE; + error = true; else bytesLeft -= rc; } @@ -175,7 +305,7 @@ channelWrite(TChannel * const channelP, -ChannelReadImpl channelRead; +static ChannelReadImpl channelRead; static void channelRead(TChannel * const channelP, @@ -184,19 +314,19 @@ channelRead(TChannel * const channelP, uint32_t * const bytesReceivedP, bool * const failedP) { - struct channelOpenssl * const channelOpensslP = channelP->implP; + struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; int rc; - rc = SSL_read(channelOpensslP->sslP, buf, len); + rc = SSL_read(channelOpenSslP->sslP, buffer, bufferSize); if (rc < 0) { - *failedP = TRUE; + *failedP = true; if (ChannelTraceIsActive) fprintf(stderr, "Failed to receive data from OpenSSL connection. " - "SSL_read() failed with rc %d (%s)\n", - rc, SSL_get_error(rc)); + "SSL_read() failed with rc %d/%d\n", + rc, SSL_get_error(channelOpenSslP->sslP, rc)); } else { - *failedP = FALSE; + *failedP = false; *bytesReceivedP = rc; if (ChannelTraceIsActive) @@ -210,10 +340,10 @@ channelRead(TChannel * const channelP, static ChannelWaitImpl channelWait; static void -channelWait(TChannel * const channelP, - bool const waitForRead, - bool const waitForWrite, - uint32_t const timeoutMs, +channelWait(TChannel * const channelP ATTR_UNUSED, + bool const waitForRead ATTR_UNUSED, + bool const waitForWrite ATTR_UNUSED, + uint32_t const timeoutMs ATTR_UNUSED, bool * const readyToReadP, bool * const readyToWriteP, bool * const failedP) { @@ -225,7 +355,12 @@ channelWait(TChannel * const channelP, how yet. Instead, we return immediately and hope that if Caller subsequently does a read or write, it blocks until it can do its thing. -----------------------------------------------------------------------------*/ - + if (readyToReadP) + *readyToReadP = true; + if (readyToWriteP) + *readyToWriteP = true; + if (failedP) + *failedP = false; } @@ -233,7 +368,7 @@ channelWait(TChannel * const channelP, static ChannelInterruptImpl channelInterrupt; static void -channelInterrupt(TChannel * const channelP) { +channelInterrupt(TChannel * const channelP ATTR_UNUSED) { /*---------------------------------------------------------------------------- Interrupt any waiting that a thread might be doing in channelWait() now or in the future. @@ -244,6 +379,19 @@ channelInterrupt(TChannel * const channelP) { +static ChannelFormatPeerInfoImpl channelFormatPeerInfo; + +static void +channelFormatPeerInfo(TChannel * const channelP, + const char ** const peerStringP) { + + struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; + + sockutil_formatPeerInfo(channelOpenSslP->fd, peerStringP); +} + + + static struct TChannelVtbl const channelVtbl = { &channelDestroy, &channelWrite, @@ -256,21 +404,60 @@ static struct TChannelVtbl const channelVtbl = { static void -makeChannelInfo(struct abyss_openssl_chaninfo ** const channelInfoPP, +getPeerAddrFromSsl(SSL * const sslP, + struct sockaddr * const peerAddrRetP, + size_t * const peerAddrLenRetP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + From the SSL connection with handle 'sslP', get the address (IP address, + normally) of the peer (the Abyss client). +-----------------------------------------------------------------------------*/ + int const sockFd = SSL_get_fd(sslP); + + struct sockaddr * peerAddrP; + size_t peerAddrLen; + const char * error; + + sockutil_getPeerName(sockFd, &peerAddrP, &peerAddrLen, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Could not get identity of client. %s", + error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + *peerAddrLenRetP = peerAddrLen; + *peerAddrRetP = *peerAddrP; + + free(peerAddrP); + } +} + + + +static void +makeChannelInfo(struct abyss_openSsl_chaninfo ** const channelInfoPP, SSL * const sslP, const char ** const errorP) { - struct abyss_openssl_chaninfo * channelInfoP; + struct abyss_openSsl_chaninfo * channelInfoP; MALLOCVAR(channelInfoP); if (channelInfoP == NULL) xmlrpc_asprintf(errorP, "Unable to allocate memory"); else { - - *channelInfoPP = channelInfoP; + channelInfoP->sslP = sslP; - *errorP = NULL; + getPeerAddrFromSsl(sslP, + &channelInfoP->peerAddr, + &channelInfoP->peerAddrLen, + errorP); + + if (*errorP) + free(channelInfoP); + else + *channelInfoPP = channelInfoP; } } @@ -278,24 +465,25 @@ makeChannelInfo(struct abyss_openssl_chaninfo ** const channelInfoPP, static void makeChannelFromSsl(SSL * const sslP, + bool const userSuppliedSsl, TChannel ** const channelPP, const char ** const errorP) { - struct channelOpenssl * channelOpensslP; + struct ChannelOpenSsl * channelOpenSslP; - MALLOCVAR(channelOpensslP); + MALLOCVAR(channelOpenSslP); - if (channelOpensslP == NULL) + if (channelOpenSslP == NULL) xmlrpc_asprintf(errorP, "Unable to allocate memory for OpenSSL " "socket descriptor"); else { TChannel * channelP; - channelOpensslP->sslP = sslP; - channelOpensslP->userSuppliedSsl = TRUE; + channelOpenSslP->sslP = sslP; + channelOpenSslP->userSuppliedSsl = userSuppliedSsl; /* This should be ok as far as I can tell */ - ChannelCreate(&channelVtbl, channelOpensslP, &channelP); + ChannelCreate(&channelVtbl, channelOpenSslP, &channelP); if (channelP == NULL) xmlrpc_asprintf(errorP, "Unable to allocate memory for " @@ -305,23 +493,25 @@ makeChannelFromSsl(SSL * const sslP, *errorP = NULL; } if (*errorP) - free(channelOpensslP); + free(channelOpenSslP); } } void -ChannelOpensslCreateSsl(SSL * const sslP, +ChannelOpenSslCreateSsl(SSL * const sslP, TChannel ** const channelPP, - struct abyss_openssl_chaninfo ** const channelInfoPP, + struct abyss_openSsl_chaninfo ** const channelInfoPP, const char ** const errorP) { assert(sslP); makeChannelInfo(channelInfoPP, sslP, errorP); if (!*errorP) { - makeChannelFromSsl(ssl, channelPP, errorP); + bool const userSuppliedTrue = true; + + makeChannelFromSsl(sslP, userSuppliedTrue, channelPP, errorP); if (*errorP) { free(*channelInfoPP); @@ -335,7 +525,7 @@ ChannelOpensslCreateSsl(SSL * const sslP, TChanSwitch =============================================================================*/ -struct opensslSwitch { +struct ChanSwitchOpenSsl { /*---------------------------------------------------------------------------- The properties/state of a TChanSwitch uniqe to the OpenSSL variety. @@ -344,14 +534,19 @@ struct opensslSwitch { creates OpenSSL TChannels. The switch is just a POSIX listening socket, and is almost identical to the Abyss Unix channel switch. -----------------------------------------------------------------------------*/ - int fd; + int listenFd; /* File descriptor of the POSIX socket (such as is created by - socket() in the C library) for the socket. + socket() in the C library) for the listening socket. */ bool userSuppliedFd; /* The file descriptor and associated POSIX socket belong to the user; we did not create it. */ + SSL_CTX * sslCtxP; + /* The context in which we create all our OpenSSL connections */ + + sockutil_InterruptPipe interruptPipe; + /* We use this to interrupt a wait for the next client to arrive */ }; @@ -361,15 +556,14 @@ static SwitchDestroyImpl chanSwitchDestroy; static void chanSwitchDestroy(TChanSwitch * const chanSwitchP) { -static void -chanSwitchDestroy(TChanSwitch * const chanSwitchP) { - - struct opensslSwitch * const opensslSwitchP = chanSwitchP->implP; + struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; + + sockutil_interruptPipeTerm(chanSwitchOpenSslP->interruptPipe); - if (!opensslSwitchP->userSuppliedFd) - close(opensslSwitchP->fd); + if (!chanSwitchOpenSslP->userSuppliedFd) + close(chanSwitchOpenSslP->listenFd); - free(opensslSwitchP); + free(chanSwitchOpenSslP); } @@ -381,24 +575,106 @@ chanSwitchListen(TChanSwitch * const chanSwitchP, uint32_t const backlog, const char ** const errorP) { - struct opensslSwitch * const opensslSwitchP = chanSwitchP->implP; + struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; - int32_t const minus1 = -1; + sockutil_listen(chanSwitchOpenSslP->listenFd, backlog, errorP); +} - int rc; - /* Disable the Nagle algorithm to make persistant connections faster */ - setsockopt(opensslSwitchP->fd, IPPROTO_TCP, TCP_NODELAY, - &minus1, sizeof(minus1)); +static void +createSslFromAcceptedConn(int const acceptedFd, + SSL_CTX * const sslCtxP, + SSL ** const sslPP, + const char ** const errorP) { + + SSL * sslP; + const char * error; - rc = listen(opensslSwitchP->fd, backlog); + sslCreate(sslCtxP, &sslP, &error); - if (rc == -1) - xmlrpc_asprintf(errorP, "listen() failed with errno %d (%s)", - errno, strerror(errno)); - else - *errorP = NULL; + if (error) { + xmlrpc_asprintf(errorP, "Failed to create SSL connection " + "object. %s", error); + xmlrpc_strfree(error); + } else { + const char * error; + + sslSetFd(sslP, acceptedFd, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Failed to set file descriptor for SSL " + "connection. %s", error); + xmlrpc_strfree(error); + } else { + const char * error; + + sslAccept(sslP, &error); + + if (error) { + xmlrpc_asprintf(errorP, + "Failed to set up SSL communication on " + "working TCP connection. %s", error); + xmlrpc_strfree(error); + } else + *errorP = NULL; + } + if (*errorP) + SSL_free(sslP); + else { + *sslPP = sslP; + } + } +} + + + +static void +createChannelFromAcceptedConn(int const acceptedFd, + SSL_CTX * const sslCtxP, + TChannel ** const channelPP, + void ** const channelInfoPP, + const char ** const errorP) { + + struct ChannelOpenSsl * channelOpenSslP; + + MALLOCVAR(channelOpenSslP); + + if (!channelOpenSslP) + xmlrpc_asprintf(errorP, "Unable to allocate memory"); + else { + SSL * sslP; + const char * error; + + createSslFromAcceptedConn(acceptedFd, sslCtxP, &sslP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Failed to create an OpenSSL connection " + "from the accepted TCP connection. %s", error); + xmlrpc_strfree(error); + } else { + struct abyss_openSsl_chaninfo * channelInfoP; + + makeChannelInfo(&channelInfoP, sslP, errorP); + if (!*errorP) { + bool const userSuppliedFalse = false; + + makeChannelFromSsl(sslP, userSuppliedFalse, + channelPP, errorP); + + if (*errorP) + free(channelInfoP); + else + *channelInfoPP = channelInfoP; + } + if (*errorP) + SSL_free(sslP); + else + channelOpenSslP->sslP = sslP; + } + if (*errorP) + free(channelOpenSslP); + } } @@ -419,58 +695,46 @@ chanSwitchAccept(TChanSwitch * const chanSwitchP, If we receive a signal while waiting, return immediately with *channelPP == NULL. -----------------------------------------------------------------------------*/ - struct opensslSwitch * const listenSocketP = chanSwitchP->implP; + struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; bool interrupted; TChannel * channelP; - interrupted = FALSE; /* Haven't been interrupted yet */ + interrupted = false; /* Haven't been interrupted yet */ channelP = NULL; /* No connection yet */ *errorP = NULL; /* No error yet */ while (!channelP && !*errorP && !interrupted) { struct sockaddr peerAddr; - socklen_t size = sizeof(peerAddr); + socklen_t peerAddrLen; int rc; - rc = accept(listenSocketP->fd, &peerAddr, &size); + peerAddrLen = sizeof(peerAddr); /* initial value */ + + rc = accept(chanSwitchOpenSslP->listenFd, &peerAddr, &peerAddrLen); if (rc >= 0) { int const acceptedFd = rc; - struct channelOpenssl * opensslChannelP; - MALLOCVAR(opensslChannelP); + const char * error; - if (!opensslChannelP) - xmlrpc_asprintf(errorP, "Unable to allocate memory"); - else { - struct abyss_openssl_chaninfo * channelInfoP; - - openChannelP->userSuppliedFd = FALSE; - TODO("turn connected socket 'acceptedFd' into an OpenSSL " - "connection opensslChannelP->sslP"); - - makeChannelInfo(&channelInfoP, peerAddr, size, errorP); - if (!*errorP) { - *channelInfoPP = channelInfoP; + createChannelFromAcceptedConn( + acceptedFd, chanSwitchOpenSslP->sslCtxP, + &channelP, channelInfoPP, &error); - ChannelCreate(&channelVtbl, opensslChannelP, &channelP); - if (!channelP) - xmlrpc_asprintf(errorP, - "Failed to create TChannel object."); - else - *errorP = NULL; + if (error) { + close(acceptedFd); - if (*errorP) - free(channelInfoP); - } - if (*errorP) - free(opensslChannelP); + if (SwitchTraceIsActive) + fprintf(stderr, + "Failed to create a channel from the " + "TCP connection we accepted. %s. " + "Closing TCP connection, waiting for the " + "next one\n", error); + xmlrpc_strfree(error); } - if (*errorP) - close(acceptedFd); } else if (errno == EINTR) - interrupted = TRUE; + interrupted = true; else xmlrpc_asprintf(errorP, "accept() failed, errno = %d (%s)", errno, strerror(errno)); @@ -488,10 +752,15 @@ chanSwitchInterrupt(TChanSwitch * const chanSwitchP) { Interrupt any waiting that a thread might be doing in chanSwitchAccept() now or in the future. - Actually, this is a no-op, since we don't yet know how to accomplish - that. + TODO: Make a way to reset this so that future chanSwitchAccept()s can once + again wait. -----------------------------------------------------------------------------*/ + struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; + + unsigned char const zero[1] = {0u}; + write(chanSwitchOpenSslP->interruptPipe.interruptorFd, + &zero, sizeof(zero)); } @@ -500,141 +769,205 @@ static struct TChanSwitchVtbl const chanSwitchVtbl = { &chanSwitchDestroy, &chanSwitchListen, &chanSwitchAccept, + &chanSwitchInterrupt, }; static void -setSocketOptions(int const fd, - const char ** const errorP) { +createChanSwitch(int const fd, + bool const userSuppliedFd, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { - int32_t n = 1; - int rc; + struct ChanSwitchOpenSsl * chanSwitchOpenSslP; - rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof(n)); + assert(!sockutil_connected(fd)); - if (rc < 0) - xmlrpc_asprintf(errorP, "Failed to set socket options. " - "setsockopt() failed with errno %d (%s)", - errno, strerror(errno)); - else - *errorP = NULL; + if (SwitchTraceIsActive) + fprintf(stderr, "Creating OpenSSL-based channel switch\n"); + + MALLOCVAR(chanSwitchOpenSslP); + + if (chanSwitchOpenSslP == NULL) + xmlrpc_asprintf(errorP, "unable to allocate memory for OpenSSL " + "channel switch descriptor."); + else { + TChanSwitch * chanSwitchP; + + chanSwitchOpenSslP->sslCtxP = sslCtxP; + + chanSwitchOpenSslP->listenFd = fd; + chanSwitchOpenSslP->userSuppliedFd = userSuppliedFd; + + sockutil_interruptPipeInit(&chanSwitchOpenSslP->interruptPipe, errorP); + + if (!*errorP) { + ChanSwitchCreate(&chanSwitchVtbl, chanSwitchOpenSslP, + &chanSwitchP); + if (*errorP) + sockutil_interruptPipeTerm(chanSwitchOpenSslP->interruptPipe); + + if (chanSwitchP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for " + "channel switch descriptor"); + else { + *chanSwitchPP = chanSwitchP; + *errorP = NULL; + } + } + if (*errorP) + free(chanSwitchOpenSslP); + } } static void -bindSocketToPort(int const fd, - struct in_addr * const addrP, - uint16_t const portNumber, - const char ** const errorP) { +switchCreateIpV4Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Create a POSIX-socket-based channel switch for an IPv4 endpoint. - struct sockaddr_in name; + Set the socket's local address so that a subsequent "listen" will listen on + all interfaces, port number 'portNumber'. +-----------------------------------------------------------------------------*/ int rc; + rc = socket(PF_INET, SOCK_STREAM, 0); + if (rc < 0) + xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + else { + int const socketFd = rc; - name.sin_family = AF_INET; - name.sin_port = htons(portNumber); - if (addrP) - name.sin_addr = *addrP; - else - name.sin_addr.s_addr = INADDR_ANY; - - rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); + sockutil_setSocketOptions(socketFd, errorP); + if (!*errorP) { + sockutil_bindSocketToPortInet(socketFd, portNumber, errorP); - if (rc == -1) - xmlrpc_asprintf(errorP, "Unable to bind socket to port number %hu. " - "bind() failed with errno %d (%s)", - portNumber, errno, strerror(errno)); - else - *errorP = NULL; + if (!*errorP) { + bool const userSupplied = false; + createChanSwitch(socketFd, userSupplied, sslCtxP, + chanSwitchPP, errorP); + } + } + if (*errorP) + close(socketFd); + } } -void -ChanSwitchOpensslCreate(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { +static void +switchCreateIpV6Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { /*---------------------------------------------------------------------------- - Create an OpenSSL-based channel switch. + Same as switchCreateIpV4Port(), except for IPv6. +-----------------------------------------------------------------------------*/ + int rc; + rc = socket(PF_INET6, SOCK_STREAM, 0); + if (rc < 0) + xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + else { + int const socketFd = rc; - Use an IP socket. + sockutil_setSocketOptions(socketFd, errorP); + if (!*errorP) { + sockutil_bindSocketToPortInet6(socketFd, portNumber, errorP); + + if (!*errorP) { + bool const userSupplied = false; + createChanSwitch(socketFd, userSupplied, sslCtxP, + chanSwitchPP, errorP); + } + } + if (*errorP) + close(socketFd); + } +} - Set the socket's local address so that a subsequent "listen" will listen - on all IP addresses, port number 'portNumber'. ------------------------------------------------------------------------------*/ - struct opensslSwitch * opensslSwitchP; - MALLOCVAR(opensslSwitchP); - if (!opensslSwitchP) - xmlrpc_asprintf(errorP, "Unable to allocate memory for Openssl " - "channel switch descriptor structure."); +void +ChanSwitchOpenSslCreate(int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + int rc; + rc = socket(protocolFamily, SOCK_STREAM, 0); + if (rc < 0) + xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", + errno, strerror(errno)); else { - int rc; - rc = socket(AF_INET, SOCK_STREAM, 0); - if (rc < 0) - xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - else { - opensslSwitchP->fd = rc; - opensslSwitchP->userSuppliedFd = FALSE; + int const socketFd = rc; + + if (SwitchTraceIsActive) + fprintf(stderr, "Created socket for protocol family %d\n", + protocolFamily); + + sockutil_setSocketOptions(socketFd, errorP); + if (!*errorP) { + sockutil_bindSocketToPort(socketFd, sockAddrP, sockAddrLen, + errorP); - setSocketOptions(opensslSwitchP->fd, errorP); if (!*errorP) { - bindSocketToPort(opensslSwitchP->fd, NULL, portNumber, errorP); - - if (!*errorP) - ChanSwitchCreate(&chanSwitchVtbl, opensslSwitchP, - chanSwitchPP); + bool const userSupplied = false; + createChanSwitch(socketFd, userSupplied, sslCtxP, + chanSwitchPP, errorP); } - if (*errorP) - close(opensslSwitchP->fd); } if (*errorP) - free(opensslSwitchP); + close(socketFd); } + +} + + + +void +ChanSwitchOpenSslCreateIpV4Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + switchCreateIpV4Port(portNumber, sslCtxP, chanSwitchPP, errorP); +} + + + +void +ChanSwitchOpenSslCreateIpV6Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + switchCreateIpV6Port(portNumber, sslCtxP, chanSwitchPP, errorP); } void -ChanSwitchOpensslCreateFd(int const fd, +ChanSwitchOpenSslCreateFd(int const fd, + SSL_CTX * const sslCtxP, TChanSwitch ** const chanSwitchPP, const char ** const errorP) { -/*---------------------------------------------------------------------------- - Create an OpenSSL-based channel switch, based on a POSIX socket that - is in listen state. ------------------------------------------------------------------------------*/ - struct opensslSwitch * opensslSwitchP; - if (connected(fd)) + if (sockutil_connected(fd)) xmlrpc_asprintf(errorP, "Socket (file descriptor %d) is in connected " "state.", fd); else { - MALLOCVAR(opensslSwitchP); - - if (opensslSwitchP == NULL) - xmlrpc_asprintf(errorP, "unable to allocate memory for Openssl " - "channel switch descriptor."); - else { - TChanSwitch * chanSwitchP; - - opensslSwitchP->fd = fd; - opensslSwitchP->userSuppliedFd = TRUE; - - ChanSwitchCreate(&chanSwitchVtbl, opensslSwitchP, &chanSwitchP); - - if (chanSwitchP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for " - "channel switch descriptor"); - else { - *chanSwitchPP = chanSwitchP; - *errorP = NULL; - } - if (*errorP) - free(opensslSwitchP); - } + bool const userSupplied = true; + createChanSwitch(fd, userSupplied, sslCtxP, chanSwitchPP, errorP); } } + + diff --git a/stable/lib/abyss/src/socket_openssl.h b/stable/lib/abyss/src/socket_openssl.h new file mode 100644 index 000000000..a9662df65 --- /dev/null +++ b/stable/lib/abyss/src/socket_openssl.h @@ -0,0 +1,14 @@ +#ifndef SOCKET_OPENSSL_H_INCLUDED +#define SOCKET_OPENSSL_H_INCLUDED + +#include + +#include + +void +SocketOpenSslInit(const char ** const errorP); + +void +SocketOpenSslTerm(void); + +#endif diff --git a/stable/lib/abyss/src/socket_unix.c b/stable/lib/abyss/src/socket_unix.c index d8c66cea8..1848f6ac3 100644 --- a/stable/lib/abyss/src/socket_unix.c +++ b/stable/lib/abyss/src/socket_unix.c @@ -29,7 +29,6 @@ #include "c_util.h" #include "int.h" -#include "girstring.h" #include "xmlrpc-c/util_int.h" #include "xmlrpc-c/string_int.h" #include "mallocvar.h" @@ -40,45 +39,9 @@ #include "netinet/in.h" #include "xmlrpc-c/abyss.h" -#include "socket_unix.h" - - - -typedef struct { - int interruptorFd; - int interrupteeFd; -} interruptPipe; - - - -static void -initInterruptPipe(interruptPipe * const pipeP, - const char ** const errorP) { - - int pipeFd[2]; - int rc; - - rc = pipe(pipeFd); - - if (rc != 0) - xmlrpc_asprintf(errorP, "Unable to create a pipe to use to interrupt " - "waits. pipe() failed with errno %d (%s)", - errno, strerror(errno)); - else { - *errorP = NULL; - pipeP->interruptorFd = pipeFd[1]; - pipeP->interrupteeFd = pipeFd[0]; - } -} +#include "sockutil.h" - - -static void -termInterruptPipe(interruptPipe const pipe) { - - close(pipe.interruptorFd); - close(pipe.interrupteeFd); -} +#include "socket_unix.h" @@ -95,36 +58,11 @@ struct socketUnix { /* The file descriptor and associated POSIX socket belong to the user; we did not create it. */ - interruptPipe interruptPipe; -}; - - + sockutil_InterruptPipe interruptPipe; -static bool -connected(int const fd) { -/*---------------------------------------------------------------------------- - Return TRUE iff the socket on file descriptor 'fd' is in the connected - state. - - If 'fd' does not identify a stream socket or we are unable to determine - the state of the stream socket, the answer is "false". ------------------------------------------------------------------------------*/ - bool connected; - struct sockaddr sockaddr; - socklen_t nameLen; - int rc; - - nameLen = sizeof(sockaddr); - - rc = getpeername(fd, &sockaddr, &nameLen); - - if (rc == 0) - connected = true; - else - connected = false; - - return connected; -} + bool isListening; + /* We've done a 'listen' on the socket */ +}; @@ -152,7 +90,7 @@ channelDestroy(TChannel * const channelP) { struct socketUnix * const socketUnixP = channelP->implP; - termInterruptPipe(socketUnixP->interruptPipe); + sockutil_interruptPipeTerm(socketUnixP->interruptPipe); if (!socketUnixP->userSuppliedFd) close(socketUnixP->fd); @@ -282,12 +220,13 @@ channelWait(TChannel * const channelP, for most purposes). Return *readyToReadP == true if the reason for returning is that - the channel is immediately readable. *readyToWriteP is analogous + the channel is immediately readable. But only if 'readyToReadP' is + non-null. *readyToWriteP is analogous for writable. Both may be true. - Return *failedP true iff we fail to wait for the requested - condition because of some unusual problem. Being interrupted by a - signal is not a failure. + Return *failedP true iff we fail to wait for the requested condition + because of some unusual problem and 'failedP' is non-null. Being + interrupted by a signal is not a failure. If one of these return value pointers is NULL, don't return that value. @@ -356,9 +295,8 @@ channelInterrupt(TChannel * const channelP) { again wait. -----------------------------------------------------------------------------*/ struct socketUnix * const socketUnixP = channelP->implP; - unsigned char const zero[1] = {0u}; - write(socketUnixP->interruptPipe.interruptorFd, &zero, sizeof(zero)); + sockutil_interruptPipeInterrupt(socketUnixP->interruptPipe); } @@ -371,97 +309,7 @@ ChannelUnixGetPeerName(TChannel * const channelP, struct socketUnix * const socketUnixP = channelP->implP; - unsigned char * peerName; - socklen_t nameSize; - - nameSize = sizeof(struct sockaddr) + 1; - - peerName = malloc(nameSize); - - if (peerName == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate space for peer name"); - else { - int rc; - socklen_t nameLen; - nameLen = nameSize; /* initial value */ - rc = getpeername(socketUnixP->fd, (struct sockaddr *)peerName, - &nameLen); - - if (rc < 0) - xmlrpc_asprintf(errorP, "getpeername() failed. errno=%d (%s)", - errno, strerror(errno)); - else { - if (nameLen > nameSize-1) - xmlrpc_asprintf(errorP, - "getpeername() says the socket name is " - "larger than %u bytes, which means it is " - "not in the expected format.", - nameSize-1); - else { - *sockaddrPP = (struct sockaddr *)peerName; - *sockaddrLenP = nameLen; - *errorP = NULL; - } - } - if (*errorP) - free(peerName); - } -} - - - -static void -formatPeerInfoInet(const struct sockaddr_in * const sockaddrInP, - socklen_t const sockaddrLen, - const char ** const peerStringP) { - - if (sockaddrLen < sizeof(*sockaddrInP)) - xmlrpc_asprintf(peerStringP, "??? getpeername() returned " - "the wrong size"); - else { - unsigned char * const ipaddr = (unsigned char *) - &sockaddrInP->sin_addr.s_addr; - xmlrpc_asprintf(peerStringP, "%u.%u.%u.%u:%hu", - ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], - ntohs(sockaddrInP->sin_port)); - } -} - - - -static void -formatPeerInfoInet6(const struct sockaddr_in6 * const sockaddrIn6P, - socklen_t const sockaddrLen, - const char ** const peerStringP) { - - if (sockaddrLen < sizeof(*sockaddrIn6P)) - xmlrpc_asprintf(peerStringP, "??? getpeername() returned " - "the wrong size"); - else { - /* Gcc on Debian 6 gives a bewildering error message about aliasing - if we try to dereference sockaddrIn6P in various ways, regardless - of casts to void * or anything else. So we copy the data structure - as raw memory contents and then access the copy. 12.02.05. - */ - struct sockaddr_in6 sockaddr; - - MEMSCPY(&sockaddr, sockaddrIn6P); - - { - char buffer[256]; - const char * rc; - - rc = inet_ntop(AF_INET6, &sockaddr.sin6_addr, - buffer, sizeof(buffer)); - - /* Punt the supposedly impossible error */ - if (rc == NULL) - STRSCPY(buffer, "???"); - - xmlrpc_asprintf(peerStringP, "[%s]:%hu", - buffer, sockaddr.sin6_port); - } - } + sockutil_getPeerName(socketUnixP->fd, sockaddrPP, sockaddrLenP, errorP); } @@ -474,33 +322,7 @@ channelFormatPeerInfo(TChannel * const channelP, struct socketUnix * const socketUnixP = channelP->implP; - struct sockaddr sockaddr; - socklen_t sockaddrLen; - int rc; - - sockaddrLen = sizeof(sockaddr); - - rc = getpeername(socketUnixP->fd, &sockaddr, &sockaddrLen); - - if (rc < 0) - xmlrpc_asprintf(peerStringP, "?? getpeername() failed. errno=%d (%s)", - errno, strerror(errno)); - else { - switch (sockaddr.sa_family) { - case AF_INET: - formatPeerInfoInet((const struct sockaddr_in *) &sockaddr, - sockaddrLen, - peerStringP); - break; - case AF_INET6: - formatPeerInfoInet6((const struct sockaddr_in6 *) &sockaddr, - sockaddrLen, - peerStringP); - break; - default: - xmlrpc_asprintf(peerStringP, "??? AF=%u", sockaddr.sa_family); - } - } + sockutil_formatPeerInfo(socketUnixP->fd, peerStringP); } @@ -557,7 +379,7 @@ makeChannelFromFd(int const fd, socketUnixP->fd = fd; socketUnixP->userSuppliedFd = true; - initInterruptPipe(&socketUnixP->interruptPipe, errorP); + sockutil_interruptPipeInit(&socketUnixP->interruptPipe, errorP); if (!*errorP) { ChannelCreate(&channelVtbl, socketUnixP, &channelP); @@ -570,7 +392,7 @@ makeChannelFromFd(int const fd, *errorP = NULL; } if (*errorP) - termInterruptPipe(socketUnixP->interruptPipe); + sockutil_interruptPipeTerm(socketUnixP->interruptPipe); } if (*errorP) free(socketUnixP); @@ -585,28 +407,29 @@ ChannelUnixCreateFd(int const fd, struct abyss_unix_chaninfo ** const channelInfoPP, const char ** const errorP) { - struct sockaddr peerAddr; - socklen_t peerAddrLen; - int rc; - - peerAddrLen = sizeof(peerAddr); + if (!sockutil_connected(fd)) + xmlrpc_asprintf(errorP, "Socket on file descriptor %d is not in " + "connected state.", fd); + else { + struct sockaddr * peerAddrP; + size_t peerAddrLen; + const char * error; - rc = getpeername(fd, &peerAddr, &peerAddrLen); + sockutil_getPeerName(fd, &peerAddrP, &peerAddrLen, &error); - if (rc != 0) { - if (errno == ENOTCONN) - xmlrpc_asprintf(errorP, "Socket on file descriptor %d is not in " - "connected state.", fd); - else - xmlrpc_asprintf(errorP, "getpeername() failed on fd %d. " - "errno=%d (%s)", fd, errno, strerror(errno)); - } else { - makeChannelInfo(channelInfoPP, peerAddr, peerAddrLen, errorP); - if (!*errorP) { - makeChannelFromFd(fd, channelPP, errorP); + if (error) { + xmlrpc_asprintf(errorP, "Failed to get identity of client. %s", + error); + xmlrpc_strfree(error); + } else { + makeChannelInfo(channelInfoPP, *peerAddrP, peerAddrLen, errorP); + if (!*errorP) { + makeChannelFromFd(fd, channelPP, errorP); - if (*errorP) - free(*channelInfoPP); + if (*errorP) + free(*channelInfoPP); + } + free(peerAddrP); } } } @@ -624,7 +447,7 @@ chanSwitchDestroy(TChanSwitch * const chanSwitchP) { struct socketUnix * const socketUnixP = chanSwitchP->implP; - termInterruptPipe(socketUnixP->interruptPipe); + sockutil_interruptPipeTerm(socketUnixP->interruptPipe); if (!socketUnixP->userSuppliedFd) close(socketUnixP->fd); @@ -634,7 +457,7 @@ chanSwitchDestroy(TChanSwitch * const chanSwitchP) { -static SwitchListenImpl chanSwitchListen; +static SwitchListenImpl chanSwitchListen; static void chanSwitchListen(TChanSwitch * const chanSwitchP, @@ -643,77 +466,13 @@ chanSwitchListen(TChanSwitch * const chanSwitchP, struct socketUnix * const socketUnixP = chanSwitchP->implP; - int32_t const minus1 = -1; - - int rc; - - /* Disable the Nagle algorithm to make persistant connections faster */ - - setsockopt(socketUnixP->fd, IPPROTO_TCP, TCP_NODELAY, - &minus1, sizeof(minus1)); - - rc = listen(socketUnixP->fd, backlog); - - if (rc == -1) - xmlrpc_asprintf(errorP, "listen() failed with errno %d (%s)", - errno, strerror(errno)); - else - *errorP = NULL; -} - - - -static void -waitForConnection(struct socketUnix * const listenSocketP, - bool * const interruptedP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Wait for the listening socket to have a connection ready to accept. - - We return before the requested condition holds if the process receives - (and catches) a signal, but only if it receives that signal a certain - time after we start running. (That means this behavior isn't useful - for most purposes). - - We furthermore return before the requested condition holds if someone sends - a byte through the listening socket's interrupt pipe (or has sent one - previously since the most recent time the pipe was drained). - - Return *interruptedP == true if we return before there is a connection - ready to accept. ------------------------------------------------------------------------------*/ - struct pollfd pollfds[2]; - int rc; - - pollfds[0].fd = listenSocketP->fd; - pollfds[0].events = POLLIN; - - pollfds[1].fd = listenSocketP->interruptPipe.interrupteeFd; - pollfds[1].events = POLLIN; - - rc = poll(pollfds, ARRAY_SIZE(pollfds), -1); + if (socketUnixP->isListening) + xmlrpc_asprintf(errorP, "Channel switch is already listening"); + else { + sockutil_listen(socketUnixP->fd, backlog, errorP); - if (rc < 0) { - if (errno == EINTR) { - *errorP = NULL; - *interruptedP = true; - } else { - xmlrpc_asprintf(errorP, "poll() failed, errno = %d (%s)", - errno, strerror(errno)); - *interruptedP = false; /* quiet compiler warning */ - } - } else if (pollfds[0].revents & POLLHUP) { - xmlrpc_asprintf(errorP, "INTERNAL ERROR: listening socket " - "is not listening"); - } else if (pollfds[1].revents & POLLHUP) { - xmlrpc_asprintf(errorP, "INTERNAL ERROR: interrupt socket hung up"); - } else if (pollfds[0].revents & POLLERR) { - xmlrpc_asprintf(errorP, "listening socket is in POLLERR status"); - } else if (pollfds[1].revents & POLLHUP) { - xmlrpc_asprintf(errorP, "interrupt socket is in POLLERR status"); - } else { - *errorP = NULL; - *interruptedP = !(pollfds[0].revents & POLLIN); + if (!*errorP) + socketUnixP->isListening = true; } } @@ -747,7 +506,8 @@ createChannelForAccept(int const acceptedFd, acceptedSocketP->fd = acceptedFd; acceptedSocketP->userSuppliedFd = false; - initInterruptPipe(&acceptedSocketP->interruptPipe, errorP); + sockutil_interruptPipeInit( + &acceptedSocketP->interruptPipe, errorP); if (!*errorP) { TChannel * channelP; @@ -762,7 +522,7 @@ createChannelForAccept(int const acceptedFd, *channelInfoPP = channelInfoP; } if (*errorP) - termInterruptPipe(acceptedSocketP->interruptPipe); + sockutil_interruptPipeTerm(acceptedSocketP->interruptPipe); } if (*errorP) free(acceptedSocketP); @@ -801,14 +561,18 @@ chanSwitchAccept(TChanSwitch * const chanSwitchP, while (!channelP && !*errorP && !interrupted) { - waitForConnection(listenSocketP, &interrupted, errorP); + sockutil_waitForConnection(listenSocketP->fd, + listenSocketP->interruptPipe, + &interrupted, errorP); if (!*errorP && !interrupted) { struct sockaddr peerAddr; - socklen_t size = sizeof(peerAddr); + socklen_t peerAddrLen; int rc; - rc = accept(listenSocketP->fd, &peerAddr, &size); + peerAddrLen = sizeof(peerAddr); /* initial value */ + + rc = accept(listenSocketP->fd, &peerAddr, &peerAddrLen); if (rc >= 0) { int const acceptedFd = rc; @@ -864,10 +628,18 @@ createChanSwitch(int const fd, bool const userSuppliedFd, TChanSwitch ** const chanSwitchPP, const char ** const errorP) { +/*---------------------------------------------------------------------------- + Create a channel switch from the bound, but not yet listening, socket + with file descriptor 'fd'. + Return the handle of the new channel switch as *chanSwitchPP. + + 'userSuppliedFd' means the file descriptor (socket) shall _not_ belong to + the channel switch, so destroying the channel switch does not close it. +-----------------------------------------------------------------------------*/ struct socketUnix * socketUnixP; - assert(!connected(fd)); + assert(!sockutil_connected(fd)); if (SwitchTraceIsActive) fprintf(stderr, "Creating Unix listen-socket based channel switch\n"); @@ -882,13 +654,14 @@ createChanSwitch(int const fd, socketUnixP->fd = fd; socketUnixP->userSuppliedFd = userSuppliedFd; + socketUnixP->isListening = false; - initInterruptPipe(&socketUnixP->interruptPipe, errorP); + sockutil_interruptPipeInit(&socketUnixP->interruptPipe, errorP); if (!*errorP) { ChanSwitchCreate(&chanSwitchVtbl, socketUnixP, &chanSwitchP); if (*errorP) - termInterruptPipe(socketUnixP->interruptPipe); + sockutil_interruptPipeTerm(socketUnixP->interruptPipe); if (chanSwitchP == NULL) xmlrpc_asprintf(errorP, "Unable to allocate memory for " @@ -905,124 +678,6 @@ createChanSwitch(int const fd, -static void -setSocketOptions(int const fd, - const char ** const errorP) { - - int32_t n = 1; - int rc; - - rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof(n)); - - if (rc < 0) - xmlrpc_asprintf(errorP, "Failed to set socket options. " - "setsockopt() failed with errno %d (%s)", - errno, strerror(errno)); - else - *errorP = NULL; -} - - - -static void -traceSocketBound(const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen) { - - if (sockAddrP->sa_family == AF_INET && - sockAddrLen >= sizeof(struct sockaddr_in)) { - const struct sockaddr_in * const sockAddrInP = - (const struct sockaddr_in *)sockAddrP; - - unsigned char * const ipaddr = (unsigned char *) - &sockAddrInP->sin_addr.s_addr; - - fprintf(stderr, "Bound socket for channel switch to " - "AF_INET port %u.%u.%u.%u:%hu\n", - ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], - ntohs(sockAddrInP->sin_port)); - } else { - fprintf(stderr, "Bound socket for channel switch to address of " - "family %d\n", sockAddrP->sa_family); - } -} - - - -static void -bindSocketToPort(int const fd, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - const char ** const errorP) { - - int rc; - - rc = bind(fd, sockAddrP, sockAddrLen); - - if (rc == -1) - xmlrpc_asprintf(errorP, "Unable to bind socket " - "to the socket address. " - "bind() failed with errno %d (%s)", - errno, strerror(errno)); - else { - *errorP = NULL; - - if (SwitchTraceIsActive) - traceSocketBound(sockAddrP, sockAddrLen); - } -} - - - -static void -bindSocketToPortInet(int const fd, - uint16_t const portNumber, - const char ** const errorP) { - - struct sockaddr_in name; - int rc; - - name.sin_family = AF_INET; - name.sin_port = htons(portNumber); - name.sin_addr.s_addr = INADDR_ANY; - - rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); - - if (rc == -1) - xmlrpc_asprintf(errorP, "Unable to bind IPv4 socket " - "to port number %hu. " - "bind() failed with errno %d (%s)", - portNumber, errno, strerror(errno)); - else - *errorP = NULL; -} - - - -static void -bindSocketToPortInet6(int const fd, - uint16_t const portNumber, - const char ** const errorP) { - - struct sockaddr_in6 name; - int rc; - - name.sin6_family = AF_INET6; - name.sin6_port = htons(portNumber); - name.sin6_addr = in6addr_any; - - rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); - - if (rc == -1) - xmlrpc_asprintf(errorP, "Unable to bind IPv6 socket " - "to port number %hu. " - "bind() failed with errno %d (%s)", - portNumber, errno, strerror(errno)); - else - *errorP = NULL; -} - - - static void switchCreateIpV4Port(unsigned short const portNumber, TChanSwitch ** const chanSwitchPP, @@ -1041,9 +696,9 @@ switchCreateIpV4Port(unsigned short const portNumber, else { int const socketFd = rc; - setSocketOptions(socketFd, errorP); + sockutil_setSocketOptions(socketFd, errorP); if (!*errorP) { - bindSocketToPortInet(socketFd, portNumber, errorP); + sockutil_bindSocketToPortInet(socketFd, portNumber, errorP); if (!*errorP) { bool const userSupplied = false; @@ -1072,9 +727,9 @@ switchCreateIpV6Port(unsigned short const portNumber, else { int const socketFd = rc; - setSocketOptions(socketFd, errorP); + sockutil_setSocketOptions(socketFd, errorP); if (!*errorP) { - bindSocketToPortInet6(socketFd, portNumber, errorP); + sockutil_bindSocketToPortInet6(socketFd, portNumber, errorP); if (!*errorP) { bool const userSupplied = false; @@ -1117,9 +772,10 @@ ChanSwitchUnixCreate2(int const protocolFamily, fprintf(stderr, "Created socket for protocol family %d\n", protocolFamily); - setSocketOptions(socketFd, errorP); + sockutil_setSocketOptions(socketFd, errorP); if (!*errorP) { - bindSocketToPort(socketFd, sockAddrP, sockAddrLen, errorP); + sockutil_bindSocketToPort(socketFd, sockAddrP, sockAddrLen, + errorP); if (!*errorP) { bool const userSupplied = false; @@ -1149,7 +805,7 @@ ChanSwitchUnixCreateFd(int const fd, TChanSwitch ** const chanSwitchPP, const char ** const errorP) { - if (connected(fd)) + if (sockutil_connected(fd)) xmlrpc_asprintf(errorP, "Socket (file descriptor %d) is in connected " "state.", fd); @@ -1161,6 +817,27 @@ ChanSwitchUnixCreateFd(int const fd, +void +ChanSwitchUnixGetListenName(TChanSwitch * const chanSwitchP, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + The primary case where this is useful is where the user created the channel + switch with a parameters telling the OS to pick the TCP port. In that + case, this is the only way the user can find out what port the OS picked. +-----------------------------------------------------------------------------*/ + struct socketUnix * const socketUnixP = chanSwitchP->implP; + + if (!socketUnixP->isListening) + xmlrpc_asprintf(errorP, "Channel Switch is not listening"); + else + sockutil_getSockName(socketUnixP->fd, + sockaddrPP, sockaddrLenP, errorP); +} + + + /*============================================================================= obsolete TSocket interface =============================================================================*/ @@ -1173,7 +850,7 @@ SocketUnixCreateFd(int const fd, TSocket * socketP; const char * error; - if (connected(fd)) { + if (sockutil_connected(fd)) { TChannel * channelP; struct abyss_unix_chaninfo * channelInfoP; ChannelUnixCreateFd(fd, &channelP, &channelInfoP, &error); diff --git a/stable/lib/abyss/src/socket_win.c b/stable/lib/abyss/src/socket_win.c index f781055d6..3204a60c1 100644 --- a/stable/lib/abyss/src/socket_win.c +++ b/stable/lib/abyss/src/socket_win.c @@ -1062,3 +1062,22 @@ ChanSwitchWinCreate2(int const protocolFamily, +void +ChanSwitchWinGetListenName(TChanSwitch * const chanSwitchP, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP) { + + struct socketWin * const socketWinP = chanSwitchP->implP; + + // Anyone who knows how to do this with Winsock, please submit a patch. + + xmlrpc_asprintf(errorP, "Code has not been written " + "(ChanSwitchWinGetListenName in " + "lib/abyss/src/socket_win.c) to determine the name of the " + "socket on which the channel switch is listening for " + "connections"); +} + + + diff --git a/stable/lib/abyss/src/sockutil.c b/stable/lib/abyss/src/sockutil.c new file mode 100644 index 000000000..bd991998b --- /dev/null +++ b/stable/lib/abyss/src/sockutil.c @@ -0,0 +1,490 @@ +/*============================================================================= + sockutil.c +=============================================================================== + This is utility functions for use in channel and channel switches + that use Unix sockets. +=============================================================================*/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_SYS_FILIO_H + #include +#endif + +#include "c_util.h" +#include "int.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" +#include "mallocvar.h" +#include "trace.h" +#include "chanswitch.h" +#include "channel.h" +#include "socket.h" +#include "netinet/in.h" +#include "xmlrpc-c/abyss.h" + +#include "sockutil.h" + + +void +sockutil_interruptPipeInit(sockutil_InterruptPipe * const pipeP, + const char ** const errorP) { + + int pipeFd[2]; + int rc; + + rc = pipe(pipeFd); + + if (rc != 0) + xmlrpc_asprintf(errorP, "Unable to create a pipe to use to interrupt " + "waits. pipe() failed with errno %d (%s)", + errno, strerror(errno)); + else { + *errorP = NULL; + pipeP->interruptorFd = pipeFd[1]; + pipeP->interrupteeFd = pipeFd[0]; + } +} + + + +void +sockutil_interruptPipeTerm(sockutil_InterruptPipe const pipe) { + + close(pipe.interruptorFd); + close(pipe.interrupteeFd); +} + + + +void +sockutil_interruptPipeInterrupt(sockutil_InterruptPipe const interruptPipe) { + + unsigned char const zero[1] = {0u}; + + write(interruptPipe.interruptorFd, &zero, sizeof(zero)); +} + + + +bool +sockutil_connected(int const fd) { +/*---------------------------------------------------------------------------- + Return TRUE iff the socket on file descriptor 'fd' is in the connected + state. + + If 'fd' does not identify a stream socket or we are unable to determine + the state of the stream socket, the answer is "false". +-----------------------------------------------------------------------------*/ + bool connected; + struct sockaddr sockaddr; + socklen_t nameLen; + int rc; + + nameLen = sizeof(sockaddr); + + rc = getpeername(fd, &sockaddr, &nameLen); + + if (rc == 0) + connected = true; + else + connected = false; + + return connected; +} + + + +void +sockutil_getSockName(int const sockFd, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP) { + + unsigned char * sockName; + socklen_t nameSize; + + nameSize = sizeof(struct sockaddr) + 1; + + sockName = malloc(nameSize); + + if (sockName == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate space for socket name"); + else { + int rc; + socklen_t nameLen; + nameLen = nameSize; /* initial value */ + rc = getsockname(sockFd, (struct sockaddr *)sockName, &nameLen); + + if (rc < 0) + xmlrpc_asprintf(errorP, "getsockname() failed. errno=%d (%s)", + errno, strerror(errno)); + else { + if (nameLen > nameSize-1) + xmlrpc_asprintf(errorP, + "getsockname() says the socket name is " + "larger than %u bytes, which means it is " + "not in the expected format.", + nameSize-1); + else { + *sockaddrPP = (struct sockaddr *)sockName; + *sockaddrLenP = nameLen; + *errorP = NULL; + } + } + if (*errorP) + free(sockName); + } +} + + + +void +sockutil_getPeerName(int const sockFd, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP) { + + unsigned char * peerName; + socklen_t nameSize; + + nameSize = sizeof(struct sockaddr) + 1; + + peerName = malloc(nameSize); + + if (peerName == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate space for peer name"); + else { + int rc; + socklen_t nameLen; + nameLen = nameSize; /* initial value */ + rc = getpeername(sockFd, (struct sockaddr *)peerName, &nameLen); + + if (rc < 0) + xmlrpc_asprintf(errorP, "getpeername() failed. errno=%d (%s)", + errno, strerror(errno)); + else { + if (nameLen > nameSize-1) + xmlrpc_asprintf(errorP, + "getpeername() says the socket name is " + "larger than %u bytes, which means it is " + "not in the expected format.", + nameSize-1); + else { + *sockaddrPP = (struct sockaddr *)peerName; + *sockaddrLenP = nameLen; + *errorP = NULL; + } + } + if (*errorP) + free(peerName); + } +} + + + +static void +formatPeerInfoInet(const struct sockaddr_in * const sockaddrInP, + socklen_t const sockaddrLen, + const char ** const peerStringP) { + + if (sockaddrLen < sizeof(*sockaddrInP)) + xmlrpc_asprintf(peerStringP, "??? getpeername() returned " + "the wrong size"); + else { + unsigned char * const ipaddr = (unsigned char *) + &sockaddrInP->sin_addr.s_addr; + xmlrpc_asprintf(peerStringP, "%u.%u.%u.%u:%hu", + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ntohs(sockaddrInP->sin_port)); + } +} + + + +static void +formatPeerInfoInet6(const struct sockaddr_in6 * const sockaddrIn6P, + socklen_t const sockaddrLen, + const char ** const peerStringP) { + + if (sockaddrLen < sizeof(*sockaddrIn6P)) + xmlrpc_asprintf(peerStringP, "??? getpeername() returned " + "the wrong size"); + else { + /* Gcc on Debian 6 gives a bewildering error message about aliasing + if we try to dereference sockaddrIn6P in various ways, regardless + of casts to void * or anything else. So we copy the data structure + as raw memory contents and then access the copy. 12.02.05. + */ + struct sockaddr_in6 sockaddr; + + MEMSCPY(&sockaddr, sockaddrIn6P); + + { + char buffer[256]; + const char * rc; + + rc = inet_ntop(AF_INET6, &sockaddr.sin6_addr, + buffer, sizeof(buffer)); + + /* Punt the supposedly impossible error */ + if (rc == NULL) + STRSCPY(buffer, "???"); + + xmlrpc_asprintf(peerStringP, "[%s]:%hu", + buffer, sockaddr.sin6_port); + } + } +} + + + +void +sockutil_formatPeerInfo(int const sockFd, + const char ** const peerStringP) { + + struct sockaddr sockaddr; + socklen_t sockaddrLen; + int rc; + + sockaddrLen = sizeof(sockaddr); + + rc = getpeername(sockFd, &sockaddr, &sockaddrLen); + + if (rc < 0) + xmlrpc_asprintf(peerStringP, "?? getpeername() failed. errno=%d (%s)", + errno, strerror(errno)); + else { + switch (sockaddr.sa_family) { + case AF_INET: + formatPeerInfoInet((const struct sockaddr_in *) &sockaddr, + sockaddrLen, + peerStringP); + break; + case AF_INET6: + formatPeerInfoInet6((const struct sockaddr_in6 *) &sockaddr, + sockaddrLen, + peerStringP); + break; + default: + xmlrpc_asprintf(peerStringP, "??? AF=%u", sockaddr.sa_family); + } + } +} + + + +void +sockutil_listen(int const sockFd, + uint32_t const backlog, + const char ** const errorP) { + + int32_t const minus1 = -1; + + int rc; + + /* Disable the Nagle algorithm to make persistant connections faster */ + + setsockopt(sockFd, IPPROTO_TCP, TCP_NODELAY, &minus1, sizeof(minus1)); + + rc = listen(sockFd, backlog); + + if (rc == -1) + xmlrpc_asprintf(errorP, "listen() failed with errno %d (%s)", + errno, strerror(errno)); + else + *errorP = NULL; +} + + + +void +sockutil_waitForConnection(int const listenSockFd, + sockutil_InterruptPipe const interruptPipe, + bool * const interruptedP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Wait for the listening socket to have a connection ready to accept. + + We return before the requested condition holds if the process receives + (and catches) a signal, but only if it receives that signal a certain + time after we start running. (That means this behavior isn't useful + for most purposes). + + We furthermore return before the requested condition holds if someone sends + a byte through the listening socket's interrupt pipe (or has sent one + previously since the most recent time the pipe was drained). + + Return *interruptedP == true if we return before there is a connection + ready to accept. +-----------------------------------------------------------------------------*/ + struct pollfd pollfds[2]; + int rc; + + pollfds[0].fd = listenSockFd; + pollfds[0].events = POLLIN; + + pollfds[1].fd = interruptPipe.interrupteeFd; + pollfds[1].events = POLLIN; + + rc = poll(pollfds, ARRAY_SIZE(pollfds), -1); + + if (rc < 0) { + if (errno == EINTR) { + *errorP = NULL; + *interruptedP = true; + } else { + xmlrpc_asprintf(errorP, "poll() failed, errno = %d (%s)", + errno, strerror(errno)); + *interruptedP = false; /* quiet compiler warning */ + } + } else if (pollfds[0].revents & POLLHUP) { + xmlrpc_asprintf(errorP, "INTERNAL ERROR: listening socket " + "is not listening"); + } else if (pollfds[1].revents & POLLHUP) { + xmlrpc_asprintf(errorP, "INTERNAL ERROR: interrupt socket hung up"); + } else if (pollfds[0].revents & POLLERR) { + xmlrpc_asprintf(errorP, "listening socket is in POLLERR status"); + } else if (pollfds[1].revents & POLLHUP) { + xmlrpc_asprintf(errorP, "interrupt socket is in POLLERR status"); + } else { + *errorP = NULL; + *interruptedP = !(pollfds[0].revents & POLLIN); + } +} + + + +void +sockutil_setSocketOptions(int const fd, + const char ** const errorP) { + + int32_t n = 1; + int rc; + + rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof(n)); + + if (rc < 0) + xmlrpc_asprintf(errorP, "Failed to set socket options. " + "setsockopt() failed with errno %d (%s)", + errno, strerror(errno)); + else + *errorP = NULL; +} + + + +static void +traceSocketBound(const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen) { + + if (sockAddrP->sa_family == AF_INET && + sockAddrLen >= sizeof(struct sockaddr_in)) { + const struct sockaddr_in * const sockAddrInP = + (const struct sockaddr_in *)sockAddrP; + + unsigned char * const ipaddr = (unsigned char *) + &sockAddrInP->sin_addr.s_addr; + + fprintf(stderr, "Bound socket for channel switch to " + "AF_INET port %u.%u.%u.%u:%hu\n", + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ntohs(sockAddrInP->sin_port)); + } else { + fprintf(stderr, "Bound socket for channel switch to address of " + "family %d\n", sockAddrP->sa_family); + } +} + + + +void +sockutil_bindSocketToPort(int const fd, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + const char ** const errorP) { + + int rc; + + rc = bind(fd, sockAddrP, sockAddrLen); + + if (rc == -1) + xmlrpc_asprintf(errorP, "Unable to bind socket " + "to the socket address. " + "bind() failed with errno %d (%s)", + errno, strerror(errno)); + else { + *errorP = NULL; + + if (SwitchTraceIsActive) + traceSocketBound(sockAddrP, sockAddrLen); + } +} + + + +void +sockutil_bindSocketToPortInet(int const fd, + uint16_t const portNumber, + const char ** const errorP) { + + struct sockaddr_in name; + int rc; + + name.sin_family = AF_INET; + name.sin_port = htons(portNumber); + name.sin_addr.s_addr = INADDR_ANY; + + rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); + + if (rc == -1) + xmlrpc_asprintf(errorP, "Unable to bind IPv4 socket " + "to port number %hu. " + "bind() failed with errno %d (%s)", + portNumber, errno, strerror(errno)); + else + *errorP = NULL; +} + + + +void +sockutil_bindSocketToPortInet6(int const fd, + uint16_t const portNumber, + const char ** const errorP) { + + struct sockaddr_in6 name; + int rc; + + name.sin6_family = AF_INET6; + name.sin6_port = htons(portNumber); + name.sin6_addr = in6addr_any; + + rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); + + if (rc == -1) + xmlrpc_asprintf(errorP, "Unable to bind IPv6 socket " + "to port number %hu. " + "bind() failed with errno %d (%s)", + portNumber, errno, strerror(errno)); + else + *errorP = NULL; +} + + + diff --git a/stable/lib/abyss/src/sockutil.h b/stable/lib/abyss/src/sockutil.h new file mode 100644 index 000000000..8d2b94e13 --- /dev/null +++ b/stable/lib/abyss/src/sockutil.h @@ -0,0 +1,72 @@ +#ifndef SOCKUTIL_H_INCLUDED +#define SOCKUTIL_H_INCLUDED + +#include +#include + +typedef struct { + int interruptorFd; + int interrupteeFd; +} sockutil_InterruptPipe; + +void +sockutil_interruptPipeInit(sockutil_InterruptPipe * const pipeP, + const char ** const errorP); + +void +sockutil_interruptPipeTerm(sockutil_InterruptPipe const pipe); + +void +sockutil_interruptPipeInterrupt(sockutil_InterruptPipe const interruptPipe); + +bool +sockutil_connected(int const fd); + +void +sockutil_getSockName(int const sockFd, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP); + +void +sockutil_getPeerName(int const sockFd, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP); + +void +sockutil_formatPeerInfo(int const sockFd, + const char ** const peerStringP); + +void +sockutil_listen(int const sockFd, + uint32_t const backlog, + const char ** const errorP); + +void +sockutil_waitForConnection(int const listenSockFd, + sockutil_InterruptPipe const interruptPipe, + bool * const interruptedP, + const char ** const errorP); + +void +sockutil_setSocketOptions(int const fd, + const char ** const errorP); + +void +sockutil_bindSocketToPort(int const fd, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + const char ** const errorP); + +void +sockutil_bindSocketToPortInet(int const fd, + uint16_t const portNumber, + const char ** const errorP); + +void +sockutil_bindSocketToPortInet6(int const fd, + uint16_t const portNumber, + const char ** const errorP); + +#endif diff --git a/stable/lib/abyss/src/thread.h b/stable/lib/abyss/src/thread.h index e1741654d..980200d4b 100644 --- a/stable/lib/abyss/src/thread.h +++ b/stable/lib/abyss/src/thread.h @@ -49,7 +49,7 @@ ThreadForks(void); void ThreadUpdateStatus(TThread * const threadP); -#ifndef WIN32 +#if !MSVCRT void ThreadHandleSigchld(pid_t const pid); #endif diff --git a/stable/lib/abyss/src/thread_fork.c b/stable/lib/abyss/src/thread_fork.c index 6e58f4d83..26d28341a 100644 --- a/stable/lib/abyss/src/thread_fork.c +++ b/stable/lib/abyss/src/thread_fork.c @@ -189,6 +189,7 @@ ThreadCreate(TThread ** const threadPP, errno, strerror(errno)); else if (rc == 0) { /* This is the child */ + free(threadP); (*func)(userHandle); /* Note that thread cleanup (threadDone) is done by the _parent_, upon seeing our exit. @@ -259,7 +260,7 @@ ThreadExit(TThread * const threadP ATTR_UNUSED, /* Note that the OS will automatically send a SIGCHLD signal to the parent process after we exit. The handler for that signal will run threadDone in parent's context. Alternatively, if - the parent is set up for signals, the parent will eventually + the parent isn't set up for signals, the parent will eventually poll for the existence of our PID and call threadDone when he sees we've gone. */ diff --git a/stable/lib/curl_transport/Makefile b/stable/lib/curl_transport/Makefile index 7bb22c819..499ab7893 100644 --- a/stable/lib/curl_transport/Makefile +++ b/stable/lib/curl_transport/Makefile @@ -70,6 +70,9 @@ distdir: .PHONY: install install: +.PHONY: uninstall +uninstall: + .PHONY: dep dep: dep-common diff --git a/stable/lib/curl_transport/curltransaction.c b/stable/lib/curl_transport/curltransaction.c index bf7b7b6c6..f0aafae8c 100644 --- a/stable/lib/curl_transport/curltransaction.c +++ b/stable/lib/curl_transport/curltransaction.c @@ -10,7 +10,7 @@ #include "mallocvar.h" -#include "xmlrpc-c/util.h" +#include "xmlrpc-c/util_int.h" #include "xmlrpc-c/string_int.h" #include "xmlrpc-c/client.h" #include "xmlrpc-c/client_int.h" @@ -514,18 +514,23 @@ assertConstantsMatch(void) { make curl option setting work. This function asserts such formally. -----------------------------------------------------------------------------*/ - assert(XMLRPC_SSLVERSION_DEFAULT == CURL_SSLVERSION_DEFAULT); - assert(XMLRPC_SSLVERSION_TLSv1 == CURL_SSLVERSION_TLSv1 ); - assert(XMLRPC_SSLVERSION_SSLv2 == CURL_SSLVERSION_SSLv2 ); - assert(XMLRPC_SSLVERSION_SSLv3 == CURL_SSLVERSION_SSLv3 ); - - assert(XMLRPC_HTTPAUTH_BASIC == CURLAUTH_BASIC ); - assert(XMLRPC_HTTPAUTH_DIGEST == CURLAUTH_DIGEST ); - assert(XMLRPC_HTTPAUTH_GSSNEGOTIATE == CURLAUTH_GSSNEGOTIATE); - assert(XMLRPC_HTTPAUTH_NTLM == CURLAUTH_NTLM ); - - assert(XMLRPC_HTTPPROXY_HTTP == CURLPROXY_HTTP ); - assert(XMLRPC_HTTPPROXY_SOCKS5 == CURLPROXY_SOCKS5 ); +#define assertMatch(xmlrpc_name, curl_name) \ + assert((unsigned)xmlrpc_name == (unsigned)curl_name) + + assertMatch(XMLRPC_SSLVERSION_DEFAULT , CURL_SSLVERSION_DEFAULT); + assertMatch(XMLRPC_SSLVERSION_TLSv1 , CURL_SSLVERSION_TLSv1 ); + assertMatch(XMLRPC_SSLVERSION_SSLv2 , CURL_SSLVERSION_SSLv2 ); + assertMatch(XMLRPC_SSLVERSION_SSLv3 , CURL_SSLVERSION_SSLv3 ); + + assertMatch(XMLRPC_HTTPAUTH_BASIC , CURLAUTH_BASIC ); + assertMatch(XMLRPC_HTTPAUTH_DIGEST , CURLAUTH_DIGEST ); + assertMatch(XMLRPC_HTTPAUTH_GSSNEGOTIATE , CURLAUTH_GSSNEGOTIATE); + assertMatch(XMLRPC_HTTPAUTH_NTLM , CURLAUTH_NTLM ); + + assertMatch(XMLRPC_HTTPPROXY_HTTP , CURLPROXY_HTTP ); + assertMatch(XMLRPC_HTTPPROXY_SOCKS5 , CURLPROXY_SOCKS5 ); + +#undef assertMatch } diff --git a/stable/lib/curl_transport/xmlrpc_curl_transport.c b/stable/lib/curl_transport/xmlrpc_curl_transport.c index 254991129..245300c3f 100644 --- a/stable/lib/curl_transport/xmlrpc_curl_transport.c +++ b/stable/lib/curl_transport/xmlrpc_curl_transport.c @@ -74,7 +74,7 @@ #include "linklist.h" #include "girstring.h" -#include "xmlrpc-c/util.h" +#include "xmlrpc-c/util_int.h" #include "xmlrpc-c/string_int.h" #include "xmlrpc-c/select_int.h" #include "xmlrpc-c/client_int.h" @@ -522,7 +522,7 @@ waitForWorkInt(xmlrpc_env * const envP, waitForWork() will suffice. -----------------------------------------------------------------------------*/ sigset_t callerBlockSet; -#ifdef _WIN32 +#if MSVCRT waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); #else sigset_t allSignals; diff --git a/stable/lib/expat/Makefile b/stable/lib/expat/Makefile index b51c08a24..cf2355302 100644 --- a/stable/lib/expat/Makefile +++ b/stable/lib/expat/Makefile @@ -59,6 +59,9 @@ distdir: distdir-common .PHONY: install install: install-common $(SUBDIRS:%=%/install) +.PHONY: uninstall +uninstall: uninstall-common $(SUBDIRS:%=%/uninstall) + .PHONY: check check: diff --git a/stable/lib/expat/gennmtab/Makefile b/stable/lib/expat/gennmtab/Makefile index ce92e09bd..93d4787f6 100644 --- a/stable/lib/expat/gennmtab/Makefile +++ b/stable/lib/expat/gennmtab/Makefile @@ -34,13 +34,16 @@ distdir: .PHONY: install install: +.PHONY: uninstall +uninstall: + .PHONY: dep dep: dep-common gennmtab.o:%.o:%.c - $(BUILDTOOL_CC) -c $< -o $@ $(CFLAGS_ALL) $(INCLUDES) + $(CC_FOR_BUILD) -c $< -o $@ $(CFLAGS_ALL_FOR_BUILD) gennmtab:%:%.o - $(BUILDTOOL_CCLD) -o $@ $(LDFLAGS_ALL) $^ + $(CC_FOR_BUILD) -o $@ $(LDFLAGS_ALL_FOR_BUILD) $^ include depend.mk diff --git a/stable/lib/expat/xmlparse/Makefile b/stable/lib/expat/xmlparse/Makefile index 71a17c080..9df0d893f 100644 --- a/stable/lib/expat/xmlparse/Makefile +++ b/stable/lib/expat/xmlparse/Makefile @@ -77,6 +77,9 @@ libxmlrpc_xmlparse.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) .PHONY: install install: install-common +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean distclean clean: clean-common diff --git a/stable/lib/expat/xmlparse/xmlparse.c b/stable/lib/expat/xmlparse/xmlparse.c index 74bd982f0..48adfb33c 100644 --- a/stable/lib/expat/xmlparse/xmlparse.c +++ b/stable/lib/expat/xmlparse/xmlparse.c @@ -214,10 +214,7 @@ int setContext(XML_Parser parser, const XML_Char *context); #define poolLastChar(pool) (((pool)->ptr)[-1]) #define poolDiscard(pool) ((pool)->ptr = (pool)->start) #define poolFinish(pool) ((pool)->start = (pool)->ptr) -#define poolAppendChar(pool, c) \ - (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ - ? 0 \ - : ((*((pool)->ptr)++ = c), 1)) + typedef struct { /* The first member must be userData so that the XML_GetUserData macro works. */ @@ -442,124 +439,251 @@ void poolDestroy(STRING_POOL *pool) pool->end = 0; } -static -int poolGrow(STRING_POOL *pool) -{ - if (pool->freeBlocks) { - if (pool->start == 0) { - pool->blocks = pool->freeBlocks; - pool->freeBlocks = pool->freeBlocks->next; - pool->blocks->next = 0; - pool->start = pool->blocks->s; - pool->end = pool->start + pool->blocks->size; - pool->ptr = pool->start; - return 1; + + +static void +poolGrowFromFreeBlocks(STRING_POOL * const poolP, + bool * const wasGrownFromFreeBlocksP) { + + if (poolP->freeBlocks) { + if (poolP->start == 0) { + poolP->blocks = poolP->freeBlocks; + poolP->freeBlocks = poolP->freeBlocks->next; + poolP->blocks->next = 0; + poolP->start = poolP->blocks->s; + poolP->end = poolP->start + poolP->blocks->size; + poolP->ptr = poolP->start; + + *wasGrownFromFreeBlocksP = true; + } else if (poolP->end - poolP->start < poolP->freeBlocks->size) { + BLOCK * const newFreeBlocks = poolP->freeBlocks->next; + + poolP->freeBlocks->next = poolP->blocks; + poolP->blocks = poolP->freeBlocks; + poolP->freeBlocks = newFreeBlocks; + memcpy(poolP->blocks->s, poolP->start, + (poolP->end - poolP->start) * sizeof(XML_Char)); + poolP->ptr = poolP->blocks->s + (poolP->ptr - poolP->start); + poolP->start = poolP->blocks->s; + poolP->end = poolP->start + poolP->blocks->size; + + *wasGrownFromFreeBlocksP = true; + } + } else + *wasGrownFromFreeBlocksP = false; +} + + + +static void +poolGrow(STRING_POOL * const poolP, + const char ** const errorP) { + + bool wasGrownFromFreeBlocks; + + poolGrowFromFreeBlocks(poolP, &wasGrownFromFreeBlocks); + + if (wasGrownFromFreeBlocks) + *errorP = NULL; + else { + if (poolP->blocks && poolP->start == poolP->blocks->s) { + size_t const blockSize = (poolP->end - poolP->start)*2; + size_t const newSize = + offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); + + BLOCK * const newBlocks = realloc(poolP->blocks, newSize); + + if (newBlocks) { + poolP->blocks = newBlocks; + poolP->blocks->size = blockSize; + poolP->ptr = poolP->blocks->s + (poolP->ptr - poolP->start); + poolP->start = poolP->blocks->s; + poolP->end = poolP->start + blockSize; + *errorP = NULL; + } else + xmlrpc_asprintf(errorP, + "Failed to allocate %u bytes of memory", + (unsigned)newSize); + } else { + size_t const poolLen = poolP->end - poolP->start; + size_t const blockSize = + poolLen < INIT_BLOCK_SIZE ? INIT_BLOCK_SIZE : poolLen * 2; + size_t const newSize = + offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); + + BLOCK * const newBlocksP = malloc(newSize); + + if (newBlocksP) { + newBlocksP->size = blockSize; + newBlocksP->next = poolP->blocks; + poolP->blocks = newBlocksP; + if (poolP->ptr != poolP->start) + memcpy(newBlocksP->s, poolP->start, + (poolP->ptr - poolP->start) * sizeof(XML_Char)); + poolP->ptr = newBlocksP->s + (poolP->ptr - poolP->start); + poolP->start = newBlocksP->s; + poolP->end = newBlocksP->s + blockSize; + *errorP = NULL; + } else + xmlrpc_asprintf(errorP, + "Failed to allocate %u bytes of memory", + (unsigned)newSize); + } } - if (pool->end - pool->start < pool->freeBlocks->size) { - BLOCK *tem = pool->freeBlocks->next; - pool->freeBlocks->next = pool->blocks; - pool->blocks = pool->freeBlocks; - pool->freeBlocks = tem; - memcpy(pool->blocks->s, pool->start, - (pool->end - pool->start) * sizeof(XML_Char)); - pool->ptr = pool->blocks->s + (pool->ptr - pool->start); - pool->start = pool->blocks->s; - pool->end = pool->start + pool->blocks->size; - return 1; +} + + + +static +XML_Char * +poolAppend(STRING_POOL * const poolP, + const ENCODING * const encodingP, + const char * const initialPtr, + const char * const end) { + + const char * ptr; + + ptr = initialPtr; /* initial value */ + + if (!poolP->ptr) { + const char * error; + + poolGrow(poolP, &error); + + if (error) { + xmlrpc_strfree(error); + return NULL; + } } - } - if (pool->blocks && pool->start == pool->blocks->s) { - size_t const blockSize = (pool->end - pool->start)*2; - BLOCK *temp = realloc(pool->blocks, offsetof(BLOCK, s) + - blockSize * sizeof(XML_Char)); - if (!temp) - return 0; - pool->blocks = temp; - pool->blocks->size = blockSize; - pool->ptr = pool->blocks->s + (pool->ptr - pool->start); - pool->start = pool->blocks->s; - pool->end = pool->start + blockSize; - } - else { - size_t const poolLen = pool->end - pool->start; - size_t const blockSize = - poolLen < INIT_BLOCK_SIZE ? INIT_BLOCK_SIZE : poolLen * 2; - BLOCK *tem; - tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char)); - if (!tem) - return 0; - tem->size = blockSize; - tem->next = pool->blocks; - pool->blocks = tem; - if (pool->ptr != pool->start) - memcpy(tem->s, pool->start, - (pool->ptr - pool->start) * sizeof(XML_Char)); - pool->ptr = tem->s + (pool->ptr - pool->start); - pool->start = tem->s; - pool->end = tem->s + blockSize; - } - return 1; + for (;;) { + const char * error; + + XmlConvert(encodingP, &ptr, end, (ICHAR **)&(poolP->ptr), + (ICHAR *)poolP->end); + + if (ptr == end) + break; + + poolGrow(poolP, &error); + + if (error) { + xmlrpc_strfree(error); + return NULL; + } + } + return poolP->start; } -static -XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end) -{ - if (!pool->ptr && !poolGrow(pool)) - return 0; - for (;;) { - XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); - if (ptr == end) - break; - if (!poolGrow(pool)) - return 0; - } - return pool->start; +static bool +poolAppendChar(STRING_POOL * const poolP, + XML_Char const c) { + + bool retval; + const char * error; + + if (poolP->ptr == poolP->end) + poolGrow(poolP, &error); + else + error = NULL; + + if (error) { + xmlrpc_strfree(error); + retval = false; + } else { + *poolP->ptr++ = c; + + retval = true; + } + return retval; } -static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s) -{ - do { - if (!poolAppendChar(pool, *s)) - return 0; - } while (*s++); - s = pool->start; - poolFinish(pool); - return s; + + +static const XML_Char * +poolCopyString(STRING_POOL * const poolP, + const XML_Char * const source) { + + const XML_Char * retval; + const XML_Char * s; + + s = &source[0]; /* initial value */ + + do { + if (!poolAppendChar(poolP, *s)) + return 0; + } while (*s++); + + retval = poolP->start; + + poolFinish(poolP); + + return retval; } + + static const XML_Char * -poolCopyStringN(STRING_POOL *pool, - const XML_Char *s, - int n) -{ - if (!pool->ptr && !poolGrow(pool)) - return 0; - for (; n > 0; --n, s++) { - if (!poolAppendChar(pool, *s)) - return 0; +poolCopyStringN(STRING_POOL * const poolP, + const XML_Char * const source, + int const size) { - } - s = pool->start; - poolFinish(pool); - return s; + const XML_Char * retval; + const XML_Char * s; + int n; + + s = source; /* initial value */ + n = size; /* initial value */ + + if (!poolP->ptr) { + const char * error; + poolGrow(poolP, &error); + if (error) { + xmlrpc_strfree(error); + return NULL; + } + } + + for (; n > 0; --n, ++s) { + if (!poolAppendChar(poolP, *s)) + return NULL; + } + retval = poolP->start; + + poolFinish(poolP); + + return retval; } -static -XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, - const char *ptr, const char *end) -{ - if (!poolAppend(pool, enc, ptr, end)) - return 0; - if (pool->ptr == pool->end && !poolGrow(pool)) - return 0; - *(pool->ptr)++ = 0; - return pool->start; + + +static XML_Char * +poolStoreString(STRING_POOL * const poolP, + const ENCODING * const encodingP, + const char * const ptr, + const char * const end) { + + if (!poolAppend(poolP, encodingP, ptr, end)) + return NULL; + + if (poolP->ptr == poolP->end) { + const char * error; + poolGrow(poolP, &error); + if (error) { + xmlrpc_strfree(error); + return NULL; + } + } + + *(poolP->ptr)++ = 0; + + return poolP->start; } + + static unsigned long generate_hash_secret_salt(void) { @@ -1775,8 +1899,7 @@ storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, -static -enum XML_Error +static enum XML_Error storeEntityValue(XML_Parser const xmlParserP, const ENCODING * const enc, const char * const entityTextPtrArg, @@ -1844,11 +1967,17 @@ storeEntityValue(XML_Parser const xmlParserP, case XML_TOK_TRAILING_CR: next = entityTextPtr + enc->minBytesPerChar; /* fall through */ - case XML_TOK_DATA_NEWLINE: - if (pool->end == pool->ptr && !poolGrow(pool)) - return XML_ERROR_NO_MEMORY; + case XML_TOK_DATA_NEWLINE: { + if (pool->end == pool->ptr) { + const char * error; + poolGrow(pool, &error); + if (error) { + xmlrpc_strfree(error); + return XML_ERROR_NO_MEMORY; + } + } *(pool->ptr)++ = 0xA; - break; + } break; case XML_TOK_CHAR_REF: { XML_Char buf[XML_ENCODE_MAX]; @@ -1866,8 +1995,14 @@ storeEntityValue(XML_Parser const xmlParserP, return XML_ERROR_BAD_CHAR_REF; } for (i = 0; i < n; i++) { - if (pool->end == pool->ptr && !poolGrow(pool)) - return XML_ERROR_NO_MEMORY; + if (pool->end == pool->ptr) { + const char * error; + poolGrow(pool, &error); + if (error) { + xmlrpc_strfree(error); + return XML_ERROR_NO_MEMORY; + } + } *(pool->ptr)++ = buf[i]; } } @@ -2413,6 +2548,118 @@ cdataSectionProcessor(XML_Parser const xmlParserP, +static void +doCharacterEntityRef(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const next, + XML_Char const ch, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parserP = (Parser *) xmlParserP; + + if (parserP->m_characterDataHandler) + parserP->m_characterDataHandler(parserP->m_handlerArg, &ch, 1); + else if (parserP->m_defaultHandler) + reportDefault(xmlParserP, enc, s, next); + + *errorCodeP = XML_ERROR_NONE; + *errorP = NULL; +} + + + +static void +doInternalEntityRef(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const next, + ENTITY * const entityP, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parserP = (Parser *) xmlParserP; + + if (parserP->m_defaultHandler && + !parserP->m_defaultExpandInternalEntities) { + reportDefault(xmlParserP, enc, s, next); + *errorCodeP = XML_ERROR_NONE; + *errorP = NULL; + } else { + OPEN_INTERNAL_ENTITY openEntity; + + entityP->open = 1; /* recursion control */ + + openEntity.next = parserP->m_openInternalEntities; + + parserP->m_openInternalEntities = &openEntity; + openEntity.entity = entityP; + openEntity.internalEventPtr = 0; + openEntity.internalEventEndPtr = 0; + + doContent(xmlParserP, + parserP->m_tagLevel, + parserP->m_internalEncoding, + (char *)entityP->textPtr, + (char *)(entityP->textPtr + entityP->textLen), + 0, errorCodeP, errorP); + + entityP->open = 0; /* recursion control */ + parserP->m_openInternalEntities = openEntity.next; + } +} + + + +static void +doExternalEntityRef(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const next, + ENTITY * const entityP, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parserP = (Parser *) xmlParserP; + + *errorP = NULL; + + if (parserP->m_externalEntityRefHandler) { + const XML_Char * contextP; + + entityP->open = 1; + contextP = getContext(xmlParserP); + entityP->open = 0; + + if (!contextP) + *errorCodeP = XML_ERROR_NO_MEMORY; + else { + int rc; + + rc = parserP->m_externalEntityRefHandler( + parserP->m_externalEntityRefHandlerArg, + contextP, + entityP->base, + entityP->systemId, + entityP->publicId); + if (rc != 0) + *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING; + else { + poolDiscard(&parserP->m_tempPool); + *errorCodeP = XML_ERROR_NONE; + } + } + } else if (parserP->m_defaultHandler) { + reportDefault(xmlParserP, enc, s, next); + + *errorCodeP = XML_ERROR_NONE; + } else + *errorCodeP = XML_ERROR_NONE; +} + + + static void doEntityRef(XML_Parser const xmlParserP, const ENCODING * const enc, @@ -2421,96 +2668,53 @@ doEntityRef(XML_Parser const xmlParserP, enum XML_Error * const errorCodeP, const char ** const errorP) { - Parser * const parser = (Parser *) xmlParserP; - XML_Char const ch = XmlPredefinedEntityName(enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); - const XML_Char *name; - ENTITY *entity; - *errorP = NULL; - if (ch) { - if (characterDataHandler) - characterDataHandler(handlerArg, &ch, 1); - else if (defaultHandler) - reportDefault(xmlParserP, enc, s, next); - *errorCodeP = XML_ERROR_NONE; - return; - } - name = poolStoreString(&dtd.pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - entity = (ENTITY *)lookup(parser, &dtd.generalEntities, name, 0); - poolDiscard(&dtd.pool); - if (!entity) { - if (dtd.complete || dtd.standalone) - *errorCodeP = XML_ERROR_UNDEFINED_ENTITY; - else { - if (defaultHandler) - reportDefault(xmlParserP, enc, s, next); - *errorCodeP = XML_ERROR_NONE; - } - return; - } - if (entity->open) { - *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF; - return; - } - if (entity->notation) { - *errorCodeP = XML_ERROR_BINARY_ENTITY_REF; - return; - } - if (entity) { - if (entity->textPtr) { - OPEN_INTERNAL_ENTITY openEntity; - if (defaultHandler && !defaultExpandInternalEntities) { - reportDefault(xmlParserP, enc, s, next); - *errorCodeP = XML_ERROR_NONE; - return; - } - entity->open = 1; - openEntity.next = openInternalEntities; - openInternalEntities = &openEntity; - openEntity.entity = entity; - openEntity.internalEventPtr = 0; - openEntity.internalEventEndPtr = 0; - doContent(xmlParserP, - tagLevel, - internalEncoding, - (char *)entity->textPtr, - (char *)(entity->textPtr + entity->textLen), - 0, errorCodeP, errorP); - entity->open = 0; - openInternalEntities = openEntity.next; - if (*errorCodeP != XML_ERROR_NONE) - return; - } else if (externalEntityRefHandler) { - const XML_Char *context; - entity->open = 1; - context = getContext(xmlParserP); - entity->open = 0; - if (!context) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - if (!externalEntityRefHandler(externalEntityRefHandlerArg, - context, - entity->base, - entity->systemId, - entity->publicId)) { - *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING; - return; + if (ch) + doCharacterEntityRef(xmlParserP, enc, s, next, ch, errorCodeP, errorP); + else { + Parser * const parserP = (Parser *) xmlParserP; + + const XML_Char * name; + ENTITY * entityP; + + *errorP = NULL; + + name = poolStoreString(&parserP->m_dtd.pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) { + *errorCodeP = XML_ERROR_NO_MEMORY; + } else { + entityP = (ENTITY *) + lookup(parserP, &parserP->m_dtd.generalEntities, name, 0); + poolDiscard(&parserP->m_dtd.pool); + if (!entityP) { + if (parserP->m_dtd.complete || parserP->m_dtd.standalone) + *errorCodeP = XML_ERROR_UNDEFINED_ENTITY; + else { + if (parserP->m_defaultHandler) + reportDefault(xmlParserP, enc, s, next); + *errorCodeP = XML_ERROR_NONE; + } + } else { + if (entityP->open) + *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF; + else if (entityP->notation) + *errorCodeP = XML_ERROR_BINARY_ENTITY_REF; + else { + if (entityP->textPtr) + doInternalEntityRef(xmlParserP, enc, s, next, entityP, + errorCodeP, errorP); + else + doExternalEntityRef(xmlParserP, enc, s, next, entityP, + errorCodeP, errorP); + } } - poolDiscard(&tempPool); - } else if (defaultHandler) - reportDefault(xmlParserP, enc, s, next); + } } - *errorCodeP = XML_ERROR_NONE; } @@ -3413,7 +3617,8 @@ doProlog(XML_Parser const xmlParserP, case XML_ROLE_DOCTYPE_CLOSE: if (dtd.complete && hadExternalDoctype) { dtd.complete = 0; - if (parser->m_paramEntityParsing && externalEntityRefHandler) { + if (parser->m_paramEntityParsing != XML_PARAM_ENTITY_PARSING_NEVER + && externalEntityRefHandler) { ENTITY *entity = (ENTITY *)lookup(parser, &dtd.paramEntities, externalSubsetName, 0); @@ -3546,7 +3751,7 @@ doProlog(XML_Parser const xmlParserP, break; case XML_ROLE_DOCTYPE_SYSTEM_ID: if (!dtd.standalone - && !parser->m_paramEntityParsing + && parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_NEVER && notStandaloneHandler && !notStandaloneHandler(handlerArg)) { *errorCodeP = XML_ERROR_NOT_STANDALONE; @@ -3778,7 +3983,7 @@ doProlog(XML_Parser const xmlParserP, break; case XML_ROLE_PARAM_ENTITY_REF: case XML_ROLE_INNER_PARAM_ENTITY_REF: - if (parser->m_paramEntityParsing + if (parser->m_paramEntityParsing != XML_PARAM_ENTITY_PARSING_NEVER && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) { const XML_Char *name; ENTITY *entity; diff --git a/stable/lib/expat/xmlparse/xmlparse.h b/stable/lib/expat/xmlparse/xmlparse.h index d12f17acf..76cf0db43 100644 --- a/stable/lib/expat/xmlparse/xmlparse.h +++ b/stable/lib/expat/xmlparse/xmlparse.h @@ -368,7 +368,8 @@ or XML_ParseBuffer. */ XMLRPC_DLLEXPORT int -xmlrpc_XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); +xmlrpc_XML_SetEncoding(XML_Parser const xmlParserP, + const XML_Char * const encodingName); /* If this function is called, then the parser will be passed as the first argument to callbacks instead of userData. diff --git a/stable/lib/expat/xmltok/Makefile b/stable/lib/expat/xmltok/Makefile index 4cb9723b3..66e706325 100644 --- a/stable/lib/expat/xmltok/Makefile +++ b/stable/lib/expat/xmltok/Makefile @@ -92,6 +92,9 @@ distdir: .PHONY: install install: install-common +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: dep dep: dep-common diff --git a/stable/lib/libutil++/Makefile b/stable/lib/libutil++/Makefile index 32f1f8edf..9c1fba11f 100644 --- a/stable/lib/libutil++/Makefile +++ b/stable/lib/libutil++/Makefile @@ -116,6 +116,9 @@ xmlrpc_util++.pc: .PHONY: install install: install-common +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean clean-local distclean distclean-local clean: clean-common clean-local clean-local: diff --git a/stable/lib/libutil++/base64.cpp b/stable/lib/libutil++/base64.cpp index b9921b0d9..c72707a06 100644 --- a/stable/lib/libutil++/base64.cpp +++ b/stable/lib/libutil++/base64.cpp @@ -2,6 +2,7 @@ #include #include #include +#include // min using namespace std; @@ -221,9 +222,6 @@ bytesFromBase64(string const& base64) { vector retval; bitBuffer buffer; - unsigned int npad; - - npad = 0; // No pad characters seen yet for (unsigned int cursor = 0; cursor < base64.length(); ++cursor) { char const thisChar(base64[cursor] & 0x7f); diff --git a/stable/lib/libutil++/girmem.cpp b/stable/lib/libutil++/girmem.cpp index 1ea79ed20..f9825507d 100644 --- a/stable/lib/libutil++/girmem.cpp +++ b/stable/lib/libutil++/girmem.cpp @@ -41,8 +41,7 @@ autoObject::Impl::Impl() { autoObject::Impl::~Impl() { - if (this->refcount > 0) - throw(error("Destroying referenced object")); + assert(this->refcount == 0); } diff --git a/stable/lib/libutil/Makefile b/stable/lib/libutil/Makefile index 3bed95814..71c99ad17 100644 --- a/stable/lib/libutil/Makefile +++ b/stable/lib/libutil/Makefile @@ -51,6 +51,7 @@ TARGET_MODS = \ lock_none \ make_printable \ memblock \ + mempool \ select \ sleep \ string_number \ @@ -58,7 +59,7 @@ TARGET_MODS = \ utf8 \ OMIT_LIBXMLRPC_UTIL_RULE=Y -MAJ=3 +MAJ=4 # Major number of shared libraries in this directory include $(SRCDIR)/common.mk @@ -122,6 +123,9 @@ xmlrpc_util.pc: .PHONY: install install: install-common +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean distclean clean: clean-common diff --git a/stable/lib/libutil/base64.c b/stable/lib/libutil/base64.c index 367dcdc90..1e7c6e705 100644 --- a/stable/lib/libutil/base64.c +++ b/stable/lib/libutil/base64.c @@ -3,7 +3,7 @@ #include "xmlrpc_config.h" #include "bool.h" -#include "xmlrpc-c/util.h" +#include "xmlrpc-c/util_int.h" #include "int.h" #include "xmlrpc-c/base64_int.h" diff --git a/stable/lib/libutil/lock_windows.c b/stable/lib/libutil/lock_windows.c index 70f687db1..22631536f 100644 --- a/stable/lib/libutil/lock_windows.c +++ b/stable/lib/libutil/lock_windows.c @@ -17,7 +17,7 @@ static lockAcquireFn acquire; static void -acquire(struct lock * const lockP) { +acquire(struct lock * lockP) { CRITICAL_SECTION * const criticalSectionP = lockP->implementationP; @@ -29,7 +29,7 @@ acquire(struct lock * const lockP) { static lockReleaseFn release; static void -release(struct lock * const lockP) { +release(struct lock * lockP) { CRITICAL_SECTION * const criticalSectionP = lockP->implementationP; diff --git a/stable/lib/libutil/memblock.c b/stable/lib/libutil/memblock.c index 9295be8b0..9469d0118 100644 --- a/stable/lib/libutil/memblock.c +++ b/stable/lib/libutil/memblock.c @@ -25,42 +25,68 @@ static bool const tracingMemory = -void -xmlrpc_mem_block_init(xmlrpc_env * const envP, - xmlrpc_mem_block * const blockP, - size_t const size) { +struct _xmlrpc_mem_block { + xmlrpc_mem_pool * poolP; + /* Pool this block is in; NULL if it is not in a pool */ + size_t size; + /* Size of the block */ + size_t allocated; + /* How much memory we've allocated from the system for this block + (pointed to by 'blockP') + */ + void * blockP; +}; + + + +xmlrpc_mem_block * +xmlrpc_mem_block_new_pool(xmlrpc_env * const envP, + size_t const size, + xmlrpc_mem_pool * const poolP) { /*---------------------------------------------------------------------------- - Initialize the provided xmlrpc_mem_block. + Create an xmlrpc_mem_block of size 'size' in pool *poolP. + + If 'poolP' is NULL, don't put it in any pool. -----------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(blockP != NULL); + xmlrpc_mem_block * blockP; - blockP->_size = size; + XMLRPC_ASSERT_ENV_OK(envP); - if (tracingMemory) - blockP->_allocated = size; - else - blockP->_allocated = MAX(BLOCK_ALLOC_MIN, size); + if (!envP->fault_occurred) { + MALLOCVAR(blockP); - blockP->_block = malloc(blockP->_allocated); - if (!blockP->_block) - xmlrpc_faultf(envP, "Can't allocate %u-byte memory block", - (unsigned)blockP->_allocated); -} - - + if (blockP == NULL) + xmlrpc_faultf(envP, "Can't allocate memory block descriptor"); + else { + blockP->poolP = poolP; -void -xmlrpc_mem_block_clean(xmlrpc_mem_block * const blockP) { -/*---------------------------------------------------------------------------- - Terminate *blockP, but don't destroy it (i.e. don't free the memory of - the structure itself). ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(blockP != NULL); - XMLRPC_ASSERT(blockP->_block != NULL); + blockP->size = size; - free(blockP->_block); - blockP->_block = XMLRPC_BAD_POINTER; + if (tracingMemory) + blockP->allocated = size; + else + blockP->allocated = MAX(BLOCK_ALLOC_MIN, size); + + if (poolP) + xmlrpc_mem_pool_alloc(envP, poolP, blockP->allocated); + + if (!envP->fault_occurred) { + blockP->blockP = malloc(blockP->allocated); + if (!blockP->blockP) + xmlrpc_faultf(envP, "Can't allocate %u-byte memory block", + (unsigned)blockP->allocated); + + + if (envP->fault_occurred) + xmlrpc_mem_pool_release(poolP, blockP->allocated); + } + if (envP->fault_occurred) { + free(blockP); + blockP = NULL; + } + } + } + return blockP; } @@ -69,25 +95,9 @@ xmlrpc_mem_block * xmlrpc_mem_block_new(xmlrpc_env * const envP, size_t const size) { /*---------------------------------------------------------------------------- - Create an xmlrpc_mem_block of size 'size'. + Create an xmlrpc_mem_block of size 'size', not in any pool -----------------------------------------------------------------------------*/ - xmlrpc_mem_block * block; - - XMLRPC_ASSERT_ENV_OK(envP); - - MALLOCVAR(block); - - if (block == NULL) - xmlrpc_faultf(envP, "Can't allocate memory block"); - else { - xmlrpc_mem_block_init(envP, block, size); - - if (envP->fault_occurred) { - free(block); - block = NULL; - } - } - return block; + return xmlrpc_mem_block_new_pool(envP, size, NULL); } @@ -98,9 +108,13 @@ xmlrpc_mem_block_free(xmlrpc_mem_block * const blockP) { Destroy xmlrpc_mem_block *blockP. -----------------------------------------------------------------------------*/ XMLRPC_ASSERT(blockP != NULL); - XMLRPC_ASSERT(blockP->_block != NULL); + XMLRPC_ASSERT(blockP->blockP != NULL); + + if (blockP->poolP) + xmlrpc_mem_pool_release(blockP->poolP, blockP->allocated); + + free(blockP->blockP); - xmlrpc_mem_block_clean(blockP); free(blockP); } @@ -112,7 +126,7 @@ xmlrpc_mem_block_size(const xmlrpc_mem_block * const blockP) { The size of the xmlrpc_mem_block. -----------------------------------------------------------------------------*/ XMLRPC_ASSERT(blockP != NULL); - return blockP->_size; + return blockP->size; } @@ -123,7 +137,7 @@ xmlrpc_mem_block_contents(const xmlrpc_mem_block * const blockP) { The contents of the xmlrpc_mem_block -----------------------------------------------------------------------------*/ XMLRPC_ASSERT(blockP != NULL); - return blockP->_block; + return blockP->blockP; } @@ -131,7 +145,7 @@ xmlrpc_mem_block_contents(const xmlrpc_mem_block * const blockP) { static size_t allocSize(size_t const requestedSize) { /*---------------------------------------------------------------------------- - The size we allocate when the user reuests to resize to 'requesteddSize'. + The size we allocate when the user requests to resize to 'requesteddSize'. We give him more than he requested in an attempt to avoid lots of copying when Caller repeatedly resizes by small amounts. @@ -175,29 +189,39 @@ xmlrpc_mem_block_resize(xmlrpc_env * const envP, XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(blockP != NULL); - if (newAllocSize != blockP->_allocated) { + if (newAllocSize > blockP->allocated) { /* Reallocate */ - void * newMem; - - newMem = malloc(newAllocSize); - if (!newMem) - xmlrpc_faultf(envP, - "Failed to allocate %u bytes of memory from the OS", - (unsigned) size); - else { - /* Copy over the data */ - size_t const sizeToCopy = MIN(blockP->_size, size); - assert(sizeToCopy <= newAllocSize); - memcpy(newMem, blockP->_block, sizeToCopy); - - free(blockP->_block); - - blockP->_block = newMem; - blockP->_allocated = newAllocSize; + if (blockP->poolP) + xmlrpc_mem_pool_alloc(envP, blockP->poolP, + newAllocSize - blockP->allocated); + + if (!envP->fault_occurred) { + void * newMem; + + newMem = malloc(newAllocSize); + if (!newMem) + xmlrpc_faultf(envP, + "Failed to allocate %u bytes of memory " + "from the OS", + (unsigned) size); + else { + /* Copy over the data */ + size_t const sizeToCopy = MIN(blockP->size, size); + assert(sizeToCopy <= newAllocSize); + memcpy(newMem, blockP->blockP, sizeToCopy); + + free(blockP->blockP); + + blockP->blockP = newMem; + blockP->allocated = newAllocSize; + } + if (envP->fault_occurred) + xmlrpc_mem_pool_release(blockP->poolP, + newAllocSize - blockP->allocated); } } - blockP->_size = size; + blockP->size = size; } @@ -208,14 +232,14 @@ xmlrpc_mem_block_append(xmlrpc_env * const envP, const void * const data, size_t const len) { - size_t const originalSize = blockP->_size; + size_t const originalSize = blockP->size; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(blockP != NULL); xmlrpc_mem_block_resize(envP, blockP, originalSize + len); if (!envP->fault_occurred) { - memcpy(((unsigned char*) blockP->_block) + originalSize, data, len); + memcpy(((unsigned char*) blockP->blockP) + originalSize, data, len); } } diff --git a/stable/lib/libutil/mempool.c b/stable/lib/libutil/mempool.c new file mode 100644 index 000000000..52584ec14 --- /dev/null +++ b/stable/lib/libutil/mempool.c @@ -0,0 +1,98 @@ +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include + +#include "bool.h" +#include "girmath.h" +#include "mallocvar.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/util.h" + +struct _xmlrpc_mem_pool { + size_t size; + size_t allocated; +}; + + + +xmlrpc_mem_pool * +xmlrpc_mem_pool_new(xmlrpc_env * const envP, + size_t const size) { +/*---------------------------------------------------------------------------- + Create an xmlrpc_mem_pool of size 'size' bytes. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_pool * poolP; + + XMLRPC_ASSERT_ENV_OK(envP); + + MALLOCVAR(poolP); + + if (poolP == NULL) + xmlrpc_faultf(envP, "Can't allocate memory pool descriptor"); + else { + poolP->size = size; + + poolP->allocated = 0; + + if (envP->fault_occurred) + free(poolP); + } + return poolP; +} + + + +void +xmlrpc_mem_pool_free(xmlrpc_mem_pool * const poolP) { +/*---------------------------------------------------------------------------- + Destroy xmlrpc_mem_pool *poolP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(poolP != NULL); + + XMLRPC_ASSERT(poolP->allocated == 0); + + free(poolP); +} + + + +void +xmlrpc_mem_pool_alloc(xmlrpc_env * const envP, + xmlrpc_mem_pool * const poolP, + size_t const size) { +/*---------------------------------------------------------------------------- + Take 'size' bytes from pool *poolP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(poolP->allocated <= poolP->size); + + if (poolP->size - poolP->allocated < size) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_LIMIT_EXCEEDED_ERROR, + "Memory pool is out of memory. %u-byte pool is %u bytes short", + (unsigned)poolP->size, + (unsigned)(poolP->allocated + size - poolP->size)); + else + poolP->allocated += size; +} + + + +void +xmlrpc_mem_pool_release(xmlrpc_mem_pool * const poolP, + size_t const size) { +/*---------------------------------------------------------------------------- + Return 'size' bytes to pool *poolP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(poolP != NULL); + + XMLRPC_ASSERT(poolP->allocated >= size); + + poolP->allocated -= size; +} + + + diff --git a/stable/lib/libutil/utf8.c b/stable/lib/libutil/utf8.c index 264a89e93..7f749dc1b 100644 --- a/stable/lib/libutil/utf8.c +++ b/stable/lib/libutil/utf8.c @@ -44,6 +44,7 @@ #include "xmlrpc_config.h" #include "bool.h" #include "xmlrpc-c/base.h" +#include "xmlrpc-c/util_int.h" /*========================================================================= ** Tables and Constants diff --git a/stable/lib/libwww_transport/Makefile b/stable/lib/libwww_transport/Makefile index c8c51faf1..ed5c0aa69 100644 --- a/stable/lib/libwww_transport/Makefile +++ b/stable/lib/libwww_transport/Makefile @@ -51,6 +51,9 @@ distdir: .PHONY: install install: +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: dep dep: dep-common diff --git a/stable/lib/openssl/Makefile b/stable/lib/openssl/Makefile new file mode 100644 index 000000000..87fda28af --- /dev/null +++ b/stable/lib/openssl/Makefile @@ -0,0 +1,121 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + LIBDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/openssl + +include $(BLDDIR)/config.mk + +default: all + +MODS := xmlrpc_openssl_thread + +TARGET_MODS = $(MODS) + +TARGET_LIBRARY_NAMES := libxmlrpc_openssl + +STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_openssl.a + +SHARED_LIBS_TO_BUILD := libxmlrpc_openssl +SHARED_LIBS_TO_INSTALL := libxmlrpc_openssl + +PKGCONFIG_FILES_TO_INSTALL := xmlrpc_openssl.pc + +MAJ := 1 + +OPENSSL_INCLUDES := $(shell pkg-config openssl --cflags) +OPENSSL_LIBS := $(shell pkg-config openssl --libs) + +include $(SRCDIR)/common.mk + +OPENSSL_SHLIB = $(call shlibfn,libxmlrpc_openssl) +#OPENSSL_SHLIB is e.g. libxmlrpc_openssl.so.3.1 +OPENSSL_SHLIBLE = $(call shliblefn,libxmlrpc_openssl) +#OPENSSL_SHLIBLE is e.g. libxmlrpc_openssl.so + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +.PHONY: all +all: libxmlrpc_openssl.a \ + $(TARGET_SHARED_LIBRARIES) \ + $(TARGET_SHARED_LE_LIBS) \ + $(PKGCONFIG_FILES_TO_INSTALL) \ + +# Rules for the above dependencies are in common.mk, +# courtesy of TARGET_MODS. + +# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES +$(OPENSSL_SHLIB): $(TARGET_MODS:%=%.osh) \ + $(LIBXMLRPC_UTIL) +$(OPENSSL_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) +$(OPENSSL_SHLIB): LIBDEP = $(LIBXMLRPC_UTIL_LIBDEP) $(OPENSSL_LIBS) + +# Rule for this is in common.mk, courtesy of TARGET_STATIC_LIBRARIES: + +libxmlrpc_openssl.a: $(TARGET_MODS:%=%.o) +libxmlrpc_openssl.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) + +#----------------------------------------------------------------------------- +# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES +#----------------------------------------------------------------------------- + +INCLUDES = \ + -I$(BLDDIR) \ + -I$(BLDDIR)/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include \ + $(OPENSSL_INCLUDES) + +#----------------------------------------------------------------------------- +# RULES TO MAKE PKGCONFIG FILES +# +# (These are files used by the 'pkg-config' program to get information about +# using the libraries we build) +#----------------------------------------------------------------------------- + +xmlrpc_openssl.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_openssl" >>$@ + @echo "Description: Openssl convenience function from Xmlrpc-c package" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_openssl" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +#----------------------------------------------------------------------------- +# MISCELLANEOUS +#----------------------------------------------------------------------------- + +.PHONY: clean +clean: clean-common + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: tags +tags: TAGS + +.PHONY: distdir +distdir: + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: dep +dep: dep-common + +include depend.mk + +# Need this dependency for those who don't use depend.mk. +# Without it, version.h doesn't get created. +xmlrpc_curl_transport.o xmlrpc_curl_transport.osh: version.h diff --git a/stable/lib/openssl/xmlrpc_openssl_thread.c b/stable/lib/openssl/xmlrpc_openssl_thread.c new file mode 100644 index 000000000..a7a7b46fe --- /dev/null +++ b/stable/lib/openssl/xmlrpc_openssl_thread.c @@ -0,0 +1,124 @@ +#include "xmlrpc_config.h" +#include +#include +#include + +#include "mallocvar.h" + +#include "xmlrpc-c/string_int.h" + +#include "xmlrpc-c/openssl_thread.h" + + +/* These ugly global variables are necessary and appropriate because our + purpose is to manipulate OpenSSL's ugly global state. +*/ + +static pthread_mutex_t * opensslMutex; + /* Dynamically allocated array with an entry for each lock OpenSSL + has created. opensslMutex[N] is the mutex for the lock known by + OpenSSL with ID N. + */ + +static unsigned int maxLockCt; + + + +static void +lock(int const mode, + int const lockId, + const char * const fileName ATTR_UNUSED, + int const lineNum ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + This is a locking function for OpenSSL to call when it wants to lock or + unlock a lock. +-----------------------------------------------------------------------------*/ + assert(lockId >= 0); + assert((unsigned int)lockId < maxLockCt); + + pthread_mutex_t * const mutexP = &opensslMutex[lockId]; + + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(mutexP); + else + pthread_mutex_unlock(mutexP); +} + + + +static unsigned long +id(void) { +/*---------------------------------------------------------------------------- + This is an ID function for OpenSSL to call when it wants a unique + identifier of the executing thread. +-----------------------------------------------------------------------------*/ + return ((unsigned long)pthread_self()); +} + + + +void +xmlrpc_openssl_thread_setup(const char ** const errorP) { +/*---------------------------------------------------------------------------- + Set up the OpenSSL library to handle being called by multiple threads + concurrently. + + This setup is process-global, so this must be called exactly once in the + program (ergo a subroutine library cannot normally call this under the + covers; if a subroutine library want to use OpenSSL in a thread-safe + manner, it must depend upon its user to call this). + + This needs to be called as the program starts up, when it is only one + thread. + + (But this need not be called at all in a program that will never call + OpenSSL functions from multiple threads). +-----------------------------------------------------------------------------*/ + maxLockCt = CRYPTO_num_locks(); + + MALLOCARRAY(opensslMutex, maxLockCt); + + if (!opensslMutex) + xmlrpc_asprintf(errorP, "Failed to allocate an array for %u " + "potential OpenSSL locks", maxLockCt); + else { + *errorP = NULL; + + unsigned int i; + + for (i = 0; i < maxLockCt; ++i) + pthread_mutex_init(&opensslMutex[i], NULL); + + CRYPTO_set_id_callback(id); + + CRYPTO_set_locking_callback(lock); + } +} + + + +void +xmlrpc_openssl_thread_cleanup() { +/*---------------------------------------------------------------------------- + Undo 'xmlrpc_openssl_thread_setup'. + + This should be called at the end of a program, when there is only one + thread left. + + (As a practical matter, there's really no need to call this at all; if the + program is just going to exit afterward, any cleanup we do is moot). +-----------------------------------------------------------------------------*/ + CRYPTO_set_locking_callback(NULL); + + CRYPTO_set_id_callback(NULL); + + { + unsigned int i; + + for (i = 0; i < maxLockCt; ++i) + pthread_mutex_destroy(&opensslMutex[i]); + } + free(opensslMutex); +} + + diff --git a/stable/lib/util/Makefile b/stable/lib/util/Makefile index eaa5febc0..0d406b6ef 100644 --- a/stable/lib/util/Makefile +++ b/stable/lib/util/Makefile @@ -77,4 +77,8 @@ distclean: clean distclean-common .PHONY: dep dep: dep-common -install: \ No newline at end of file +.PHONY: install +install: + +.PHONY: uninstall +uninstall: \ No newline at end of file diff --git a/stable/lib/wininet_transport/Makefile b/stable/lib/wininet_transport/Makefile index 1b24efc41..9ee33f46e 100644 --- a/stable/lib/wininet_transport/Makefile +++ b/stable/lib/wininet_transport/Makefile @@ -48,6 +48,9 @@ distdir: .PHONY: install install: +.PHONY: uninstall +uninstall: + .PHONY: dep dep: dep-common diff --git a/stable/lib/wininet_transport/xmlrpc_wininet_transport.c b/stable/lib/wininet_transport/xmlrpc_wininet_transport.c index 1690feead..f990afb7b 100644 --- a/stable/lib/wininet_transport/xmlrpc_wininet_transport.c +++ b/stable/lib/wininet_transport/xmlrpc_wininet_transport.c @@ -52,7 +52,7 @@ statusCallback(HINTERNET const hInternet, struct xmlrpc_client_transport { - lock * listLockP; + struct lock * listLockP; struct list_head rpcList; /* List of all RPCs that exist for this transport. An RPC exists from the time the user requests it until the time the user diff --git a/stable/src/Makefile b/stable/src/Makefile index 4e71d17b9..315097c64 100644 --- a/stable/src/Makefile +++ b/stable/src/Makefile @@ -391,6 +391,9 @@ check: .PHONY: install install: install-common $(SUBDIRS:%=%/install) +.PHONY: uninstall +uninstall: uninstall-common $(SUBDIRS:%=%/uninstall) + .PHONY: clean clean-local distclean distclean-local clean: $(SUBDIRS:%=%/clean) clean-common clean-local clean-local: diff --git a/stable/src/abyss_handler.c b/stable/src/abyss_handler.c index 8b5b323b4..7698703bb 100644 --- a/stable/src/abyss_handler.c +++ b/stable/src/abyss_handler.c @@ -361,6 +361,11 @@ processCall(TSession * const abyssSessionP, RPC, i.e. turn the XML-RPC call into an XML-RPC response. 'wantChunk' means Caller wants the HTTP reponse chunked. + + We use the Abyss session's memory pool for some memory allocations - + essentially those that aren't predictable because they depend upon the data + from the client. We do this because the session's memory pool has a size + limit designed to keep the client from monopolizing the server's memory. -----------------------------------------------------------------------------*/ xmlrpc_env env; @@ -469,6 +474,11 @@ handleXmlRpcCallReq(TSession * const abyssSessionP, Handle it by feeding the XML which is its content to 'xmlProcessor' along with argument 'xmlProcessorArg'. + + (There doesn't seem to be any way 'xmlProcessor' could ever be anything but + 'processXmlrpcCall' in xmlrpc_server_abyss.c (with 'xmlProcessorArg' being + the handle of a method registry), so I'm not sure why we didn't just put + that in this module and call it explicitly). -----------------------------------------------------------------------------*/ /* We used to reject the call if content-type was not present and text/xml, on some security theory (a firewall may block text/xml with diff --git a/stable/src/base_global.c b/stable/src/base_global.c index cb20cfee5..1c34a763f 100644 --- a/stable/src/base_global.c +++ b/stable/src/base_global.c @@ -1,5 +1,5 @@ #include "xmlrpc-c/base.h" -#include "xmlrpc-c/xmlparser.h" +#include "xmlparser.h" @@ -24,7 +24,7 @@ xmlrpc_init(xmlrpc_env * const envP) { */ XMLRPC_ASSERT_ENV_OK(envP); - + if (globallyInitialized == 0) { xml_init(envP); /* Initialize the XML parser library */ } diff --git a/stable/src/cpp/Makefile b/stable/src/cpp/Makefile index c27a89a45..cc654a0ac 100644 --- a/stable/src/cpp/Makefile +++ b/stable/src/cpp/Makefile @@ -414,6 +414,9 @@ xmlrpc_server_pstream++.pc: .PHONY: install install: install-common +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean clean-local distclean distclean-local clean: clean-common clean-local clean-local: diff --git a/stable/src/cpp/XmlRpcCpp.cpp b/stable/src/cpp/XmlRpcCpp.cpp index 11099cb05..2270ee917 100644 --- a/stable/src/cpp/XmlRpcCpp.cpp +++ b/stable/src/cpp/XmlRpcCpp.cpp @@ -27,6 +27,8 @@ #include #include +#include "xmlrpc-c/util_int.h" + #include "xmlrpc-c/oldcppwrapper.hpp" using std::string; diff --git a/stable/src/cpp/client.cpp b/stable/src/cpp/client.cpp index 2ce59acb8..6b7d27a50 100644 --- a/stable/src/cpp/client.cpp +++ b/stable/src/cpp/client.cpp @@ -21,6 +21,7 @@ using girerr::throwf; using girmem::autoObjectPtr; using girmem::autoObject; #include "xmlrpc-c/env_wrap.hpp" +#include "xmlrpc-c/util_int.h" #include "xmlrpc-c/base.h" #include "xmlrpc-c/client.h" #include "xmlrpc-c/transport.h" diff --git a/stable/src/cpp/packetsocket.cpp b/stable/src/cpp/packetsocket.cpp index 754e5d36e..328e2c477 100644 --- a/stable/src/cpp/packetsocket.cpp +++ b/stable/src/cpp/packetsocket.cpp @@ -80,6 +80,9 @@ using namespace std; #define ESC 0x1B // ASCII Escape character #define ESC_STR "\x1B" +class BrokenConnectionEx { +}; + class XMLRPC_DLLEXPORT socketx { public: @@ -224,6 +227,48 @@ wouldBlock() { +static bool +lastErrorIsBrokenConn() { +/*---------------------------------------------------------------------------- + The last system call failure in this process, assuming the system call was + to read or write a steram socket, indicates the problem was that the + connection broke, e.g. because a network cable was cut, the peer powered + off, or the peer just got tired of talking to us and closed down the + connection. + + The underlying signficance of this distinction is that when a connection + has broken, the caller might reasonably respond by trying to establish a + new connection, and possibly doing so with a different network path or a + different peer. +-----------------------------------------------------------------------------*/ + bool retval; + +#if MSVCRT + // We don't know how to determine this on Windows, so we just punt + retval = false; +#else + switch (errno) { + // Some of these are probably not defined on some systems; we will + // need some build system magic to deal with that as error reports + // come in. + case EPIPE: + case ETIMEDOUT: + case ECONNRESET: + case ENOTCONN: + case ESHUTDOWN: + retval = true; + break; + default: + retval = false; + } + +#endif + + return retval; +} + + + static string const lastErrorDesc() { /*---------------------------------------------------------------------------- @@ -249,7 +294,17 @@ socketx::read(unsigned char * const buffer, size_t const bufferSize, bool * const wouldblockP, size_t * const bytesReadP) const { - +/*---------------------------------------------------------------------------- + Put any bytes that are in the OS buffer waiting to be read in 'buffer', + up to 'bufferSize'. + + Return *wouldblockP == true iff the buffer is empty now, but more could + arrive later. + + Return as *bytesReadP the number of bytes put into 'buffer'. + + Throw a BrokenConnectionEx exception if the connection has been broken. +-----------------------------------------------------------------------------*/ int rc; // We've seen a Windows library whose recv() expects a char * buffer @@ -261,7 +316,9 @@ socketx::read(unsigned char * const buffer, if (wouldBlock()) { *wouldblockP = true; *bytesReadP = 0; - } else + } else if (lastErrorIsBrokenConn()) + throw BrokenConnectionEx(); + else throwf("read() of socket failed with %s", lastErrorDesc().c_str()); } else { *wouldblockP = false; @@ -276,7 +333,14 @@ writeFd(int const fd, const unsigned char * const data, size_t const size, size_t * const bytesWrittenP) { +/*---------------------------------------------------------------------------- + Write as much of the 'size' bytes at 'data' to socket 'fd' as can be + written immediately (i.e. into the OS buffer). + Return as *bytesWrittenP the number of bytes written. + + Throw a BrokenConnectionEx exception if the connection has been broken. +-----------------------------------------------------------------------------*/ size_t totalBytesWritten; bool full; // File image is "full" for now - won't take any more data @@ -292,9 +356,13 @@ writeFd(int const fd, if (rc < 0) { if (wouldBlock()) full = true; - else - throwf("write() of socket failed with %s", - lastErrorDesc().c_str()); + else { + if (lastErrorIsBrokenConn()) + throw BrokenConnectionEx(); + else + throwf("write() of socket failed with %s", + lastErrorDesc().c_str()); + } } else if (rc == 0) throwf("Zero byte short write."); else { @@ -311,8 +379,10 @@ void socketx::writeWait(const unsigned char * const data, size_t const size) const { /*---------------------------------------------------------------------------- - Write the 'size' bytes at 'data' to the socket. Wait as long - as it takes for the file image to be able to take all the data. + Write the 'size' bytes at 'data' to the socket. Wait as long + as it takes for the file image to be able to take all the data. + + Throw a BrokenConnectionEx exception if the connection has been broken. -----------------------------------------------------------------------------*/ size_t totalBytesWritten; @@ -586,7 +656,13 @@ escapePos(const unsigned char * const start, void packetSocket_impl::writeWait(packetPtr const& packetP) const { +/*---------------------------------------------------------------------------- + Write the packet to the socket, waiting for the recipient to take it as + necessary. + Throw a BrokenConnectionEx exception if we can't send because of a broken + connection. +-----------------------------------------------------------------------------*/ const unsigned char * const packetStart( reinterpret_cast(ESC_STR "PKT")); const unsigned char * const packetEnd( @@ -597,6 +673,7 @@ packetSocket_impl::writeWait(packetPtr const& packetP) const { if (this->mustTrace) traceWrite(packetP->getBytes(), packetP->getLength()); + this->sock.writeWait(packetStart, 4); const unsigned char * const end( @@ -646,7 +723,7 @@ traceReceivedPacket(const unsigned char * const data, -void +void // private packetSocket_impl::takeSomeEscapeSeq(const unsigned char * const buffer, size_t const length, size_t * const bytesTakenP) { @@ -701,7 +778,7 @@ packetSocket_impl::takeSomeEscapeSeq(const unsigned char * const buffer, -void +void // private packetSocket_impl::takeSomePacket(const unsigned char * const buffer, size_t const length, size_t * const bytesTakenP) { @@ -737,7 +814,7 @@ packetSocket_impl::takeSomePacket(const unsigned char * const buffer, -void +void // private packetSocket_impl::verifyNothingAccumulated() { /*---------------------------------------------------------------------------- Throw an error if there is a partial packet accumulated. @@ -754,7 +831,7 @@ packetSocket_impl::verifyNothingAccumulated() { -void +void // private packetSocket_impl::processBytesRead(const unsigned char * const buffer, size_t const bytesRead) { @@ -801,17 +878,20 @@ traceBytesRead(const unsigned char * const buffer, -void +void //private packetSocket_impl::readFromFile() { /*---------------------------------------------------------------------------- Read some data from the underlying stream socket. Read as much as is - available right now, up to 4K. Update 'this' to reflect the data read. + available right now, up to 4K. Update *this to reflect the data read. E.g. if we read an entire packet, we add it to the packet buffer (this->readBuffer). If we read the first part of a packet, we add it to the packet accumulator (*this->packetAccumP). If we read the end of a packet, we add the full packet to the packet buffer and empty the packet accumulator. Etc. + + Throw a BrokenConnectionEx exception if we can't read because of a broken + connection. -----------------------------------------------------------------------------*/ bool wouldblock; @@ -850,13 +930,16 @@ packetSocket_impl::read(bool * const eofP, return *gotPacketP true. Otherwise, return *gotPacketP false. Iff the socket has no more data coming (it is shut down) and there - is no complete packet in the packet buffer, return *eofP. + is no complete packet in the packet buffer, return *eofP true. This leaves one other possibility: there is no full packet immediately available, but there may be in the future because the socket is still alive. In that case, we return *eofP == false and *gotPacketP == false. Any packet we return belongs to caller; Caller must delete it. + + Throw a BrokenConnectionEx exception if we can't read because of a broken + connection. -----------------------------------------------------------------------------*/ // Move any packets now waiting to be read in the underlying stream // socket into our packet buffer (this->readBuffer). @@ -896,6 +979,9 @@ packetSocket_impl::readWait(volatile const int * const interruptP, Return *gotPacketP true iff we return a packet. Return *eofP true iff we hit EOF. + + Throw a BrokenConnectionEx exception if we can't read because of a broken + connection. -----------------------------------------------------------------------------*/ bool gotPacket; bool eof; @@ -932,7 +1018,25 @@ packetSocket::~packetSocket() { void packetSocket::writeWait(packetPtr const& packetP) const { - implP->writeWait(packetP); + try { + implP->writeWait(packetP); + } catch (BrokenConnectionEx) { + throwf("Recipient hung up or connection broke"); + } +} + + + +void +packetSocket::writeWait(packetPtr const& packetP, + bool * const brokenConnP) const { + + try { + implP->writeWait(packetP); + *brokenConnP = false; + } catch (BrokenConnectionEx) { + *brokenConnP = true; + } } @@ -942,7 +1046,12 @@ packetSocket::read(bool * const eofP, bool * const gotPacketP, packetPtr * const packetPP) { - this->implP->read(eofP, gotPacketP, packetPP); + try { + this->implP->read(eofP, gotPacketP, packetPP); + } catch (BrokenConnectionEx) { + *gotPacketP = false; + *eofP = true; + } } @@ -953,7 +1062,12 @@ packetSocket::readWait(volatile const int * const interruptP, bool * const gotPacketP, packetPtr * const packetPP) { - this->implP->readWait(interruptP, eofP, gotPacketP, packetPP); + try { + this->implP->readWait(interruptP, eofP, gotPacketP, packetPP); + } catch (BrokenConnectionEx) { + *gotPacketP = false; + *eofP = true; + } } @@ -963,12 +1077,16 @@ packetSocket::readWait(volatile const int * const interruptP, bool * const eofP, packetPtr * const packetPP) { - bool gotPacket; + try { + bool gotPacket; - this->implP->readWait(interruptP, eofP, &gotPacket, packetPP); + this->implP->readWait(interruptP, eofP, &gotPacket, packetPP); - if (!gotPacket && !*eofP) - throwf("Packet read was interrupted"); + if (!gotPacket && !*eofP) + throwf("Packet read was interrupted"); + } catch (BrokenConnectionEx) { + *eofP = true; + } } @@ -982,4 +1100,6 @@ packetSocket::readWait(bool * const eofP, this->readWait(&interrupt, eofP, packetPP); } + + } // namespace diff --git a/stable/src/cpp/pstream.cpp b/stable/src/cpp/pstream.cpp index fd2a31d6c..d267315df 100644 --- a/stable/src/cpp/pstream.cpp +++ b/stable/src/cpp/pstream.cpp @@ -26,27 +26,30 @@ #include +using namespace std; + #include "xmlrpc-c/girerr.hpp" using girerr::throwf; #include "xmlrpc-c/packetsocket.hpp" #include "xmlrpc-c/client_transport.hpp" -using namespace std; +typedef xmlrpc_c::clientXmlTransport_pstream::BrokenConnectionEx + BrokenConnectionEx; namespace xmlrpc_c { - - struct clientXmlTransport_pstream::constrOpt_impl { constrOpt_impl(); struct { int fd; + bool useBrokenConnEx; } value; struct { bool fd; + bool useBrokenConnEx; } present; }; @@ -54,7 +57,8 @@ struct clientXmlTransport_pstream::constrOpt_impl { clientXmlTransport_pstream::constrOpt_impl::constrOpt_impl() { - this->present.fd = false; + this->present.fd = false; + this->present.useBrokenConnEx = false; } @@ -68,6 +72,7 @@ clientXmlTransport_pstream::constrOpt::OPTION_NAME(TYPE const& arg) { \ } DEFINE_OPTION_SETTER(fd, xmlrpc_socket); +DEFINE_OPTION_SETTER(useBrokenConnEx, bool); #undef DEFINE_OPTION_SETTER @@ -94,10 +99,38 @@ clientXmlTransport_pstream::constrOpt::constrOpt(constrOpt& arg) { -clientXmlTransport_pstream::clientXmlTransport_pstream( - constrOpt const& optExt) { +class clientXmlTransport_pstream_impl { + +public: + clientXmlTransport_pstream_impl( + clientXmlTransport_pstream::constrOpt_impl const& opt); + + ~clientXmlTransport_pstream_impl(); + + void + call(xmlrpc_c::carriageParm * const carriageParmP, + std::string const& callXml, + std::string * const responseXmlP); - constrOpt_impl const opt(*optExt.implP); +private: + packetSocket * packetSocketP; + + bool usingBrokenConnEx; + // We're throwing a Broken Connection object when something fails + // because the connection to the server is broken. When this is false, + // we throw an ordinary error when that happens. + + void + sendCall(std::string const& callXml); + + void + recvResp(std::string * const responseXmlP); +}; + + + +clientXmlTransport_pstream_impl::clientXmlTransport_pstream_impl( + clientXmlTransport_pstream::constrOpt_impl const& opt) { if (!opt.present.fd) throwf("You must provide a 'fd' constructor option."); @@ -111,47 +144,83 @@ clientXmlTransport_pstream::clientXmlTransport_pstream( throwf("Unable to create packet socket out of file descriptor %d. %s", opt.value.fd, e.what()); } - this->packetSocketP = packetSocketAP.get(); - packetSocketAP.release(); + + if (opt.present.useBrokenConnEx) + this->usingBrokenConnEx = opt.value.useBrokenConnEx; + else + this->usingBrokenConnEx = false; + + this->packetSocketP = packetSocketAP.release(); } -clientXmlTransport_pstream::~clientXmlTransport_pstream() { +clientXmlTransport_pstream::clientXmlTransport_pstream( + constrOpt const& optExt) : + + implP(new clientXmlTransport_pstream_impl(*optExt.implP)) +{} + + + +clientXmlTransport_pstream_impl::~clientXmlTransport_pstream_impl() { delete(this->packetSocketP); } -void -clientXmlTransport_pstream::call( - carriageParm * const carriageParmP, - string const& callXml, - string * const responseXmlP) { - carriageParm_pstream * const carriageParmPstreamP( - dynamic_cast(carriageParmP)); +clientXmlTransport_pstream::~clientXmlTransport_pstream() { + + delete(this->implP); +} + - if (carriageParmPstreamP == NULL) - throwf("Pstream client XML transport called with carriage " - "parameter object not of class carriageParm_pstream"); +void // private +clientXmlTransport_pstream_impl::sendCall(string const& callXml) { +/*---------------------------------------------------------------------------- + Send the text 'callXml' down the pipe as a packet which is the RPC call. +-----------------------------------------------------------------------------*/ packetPtr const callPacketP(new packet(callXml.c_str(), callXml.length())); try { - this->packetSocketP->writeWait(callPacketP); + bool brokenConn; + + this->packetSocketP->writeWait(callPacketP, &brokenConn); + + if (brokenConn) { + if (this->usingBrokenConnEx) + throw BrokenConnectionEx(); + else + throwf("Server hung up or connection broke"); + } } catch (exception const& e) { throwf("Failed to write the call to the packet socket. %s", e.what()); } +} + + + +void +clientXmlTransport_pstream_impl::recvResp(string * const responseXmlP) { +/*---------------------------------------------------------------------------- + Receive a packet which is the RPC response and return its contents + as the text *responseXmlP. +-----------------------------------------------------------------------------*/ packetPtr responsePacketP; try { bool eof; this->packetSocketP->readWait(&eof, &responsePacketP); - if (eof) - throwf("The other end closed the socket before sending " - "the response."); + if (eof) { + if (this->usingBrokenConnEx) + throw BrokenConnectionEx(); + else + throwf("The other end closed the socket before sending " + "the response."); + } } catch (exception const& e) { throwf("We sent the call, but couldn't get the response. %s", e.what()); @@ -163,4 +232,33 @@ clientXmlTransport_pstream::call( +void +clientXmlTransport_pstream_impl::call( + carriageParm * const carriageParmP, + string const& callXml, + string * const responseXmlP) { + + carriageParm_pstream * const carriageParmPstreamP( + dynamic_cast(carriageParmP)); + + if (carriageParmPstreamP == NULL) + throwf("Pstream client XML transport called with carriage " + "parameter object not of class carriageParm_pstream"); + + this->sendCall(callXml); + + this->recvResp(responseXmlP); +} + + + +void +clientXmlTransport_pstream::call( + carriageParm * const carriageParmP, + string const& callXml, + string * const responseXmlP) { + + this->implP->call(carriageParmP, callXml, responseXmlP); +} + } // namespace diff --git a/stable/src/cpp/registry.cpp b/stable/src/cpp/registry.cpp index 1a5e5a23e..07f795a02 100644 --- a/stable/src/cpp/registry.cpp +++ b/stable/src/cpp/registry.cpp @@ -8,6 +8,7 @@ using girerr::throwf; #include "xmlrpc-c/girmem.hpp" using girmem::autoObject; using girmem::autoObjectPtr; +#include "xmlrpc-c/util_int.h" #include "xmlrpc-c/base.h" #include "xmlrpc-c/base.hpp" #include "xmlrpc-c/env_wrap.hpp" diff --git a/stable/src/cpp/server_abyss.cpp b/stable/src/cpp/server_abyss.cpp index 61a0d0197..2f70516de 100644 --- a/stable/src/cpp/server_abyss.cpp +++ b/stable/src/cpp/server_abyss.cpp @@ -16,7 +16,7 @@ using girerr::error; using girerr::throwf; #include "xmlrpc-c/base.h" -#include "xmlrpc-c/util.h" +#include "xmlrpc-c/util_int.h" #include "xmlrpc-c/base.hpp" #include "xmlrpc-c/abyss.h" #include "xmlrpc-c/server_abyss.h" @@ -184,6 +184,7 @@ struct serverAbyss::constrOpt_impl { unsigned int portNumber; unsigned int maxConn; unsigned int maxConnBacklog; + size_t maxRpcMem; unsigned int keepaliveTimeout; unsigned int keepaliveMaxConn; unsigned int timeout; @@ -205,6 +206,7 @@ struct serverAbyss::constrOpt_impl { bool portNumber; bool maxConn; bool maxConnBacklog; + bool maxRpcMem; bool keepaliveTimeout; bool keepaliveMaxConn; bool timeout; @@ -231,6 +233,7 @@ serverAbyss::constrOpt_impl::constrOpt_impl() { present.logFileName = false; present.maxConn = false; present.maxConnBacklog = false; + present.maxRpcMem = false; present.keepaliveTimeout = false; present.keepaliveMaxConn = false; present.timeout = false; @@ -268,6 +271,7 @@ DEFINE_OPTION_SETTER(socketFd, XMLRPC_SOCKET); DEFINE_OPTION_SETTER(portNumber, unsigned int); DEFINE_OPTION_SETTER(maxConn, unsigned int); DEFINE_OPTION_SETTER(maxConnBacklog, unsigned int); +DEFINE_OPTION_SETTER(maxRpcMem, size_t); DEFINE_OPTION_SETTER(keepaliveTimeout, unsigned int); DEFINE_OPTION_SETTER(keepaliveMaxConn, unsigned int); DEFINE_OPTION_SETTER(timeout, unsigned int); @@ -331,10 +335,14 @@ struct serverAbyss_impl { // switch and create a server based on it; otherwise, we don't. serverAbyss_impl(serverAbyss::constrOpt_impl const& opt, - serverAbyss * const serverAbyssP); + serverAbyss * const serverAbyssP); ~serverAbyss_impl(); + void + getListenName(struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP); + void run(); @@ -602,6 +610,8 @@ setAdditionalServerParms(TServer * const serverP, ServerSetMaxConn(serverP, opt.value.maxConn); if (opt.present.maxConnBacklog) ServerSetMaxConnBacklog(serverP, opt.value.maxConnBacklog); + if (opt.present.maxRpcMem) + ServerSetMaxSessionMem(serverP, opt.value.maxRpcMem); if (opt.present.keepaliveTimeout) ServerSetKeepaliveTimeout(serverP, opt.value.keepaliveTimeout); if (opt.present.keepaliveMaxConn) @@ -736,6 +746,33 @@ serverAbyss_impl::~serverAbyss_impl() { +void +serverAbyss_impl::getListenName(struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP) { + + if (!this->chanSwitchP) + throwf("%s", + "Server is not configured to listen for client connections"); + + const char * error; + +#ifdef WIN32 + ChanSwitchWinGetListenName(this->chanSwitchP, + sockaddrPP, sockaddrLenP, &error); +#else + ChanSwitchUnixGetListenName(this->chanSwitchP, + sockaddrPP, sockaddrLenP, &error); +#endif + + if (error) { + string const e(error); + xmlrpc_strfree(error); + throwf("%s", e.c_str()); + } +} + + + static void setupSignalsAndRunAbyss(TServer * const abyssServerP) { @@ -867,6 +904,15 @@ serverAbyss::~serverAbyss() { +void +serverAbyss::getListenName(struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP) { + + this->implP->getListenName(sockaddrPP, sockaddrLenP); +} + + + void serverAbyss::run() { diff --git a/stable/src/cpp/value.cpp b/stable/src/cpp/value.cpp index 2695f1af7..e2c123729 100644 --- a/stable/src/cpp/value.cpp +++ b/stable/src/cpp/value.cpp @@ -1,3 +1,4 @@ +#include /***************************************************************************** value.cpp ****************************************************************************** @@ -58,23 +59,23 @@ throwIfError(env_wrap const& env) { class cDatetimeValueWrapper { public: xmlrpc_value * valueP; - + cDatetimeValueWrapper(xmlrpc_datetime const cppvalue) { env_wrap env; - + this->valueP = xmlrpc_datetime_new(&env.env_c, cppvalue); throwIfError(env); } cDatetimeValueWrapper(time_t const cppvalue) { env_wrap env; - + this->valueP = xmlrpc_datetime_new_sec(&env.env_c, cppvalue); throwIfError(env); } #if XMLRPC_HAVE_TIMEVAL cDatetimeValueWrapper(struct timeval const cppvalue) { env_wrap env; - + this->valueP = xmlrpc_datetime_new_timeval(&env.env_c, cppvalue); throwIfError(env); } @@ -82,7 +83,7 @@ class cDatetimeValueWrapper { #if XMLRPC_HAVE_TIMESPEC cDatetimeValueWrapper(struct timespec const cppvalue) { env_wrap env; - + this->valueP = xmlrpc_datetime_new_timespec(&env.env_c, cppvalue); throwIfError(env); } @@ -235,7 +236,7 @@ value::addToCStruct(xmlrpc_value * const structP, -value::type_t +value::type_t value::type() const { this->validateInstantiated(); @@ -270,10 +271,10 @@ value_int::value_int(int const cppvalue) { class cWrapper { public: xmlrpc_value * valueP; - + cWrapper(int const cppvalue) { env_wrap env; - + this->valueP = xmlrpc_int_new(&env.env_c, cppvalue); throwIfError(env); } @@ -281,9 +282,9 @@ value_int::value_int(int const cppvalue) { xmlrpc_DECREF(this->valueP); } }; - + cWrapper wrapper(cppvalue); - + this->instantiate(wrapper.valueP); } @@ -328,10 +329,10 @@ value_double::value_double(double const cppvalue) { class cWrapper { public: xmlrpc_value * valueP; - + cWrapper(double const cppvalue) { env_wrap env; - + this->valueP = xmlrpc_double_new(&env.env_c, cppvalue); throwIfError(env); } @@ -339,7 +340,7 @@ value_double::value_double(double const cppvalue) { xmlrpc_DECREF(this->valueP); } }; - + this->instantiate(cWrapper(cppvalue).valueP); } @@ -385,10 +386,10 @@ value_boolean::value_boolean(bool const cppvalue) { class cWrapper { public: xmlrpc_value * valueP; - + cWrapper(xmlrpc_bool const cppvalue) { env_wrap env; - + this->valueP = xmlrpc_bool_new(&env.env_c, cppvalue); throwIfError(env); } @@ -396,9 +397,9 @@ value_boolean::value_boolean(bool const cppvalue) { xmlrpc_DECREF(this->valueP); } }; - + cWrapper wrapper(cppvalue); - + this->instantiate(wrapper.valueP); } @@ -444,10 +445,10 @@ value_datetime::value_datetime(string const cppvalue) { class cWrapper { public: xmlrpc_value * valueP; - + cWrapper(string const cppvalue) { env_wrap env; - + this->valueP = xmlrpc_datetime_new_str(&env.env_c, cppvalue.c_str()); throwIfError(env); @@ -456,9 +457,9 @@ value_datetime::value_datetime(string const cppvalue) { xmlrpc_DECREF(this->valueP); } }; - + cWrapper wrapper(cppvalue); - + this->instantiate(wrapper.valueP); } @@ -467,7 +468,7 @@ value_datetime::value_datetime(string const cppvalue) { value_datetime::value_datetime(xmlrpc_datetime const cppvalue) { cDatetimeValueWrapper wrapper(cppvalue); - + this->instantiate(wrapper.valueP); } @@ -476,7 +477,7 @@ value_datetime::value_datetime(xmlrpc_datetime const cppvalue) { value_datetime::value_datetime(time_t const cppvalue) { cDatetimeValueWrapper wrapper(cppvalue); - + this->instantiate(wrapper.valueP); } @@ -614,16 +615,20 @@ value_datetime::iso8601Value() const { class cNewStringWrapper { public: xmlrpc_value * valueP; - + cNewStringWrapper(string const cppvalue, value_string::nlCode const nlCode) { env_wrap env; - + switch (nlCode) { case value_string::nlCode_all: + cerr << "Going to call xmlrpc_string_new_lp" << endl; + cerr << "length = " << cppvalue.length() << ", value = " + << cppvalue.c_str() << endl; this->valueP = xmlrpc_string_new_lp(&env.env_c, cppvalue.length(), cppvalue.c_str()); + cerr << "Back from xmlrpc_string_new_lp" << endl; break; case value_string::nlCode_lf: this->valueP = xmlrpc_string_new_lp_cr(&env.env_c, @@ -641,14 +646,14 @@ class cNewStringWrapper { xmlrpc_DECREF(this->valueP); } }; - + value_string::value_string(std::string const& cppvalue, value_string::nlCode const nlCode) { - + cNewStringWrapper wrapper(cppvalue, nlCode); - + this->instantiate(wrapper.valueP); } @@ -656,13 +661,16 @@ value_string::value_string(std::string const& cppvalue, value_string::value_string(std::string const& cppvalue) { + cerr << "value_string constructor entered" << endl; cNewStringWrapper wrapper(cppvalue, nlCode_all); - + cerr << "wrapper constructed" << endl; + this->instantiate(wrapper.valueP); + cerr << "value_string constructor exiting" << endl; } - + value_string::value_string(xmlrpc_c::value const baseValue) { if (baseValue.type() != xmlrpc_c::value::TYPE_STRING) @@ -683,7 +691,7 @@ value_string::crlfValue() const { size_t length; cWrapper(xmlrpc_value * valueP) { env_wrap env; - + xmlrpc_read_string_lp_crlf(&env.env_c, valueP, &length, &str); throwIfError(env); } @@ -691,7 +699,7 @@ value_string::crlfValue() const { free((char*)str); } }; - + this->validateInstantiated(); cWrapper wrapper(this->cValueP); @@ -747,11 +755,11 @@ value_bytestring::value_bytestring( class cWrapper { public: xmlrpc_value * valueP; - + cWrapper(vector const& cppvalue) { env_wrap env; - - this->valueP = + + this->valueP = xmlrpc_base64_new(&env.env_c, cppvalue.size(), &cppvalue[0]); throwIfError(env); } @@ -759,9 +767,9 @@ value_bytestring::value_bytestring( xmlrpc_DECREF(this->valueP); } }; - + cWrapper wrapper(cppvalue); - + this->instantiate(wrapper.valueP); } @@ -796,12 +804,12 @@ value_bytestring::vectorUcharValue() const { free((void*)contents); } }; - + this->validateInstantiated(); cWrapper wrapper(this->cValueP); - return vector(&wrapper.contents[0], + return vector(&wrapper.contents[0], &wrapper.contents[wrapper.length]); } @@ -832,14 +840,14 @@ value_bytestring::length() const { value_array::value_array(vector const& cppvalue) { - + class cWrapper { public: xmlrpc_value * valueP; - + cWrapper() { env_wrap env; - + this->valueP = xmlrpc_array_new(&env.env_c); throwIfError(env); } @@ -847,9 +855,9 @@ value_array::value_array(vector const& cppvalue) { xmlrpc_DECREF(this->valueP); } }; - + cWrapper wrapper; - + vector::const_iterator i; for (i = cppvalue.begin(); i != cppvalue.end(); ++i) i->appendToCArray(wrapper.valueP); @@ -881,9 +889,9 @@ value_array::vectorValueValue() const { arraySize = xmlrpc_array_size(&env.env_c, this->cValueP); throwIfError(env); - + vector retval(arraySize); - + for (unsigned int i = 0; i < arraySize; ++i) { class cWrapper { @@ -895,7 +903,7 @@ value_array::vectorValueValue() const { env_wrap env; xmlrpc_array_read_item(&env.env_c, arrayP, index, &valueP); - + throwIfError(env); } ~cWrapper() { @@ -931,7 +939,7 @@ value_array::size() const { arraySize = xmlrpc_array_size(&env.env_c, this->cValueP); throwIfError(env); - + return arraySize; } @@ -943,10 +951,10 @@ value_struct::value_struct( class cWrapper { public: xmlrpc_value * valueP; - + cWrapper() { env_wrap env; - + this->valueP = xmlrpc_struct_new(&env.env_c); throwIfError(env); } @@ -954,7 +962,7 @@ value_struct::value_struct( xmlrpc_DECREF(this->valueP); } }; - + cWrapper wrapper; map::const_iterator i; @@ -963,7 +971,7 @@ value_struct::value_struct( string mapkey(i->first); mapvalue.addToCStruct(wrapper.valueP, mapkey); } - + this->instantiate(wrapper.valueP); } @@ -989,9 +997,9 @@ value_struct::operator map() const { structSize = xmlrpc_struct_size(&env.env_c, this->cValueP); throwIfError(env); - + map retval; - + for (unsigned int i = 0; i < structSize; ++i) { class cMemberWrapper { public: @@ -1002,10 +1010,10 @@ value_struct::operator map() const { unsigned int const index) { env_wrap env; - - xmlrpc_struct_read_member(&env.env_c, structP, index, + + xmlrpc_struct_read_member(&env.env_c, structP, index, &keyP, &valueP); - + throwIfError(env); } ~cMemberWrapper() { @@ -1037,14 +1045,14 @@ value_struct::cvalue() const { value_nil::value_nil() { - + class cWrapper { public: xmlrpc_value * valueP; - + cWrapper() { env_wrap env; - + this->valueP = xmlrpc_nil_new(&env.env_c); throwIfError(env); } @@ -1052,12 +1060,12 @@ value_nil::value_nil() { xmlrpc_DECREF(this->valueP); } }; - + cWrapper wrapper; - + this->instantiate(wrapper.valueP); } - + value_nil::value_nil(xmlrpc_c::value const baseValue) { @@ -1084,10 +1092,10 @@ value_i8::value_i8(xmlrpc_int64 const cppvalue) { class cWrapper { public: xmlrpc_value * valueP; - + cWrapper(xmlrpc_int64 const cppvalue) { env_wrap env; - + this->valueP = xmlrpc_i8_new(&env.env_c, cppvalue); throwIfError(env); } @@ -1095,9 +1103,9 @@ value_i8::value_i8(xmlrpc_int64 const cppvalue) { xmlrpc_DECREF(this->valueP); } }; - + cWrapper wrapper(cppvalue); - + this->instantiate(wrapper.valueP); } diff --git a/stable/src/double.c b/stable/src/double.c index 3a46574d1..58f8f0056 100644 --- a/stable/src/double.c +++ b/stable/src/double.c @@ -1,3 +1,5 @@ +#include "xmlrpc_config.h" + #include #include #include @@ -261,7 +263,7 @@ xmlrpc_formatFloat(xmlrpc_env * const envP, double absvalue; buffer formatted; - assert(finite(value)); + assert(XMLRPC_FINITE(value)); bufferInit(&formatted); diff --git a/stable/src/json.c b/stable/src/json.c index 3a31f168c..394202b8e 100644 --- a/stable/src/json.c +++ b/stable/src/json.c @@ -572,12 +572,14 @@ getBackslashSequence(xmlrpc_env * const envP, static void -unescapeString(xmlrpc_env * const envP, - const char * const begin, - const char * const end, - xmlrpc_mem_block * const memBlockP) { +unescapeString(xmlrpc_env * const envP, + const char * const begin, + const char * const end, + xmlrpc_mem_block ** const memBlockPP) { - XMLRPC_MEMBLOCK_INIT(char, envP, memBlockP, 0); + xmlrpc_mem_block * memBlockP; + + memBlockP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); if (!envP->fault_occurred) { const char * cur; @@ -621,8 +623,9 @@ unescapeString(xmlrpc_env * const envP, XMLRPC_MEMBLOCK_APPEND(char, envP, memBlockP, "", 1); } if (envP->fault_occurred) - XMLRPC_MEMBLOCK_CLEAN(char, memBlockP); + XMLRPC_MEMBLOCK_FREE(char, memBlockP); } + *memBlockPP = memBlockP; } @@ -646,7 +649,7 @@ makeUtf8String(xmlrpc_env * const envP, valP->_wcs_block = NULL; if (!envP->fault_occurred) - unescapeString(envP, begin, end, &valP->_block); + unescapeString(envP, begin, end, &valP->blockP); if (envP->fault_occurred) xmlrpc_DECREF(valP); @@ -1156,9 +1159,6 @@ makeJsonString(xmlrpc_env * const envP, /* Copy all characters since the last escaped character to the output */ if (cur != last) XMLRPC_MEMBLOCK_APPEND(char, envP, outP, last, cur - last); - - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_CLEAN(char, outP); } @@ -1408,7 +1408,11 @@ serializeValue(xmlrpc_env * const envP, xmlrpc_value * const valP, unsigned int const level, xmlrpc_mem_block * const outP) { +/*---------------------------------------------------------------------------- + Generate JSON to represent the value *valP. Append it to *outP. + The JSON consists of lines of text. Indent them 'level' levels. +-----------------------------------------------------------------------------*/ XMLRPC_ASSERT_ENV_OK(envP); indent(envP, level, outP); @@ -1474,6 +1478,8 @@ void xmlrpc_serialize_json(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - +/*---------------------------------------------------------------------------- + Generate JSON to represent the value *valP. Append it to *outP. +-----------------------------------------------------------------------------*/ serializeValue(envP, valP, 0, outP); } diff --git a/stable/src/parse_datetime.c b/stable/src/parse_datetime.c index 64a3042b1..bedf67165 100644 --- a/stable/src/parse_datetime.c +++ b/stable/src/parse_datetime.c @@ -188,7 +188,7 @@ parseDtRegex(xmlrpc_env * const envP, status = regcomp(&re, thisParserP->regex, REG_ICASE | REG_EXTENDED); /* Our regex is valid, so it must have compiled: */ - assert(status == 0); + assert(status == 0); if (status){}; /* quiet compiler warning */ { int status; @@ -200,8 +200,8 @@ parseDtRegex(xmlrpc_env * const envP, parserP = thisParserP; } - regfree(&re); } + regfree(&re); } if (parserP) { diff --git a/stable/src/parse_value.c b/stable/src/parse_value.c index 9476c9f40..7886c7d9d 100644 --- a/stable/src/parse_value.c +++ b/stable/src/parse_value.c @@ -15,7 +15,7 @@ #include "xmlrpc-c/string_int.h" #include "xmlrpc-c/string_number.h" #include "xmlrpc-c/util.h" -#include "xmlrpc-c/xmlparser.h" +#include "xmlparser.h" #include "parse_datetime.h" #include "parse_value.h" @@ -717,8 +717,8 @@ xmlrpc_parseValue(xmlrpc_env * const envP, if (childCount == 0) { /* We have no type element, so treat the value as a string. */ - char * const cdata = xml_element_cdata(elemP); - size_t const cdata_size = xml_element_cdata_size(elemP); + const char * const cdata = xml_element_cdata(elemP); + size_t const cdata_size = xml_element_cdata_size(elemP); *valuePP = xmlrpc_string_new_lp(envP, cdata_size, cdata); } else if (childCount > 1) setParseFault(envP, " has %u child elements. " diff --git a/stable/src/parse_value.h b/stable/src/parse_value.h index 9cf37195c..bca801113 100644 --- a/stable/src/parse_value.h +++ b/stable/src/parse_value.h @@ -2,7 +2,7 @@ #define PARSE_VALUE_H_INCLUDED #include "xmlrpc-c/base.h" -#include "xmlrpc-c/xmlparser.h" +#include "xmlparser.h" void xmlrpc_parseValue(xmlrpc_env * const envP, diff --git a/stable/examples/parse_xml.c b/stable/src/parse_xml.c similarity index 93% rename from stable/examples/parse_xml.c rename to stable/src/parse_xml.c index 2e6c5083a..2618a72df 100644 --- a/stable/examples/parse_xml.c +++ b/stable/src/parse_xml.c @@ -58,9 +58,15 @@ describeXmlElement(const xml_element * const elemP, printf("%sXML element type: '%s'\n", prefix, xml_element_name(elemP)); + printf("%sCdata: '%s'\n", + prefix, xml_element_cdata(elemP)); + printf("%sNumber of child elements: %u\n", prefix, xml_element_children_size(elemP)); + if (xml_element_children_size(elemP) == 0) + printf("\n"); + for (i = 0; i < xml_element_children_size(elemP); ++i) { char * const newPrefix = malloc(strlen(prefix) + 2); sprintf(newPrefix, "%s ", prefix); diff --git a/stable/src/xmlparser.h b/stable/src/xmlparser.h new file mode 100644 index 000000000..3dc17d69f --- /dev/null +++ b/stable/src/xmlparser.h @@ -0,0 +1,131 @@ +/* Copyright and license information is at the end of the file */ + +#ifndef XMLRPC_XMLPARSER_H_INCLUDED +#define XMLRPC_XMLPARSER_H_INCLUDED + +#include "xmlrpc-c/util_int.h" +/*============================================================================= + Abstract XML Parser Interface +=============================================================================== + This file provides an abstract interface to the XML parser, so we can + use multiple XML parsers with the main XML-RPC code not having to know + their specific interfaces. + + It works like this: When you need to parse some XML (we don't care what the + XML is as long as it is one valid XML element, but in practice it is going + to be an XML-RPC call or response), you call our 'xml_init' with the XML + text as argument. That generates an object of type 'xml_element' to + represent the XML element. + + You then call methods of that object to parse the XML element, e.g. to + find out its name or its children. +=============================================================================*/ + + +typedef struct _xml_element xml_element; + /* An object that represents an XML element */ + +void +xml_element_free(xml_element * const elemP); + /* Destroy the element */ + +const char * +xml_element_name(const xml_element * const elemP); + /* The XML element name. UTF-8. + + This points to memory owned by *elemP. + */ + +size_t +xml_element_cdata_size(const xml_element * const elemP); + /* The size of the element's cdata */ + +const char * +xml_element_cdata(const xml_element * const elemP); + /* The XML element's CDATA. UTF-8. + + This is a pointer to the cdata. + + There is a NUL character appended to the CDATA, but it is not part of + the CDATA, so is not included in the value returned by + xml_element_cdata_size(). + + This is memory owned by *elemP. + + 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. + */ + +unsigned int +xml_element_children_size(const xml_element * const elemP); + /* Number of children the XML element has */ + +xml_element ** +xml_element_children(const xml_element * const elemP); + /* All the child elements of the element. + + Each pointer points to an object owned by *elemP. + */ + +void +xml_parse(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xml_element ** const resultPP); + /* + Create an xml_elemnt object to represent it. + + Caller must ultimately destroy this object. + + Parse the XML text 'xmlData', of length 'xmlDataLen'. Return the + description of the element that the XML text contains as *resultPP. + Normally, the element has children, so that *resultPP is just the + root of a tree of elements. + + Use *memPoolP for some memory allocations. It is primarily for memory + uses whose size we cannot bound right now, like because it depends on + what the XML looks like - *memPoolP has bounds, so this prevents us + from using more than our share of system memory. If 'memPoolP' is + null, just use the default system pool (which is unbounded). + */ + + +/* Initialize and terminate static global parser state. This should be done + once per run of a program, and while the program is just one thread. +*/ +void +xml_init(xmlrpc_env * const envP); + +void +xml_term(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. */ + +#endif diff --git a/stable/src/xmlrpc_array.c b/stable/src/xmlrpc_array.c index 822dd20fe..45f15c3d7 100644 --- a/stable/src/xmlrpc_array.c +++ b/stable/src/xmlrpc_array.c @@ -26,9 +26,9 @@ xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP) { abort(); else { size_t const arraySize = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value*, &arrayP->_block); + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block); + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); if (contents == NULL) abort(); @@ -55,9 +55,9 @@ xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP) { The value is not valid after this. -----------------------------------------------------------------------------*/ size_t const arraySize = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value*, &arrayP->_block); + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block); + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); size_t index; @@ -68,7 +68,7 @@ xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP) { xmlrpc_value * const itemP = contents[index]; xmlrpc_DECREF(itemP); } - XMLRPC_MEMBLOCK_CLEAN(xmlrpc_value *, &arrayP->_block); + XMLRPC_MEMBLOCK_FREE(xmlrpc_value *, arrayP->blockP); } @@ -88,7 +88,7 @@ xmlrpc_array_size(xmlrpc_env * const envP, retval = -1; } else { size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block); + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); assert((size_t)(int)(size) == size); @@ -112,13 +112,13 @@ xmlrpc_array_append_item(xmlrpc_env * const envP, envP, XMLRPC_TYPE_ERROR, "Value is not an array"); else { size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block); + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); - XMLRPC_MEMBLOCK_RESIZE(xmlrpc_value *, envP, &arrayP->_block, size+1); + XMLRPC_MEMBLOCK_RESIZE(xmlrpc_value *, envP, arrayP->blockP, size+1); if (!envP->fault_occurred) { xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block); + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); xmlrpc_INCREF(valueP); contents[size] = valueP; } @@ -143,9 +143,9 @@ xmlrpc_array_read_item(xmlrpc_env * const envP, "a value that is not an array"); else { xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, &arrayP->_block); + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block); + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); if (index >= size) xmlrpc_env_set_fault_formatted( @@ -194,7 +194,7 @@ xmlrpc_array_new(xmlrpc_env * const envP) { xmlrpc_createXmlrpcValue(envP, &arrayP); if (!envP->fault_occurred) { arrayP->_type = XMLRPC_TYPE_ARRAY; - XMLRPC_MEMBLOCK_INIT(xmlrpc_value*, envP, &arrayP->_block, 0); + arrayP->blockP = XMLRPC_MEMBLOCK_NEW(xmlrpc_value *, envP, 0); if (envP->fault_occurred) free(arrayP); } @@ -216,19 +216,19 @@ xmlrpc_array_new_value(xmlrpc_env * const envP, arrayP = NULL; } else { size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &valueP->_block); + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, valueP->blockP); xmlrpc_createXmlrpcValue(envP, &arrayP); if (!envP->fault_occurred) { arrayP->_type = XMLRPC_TYPE_ARRAY; - XMLRPC_MEMBLOCK_INIT(xmlrpc_value*, envP, &arrayP->_block, 0); + arrayP->blockP = XMLRPC_MEMBLOCK_NEW(xmlrpc_value *, envP, 0); if (envP->fault_occurred) free(arrayP); else { xmlrpc_value ** const srcValuePList = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, &valueP->_block); + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, valueP->blockP); unsigned int i; diff --git a/stable/src/xmlrpc_authcookie.c b/stable/src/xmlrpc_authcookie.c index ae6bb85ca..c0f19eb8d 100644 --- a/stable/src/xmlrpc_authcookie.c +++ b/stable/src/xmlrpc_authcookie.c @@ -31,6 +31,7 @@ #include "mallocvar.h" #include "xmlrpc-c/base.h" +#include "xmlrpc-c/util_int.h" /***************************************************************************** I don't see how these were expected to be used. And I probably diff --git a/stable/src/xmlrpc_client.c b/stable/src/xmlrpc_client.c index 73cdd3924..9466b5b5d 100644 --- a/stable/src/xmlrpc_client.c +++ b/stable/src/xmlrpc_client.c @@ -512,7 +512,13 @@ makeCallXml(xmlrpc_env * const envP, xmlrpc_value * const paramArrayP, xmlrpc_dialect const dialect, xmlrpc_mem_block ** const callXmlPP) { +/*---------------------------------------------------------------------------- + Make the XML for an XML-RPC call of method named 'methodName', with + parameters *paramArrayP, in XML-RPC dialect 'dialect'. + Return the XML in a newly created xmlrpc_memblock and return a pointer to + it as *callXmlPP. +-----------------------------------------------------------------------------*/ XMLRPC_ASSERT_VALUE_OK(paramArrayP); XMLRPC_ASSERT_PTR_OK(callXmlPP); diff --git a/stable/src/xmlrpc_data.c b/stable/src/xmlrpc_data.c index 3c335ee42..b0517f9f0 100644 --- a/stable/src/xmlrpc_data.c +++ b/stable/src/xmlrpc_data.c @@ -56,7 +56,7 @@ destroyValue(xmlrpc_value * const valueP) { switch (valueP->_type) { case XMLRPC_TYPE_INT: break; - + case XMLRPC_TYPE_BOOL: break; @@ -70,15 +70,15 @@ destroyValue(xmlrpc_value * const valueP) { case XMLRPC_TYPE_STRING: xmlrpc_destroyString(valueP); break; - + case XMLRPC_TYPE_BASE64: - xmlrpc_mem_block_clean(&valueP->_block); + xmlrpc_mem_block_free(valueP->blockP); break; case XMLRPC_TYPE_ARRAY: xmlrpc_destroyArrayContents(valueP); break; - + case XMLRPC_TYPE_STRUCT: xmlrpc_destroyStruct(valueP); break; @@ -119,7 +119,7 @@ destroyValue(xmlrpc_value * const valueP) { charge of destroying values when their reference count reaches zero. ============================================================================*/ -void +void xmlrpc_INCREF (xmlrpc_value * const valueP) { XMLRPC_ASSERT_VALUE_OK(valueP); @@ -127,7 +127,7 @@ xmlrpc_INCREF (xmlrpc_value * const valueP) { valueP->lockP->acquire(valueP->lockP); XMLRPC_ASSERT(valueP->refcount > 0); - + ++valueP->refcount; valueP->lockP->release(valueP->lockP); @@ -135,7 +135,7 @@ xmlrpc_INCREF (xmlrpc_value * const valueP) { -void +void xmlrpc_DECREF (xmlrpc_value * const valueP) { bool died; @@ -195,7 +195,7 @@ validateType(xmlrpc_env * const envP, if (valueP->_type != expectedType) { xmlrpc_env_set_fault_formatted( envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " - "type %s was expected.", + "type %s was expected.", xmlrpc_type_name(valueP->_type), xmlrpc_type_name(expectedType)); } } @@ -211,7 +211,7 @@ validateType(xmlrpc_env * const envP, and xmlrpc_struct.c. =========================================================================*/ -void +void xmlrpc_read_int(xmlrpc_env * const envP, const xmlrpc_value * const valueP, xmlrpc_int32 * const intValueP) { @@ -239,7 +239,7 @@ void xmlrpc_read_double(xmlrpc_env * const envP, const xmlrpc_value * const valueP, xmlrpc_double * const doubleValueP) { - + validateType(envP, valueP, XMLRPC_TYPE_DOUBLE); if (!envP->fault_occurred) *doubleValueP = valueP->_value.d; @@ -262,10 +262,10 @@ xmlrpc_read_base64(xmlrpc_env * const envP, validateType(envP, valueP, XMLRPC_TYPE_BASE64); if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block); - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); char * byteStringValue; @@ -293,9 +293,9 @@ xmlrpc_read_base64_old(xmlrpc_env * const envP, validateType(envP, valueP, XMLRPC_TYPE_BASE64); if (!envP->fault_occurred) { *lengthP = - XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block); + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); *byteStringValueP = (const unsigned char *) - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); } } @@ -308,7 +308,7 @@ xmlrpc_read_base64_size(xmlrpc_env * const envP, validateType(envP, valueP, XMLRPC_TYPE_BASE64); if (!envP->fault_occurred) - *lengthP = XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block); + *lengthP = XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); } @@ -338,7 +338,7 @@ xmlrpc_read_nil(xmlrpc_env * const envP, -void +void xmlrpc_read_i8(xmlrpc_env * const envP, const xmlrpc_value * const valueP, xmlrpc_int64 * const intValueP) { @@ -424,7 +424,7 @@ xmlrpc_value_new(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_int_new(xmlrpc_env * const envP, +xmlrpc_int_new(xmlrpc_env * const envP, xmlrpc_int32 const value) { xmlrpc_value * valP; @@ -460,7 +460,7 @@ xmlrpc_int_new_value(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_i8_new(xmlrpc_env * const envP, +xmlrpc_i8_new(xmlrpc_env * const envP, xmlrpc_int64 const value) { xmlrpc_value * valP; @@ -496,7 +496,7 @@ xmlrpc_i8_new_value(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_bool_new(xmlrpc_env * const envP, +xmlrpc_bool_new(xmlrpc_env * const envP, xmlrpc_bool const value) { xmlrpc_value * valP; @@ -532,15 +532,16 @@ xmlrpc_bool_new_value(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_double_new(xmlrpc_env * const envP, +xmlrpc_double_new(xmlrpc_env * const envP, double const value) { xmlrpc_value * valP; - if (!finite(value)) + if (!XMLRPC_FINITE(value)) { xmlrpc_faultf(envP, "Value is not a finite number, " "so cannot be represented in XML-RPC"); - else { + valP = NULL; + } else { xmlrpc_createXmlrpcValue(envP, &valP); if (!envP->fault_occurred) { @@ -574,7 +575,7 @@ xmlrpc_double_new_value(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_base64_new(xmlrpc_env * const envP, +xmlrpc_base64_new(xmlrpc_env * const envP, size_t const length, const unsigned char * const value) { @@ -585,10 +586,10 @@ xmlrpc_base64_new(xmlrpc_env * const envP, if (!envP->fault_occurred) { valP->_type = XMLRPC_TYPE_BASE64; - xmlrpc_mem_block_init(envP, &valP->_block, length); + valP->blockP = xmlrpc_mem_block_new(envP, length); if (!envP->fault_occurred) { - char * const contents = - xmlrpc_mem_block_contents(&valP->_block); + char * const contents = + xmlrpc_mem_block_contents(valP->blockP); memcpy(contents, value, length); } if (envP->fault_occurred) @@ -612,8 +613,8 @@ xmlrpc_base64_new_value(xmlrpc_env * const envP, retval = NULL; } else retval = xmlrpc_base64_new(envP, - xmlrpc_mem_block_size(&valueP->_block), - xmlrpc_mem_block_contents(&valueP->_block)); + xmlrpc_mem_block_size(valueP->blockP), + xmlrpc_mem_block_contents(valueP->blockP)); return retval; } @@ -700,8 +701,8 @@ xmlrpc_nil_new(xmlrpc_env * const envP) { ** 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. -** +** 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 diff --git a/stable/src/xmlrpc_decompose.c b/stable/src/xmlrpc_decompose.c index 951915307..86727121a 100644 --- a/stable/src/xmlrpc_decompose.c +++ b/stable/src/xmlrpc_decompose.c @@ -114,7 +114,7 @@ struct structValDecomp { struct arrayDecomp { unsigned int itemCnt; bool ignoreExcess; - /* If there are more that 'itemCnt' items in the array, just + /* If there are more than 'itemCnt' items in the array, just extract the first 'itemCnt' and ignore the rest, rather than fail the decomposition. */ diff --git a/stable/src/xmlrpc_expat.c b/stable/src/xmlrpc_expat.c index d69e43e27..30fae15c7 100644 --- a/stable/src/xmlrpc_expat.c +++ b/stable/src/xmlrpc_expat.c @@ -12,15 +12,20 @@ #include "xmlrpc-c/base.h" #include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/util_int.h" #include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/xmlparser.h" -/* Define the contents of our internal structure. */ +#include "xmlparser.h" + struct _xml_element { - struct _xml_element *_parent; - char *_name; - xmlrpc_mem_block _cdata; /* char */ - xmlrpc_mem_block _children; /* xml_element* */ +/*---------------------------------------------------------------------------- + Information about an XML element +-----------------------------------------------------------------------------*/ + struct _xml_element * parentP; + const char * name; + xmlrpc_mem_block * cdataP; /* char */ + xmlrpc_mem_block * childrenP; /* xml_element* */ }; /* Check that we're using expat in UTF-8 mode, not wchar_t mode. @@ -35,7 +40,7 @@ struct _xml_element { */ #define XMLRPC_ASSERT_ELEM_OK(elem) \ - XMLRPC_ASSERT((elem) != NULL && (elem)->_name != XMLRPC_BAD_POINTER) + XMLRPC_ASSERT((elem) != NULL && (elem)->name != XMLRPC_BAD_POINTER) void @@ -53,21 +58,17 @@ xml_term(void) { -/*========================================================================= -** xml_element_new -**========================================================================= -** Create a new xml_element. This routine isn't exported, because the -** arguments are implementation-dependent. -*/ - static xml_element * -xml_element_new (xmlrpc_env * const env, - const char * const name) { - - xml_element *retval; +xmlElementNew(xmlrpc_env * const envP, + const char * const name) { +/*---------------------------------------------------------------------------- + A new skeleton element object - ready to be filled in to represent an + actual element. +-----------------------------------------------------------------------------*/ + xml_element * retval; int name_valid, cdata_valid, children_valid; - XMLRPC_ASSERT_ENV_OK(env); + XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(name != NULL); /* Set up our error-handling preconditions. */ @@ -76,38 +77,35 @@ xml_element_new (xmlrpc_env * const env, /* Allocate our xml_element structure. */ retval = (xml_element*) malloc(sizeof(xml_element)); - XMLRPC_FAIL_IF_NULL(retval, env, XMLRPC_INTERNAL_ERROR, + XMLRPC_FAIL_IF_NULL(retval, envP, XMLRPC_INTERNAL_ERROR, "Couldn't allocate memory for XML element"); /* Set our parent field to NULL. */ - retval->_parent = NULL; - + retval->parentP = NULL; + /* Copy over the element name. */ - retval->_name = (char*) malloc(strlen(name) + 1); - XMLRPC_FAIL_IF_NULL(retval->_name, env, XMLRPC_INTERNAL_ERROR, + retval->name = xmlrpc_strdupnull(name); + XMLRPC_FAIL_IF_NULL(retval->name, envP, XMLRPC_INTERNAL_ERROR, "Couldn't allocate memory for XML element"); name_valid = 1; - strcpy(retval->_name, name); - /* Initialize a block to hold our CDATA. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(char, env, &retval->_cdata, 0); - XMLRPC_FAIL_IF_FAULT(env); + retval->cdataP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + XMLRPC_FAIL_IF_FAULT(envP); cdata_valid = 1; - /* Initialize a block to hold our child elements. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(xml_element*, env, &retval->_children, 0); - XMLRPC_FAIL_IF_FAULT(env); + retval->childrenP = XMLRPC_MEMBLOCK_NEW(xml_element *, envP, 0); + XMLRPC_FAIL_IF_FAULT(envP); children_valid = 1; cleanup: - if (env->fault_occurred) { + if (envP->fault_occurred) { if (retval) { if (name_valid) - free(retval->_name); + xmlrpc_strfree(retval->name); if (cdata_valid) - xmlrpc_mem_block_clean(&retval->_cdata); + XMLRPC_MEMBLOCK_FREE(char, retval->cdataP); if (children_valid) - xmlrpc_mem_block_clean(&retval->_children); + XMLRPC_MEMBLOCK_FREE(xml_element *, retval->childrenP); free(retval); } return NULL; @@ -131,18 +129,19 @@ xml_element_free(xml_element * const elemP) { XMLRPC_ASSERT_ELEM_OK(elemP); - free(elemP->_name); - elemP->_name = XMLRPC_BAD_POINTER; - XMLRPC_MEMBLOCK_CLEAN(xml_element *, &elemP->_cdata); + xmlrpc_strfree(elemP->name); + elemP->name = XMLRPC_BAD_POINTER; + + XMLRPC_MEMBLOCK_FREE(char, elemP->cdataP); /* Deallocate all of our children recursively. */ - childrenP = &elemP->_children; + childrenP = elemP->childrenP; contents = XMLRPC_MEMBLOCK_CONTENTS(xml_element *, childrenP); size = XMLRPC_MEMBLOCK_SIZE(xml_element *, childrenP); for (i = 0; i < size; ++i) xml_element_free(contents[i]); - XMLRPC_MEMBLOCK_CLEAN(xml_element *, &elemP->_children); + XMLRPC_MEMBLOCK_FREE(xml_element *, elemP->childrenP); free(elemP); } @@ -161,31 +160,41 @@ const char * xml_element_name(const xml_element * const elemP) { XMLRPC_ASSERT_ELEM_OK(elemP); - return elemP->_name; + + return elemP->name; } -/* The result of this function is NOT VALID until the end_element handler -** has been called! */ -size_t xml_element_cdata_size (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_SIZE(char, &elem->_cdata) - 1; +size_t +xml_element_cdata_size (const xml_element * const elemP) { +/*---------------------------------------------------------------------------- + The result of this function is NOT VALID until the end_element handler + has been called! +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ELEM_OK(elemP); + + return XMLRPC_MEMBLOCK_SIZE(char, elemP->cdataP) - 1; } -char *xml_element_cdata (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &elem->_cdata); + + +const char * +xml_element_cdata(const xml_element * const elemP) { + + XMLRPC_ASSERT_ELEM_OK(elemP); + + return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(const char, elemP->cdataP); } -size_t +unsigned int xml_element_children_size(const xml_element * const elemP) { + XMLRPC_ASSERT_ELEM_OK(elemP); - return XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, &elemP->_children); + + return XMLRPC_MEMBLOCK_SIZE(xml_element *, elemP->childrenP); } @@ -193,72 +202,98 @@ xml_element_children_size(const xml_element * const elemP) { xml_element ** xml_element_children(const xml_element * const elemP) { XMLRPC_ASSERT_ELEM_OK(elemP); - return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element *, &elemP->_children); + return XMLRPC_MEMBLOCK_CONTENTS(xml_element *, elemP->childrenP); } -/*========================================================================= -** Internal xml_element Utility Functions -**========================================================================= -*/ +/*============================================================================= + Internal xml_element Utility Functions +=============================================================================*/ + +static void +xml_element_append_cdata(xmlrpc_env * const envP, + xml_element * const elemP, + const char * const cdata, + size_t const size) { -static void xml_element_append_cdata (xmlrpc_env *env, - xml_element *elem, - char *cdata, - size_t size) -{ - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_ELEM_OK(elem); + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_ELEM_OK(elemP); - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, &elem->_cdata, cdata, size); + XMLRPC_MEMBLOCK_APPEND(char, envP, elemP->cdataP, cdata, size); } -/* Whether or not this function succeeds, it takes ownership of the 'child' -** argument. -** WARNING - This is the exact opposite of the usual memory ownership -** rules for xmlrpc_value! So please pay attention. */ -static void xml_element_append_child (xmlrpc_env *env, - xml_element *elem, - xml_element *child) -{ - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_ELEM_OK(elem); - XMLRPC_ASSERT_ELEM_OK(child); - XMLRPC_ASSERT(child->_parent == NULL); - - XMLRPC_TYPED_MEM_BLOCK_APPEND(xml_element*, env, &elem->_children, - &child, 1); - if (!env->fault_occurred) - child->_parent = elem; + + +static void +xml_element_append_child(xmlrpc_env * const envP, + xml_element * const elemP, + xml_element * const childP) { +/*---------------------------------------------------------------------------- + Whether or not this function succeeds, it takes ownership of *childP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_ELEM_OK(elemP); + XMLRPC_ASSERT_ELEM_OK(childP); + XMLRPC_ASSERT(childP->parentP == NULL); + + XMLRPC_MEMBLOCK_APPEND(xml_element *, envP, elemP->childrenP, &childP, 1); + if (!envP->fault_occurred) + childP->parentP = elemP; else - xml_element_free(child); + xml_element_free(childP); } -/*========================================================================= -** Our parse context. We pass this around as expat user data. -**========================================================================= -*/ typedef struct { - xmlrpc_env env; - xml_element * rootP; - xml_element * currentP; -} parseContext; +/*---------------------------------------------------------------------------- + Our parse context. We pass this around as expat user data. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xml_element * rootP; + xml_element * currentP; + xmlrpc_mem_pool * memPoolP; + /* The memory pool we use for as much memory allocation as we can; + It's purpose is that it is of limited size, so especially use it + for things that need to be limited, like to prevent an XML-RPC + client from using up all the memory by sending a cleverly crafted + XML document. + */ +} ParseContext; -/*========================================================================= -** Expat Event Handler Functions -**========================================================================= -*/ + +static void +initParseContext(ParseContext * const contextP, + xmlrpc_mem_pool * const memPoolP) { + + xmlrpc_env_init(&contextP->env); + + contextP->rootP = NULL; + contextP->currentP = NULL; + contextP->memPoolP = memPoolP; +} + + + +static void +termParseContext(ParseContext * const contextP) { + + xmlrpc_env_clean(&contextP->env); +} + + +/*============================================================================= + Expat Event Handler Functions +=============================================================================*/ static void startElement(void * const userData, XML_Char * const name, XML_Char ** const atts ATTR_UNUSED) { - parseContext * const contextP = userData; + ParseContext * const contextP = userData; XMLRPC_ASSERT(contextP != NULL); XMLRPC_ASSERT(name != NULL); @@ -266,7 +301,7 @@ startElement(void * const userData, if (!contextP->env.fault_occurred) { xml_element * elemP; - elemP = xml_element_new(&contextP->env, name); + elemP = xmlElementNew(&contextP->env, name); if (!contextP->env.fault_occurred) { XMLRPC_ASSERT(elemP != NULL); @@ -307,22 +342,22 @@ static void endElement(void * const userData, XML_Char * const name ATTR_UNUSED) { - parseContext * const contextP = userData; + ParseContext * const contextP = userData; XMLRPC_ASSERT(contextP != NULL); XMLRPC_ASSERT(name != NULL); if (!contextP->env.fault_occurred) { /* I think Expat enforces these facts: */ - XMLRPC_ASSERT(xmlrpc_streq(name, contextP->currentP->_name)); - XMLRPC_ASSERT(contextP->currentP->_parent != NULL || + XMLRPC_ASSERT(xmlrpc_streq(name, contextP->currentP->name)); + XMLRPC_ASSERT(contextP->currentP->parentP != NULL || contextP->currentP == contextP->rootP); /* Add a trailing NUL to our cdata. */ xml_element_append_cdata(&contextP->env, contextP->currentP, "\0", 1); if (!contextP->env.fault_occurred) /* Pop our "stack" of elements. */ - contextP->currentP = contextP->currentP->_parent; + contextP->currentP = contextP->currentP->parentP; if (contextP->env.fault_occurred) { /* Having changed *contextP to reflect failure, we are responsible @@ -349,7 +384,7 @@ characterData(void * const userData, We simply append the cdata to the cdata buffer for whatever XML element the parser is presently parsing. -----------------------------------------------------------------------------*/ - parseContext * const contextP = userData; + ParseContext * const contextP = userData; XMLRPC_ASSERT(contextP != NULL); XMLRPC_ASSERT(s != NULL); @@ -365,11 +400,22 @@ characterData(void * const userData, static void -createParser(xmlrpc_env * const envP, - parseContext * const contextP, - XML_Parser * const parserP) { +createParser(xmlrpc_env * const envP, + xmlrpc_mem_pool * const memPoolP, + ParseContext * const contextP, + XML_Parser * const parserP) { /*---------------------------------------------------------------------------- Create an Expat parser to parse our XML. + + Return the parser handle as *parserP. + + Set up *contextP as a context specific to this module for Expat to + associate with the parser. The XML element handlers in this module get a + pointer to *contextP to use for context. + + Use memory pool *memPoolP for certain memory allocations needed to parse + the document. Especially allocations for which we cannot predict a bound + until we see the XML. -----------------------------------------------------------------------------*/ XML_Parser parser; @@ -377,10 +423,7 @@ createParser(xmlrpc_env * const envP, if (parser == NULL) xmlrpc_faultf(envP, "Could not create expat parser"); else { - /* Initialize our parse context. */ - xmlrpc_env_init(&contextP->env); - contextP->rootP = NULL; - contextP->currentP = NULL; + initParseContext(contextP, memPoolP); xmlrpc_XML_SetUserData(parser, contextP); xmlrpc_XML_SetElementHandler( @@ -398,9 +441,9 @@ createParser(xmlrpc_env * const envP, static void destroyParser(XML_Parser const parser, - parseContext * const contextP) { + ParseContext * const contextP) { - xmlrpc_env_clean(&contextP->env); + termParseContext(contextP); xmlrpc_XML_ParserFree(parser); } @@ -408,13 +451,14 @@ destroyParser(XML_Parser const parser, void -xml_parse(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xml_element ** const resultPP) { +xml_parse(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xml_element ** const resultPP) { /*---------------------------------------------------------------------------- - Parse the XML text 'xmlData', of length 'xmlDataLen'. Return the - description of the element that the XML text contains as *resultPP. + This is an implementation of the interface declared in xmlparser.h. This + implementation uses Xmlrpc-c's private fork of Expat. -----------------------------------------------------------------------------*/ /* This is an Expat driver. @@ -429,12 +473,12 @@ xml_parse(xmlrpc_env * const envP, we don't. */ XML_Parser parser; - parseContext context; + ParseContext context; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(xmlData != NULL); - createParser(envP, &context, &parser); + createParser(envP, memPoolP, &context, &parser); if (!envP->fault_occurred) { bool ok; diff --git a/stable/src/xmlrpc_libxml2.c b/stable/src/xmlrpc_libxml2.c index 98dc80cec..207036ffb 100644 --- a/stable/src/xmlrpc_libxml2.c +++ b/stable/src/xmlrpc_libxml2.c @@ -43,7 +43,8 @@ #include "xmlrpc-c/base.h" #include "xmlrpc-c/base_int.h" #include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/xmlparser.h" + +#include "xmlparser.h" struct _xml_element { xml_element * parentP; @@ -192,7 +193,7 @@ xml_element_name(const xml_element * const elemP) { } size_t -xml_element_cdata_size(xml_element * const elemP) { +xml_element_cdata_size(const xml_element * const elemP) { /* The result of this function is NOT VALID until the end_element handler has been called! */ @@ -202,15 +203,15 @@ xml_element_cdata_size(xml_element * const elemP) { -char * -xml_element_cdata(xml_element * const elemP) { +const char * +xml_element_cdata(const xml_element * const elemP) { XMLRPC_ASSERT_ELEM_OK(elemP); return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &elemP->cdata); } -size_t +unsigned int xml_element_children_size(const xml_element * const elemP) { XMLRPC_ASSERT_ELEM_OK(elemP); return XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, &elemP->children); @@ -473,11 +474,15 @@ createParser(xmlrpc_env * const envP, void -xml_parse(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xml_element ** const resultPP) { - +xml_parse(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP ATTR_UNUSED, + xml_element ** const resultPP) { +/*---------------------------------------------------------------------------- + This is an implementation of the interface declared in xmlparser.h. This + implementation uses Libxml2. +-----------------------------------------------------------------------------*/ ParseContext context; xmlParserCtxt * parserP; diff --git a/stable/src/xmlrpc_parse.c b/stable/src/xmlrpc_parse.c index 3e8fc6492..0d86d72a4 100644 --- a/stable/src/xmlrpc_parse.c +++ b/stable/src/xmlrpc_parse.c @@ -4,6 +4,7 @@ #include "xmlrpc_config.h" +#include #include #include #include @@ -17,9 +18,10 @@ #include "xmlrpc-c/base_int.h" #include "xmlrpc-c/string_int.h" #include "xmlrpc-c/util.h" -#include "xmlrpc-c/xmlparser.h" +#include "xmlparser.h" #include "parse_value.h" +#include "xmlrpc_parse.h" /* Notes about XML-RPC XML documents: @@ -90,7 +92,7 @@ getChildByName (xmlrpc_env * const envP, if (xmlrpc_streq(xml_element_name(childrenP[i]), name)) return childrenP[i]; } - + setParseFault(envP, "Expected <%s> to have child <%s>", xml_element_name(parentP), name); return NULL; @@ -118,7 +120,7 @@ convertParams(xmlrpc_env * const envP, arrayP = xmlrpc_array_new(envP); if (!envP->fault_occurred) { /* We're responsible for checking our own element name. */ - validateName(envP, elemP, "params"); + validateName(envP, elemP, "params"); if (!envP->fault_occurred) { /* Iterate over our children. */ @@ -162,10 +164,11 @@ convertParams(xmlrpc_env * const envP, static void -parseCallXml(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xml_element ** const callElemPP) { +parseCallXml(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xml_element ** const callElemPP) { /*---------------------------------------------------------------------------- Parse the XML of an XML-RPC call. -----------------------------------------------------------------------------*/ @@ -173,7 +176,7 @@ parseCallXml(xmlrpc_env * const envP, xmlrpc_env env; xmlrpc_env_init(&env); - xml_parse(&env, xmlData, xmlDataLen, &callElemP); + xml_parse(&env, xmlData, xmlDataLen, memPoolP, &callElemP); if (env.fault_occurred) xmlrpc_env_set_fault_formatted( envP, env.fault_code, "Call is not valid XML. %s", @@ -199,7 +202,7 @@ static void parseMethodNameElement(xmlrpc_env * const envP, xml_element * const nameElemP, const char ** const methodNameP) { - + XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(nameElemP), "methodName")); if (xml_element_children_size(nameElemP) > 0) @@ -218,15 +221,15 @@ parseMethodNameElement(xmlrpc_env * const envP, "Could not allocate memory for method name"); } } -} +} static void -parseCallChildren(xmlrpc_env * const envP, - xml_element * const callElemP, - const char ** const methodNameP, - xmlrpc_value ** const paramArrayPP ) { +parseCallChildren(xmlrpc_env * const envP, + xml_element * const callElemP, + const char ** const methodNameP, + xmlrpc_value ** const paramArrayPP ) { /*---------------------------------------------------------------------------- Parse the children of a XML element *callElemP. They should be and . @@ -234,21 +237,21 @@ parseCallChildren(xmlrpc_env * const envP, size_t const callChildCount = xml_element_children_size(callElemP); xml_element * nameElemP; - + XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(callElemP), "methodCall")); - + nameElemP = getChildByName(envP, callElemP, "methodName"); - + if (!envP->fault_occurred) { parseMethodNameElement(envP, nameElemP, methodNameP); - + if (!envP->fault_occurred) { /* Convert our parameters. */ if (callChildCount > 1) { xml_element * paramsElemP; paramsElemP = getChildByName(envP, callElemP, "params"); - + if (!envP->fault_occurred) *paramArrayPP = convertParams(envP, paramsElemP); } else { @@ -265,7 +268,7 @@ parseCallChildren(xmlrpc_env * const envP, "children, other than and " ". Total child count = %u", callChildCount); - + if (envP->fault_occurred) xmlrpc_DECREF(*paramArrayPP); } @@ -277,12 +280,13 @@ parseCallChildren(xmlrpc_env * const envP, -void -xmlrpc_parse_call(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - const char ** const methodNameP, - xmlrpc_value ** const paramArrayPP) { +void +xmlrpc_parse_call2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + const char ** const methodNameP, + xmlrpc_value ** const paramArrayPP) { /*---------------------------------------------------------------------------- Given some XML text, attempt to parse it as an XML-RPC call. Return as *methodNameP the name of the method identified in the call @@ -305,7 +309,7 @@ xmlrpc_parse_call(xmlrpc_env * const envP, (unsigned)xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)); else { xml_element * callElemP; - parseCallXml(envP, xmlData, xmlDataLen, &callElemP); + parseCallXml(envP, xmlData, xmlDataLen, memPoolP, &callElemP); if (!envP->fault_occurred) { parseCallChildren(envP, callElemP, methodNameP, paramArrayPP); @@ -321,11 +325,24 @@ xmlrpc_parse_call(xmlrpc_env * const envP, +void +xmlrpc_parse_call(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + const char ** const methodNameP, + xmlrpc_value ** const paramArrayPP) { + + xmlrpc_parse_call2(envP, xmlData, xmlDataLen, NULL, + methodNameP, paramArrayPP); +} + + + static void interpretFaultCode(xmlrpc_env * const envP, xmlrpc_value * const faultCodeVP, int * const faultCodeP) { - + xmlrpc_env fcEnv; xmlrpc_env_init(&fcEnv); @@ -363,7 +380,7 @@ interpretFaultValue(xmlrpc_env * const envP, xmlrpc_value * const faultVP, int * const faultCodeP, const char ** const faultStringP) { - + if (faultVP->_type != XMLRPC_TYPE_STRUCT) setParseFault(envP, " element of response is not " @@ -377,7 +394,7 @@ interpretFaultValue(xmlrpc_env * const envP, xmlrpc_struct_read_value(&fvEnv, faultVP, "faultCode", &faultCodeVP); if (!fvEnv.fault_occurred) { interpretFaultCode(&fvEnv, faultCodeVP, faultCodeP); - + if (!fvEnv.fault_occurred) { xmlrpc_value * faultStringVP; @@ -406,7 +423,7 @@ parseFaultElement(xmlrpc_env * const envP, const xml_element * const faultElement, int * const faultCodeP, const char ** const faultStringP) { - + unsigned int const maxRecursion = (unsigned int) xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); @@ -430,10 +447,10 @@ parseFaultElement(xmlrpc_env * const envP, xmlrpc_value * faultVP; xmlrpc_parseValue(envP, maxRecursion, faultValueP, &faultVP); - + if (!envP->fault_occurred) { interpretFaultValue(envP, faultVP, faultCodeP, faultStringP); - + xmlrpc_DECREF(faultVP); } } @@ -461,7 +478,7 @@ parseParamsElement(xmlrpc_env * const envP, xmlrpc_env sizeEnv; XMLRPC_ASSERT_ARRAY_OK(paramsVP); - + xmlrpc_env_init(&sizeEnv); arraySize = xmlrpc_array_size(&sizeEnv, paramsVP); @@ -493,14 +510,14 @@ parseMethodResponseElt(xmlrpc_env * const envP, xmlrpc_value ** const resultPP, int * const faultCodeP, const char ** const faultStringP) { - + XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(methodResponseEltP), "methodResponse")); if (xml_element_children_size(methodResponseEltP) == 1) { xml_element * const child = xml_element_children(methodResponseEltP)[0]; - + if (xmlrpc_streq(xml_element_name(child), "params")) { /* It's a successful response */ parseParamsElement(envP, child, resultPP); @@ -520,13 +537,34 @@ parseMethodResponseElt(xmlrpc_env * const envP, +static void +parseResponseXml(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xml_element ** const responseEltPP) { + + xmlrpc_env env; + xmlrpc_env_init(&env); + + xml_parse(&env, xmlData, xmlDataLen, memPoolP, responseEltPP); + + if (env.fault_occurred) + setParseFault(envP, "Not valid XML. %s", env.fault_string); + + xmlrpc_env_clean(&env); +} + + + void -xmlrpc_parse_response2(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_value ** const resultPP, - int * const faultCodeP, - const char ** const faultStringP) { +xmlrpc_parse_response3(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xmlrpc_value ** const resultPP, + int * const faultCodeP, + const char ** const faultStringP) { /*---------------------------------------------------------------------------- Given some XML text, attempt to parse it as an XML-RPC response. @@ -541,8 +579,6 @@ xmlrpc_parse_response2(xmlrpc_env * const envP, If the XML text is not a valid response or something prevents us from parsing it, return a description of the error as *envP and nothing else. -----------------------------------------------------------------------------*/ - xml_element * responseEltP; - XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(xmlData != NULL); @@ -558,15 +594,10 @@ xmlrpc_parse_response2(xmlrpc_env * const envP, (unsigned)xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID), (unsigned)xmlDataLen); else { - xmlrpc_env env; - xmlrpc_env_init(&env); - - xml_parse(&env, xmlData, xmlDataLen, &responseEltP); + xml_element * responseEltP; + parseResponseXml(envP, xmlData, xmlDataLen, memPoolP, &responseEltP); - if (env.fault_occurred) - setParseFault(envP, "Not valid XML. %s", env.fault_string); - else { - /* Pick apart and verify our structure. */ + if (!envP->fault_occurred) { if (xmlrpc_streq(xml_element_name(responseEltP), "methodResponse")) { parseMethodResponseElt(envP, responseEltP, @@ -576,15 +607,32 @@ xmlrpc_parse_response2(xmlrpc_env * const envP, " element. " "This has a <%s> instead.", xml_element_name(responseEltP)); - + xml_element_free(responseEltP); } - xmlrpc_env_clean(&env); } } +void +xmlrpc_parse_response2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_value ** const resultPP, + int * const faultCodeP, + const char ** const faultStringP) { +/*---------------------------------------------------------------------------- + This exists for backward compatibility. It is like + xmlrpc_parse_response3(), except that it uses the unlimited system memory + pool. +-----------------------------------------------------------------------------*/ + xmlrpc_parse_response3(envP, xmlData, xmlDataLen, NULL, + resultPP, faultCodeP, faultStringP); +} + + + xmlrpc_value * xmlrpc_parse_response(xmlrpc_env * const envP, const char * const xmlData, @@ -599,9 +647,9 @@ xmlrpc_parse_response(xmlrpc_env * const envP, const char * faultString; int faultCode; - xmlrpc_parse_response2(envP, xmlData, xmlDataLen, + xmlrpc_parse_response3(envP, xmlData, xmlDataLen, NULL, &result, &faultCode, &faultString); - + if (envP->fault_occurred) retval = NULL; else { @@ -618,10 +666,11 @@ xmlrpc_parse_response(xmlrpc_env * const envP, void -xmlrpc_parse_value_xml(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_value ** const valuePP) { +xmlrpc_parse_value_xml2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xmlrpc_value ** const valuePP) { /*---------------------------------------------------------------------------- Compute the xmlrpc_value represented by the XML document 'xmlData' (of length 'xmlDataLen' characters), which must consist of a single @@ -648,7 +697,7 @@ xmlrpc_parse_value_xml(xmlrpc_env * const envP, xmlrpc_env_init(&env); - xml_parse(&env, xmlData, xmlDataLen, &valueEltP); + xml_parse(&env, xmlData, xmlDataLen, memPoolP, &valueEltP); if (env.fault_occurred) { setParseFault(envP, "Not valid XML. %s", env.fault_string); @@ -668,6 +717,17 @@ xmlrpc_parse_value_xml(xmlrpc_env * const envP, +void +xmlrpc_parse_value_xml(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_value ** const valuePP) { + + xmlrpc_parse_value_xml2(envP, xmlData, xmlDataLen, NULL, valuePP); +} + + + /* Copyright (C) 2001 by First Peer, Inc. All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -679,8 +739,8 @@ xmlrpc_parse_value_xml(xmlrpc_env * const envP, ** 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. -** +** 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 diff --git a/stable/src/xmlrpc_parse.h b/stable/src/xmlrpc_parse.h new file mode 100644 index 000000000..79bf1afc0 --- /dev/null +++ b/stable/src/xmlrpc_parse.h @@ -0,0 +1,42 @@ +#ifndef XMLRPC_PARSE_H_INCLUDED +#define XMLRPC_PARSE_H_INCLUDED +/*============================================================================= + xmlrpc_parse.h +=============================================================================== + This declares the interface to the _internal_ XML-RPC XML parsing functions + in xmlrpc_parse.c. + + There are also _external_ functions in xmlrpc_parse.c, and those are + declared in an external interface header file. + + xmlrpc_parse.c is split that way because some functions use memory pools, + which is an internal concept we don't feel like making external right now. +=============================================================================*/ + +#include "xmlrpc-c/util_int.h" + +void +xmlrpc_parse_call2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + const char ** const methodNameP, + xmlrpc_value ** const paramArrayPP); + +void +xmlrpc_parse_response3(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xmlrpc_value ** const resultPP, + int * const faultCodeP, + const char ** const faultStringP); + +void +xmlrpc_parse_value_xml2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xmlrpc_value ** const valuePP); + +#endif diff --git a/stable/src/xmlrpc_serialize.c b/stable/src/xmlrpc_serialize.c index 0e7870366..f1679a07b 100644 --- a/stable/src/xmlrpc_serialize.c +++ b/stable/src/xmlrpc_serialize.c @@ -332,7 +332,7 @@ serializeStructMember(xmlrpc_env * const envP, addString(envP, outputP, ""); if (!envP->fault_occurred) { - serializeUtf8MemBlock(envP, outputP, &memberKeyP->_block); + serializeUtf8MemBlock(envP, outputP, memberKeyP->blockP); if (!envP->fault_occurred) { addString(envP, outputP, ""CRLF); @@ -465,7 +465,7 @@ formatValueContent(xmlrpc_env * const envP, case XMLRPC_TYPE_STRING: addString(envP, outputP, ""); if (!envP->fault_occurred) { - serializeUtf8MemBlock(envP, outputP, &valueP->_block); + serializeUtf8MemBlock(envP, outputP, valueP->blockP); if (!envP->fault_occurred) addString(envP, outputP, ""); } @@ -473,9 +473,9 @@ formatValueContent(xmlrpc_env * const envP, case XMLRPC_TYPE_BASE64: { unsigned char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(unsigned char, &valueP->_block); + XMLRPC_MEMBLOCK_CONTENTS(unsigned char, valueP->blockP); size_t const size = - XMLRPC_MEMBLOCK_SIZE(unsigned char, &valueP->_block); + XMLRPC_MEMBLOCK_SIZE(unsigned char, valueP->blockP); addString(envP, outputP, ""CRLF); if (!envP->fault_occurred) { xmlrpc_serialize_base64_data(envP, outputP, contents, size); @@ -620,7 +620,7 @@ xmlrpc_serialize_call2(xmlrpc_env * const envP, Serialize an XML-RPC call of method named 'methodName' with parameter list *paramArrayP. Use XML-RPC dialect 'dialect'. - Append the call XML ot *outputP. + Append the call XML to *outputP. -----------------------------------------------------------------------------*/ XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(outputP != NULL); diff --git a/stable/src/xmlrpc_server_abyss.c b/stable/src/xmlrpc_server_abyss.c index ac482421e..f22aee7d8 100644 --- a/stable/src/xmlrpc_server_abyss.c +++ b/stable/src/xmlrpc_server_abyss.c @@ -12,7 +12,7 @@ #include #include #include -#ifdef _WIN32 +#if MSVCRT # include # pragma comment(lib, "Ws2_32.lib") #else @@ -409,6 +409,10 @@ setAdditionalServerParms(const xmlrpc_server_abyss_parms * const parmsP, if (parmsP->max_conn_backlog != 0) ServerSetMaxConnBacklog(serverP, parmsP->max_conn_backlog); } + if (parmSize >= XMLRPC_APSIZE(max_rpc_mem)) { + if (parmsP->max_rpc_mem != 0) + ServerSetMaxSessionMem(serverP, parmsP->max_rpc_mem); + } } @@ -519,7 +523,7 @@ chanSwitchCreateOsSocket(TOsSocket const socketFd, TChanSwitch ** const chanSwitchPP, const char ** const errorP) { -#ifdef _WIN32 +#if MSVCRT ChanSwitchWinCreateWinsock(socketFd, chanSwitchPP, errorP); #else ChanSwitchUnixCreateFd(socketFd, chanSwitchPP, errorP); @@ -554,7 +558,7 @@ chanSwitchCreateSockAddr(int const protocolFamily, TChanSwitch ** const chanSwitchPP, const char ** const errorP) { -#ifdef _WIN32 +#if MSVCRT ChanSwitchWinCreate2(protocolFamily, sockAddrP, sockAddrLen, chanSwitchPP, errorP); #else @@ -945,7 +949,7 @@ sigchld(int const signalClass ATTR_UNUSED) { forking as a threading mechanism), so we respond by passing the signal on to the Abyss server. And reaping the dead child. -----------------------------------------------------------------------------*/ -#ifndef _WIN32 +#if !MSVCRT /* Reap zombie children / report to Abyss until there aren't any more. */ bool childrenLeft; @@ -972,7 +976,7 @@ sigchld(int const signalClass ATTR_UNUSED) { } else ServerHandleSigchld(pid); } -#endif /* _WIN32 */ +#endif /* MSVCRT */ } @@ -982,11 +986,11 @@ struct xmlrpc_server_abyss_sig { functions in this library messed with them; useful for restoring them later. */ -#ifndef _WIN32 +#if MSVCRT + int dummy; +#else struct sigaction pipe; struct sigaction chld; -#else - int dummy; #endif }; @@ -994,7 +998,7 @@ struct xmlrpc_server_abyss_sig { static void setupSignalHandlers(xmlrpc_server_abyss_sig * const oldHandlersP) { -#ifndef _WIN32 +#if !MSVCRT struct sigaction mysigaction; sigemptyset(&mysigaction.sa_mask); @@ -1014,8 +1018,7 @@ setupSignalHandlers(xmlrpc_server_abyss_sig * const oldHandlersP) { static void restoreSignalHandlers(const xmlrpc_server_abyss_sig * const oldHandlersP) { -#ifndef _WIN32 - +#if !MSVCRT sigaction(SIGPIPE, &oldHandlersP->pipe, NULL); sigaction(SIGCHLD, &oldHandlersP->chld, NULL); diff --git a/stable/src/xmlrpc_server_cgi.c b/stable/src/xmlrpc_server_cgi.c index b208fefc4..00ca5042f 100644 --- a/stable/src/xmlrpc_server_cgi.c +++ b/stable/src/xmlrpc_server_cgi.c @@ -31,11 +31,12 @@ #include /* Windows NT stdout binary mode fix. */ -#ifdef _WIN32 +#if MSVCRT #include #include #endif +#include "xmlrpc-c/util_int.h" #include "xmlrpc-c/base.h" #include "xmlrpc-c/server.h" #include "xmlrpc-c/string_int.h" @@ -51,7 +52,7 @@ static void send_xml(const char * const xml_data, size_t const xml_len) { -#ifdef _WIN32 +#if MSVCRT _setmode(_fileno(stdout), _O_BINARY); #endif /* Send our CGI headers back to the server. @@ -75,7 +76,7 @@ send_error(int const code, const char * const message, xmlrpc_env * const env) { -#ifdef _WIN32 +#if MSVCRT _setmode(_fileno(stdout), _O_BINARY); #endif /* Send an error header. */ @@ -140,7 +141,7 @@ get_body(xmlrpc_env * const env, /* Error-handling preconditions. */ result = NULL; -#ifdef _WIN32 +#if MSVCRT /* Fix from Jeff Stewart: NT opens stdin and stdout in text mode by default, badly confusing our length calculations. So we need to set the file handle to binary. diff --git a/stable/src/xmlrpc_server_w32httpsys.c b/stable/src/xmlrpc_server_w32httpsys.c index ce1587dae..7e96d208b 100644 --- a/stable/src/xmlrpc_server_w32httpsys.c +++ b/stable/src/xmlrpc_server_w32httpsys.c @@ -36,6 +36,7 @@ #include #include "xmlrpc_config.h" +#include "xmlrpc-c/util.h" #include "xmlrpc-c/base.h" #include "xmlrpc-c/server.h" #include "xmlrpc-c/server_w32httpsys.h" @@ -433,11 +434,11 @@ DoReceiveRequests( char *pColon; pDecodedStr = (char*) - malloc(decoded->_size+1); + malloc(xmlrpc_mem_block_size(decoded)+1); memcpy(pDecodedStr, - decoded->_block, - decoded->_size); - pDecodedStr[decoded->_size]='\0'; + xmlrpc_mem_block_contents(decoded), + xmlrpc_mem_block_size(decoded)); + pDecodedStr[xmlrpc_mem_block_size(decoded)]='\0'; pUser = pPass = pDecodedStr; pColon=strchr(pDecodedStr,':'); if(pColon) diff --git a/stable/src/xmlrpc_string.c b/stable/src/xmlrpc_string.c index d6b41ec11..2da61e4ee 100644 --- a/stable/src/xmlrpc_string.c +++ b/stable/src/xmlrpc_string.c @@ -1,3 +1,4 @@ +#include /*============================================================================= xmlrpc_string =============================================================================== @@ -22,6 +23,7 @@ #include "xmlrpc-c/base.h" #include "xmlrpc-c/base_int.h" #include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/util.h" @@ -31,7 +33,7 @@ xmlrpc_destroyString(xmlrpc_value * const valueP) { if (valueP->_wcs_block) xmlrpc_mem_block_free(valueP->_wcs_block); - xmlrpc_mem_block_clean(&valueP->_block); + xmlrpc_mem_block_free(valueP->blockP); } @@ -52,7 +54,7 @@ verifyNoNulls(xmlrpc_env * const envP, for (i = 0; i < len && !envP->fault_occurred; ++i) if (contents[i] == '\0') xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, + envP, XMLRPC_TYPE_ERROR, "String must not contain NUL characters"); } @@ -72,7 +74,7 @@ verifyNoNullsW(xmlrpc_env * const envP, for (i = 0; i < len && !envP->fault_occurred; i++) if (contents[i] == '\0') xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, + envP, XMLRPC_TYPE_ERROR, "String must not contain NUL characters"); } #endif @@ -86,7 +88,7 @@ validateStringType(xmlrpc_env * const envP, if (valueP->_type != XMLRPC_TYPE_STRING) { xmlrpc_env_set_fault_formatted( envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " - "string type was expected.", + "string type was expected.", xmlrpc_type_name(valueP->_type)); } } @@ -98,13 +100,13 @@ accessStringValue(xmlrpc_env * const envP, const xmlrpc_value * const valueP, size_t * const lengthP, const char ** const contentsP) { - + validateStringType(envP, valueP); if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block); - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); size_t const len = size - 1; /* The memblock has a null character added to the end */ @@ -114,7 +116,7 @@ accessStringValue(xmlrpc_env * const envP, *contentsP = contents; } } - + void @@ -138,7 +140,7 @@ xmlrpc_read_string(xmlrpc_env * const envP, if (!envP->fault_occurred) { char * stringValue; - + MALLOCARRAY(stringValue, length + 1); if (stringValue == NULL) xmlrpc_faultf(envP, "Unable to allocate space " @@ -157,7 +159,7 @@ xmlrpc_read_string(xmlrpc_env * const envP, static unsigned int lineDelimCount(const char * const start, const char * const end) { - + unsigned int count; const char * p; @@ -181,7 +183,7 @@ copyAndConvertLfToCrlf(xmlrpc_env * const envP, const char * const src, size_t * const dstLenP, const char ** const dstP) { - + const char * const srcEnd = src + srcLen; unsigned int const nLineDelim = lineDelimCount(src, srcEnd); size_t const dstLen = srcLen + nLineDelim; @@ -227,7 +229,7 @@ xmlrpc_read_string_crlf(xmlrpc_env * const envP, if (!envP->fault_occurred) { size_t stringLen; - + copyAndConvertLfToCrlf(envP, length, contents, &stringLen, stringValueP); } @@ -262,10 +264,10 @@ xmlrpc_read_string_lp(xmlrpc_env * const envP, validateStringType(envP, valueP); if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block); - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); char * stringValue; @@ -291,10 +293,10 @@ xmlrpc_read_string_lp_crlf(xmlrpc_env * const envP, validateStringType(envP, valueP); if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block); /* Includes NUL */ - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); /* Includes NUL */ + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); copyAndConvertLfToCrlf(envP, size-1, contents, lengthP, stringValueP); @@ -314,8 +316,8 @@ xmlrpc_read_string_lp_old(xmlrpc_env * const envP, -----------------------------------------------------------------------------*/ validateStringType(envP, valueP); if (!envP->fault_occurred) { - *lengthP = XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block) - 1; - *stringValueP = XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); + *lengthP = XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP) - 1; + *stringValueP = XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); } } @@ -329,11 +331,11 @@ setupWcsBlock(xmlrpc_env * const envP, doesn't have one already. -----------------------------------------------------------------------------*/ if (!valueP->_wcs_block) { - char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); - size_t const len = - XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block) - 1; - valueP->_wcs_block = + char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); + size_t const len = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP) - 1; + valueP->_wcs_block = xmlrpc_utf8_to_wcs(envP, contents, len + 1); } } @@ -353,11 +355,11 @@ accessStringValueW(xmlrpc_env * const envP, setupWcsBlock(envP, valueP); if (!envP->fault_occurred) { - wchar_t * const wcontents = + wchar_t * const wcontents = XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); - size_t const len = + size_t const len = XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block) - 1; - + verifyNoNullsW(envP, wcontents, len); *lengthP = len; @@ -367,7 +369,7 @@ accessStringValueW(xmlrpc_env * const envP, } - + void xmlrpc_read_string_w(xmlrpc_env * const envP, xmlrpc_value * const valueP, @@ -375,19 +377,19 @@ xmlrpc_read_string_w(xmlrpc_env * const envP, size_t length; const wchar_t * wcontents; - + accessStringValueW(envP, valueP, &length, &wcontents); if (!envP->fault_occurred) { wchar_t * stringValue; MALLOCARRAY(stringValue, length + 1); if (stringValue == NULL) - xmlrpc_faultf(envP, "Unable to allocate space for %u-byte string", + xmlrpc_faultf(envP, "Unable to allocate space for %u-byte string", (unsigned)length); else { memcpy(stringValue, wcontents, length * sizeof(wchar_t)); stringValue[length] = '\0'; - + *stringValueP = stringValue; } } @@ -398,7 +400,7 @@ xmlrpc_read_string_w(xmlrpc_env * const envP, static unsigned int lineDelimCountW(const wchar_t * const start, const wchar_t * const end) { - + unsigned int count; const wchar_t * p; @@ -463,7 +465,7 @@ xmlrpc_read_string_w_crlf(xmlrpc_env * const envP, size_t size; const wchar_t * contents; - + accessStringValueW(envP, valueP, &size, &contents); if (!envP->fault_occurred) { @@ -502,21 +504,21 @@ xmlrpc_read_string_w_lp(xmlrpc_env * const envP, setupWcsBlock(envP, valueP); if (!envP->fault_occurred) { - wchar_t * const wcontents = + wchar_t * const wcontents = XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); - size_t const size = + size_t const size = XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block); wchar_t * stringValue; - MALLOCARRAY(stringValue, size); + MALLOCARRAY(stringValue, size); if (stringValue == NULL) xmlrpc_faultf(envP, - "Unable to allocate space for %u-byte string", + "Unable to allocate space for %u-byte string", (unsigned int)size); else { memcpy(stringValue, wcontents, size * sizeof(wchar_t)); - + *lengthP = size - 1; /* size includes terminating NUL */ *stringValueP = stringValue; } @@ -537,9 +539,9 @@ xmlrpc_read_string_w_lp_crlf(xmlrpc_env * const envP, setupWcsBlock(envP, valueP); if (!envP->fault_occurred) { - size_t const size = + size_t const size = XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block); - wchar_t * const wcontents = + wchar_t * const wcontents = XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); wCopyAndConvertLfToCrlf(envP, size-1, wcontents, @@ -564,11 +566,11 @@ xmlrpc_read_string_w_lp_old(xmlrpc_env * const envP, setupWcsBlock(envP, valueP); if (!envP->fault_occurred) { - wchar_t * const wcontents = + wchar_t * const wcontents = XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); - size_t const size = + size_t const size = XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block); - + *lengthP = size - 1; /* size includes terminating NUL */ *stringValueP = wcontents; } @@ -621,14 +623,14 @@ xmlrpc_string_validate(xmlrpc_env * const envP, static void -copyLines(xmlrpc_env * const envP, - const char * const src, - size_t const srcLen, - xmlrpc_mem_block * const dstP) { +copyLines(xmlrpc_env * const envP, + const char * const src, + size_t const srcLen, + xmlrpc_mem_block ** const dstPP) { /*---------------------------------------------------------------------------- - Copy the string 'src', 'srcLen' characters long, into 'dst', where - 'dst' is the internal representation of string xmlrpc_value contents, - and 'src' has lines separated by LF, CR, and/or CRLF. + Generate the internal representation of string xmlrpc_value contents for + string 'src', which is 'srcLen' characters long and has lines separated by + LF, CR, and/or CRLF. Return it as a new xmlrpc_mem_block at *dstPP. Note that the source format differs from the destination format in that in the destination format, lines are separated only by newline @@ -656,7 +658,9 @@ copyLines(xmlrpc_env * const envP, skip the CR and any following LF, and repeat. */ - XMLRPC_MEMBLOCK_INIT(char, envP, dstP, srcLen + 1); + xmlrpc_mem_block * dstP; + + dstP = XMLRPC_MEMBLOCK_NEW(char, envP, srcLen + 1); if (!envP->fault_occurred) { const char * const srcEnd = &src[srcLen]; @@ -677,7 +681,7 @@ copyLines(xmlrpc_env * const envP, dstCursor += copyLen; *(dstCursor++) = '\n'; - + XMLRPC_ASSERT(*srcCursor == '\r'); ++srcCursor; /* Move past CR */ if (*srcCursor == '\n') @@ -695,30 +699,40 @@ copyLines(xmlrpc_env * const envP, XMLRPC_ASSERT((unsigned)(dstCursor - &contents[0]) <= srcLen + 1); XMLRPC_MEMBLOCK_RESIZE(char, envP, dstP, dstCursor - &contents[0]); + + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, dstP); } + *dstPP = dstP; } static void -copySimple(xmlrpc_env * const envP, - const char * const src, - size_t const srcLen, - xmlrpc_mem_block * const dstP) { +copySimple(xmlrpc_env * const envP, + const char * const src, + size_t const srcLen, + xmlrpc_mem_block ** const dstPP) { /*---------------------------------------------------------------------------- - Copy the string 'src', 'srcLen' characters long, into 'dst', where - 'dst' is the internal representation of string xmlrpc_value contents, - and 'src', conveniently enough, is in the exact same format. + Generate the internal representation of string xmlrpc_value contents for + string 'src', which is 'srcLen' characters long and, conveniently enough, + has the exact same format as the internal representation. To wit, 'src' has lines separated by LFs only -- no CR or CRLF. + + Return it as a new xmlrpc_mem_block at *dstPP. -----------------------------------------------------------------------------*/ - XMLRPC_MEMBLOCK_INIT(char, envP, dstP, srcLen + 1); + xmlrpc_mem_block * dstP; + + dstP = XMLRPC_MEMBLOCK_NEW(char, envP, srcLen + 1); + if (!envP->fault_occurred) { char * const contents = XMLRPC_MEMBLOCK_CONTENTS(char, dstP); - + memcpy(contents, src, srcLen); contents[srcLen] = '\0'; } + *dstPP = dstP; } @@ -726,18 +740,21 @@ copySimple(xmlrpc_env * const envP, enum crTreatment { CR_IS_LINEDELIM, CR_IS_CHAR }; static void -stringNew(xmlrpc_env * const envP, +stringNew(xmlrpc_env * const envP, size_t const length, const char * const value, enum crTreatment const crTreatment, xmlrpc_value ** const valPP) { + fprintf(stderr, "stringNew entered\n"); xmlrpc_value * valP; xmlrpc_validate_utf8(envP, value, length); if (!envP->fault_occurred) { + fprintf(stderr, "Going to xmlrpc_createXmlrpcValue\n"); xmlrpc_createXmlrpcValue(envP, &valP); + fprintf(stderr, "Back from createXmlrpcValue\n"); if (!envP->fault_occurred) { valP->_type = XMLRPC_TYPE_STRING; @@ -747,9 +764,9 @@ stringNew(xmlrpc_env * const envP, it's slower. */ if (memchr(value, '\r', length) && crTreatment == CR_IS_LINEDELIM) - copyLines(envP, value, length, &valP->_block); + copyLines(envP, value, length, &valP->blockP); else - copySimple(envP, value, length, &valP->_block); + copySimple(envP, value, length, &valP->blockP); if (envP->fault_occurred) free(valP); @@ -757,12 +774,13 @@ stringNew(xmlrpc_env * const envP, *valPP = valP; } } + fprintf(stderr, "stringNew exiting\n"); } xmlrpc_value * -xmlrpc_string_new_lp(xmlrpc_env * const envP, +xmlrpc_string_new_lp(xmlrpc_env * const envP, size_t const length, const char * const value) { @@ -774,7 +792,7 @@ xmlrpc_string_new_lp(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_string_new_lp_cr(xmlrpc_env * const envP, +xmlrpc_string_new_lp_cr(xmlrpc_env * const envP, size_t const length, const char * const value) { @@ -788,7 +806,7 @@ xmlrpc_string_new_lp_cr(xmlrpc_env * const envP, xmlrpc_value * xmlrpc_string_new(xmlrpc_env * const envP, const char * const value) { - + xmlrpc_value * retval; stringNew(envP, strlen(value), value, CR_IS_LINEDELIM, &retval); return retval; @@ -817,7 +835,7 @@ xmlrpc_string_new_va(xmlrpc_env * const envP, XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT(format != NULL); - + xmlrpc_vasprintf(&formattedString, format, args); if (xmlrpc_strnomem(formattedString)) { @@ -840,11 +858,11 @@ xmlrpc_string_new_f(xmlrpc_env * const envP, va_list args; xmlrpc_value * retval; - + va_start(args, format); - + retval = xmlrpc_string_new_va(envP, format, args); - + va_end(args); return retval; @@ -855,7 +873,7 @@ xmlrpc_string_new_f(xmlrpc_env * const envP, #if HAVE_UNICODE_WCHAR static void -stringWNew(xmlrpc_env * const envP, +stringWNew(xmlrpc_env * const envP, size_t const length, const wchar_t * const value, enum crTreatment const crTreatment, @@ -867,7 +885,7 @@ stringWNew(xmlrpc_env * const envP, if (!envP->fault_occurred) { char * const utf8_value = XMLRPC_MEMBLOCK_CONTENTS(char, utf8P); size_t const utf8_len = XMLRPC_MEMBLOCK_SIZE(char, utf8P); - + if (!envP->fault_occurred) { stringNew(envP, utf8_len, utf8_value, crTreatment, valPP); @@ -879,7 +897,7 @@ stringWNew(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_string_w_new_lp(xmlrpc_env * const envP, +xmlrpc_string_w_new_lp(xmlrpc_env * const envP, size_t const length, const wchar_t * const value) { @@ -892,7 +910,7 @@ xmlrpc_string_w_new_lp(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_string_w_new_lp_cr(xmlrpc_env * const envP, +xmlrpc_string_w_new_lp_cr(xmlrpc_env * const envP, size_t const length, const wchar_t * const value) { @@ -947,22 +965,23 @@ xmlrpc_string_new_value(xmlrpc_env * const envP, if (!envP->fault_occurred) { valP->_type = XMLRPC_TYPE_STRING; - xmlrpc_mem_block_init(envP, &valP->_block, - xmlrpc_mem_block_size(&valueP->_block)); + valP->blockP = + xmlrpc_mem_block_new(envP, + xmlrpc_mem_block_size(valueP->blockP)); if (!envP->fault_occurred) { - memcpy(xmlrpc_mem_block_contents(&valP->_block), - xmlrpc_mem_block_contents(&valueP->_block), - xmlrpc_mem_block_size(&valueP->_block)); + memcpy(xmlrpc_mem_block_contents(valP->blockP), + xmlrpc_mem_block_contents(valueP->blockP), + xmlrpc_mem_block_size(valueP->blockP)); } } if (!envP->fault_occurred) { if (valueP->_wcs_block) { valP->_wcs_block = xmlrpc_mem_block_new( - envP, + envP, xmlrpc_mem_block_size(valueP->_wcs_block)); - + if (!envP->fault_occurred) { memcpy(xmlrpc_mem_block_contents(valP->_wcs_block), xmlrpc_mem_block_contents(valueP->_wcs_block), diff --git a/stable/src/xmlrpc_struct.c b/stable/src/xmlrpc_struct.c index b90079d05..d5606906b 100644 --- a/stable/src/xmlrpc_struct.c +++ b/stable/src/xmlrpc_struct.c @@ -44,7 +44,7 @@ changeMemberValue(xmlrpc_value * const structP, calls!) -----------------------------------------------------------------------------*/ _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); _struct_member * const memberP = &members[mbrIndex]; xmlrpc_value * const oldValueP = memberP->value; @@ -65,9 +65,9 @@ addNewMember(xmlrpc_env * const envP, Add a new member. Assume no member already exists with this key. -----------------------------------------------------------------------------*/ const char * const key = - XMLRPC_MEMBLOCK_CONTENTS(char, &keyvalP->_block); + XMLRPC_MEMBLOCK_CONTENTS(char, keyvalP->blockP); size_t const keyLen = - XMLRPC_MEMBLOCK_SIZE(char, &keyvalP->_block) - 1; + XMLRPC_MEMBLOCK_SIZE(char, keyvalP->blockP) - 1; _struct_member newMember; @@ -75,7 +75,7 @@ addNewMember(xmlrpc_env * const envP, newMember.key = keyvalP; newMember.value = valueP; - XMLRPC_MEMBLOCK_APPEND(_struct_member, envP, &structP->_block, + XMLRPC_MEMBLOCK_APPEND(_struct_member, envP, structP->blockP, &newMember, 1); if (!envP->fault_occurred) { @@ -93,9 +93,9 @@ xmlrpc_destroyStruct(xmlrpc_value * const structP) { itself). The value is not valid after this. -----------------------------------------------------------------------------*/ _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block); + XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); unsigned int i; @@ -103,7 +103,7 @@ xmlrpc_destroyStruct(xmlrpc_value * const structP) { xmlrpc_DECREF(members[i].key); xmlrpc_DECREF(members[i].value); } - XMLRPC_MEMBLOCK_CLEAN(_struct_member, &structP->_block); + XMLRPC_MEMBLOCK_FREE(_struct_member, structP->blockP); } @@ -130,7 +130,7 @@ xmlrpc_struct_new(xmlrpc_env * const envP) { if (!envP->fault_occurred) { valP->_type = XMLRPC_TYPE_STRUCT; - XMLRPC_MEMBLOCK_INIT(_struct_member, envP, &valP->_block, 0); + valP->blockP = XMLRPC_MEMBLOCK_NEW(_struct_member, envP, 0); if (envP->fault_occurred) free(valP); @@ -153,19 +153,19 @@ xmlrpc_struct_new_value(xmlrpc_env * const envP, structP = NULL; } else { size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &structP->_block); + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, structP->blockP); xmlrpc_createXmlrpcValue(envP, &structP); if (!envP->fault_occurred) { structP->_type = XMLRPC_TYPE_STRUCT; - XMLRPC_MEMBLOCK_INIT(xmlrpc_value*, envP, &structP->_block, 0); + structP->blockP = XMLRPC_MEMBLOCK_NEW(xmlrpc_value *, envP, 0); if (envP->fault_occurred) free(structP); else { _struct_member * const srcMemberList = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &valueP->_block); + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, valueP->blockP); unsigned int i; @@ -223,7 +223,7 @@ xmlrpc_struct_size(xmlrpc_env * const envP, retval = -1; } else { size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block); + XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); assert((size_t)(int)size == size); /* Because structs are defined to have few enough members */ @@ -254,15 +254,15 @@ findMember(xmlrpc_value * const structP, /* Look for our key. */ searchHash = hashStructKey(key, keyLen); - size = XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block); - contents = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); + size = XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); + contents = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); for (i = 0, found = false; i < size && !found; ++i) { if (contents[i].keyHash == searchHash) { xmlrpc_value * const keyvalP = contents[i].key; const char * const keystr = - XMLRPC_MEMBLOCK_CONTENTS(char, &keyvalP->_block); + XMLRPC_MEMBLOCK_CONTENTS(char, keyvalP->blockP); size_t const keystrSize = - XMLRPC_MEMBLOCK_SIZE(char, &keyvalP->_block)-1; + XMLRPC_MEMBLOCK_SIZE(char, keyvalP->blockP)-1; if (keystrSize == keyLen && memcmp(key, keystr, keyLen) == 0) { found = true; foundIndex = i; @@ -365,7 +365,7 @@ xmlrpc_struct_find_value(xmlrpc_env * const envP, *valuePP = NULL; else { _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); *valuePP = members[index].value; XMLRPC_ASSERT_VALUE_OK(*valuePP); @@ -406,14 +406,14 @@ xmlrpc_struct_find_value_v(xmlrpc_env * const envP, /* Get our member index. */ findMember(structP, - XMLRPC_MEMBLOCK_CONTENTS(char, &keyP->_block), - XMLRPC_MEMBLOCK_SIZE(char, &keyP->_block)-1, + XMLRPC_MEMBLOCK_CONTENTS(char, keyP->blockP), + XMLRPC_MEMBLOCK_SIZE(char, keyP->blockP)-1, &found, &index); if (!found) *valuePP = NULL; else { _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); *valuePP = members[index].value; XMLRPC_ASSERT_VALUE_OK(*valuePP); @@ -445,8 +445,8 @@ xmlrpc_struct_read_value_v(xmlrpc_env * const envP, if (*valuePP == NULL) { xmlrpc_env_set_fault_formatted( envP, XMLRPC_INDEX_ERROR, "No member of struct has key '%.*s'", - (int)XMLRPC_MEMBLOCK_SIZE(char, &keyP->_block), - XMLRPC_MEMBLOCK_CONTENTS(char, &keyP->_block)); + (int)XMLRPC_MEMBLOCK_SIZE(char, keyP->blockP), + XMLRPC_MEMBLOCK_CONTENTS(char, keyP->blockP)); } } } @@ -589,9 +589,9 @@ xmlrpc_struct_set_value_v(xmlrpc_env * const envP, "Key value is not a string"); else { const char * const key = - XMLRPC_MEMBLOCK_CONTENTS(char, &keyvalP->_block); + XMLRPC_MEMBLOCK_CONTENTS(char, keyvalP->blockP); size_t const keyLen = - XMLRPC_MEMBLOCK_SIZE(char, &keyvalP->_block) - 1; + XMLRPC_MEMBLOCK_SIZE(char, keyvalP->blockP) - 1; bool found; unsigned int index; @@ -629,9 +629,9 @@ xmlrpc_struct_read_member(xmlrpc_env * const envP, "of something that is not a struct"); else { _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block); + XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); if (index >= size) xmlrpc_env_set_fault_formatted( diff --git a/stable/test/Makefile b/stable/test/Makefile index 73197cad0..4fce824c7 100644 --- a/stable/test/Makefile +++ b/stable/test/Makefile @@ -26,6 +26,7 @@ TEST_OBJS = \ testtool.o \ test.o \ cgi.o \ + memblock.o \ method_registry.o \ parse_xml.o \ serialize.o \ @@ -105,6 +106,9 @@ cpp/runtests: FORCE .PHONY: install install: +.PHONY: uninstall +uninstall: + .PHONY: clean clean-local distclean clean: clean-common clean-local clean-local: $(SUBDIRS:%=%/clean) diff --git a/stable/test/cpp/Makefile b/stable/test/cpp/Makefile index 6cfc8ecc9..7e57d36b5 100644 --- a/stable/test/cpp/Makefile +++ b/stable/test/cpp/Makefile @@ -118,6 +118,9 @@ runtests: test .PHONY: install install: +.PHONY: uninstall +uninstall: + .PHONY: clean clean-local distclean clean: clean-common clean-local clean-local: diff --git a/stable/test/cpp/abyss.cpp b/stable/test/cpp/abyss.cpp index b02effbf5..473670505 100644 --- a/stable/test/cpp/abyss.cpp +++ b/stable/test/cpp/abyss.cpp @@ -17,7 +17,11 @@ using girerr::throwf; #include "xmlrpc-c/AbyssServer.hpp" #include "xmlrpc-c/AbyssEnvironment.hpp" #include "xmlrpc-c/AbyssChanSwitch.hpp" +#ifdef _WIN32 +#include "xmlrpc-c/AbyssChanSwitchWin.hpp" +#else #include "xmlrpc-c/AbyssChanSwitchUnix.hpp" +#endif using namespace xmlrpc_c; @@ -54,7 +58,11 @@ class addHandlerTestSuite : public testSuite { bool * const ) {} }; +#ifdef _WIN32 + AbyssChanSwitchWin chanSwitch(8080); +#else AbyssChanSwitchUnix chanSwitch(8080); +#endif AbyssServer abyssServer(&chanSwitch); @@ -73,9 +81,11 @@ class createTestSuite : public testSuite { return "createTestSuite"; } virtual void runtests(unsigned int const) { - +#ifdef _WIN32 + AbyssChanSwitchWin chanSwitch(8080); +#else AbyssChanSwitchUnix chanSwitch(8080); - +#endif AbyssServer abyssServer(&chanSwitch); } diff --git a/stable/test/cpp/testclient.cpp b/stable/test/cpp/testclient.cpp index d88e3508b..7ad3eeef7 100644 --- a/stable/test/cpp/testclient.cpp +++ b/stable/test/cpp/testclient.cpp @@ -502,6 +502,13 @@ class pstreamTransportTestSuite : public testSuite { &responseXml);); // Error: no response } + { + clientXmlTransport_pstream transport2( + clientXmlTransport_pstream::constrOpt() + .fd(devNullFd) + .useBrokenConnEx(true) + ); + } clientXmlTransportPtr transport1P(new clientXmlTransport_pstream( clientXmlTransport_pstream::constrOpt() .fd(devNullFd) @@ -575,7 +582,7 @@ class clientCurlIntTestSuite : public testSuite { #if MUST_BUILD_CURL_CLIENT clientXmlTransport_curl transportc0; client_xml client0(&transportc0); - carriageParm_curl0 carriageParmCurl("http://suckthis.com"); + carriageParm_curl0 carriageParmCurl("http://nosuchserver8677.com"); paramList paramList0; @@ -619,8 +626,8 @@ class clientCurlTestSuite : public testSuite { #if MUST_BUILD_CURL_CLIENT clientXmlTransport_curl transportc0; client_xml client0(&transportc0); - carriageParm_http0 carriageParmHttp("http://suckthis.com"); - carriageParm_curl0 carriageParmCurl("http://suckthis.com"); + carriageParm_http0 carriageParmHttp("http://nosuchserver8677.com"); + carriageParm_curl0 carriageParmCurl("http://nosuchserver8677.com"); connection connection0(&client0, &carriageParmHttp); paramList paramList0; diff --git a/stable/test/cpp/value.cpp b/stable/test/cpp/value.cpp index 7799462dc..30e758c78 100644 --- a/stable/test/cpp/value.cpp +++ b/stable/test/cpp/value.cpp @@ -375,6 +375,14 @@ class i8TestSuite : public testSuite { value_i8 int4(value_double(3.7)); TEST_FAILED("invalid cast double-i8 suceeded"); } catch (error const&) {} + + value const int1x(toValue((xmlrpc_int64)7)); + TEST(int1x.type() == value::TYPE_I8); + TEST(static_cast(value_i8(int1x)) == 7); + + xmlrpc_int64 test1x; + fromValue(test1x, int1x); + TEST(test1x == 7); } }; diff --git a/stable/test/memblock.c b/stable/test/memblock.c new file mode 100644 index 000000000..781afb4f6 --- /dev/null +++ b/stable/test/memblock.c @@ -0,0 +1,237 @@ +#include + +#include "xmlrpc_config.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" + +#include "testtool.h" + + +#include "memblock.h" + + + +static char* test_string_1 = "foo"; +static int test_int_array_1[5] = {1, 2, 3, 4, 5}; +static int test_int_array_2[3] = {6, 7, 8}; +static int test_int_array_3[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + + + +static void +testMemBlock(void) { + + xmlrpc_env env; + xmlrpc_mem_block * blockP; + + xmlrpc_mem_block * typedHeapBlockP; + void ** typedContents; + + xmlrpc_env_init(&env); + + /* Allocate a zero-size block. */ + blockP = xmlrpc_mem_block_new(&env, 0); + TEST_NO_FAULT(&env); + TEST(blockP != NULL); + TEST(xmlrpc_mem_block_size(blockP) == 0); + + /* Grow the block a little bit. */ + xmlrpc_mem_block_resize(&env, blockP, strlen(test_string_1) + 1); + TEST_NO_FAULT(&env); + TEST(xmlrpc_mem_block_size(blockP) == strlen(test_string_1) + 1); + + /* Insert a string into the block, and resize it by large amount. + ** We want to cause a reallocation and copy of the block contents. */ + strcpy(xmlrpc_mem_block_contents(blockP), test_string_1); + xmlrpc_mem_block_resize(&env, blockP, 10000); + TEST_NO_FAULT(&env); + TEST(xmlrpc_mem_block_size(blockP) == 10000); + TEST(xmlrpc_streq(xmlrpc_mem_block_contents(blockP), test_string_1)); + + /* Test growing beyond a megabyte */ + xmlrpc_mem_block_resize(&env, blockP, 1024*1024+1); + TEST_NO_FAULT(&env); + TEST(xmlrpc_mem_block_size(blockP) == 1024*1024+1); + TEST(xmlrpc_streq(xmlrpc_mem_block_contents(blockP), test_string_1)); + + /* Test shrinking */ + xmlrpc_mem_block_resize(&env, blockP, 2); + TEST_NO_FAULT(&env); + TEST(xmlrpc_mem_block_size(blockP) == 2); + TEST(xmlrpc_memeq(xmlrpc_mem_block_contents(blockP), test_string_1, 2)); + + /* Test cleanup code (with help from memprof). */ + xmlrpc_mem_block_free(blockP); + + /* Allocate a bigger block. */ + blockP = xmlrpc_mem_block_new(&env, 128); + TEST_NO_FAULT(&env); + TEST(blockP != NULL); + TEST(xmlrpc_mem_block_size(blockP) == 128); + + /* Test cleanup code (with help from memprof). */ + xmlrpc_mem_block_free(blockP); + + /* Allocate a "typed" memory block. */ + typedHeapBlockP = XMLRPC_TYPED_MEM_BLOCK_NEW(void *, &env, 20); + TEST_NO_FAULT(&env); + TEST(typedHeapBlockP != NULL); + TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(void*, typedHeapBlockP) == 20); + typedContents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(void*, typedHeapBlockP); + TEST(typedContents != NULL); + + /* Resize a typed memory block. */ + XMLRPC_TYPED_MEM_BLOCK_RESIZE(void*, &env, typedHeapBlockP, 100); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(void*, typedHeapBlockP) == 100); + + /* Test cleanup code (with help from memprof). */ + XMLRPC_TYPED_MEM_BLOCK_FREE(void*, typedHeapBlockP); + + /* Test xmlrpc_mem_block_append. */ + blockP = XMLRPC_TYPED_MEM_BLOCK_NEW(int, &env, 5); + TEST_NO_FAULT(&env); + memcpy(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(int, blockP), + test_int_array_1, sizeof(test_int_array_1)); + XMLRPC_TYPED_MEM_BLOCK_APPEND(int, &env, blockP, test_int_array_2, 3); + TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(int, blockP) == 8); + TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(int, blockP), + test_int_array_3, sizeof(test_int_array_3)) == 0); + XMLRPC_TYPED_MEM_BLOCK_FREE(int, blockP); + + xmlrpc_env_clean(&env); +} + + + +static void +testMemPool(void) { + + xmlrpc_env env; + + xmlrpc_mem_pool * poolP; + + xmlrpc_env_init(&env); + + poolP = xmlrpc_mem_pool_new(&env, 1); + TEST_NO_FAULT(&env); + TEST(poolP != NULL); + + xmlrpc_mem_pool_free(poolP); + + poolP = xmlrpc_mem_pool_new(&env, 10); + TEST_NO_FAULT(&env); + TEST(poolP != NULL); + + xmlrpc_mem_pool_alloc(&env, poolP, 1); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_release(poolP, 1); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_alloc(&env, poolP, 5); + TEST_NO_FAULT(&env); + + { + xmlrpc_env env2; + xmlrpc_env_init(&env2); + xmlrpc_mem_pool_alloc(&env2, poolP, 6); + TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env2); + } + + xmlrpc_mem_pool_alloc(&env, poolP, 5); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_release(poolP, 5); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_release(poolP, 5); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_free(poolP); + + xmlrpc_env_clean(&env); +} + + + +static void +testMemBlockPool(void) { + + xmlrpc_env env; + + xmlrpc_mem_pool * poolP; + xmlrpc_mem_block * block1P; + + xmlrpc_env_init(&env); + + /* The memory block facility often allocates more memory that we request, + anticipating the future (e.g. if we create a 1-byte block, it allocates + 16), so we work in large numbers. + */ + + poolP = xmlrpc_mem_pool_new(&env, 1000); + TEST_NO_FAULT(&env); + TEST(poolP != NULL); + + block1P = xmlrpc_mem_block_new_pool(&env, 1000, poolP); + TEST_NO_FAULT(&env); + TEST(block1P != NULL); + + xmlrpc_mem_block_free(block1P); + + block1P = xmlrpc_mem_block_new_pool(&env, 200, poolP); + + { + xmlrpc_env env2; + xmlrpc_env_init(&env2); + xmlrpc_mem_block_new_pool(&env2, 900, poolP); + TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env2); + } + + xmlrpc_mem_block_resize(&env, block1P, 500); + TEST_NO_FAULT(&env); + + { + xmlrpc_env env2; + xmlrpc_env_init(&env2); + xmlrpc_mem_block_resize(&env2, block1P, 1100); + TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env2); + } + + { + xmlrpc_env env2; + xmlrpc_env_init(&env2); + xmlrpc_mem_block_new_pool(&env2, 600, poolP); + TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env2); + } + + xmlrpc_mem_block_free(block1P); + + xmlrpc_mem_pool_free(poolP); + + xmlrpc_env_clean(&env); +} + + + +void +test_memBlock() { + + printf("Running memory manager tests..."); + + testMemBlock(); + + testMemPool(); + + testMemBlockPool(); + + printf("\n"); + printf("Memory manager tests done.\n"); +} + + diff --git a/stable/test/memblock.h b/stable/test/memblock.h new file mode 100644 index 000000000..30ed9fc71 --- /dev/null +++ b/stable/test/memblock.h @@ -0,0 +1,7 @@ +#ifndef TEST_MEMBLOCK_H_INCLUDED +#define TEST_MEMBLOCK_H_INCLUDED + +void +test_memBlock(void); + +#endif diff --git a/stable/test/parse_xml.c b/stable/test/parse_xml.c index 0f3237d83..d6abe5904 100644 --- a/stable/test/parse_xml.c +++ b/stable/test/parse_xml.c @@ -6,7 +6,6 @@ #include "girstring.h" #include "casprintf.h" #include "xmlrpc-c/base.h" -#include "xmlrpc-c/xmlparser.h" #include "testtool.h" #include "xml_data.h" @@ -14,52 +13,6 @@ -static void test_expat (void) -{ - xmlrpc_env env; - xml_element *elem, *array, *data, *value1, *i4; - char *cdata; - size_t size; - - xmlrpc_env_init(&env); - - /* Parse a moderately complex XML document. */ - xml_parse(&env, expat_data, strlen(expat_data), &elem); - TEST_NO_FAULT(&env); - TEST(elem != NULL); - - /* Verify our results. */ - TEST(streq(xml_element_name(elem), "value")); - TEST(xml_element_children_size(elem) == 1); - array = xml_element_children(elem)[0]; - TEST(streq(xml_element_name(array), "array")); - TEST(xml_element_children_size(array) == 1); - data = xml_element_children(array)[0]; - TEST(streq(xml_element_name(data), "data")); - TEST(xml_element_children_size(data) > 1); - value1 = xml_element_children(data)[0]; - TEST(streq(xml_element_name(value1), "value")); - TEST(xml_element_children_size(value1) == 1); - i4 = xml_element_children(value1)[0]; - TEST(streq(xml_element_name(i4), "i4")); - TEST(xml_element_children_size(i4) == 0); - cdata = xml_element_cdata(i4); - size = xml_element_cdata_size(i4); - TEST(size == strlen("2147483647")); - TEST(memcmp(cdata, "2147483647", strlen("2147483647")) == 0); - - /* Test cleanup code (w/memprof). */ - xml_element_free(elem); - - /* Test broken XML */ - xml_parse(&env, expat_error_data, strlen(expat_error_data), &elem); - TEST(env.fault_occurred); - - xmlrpc_env_clean(&env); -} - - - static void testParseNumberValue(void) { @@ -375,16 +328,9 @@ testParseBadResponseXmlRpc(void) { const char * const bad_resp = bad_responses[i]; xmlrpc_env env; xmlrpc_value * v; - xml_element *elem; xmlrpc_env_init(&env); - /* First, check to make sure that our test case is well-formed XML. - ** (It's easy to make mistakes when writing the test cases!) */ - xml_parse(&env, bad_resp, strlen(bad_resp), &elem); - TEST_NO_FAULT(&env); - xml_element_free(elem); - /* Now, make sure the higher-level routine barfs appropriately. */ v = xmlrpc_parse_response(&env, bad_resp, strlen(bad_resp)); TEST(env.fault_occurred); @@ -409,20 +355,11 @@ testParseBadResult(void) { const char * const bad_resp = bad_values[i]; xmlrpc_env env; xmlrpc_value * valueP; - xml_element *elem; int faultCode; const char * faultString; xmlrpc_env_init(&env); - /* First, check to make sure that our test case is well-formed XML. - ** (It's easy to make mistakes when writing the test cases!) */ - xml_parse(&env, bad_resp, strlen(bad_resp), &elem); - TEST_NO_FAULT(&env); - xml_element_free(elem); - - /* Now, make sure the higher-level routine barfs appropriately. */ - xmlrpc_parse_response2(&env, bad_resp, strlen(bad_resp), &valueP, &faultCode, &faultString); @@ -483,13 +420,12 @@ testParseFaultResponse(void) { } /* Now with the old interface */ { - xmlrpc_value * valueP; xmlrpc_env fault; /* Parse a valid fault. */ xmlrpc_env_init(&fault); - valueP = xmlrpc_parse_response(&fault, serialized_fault, - strlen(serialized_fault)); + xmlrpc_parse_response(&fault, serialized_fault, + strlen(serialized_fault)); TEST(fault.fault_occurred); TEST(fault.fault_code == 6); @@ -510,7 +446,6 @@ testParseXmlCall(void) { xmlrpc_value *params; int i1, i2; const char **bad_call; - xml_element *elem; xmlrpc_env_init(&env); @@ -536,14 +471,6 @@ testParseXmlCall(void) { they aren't legal XML-RPC. */ for (bad_call = bad_calls; *bad_call != NULL; ++bad_call) { - - /* First, check to make sure that our test case is well-formed XML. - ** (It's easy to make mistakes when writing the test cases!) */ - xml_parse(&env, *bad_call, strlen(*bad_call), &elem); - TEST_NO_FAULT(&env); - xml_element_free(elem); - - /* Now, make sure the higher-level routine barfs appropriately. */ xmlrpc_parse_call(&env, *bad_call, strlen(*bad_call), &method_name, ¶ms); TEST_FAULT(&env, XMLRPC_PARSE_ERROR); @@ -590,7 +517,6 @@ void test_parse_xml(void) { printf("Running XML parsing tests.\n"); - test_expat(); testParseNumberValue(); testParseMiscSimpleValue(); testParseGoodResponse(); diff --git a/stable/test/server_abyss.c b/stable/test/server_abyss.c index b774305ed..591a9880d 100644 --- a/stable/test/server_abyss.c +++ b/stable/test/server_abyss.c @@ -107,6 +107,8 @@ testServerParms(void) { parms.sockaddr_p = &sockaddr; parms.sockaddrlen = sizeof(sockaddr); parms.log_file_name = "/tmp/xmlrpc_logfile"; + + if (parms.config_file_name) {} // Defeat set-but-unused compiler warning }; @@ -258,6 +260,7 @@ test_server_abyss(void) { ServerSetMaxConn(&abyssServer, 10); ServerSetMaxConnBacklog(&abyssServer, 10); + ServerSetMaxSessionMem(&abyssServer, 64*1024); ServerSetKeepaliveTimeout(&abyssServer, 60); ServerSetKeepaliveMaxConn(&abyssServer, 10); ServerSetTimeout(&abyssServer, 0); diff --git a/stable/test/test.c b/stable/test/test.c index 8aa55ded9..d130a733a 100644 --- a/stable/test/test.c +++ b/stable/test/test.c @@ -30,6 +30,7 @@ #include "abyss.h" #include "server_abyss.h" #include "method_registry.h" +#include "memblock.h" /*========================================================================= ** Test Harness @@ -68,9 +69,6 @@ bool const runningUnderWindows = static char* test_string_1 = "foo"; static char* test_string_2 = "bar"; -static int test_int_array_1[5] = {1, 2, 3, 4, 5}; -static int test_int_array_2[3] = {6, 7, 8}; -static int test_int_array_3[8] = {1, 2, 3, 4, 5, 6, 7, 8}; /*========================================================================= ** Test Suites @@ -134,97 +132,6 @@ testEnv(void) { -static void -testMemBlock(void) { - xmlrpc_env env; - xmlrpc_mem_block * blockP; - - xmlrpc_mem_block * typedHeapBlockP; - xmlrpc_mem_block typedAutoBlockP; - void ** typedContents; - - xmlrpc_env_init(&env); - - /* Allocate a zero-size block. */ - blockP = xmlrpc_mem_block_new(&env, 0); - TEST_NO_FAULT(&env); - TEST(blockP != NULL); - TEST(xmlrpc_mem_block_size(blockP) == 0); - - /* Grow the block a little bit. */ - xmlrpc_mem_block_resize(&env, blockP, strlen(test_string_1) + 1); - TEST_NO_FAULT(&env); - TEST(xmlrpc_mem_block_size(blockP) == strlen(test_string_1) + 1); - - /* Insert a string into the block, and resize it by large amount. - ** We want to cause a reallocation and copy of the block contents. */ - strcpy(xmlrpc_mem_block_contents(blockP), test_string_1); - xmlrpc_mem_block_resize(&env, blockP, 10000); - TEST_NO_FAULT(&env); - TEST(xmlrpc_mem_block_size(blockP) == 10000); - TEST(xmlrpc_streq(xmlrpc_mem_block_contents(blockP), test_string_1)); - - /* Test growing beyond a megabyte */ - xmlrpc_mem_block_resize(&env, blockP, 1024*1024+1); - TEST_NO_FAULT(&env); - TEST(xmlrpc_mem_block_size(blockP) == 1024*1024+1); - TEST(xmlrpc_streq(xmlrpc_mem_block_contents(blockP), test_string_1)); - - /* Test shrinking */ - xmlrpc_mem_block_resize(&env, blockP, 2); - TEST_NO_FAULT(&env); - TEST(xmlrpc_mem_block_size(blockP) == 2); - TEST(xmlrpc_memeq(xmlrpc_mem_block_contents(blockP), test_string_1, 2)); - - /* Test cleanup code (with help from memprof). */ - xmlrpc_mem_block_free(blockP); - - /* Allocate a bigger block. */ - blockP = xmlrpc_mem_block_new(&env, 128); - TEST_NO_FAULT(&env); - TEST(blockP != NULL); - TEST(xmlrpc_mem_block_size(blockP) == 128); - - /* Test cleanup code (with help from memprof). */ - xmlrpc_mem_block_free(blockP); - - /* Allocate a "typed" memory block. */ - typedHeapBlockP = XMLRPC_TYPED_MEM_BLOCK_NEW(void *, &env, 20); - TEST_NO_FAULT(&env); - TEST(typedHeapBlockP != NULL); - TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(void*, typedHeapBlockP) == 20); - typedContents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(void*, typedHeapBlockP); - TEST(typedContents != NULL); - - /* Resize a typed memory block. */ - XMLRPC_TYPED_MEM_BLOCK_RESIZE(void*, &env, typedHeapBlockP, 100); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(void*, typedHeapBlockP) == 100); - - /* Test cleanup code (with help from memprof). */ - XMLRPC_TYPED_MEM_BLOCK_FREE(void*, typedHeapBlockP); - - /* Test _INIT and _CLEAN for stack-based memory blocks. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(void*, &env, &typedAutoBlockP, 30); - TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(void*, &typedAutoBlockP) == 30); - XMLRPC_TYPED_MEM_BLOCK_CLEAN(void*, &typedAutoBlockP); - - /* Test xmlrpc_mem_block_append. */ - blockP = XMLRPC_TYPED_MEM_BLOCK_NEW(int, &env, 5); - TEST_NO_FAULT(&env); - memcpy(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(int, blockP), - test_int_array_1, sizeof(test_int_array_1)); - XMLRPC_TYPED_MEM_BLOCK_APPEND(int, &env, blockP, test_int_array_2, 3); - TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(int, blockP) == 8); - TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(int, blockP), - test_int_array_3, sizeof(test_int_array_3)) == 0); - XMLRPC_TYPED_MEM_BLOCK_FREE(int, blockP); - - xmlrpc_env_clean(&env); -} - - - static char *(base64_triplets[]) = { "", "", "\r\n", "a", "YQ==", "YQ==\r\n", @@ -758,7 +665,8 @@ main(int argc, xmlrpc_init(&env); testVersion(); testEnv(); - testMemBlock(); + printf("\n"); + test_memBlock(); testBase64Conversion(); printf("\n"); test_value(); diff --git a/stable/test/value.c b/stable/test/value.c index 78b6ecad7..8c786058f 100644 --- a/stable/test/value.c +++ b/stable/test/value.c @@ -190,13 +190,19 @@ test_value_double(void) { TEST(d == -3.25); xmlrpc_DECREF(v2); - v = xmlrpc_double_new(&env, 1.0/0.0); + /* Older compilers don't have INFINITY and NAN, so we compute them here. + But newer compilers recognize an error if they see you dividing by + zero, so we have to make it nonobvious that we're doing that. + */ + double const zero = sin(0); + + v = xmlrpc_double_new(&env, 1.0/zero); /* +INFINITY */ TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - v = xmlrpc_double_new(&env, -1.0/0.0); + v = xmlrpc_double_new(&env, -1.0/zero); /* -INFINITY */ TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - v = xmlrpc_double_new(&env, 0.0/0.0); + v = xmlrpc_double_new(&env, 0.0/zero); /* NAN */ TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_env_clean(&env); @@ -1384,14 +1390,13 @@ test_value_type_mismatch(void) { static void test_value_invalid_type(void) { - xmlrpc_value * v; xmlrpc_env env; /* Test invalid type specifier in format string */ xmlrpc_env_init(&env); - v = xmlrpc_build_value(&env, "Q"); + xmlrpc_build_value(&env, "Q"); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_env_clean(&env); @@ -1402,17 +1407,16 @@ test_value_invalid_type(void) { static void test_value_missing_array_delim(void) { - xmlrpc_value * v; xmlrpc_env env; /* Test missing close parenthesis on array */ xmlrpc_env_init(&env); - v = xmlrpc_build_value(&env, "("); + xmlrpc_build_value(&env, "("); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - v = xmlrpc_build_value(&env, "(i"); + xmlrpc_build_value(&env, "(i"); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_env_clean(&env); @@ -1423,20 +1427,19 @@ test_value_missing_array_delim(void) { static void test_value_missing_struct_delim(void) { - xmlrpc_value * v; xmlrpc_env env; /* Test missing closing brace on struct */ xmlrpc_env_init(&env); - v = xmlrpc_build_value(&env, "{"); + xmlrpc_build_value(&env, "{"); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - v = xmlrpc_build_value(&env, "{s:i", "key1", 7); + xmlrpc_build_value(&env, "{s:i", "key1", 7); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - v = xmlrpc_build_value(&env, "{s:i,s:i", "key1", 9, "key2", -4); + xmlrpc_build_value(&env, "{s:i,s:i", "key1", 9, "key2", -4); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_env_clean(&env); @@ -1447,7 +1450,6 @@ test_value_missing_struct_delim(void) { static void test_value_invalid_struct(void) { - xmlrpc_value * v; xmlrpc_env env; /* Note that even though the format strings are invalid, we have @@ -1458,13 +1460,13 @@ test_value_invalid_struct(void) { xmlrpc_env_init(&env); - v = xmlrpc_build_value(&env, "{s:ii", "key1", 9, 9); + xmlrpc_build_value(&env, "{s:ii", "key1", 9, 9); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - v = xmlrpc_build_value(&env, "{si:", "key1", 9); + xmlrpc_build_value(&env, "{si:", "key1", 9); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - v = xmlrpc_build_value(&env, "{s", "key1"); + xmlrpc_build_value(&env, "{s", "key1"); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_env_clean(&env); @@ -1504,6 +1506,8 @@ test_value_parse_value(void) { xmlrpc_env env; xmlrpc_value * valueP; + const char * base64_data = "base64 data"; + size_t base64_data_length = strlen(base64_data); const char * datestring = "19980717T14:08:55"; xmlrpc_env_init(&env); @@ -1511,7 +1515,7 @@ test_value_parse_value(void) { valueP = xmlrpc_build_value(&env, "(idb8ss#6(i){s:i}np(i))", 7, 3.14, (xmlrpc_bool)1, datestring, "hello world", "a\0b", (size_t)3, - "base64 data", strlen("base64 data"), + base64_data, base64_data_length, 15, "member9", 9, &valueP, -5); TEST_NO_FAULT(&env); diff --git a/stable/test/value_datetime.c b/stable/test/value_datetime.c index 350e770d7..ff48456ce 100644 --- a/stable/test/value_datetime.c +++ b/stable/test/value_datetime.c @@ -282,12 +282,11 @@ test_value_datetime_str_invalid1(const char * const datestring) { static void test_value_datetime_str_invalid2(const char * const datestring) { - xmlrpc_value * v; xmlrpc_env env; xmlrpc_env_init(&env); - v = xmlrpc_datetime_new_str(&env, datestring); + xmlrpc_datetime_new_str(&env, datestring); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_env_clean(&env); diff --git a/stable/tools/Makefile b/stable/tools/Makefile index 9a4e4c06b..7cd2e5f5f 100644 --- a/stable/tools/Makefile +++ b/stable/tools/Makefile @@ -25,7 +25,11 @@ ifeq ($(MUST_BUILD_CLIENT),yes) endif endif -.PHONY: all clean distclean install check dep +ifeq ($(ENABLE_CPLUSPLUS),yes) + SUBDIRS += xmlrpc_dumpserver +endif + +.PHONY: all clean distclean install uninstall check dep all: $(SUBDIRS:%=%/all) @@ -35,6 +39,8 @@ distclean: $(SUBDIRS:%=%/distclean) install: $(SUBDIRS:%=%/install) +uninstall: $(SUBDIRS:%=%/uninstall) + check: dep: $(SUBDIRS:%=%/dep) diff --git a/stable/tools/binmode-rpc-kit/Makefile b/stable/tools/binmode-rpc-kit/Makefile index e5df68d7e..ea34b1982 100644 --- a/stable/tools/binmode-rpc-kit/Makefile +++ b/stable/tools/binmode-rpc-kit/Makefile @@ -2,4 +2,5 @@ all: clean: distclean: install: +uninstall: dep: diff --git a/stable/tools/common.mk b/stable/tools/common.mk index a70022b54..1218e18cb 100644 --- a/stable/tools/common.mk +++ b/stable/tools/common.mk @@ -15,6 +15,23 @@ CLIENTPP_LDLIBS = \ -Lblddir/lib/libutil++ \ -lxmlrpc_util++ \ +SERVER_ABYSS_LDLIBS = \ + $(LIBXMLRPC_SERVER_ABYSS) \ + $(LIBXMLRPC_ABYSS) \ + $(LIBXMLRPC_SERVER) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_XML) \ + $(LIBXMLRPC_UTIL) \ + $(LDLIBS_XML) \ + +SERVER_ABYSS_LIBS_DEP = \ + $(LIBXMLRPC_SERVER_ABYSS) \ + $(LIBXMLRPC_ABYSS) \ + $(LIBXMLRPC_SERVER) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_XML) \ + $(LIBXMLRPC_UTIL) \ + include $(SRCDIR)/common.mk ifneq ($(OMIT_LIB_RULE),Y) diff --git a/stable/tools/turbocharger/Makefile b/stable/tools/turbocharger/Makefile index 8772c3586..ff09f9741 100644 --- a/stable/tools/turbocharger/Makefile +++ b/stable/tools/turbocharger/Makefile @@ -2,4 +2,5 @@ all: clean: distclean: install: +uninstall: dep: \ No newline at end of file diff --git a/stable/tools/xml-rpc-api2cpp/Makefile b/stable/tools/xml-rpc-api2cpp/Makefile index 014e09fde..4e3b7a363 100644 --- a/stable/tools/xml-rpc-api2cpp/Makefile +++ b/stable/tools/xml-rpc-api2cpp/Makefile @@ -56,6 +56,12 @@ $(SRCDIR)/tools/common.mk: srcdir blddir include depend.mk +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean clean: clean-common rm -f $(PROGS) diff --git a/stable/tools/xml-rpc-api2txt/Makefile b/stable/tools/xml-rpc-api2txt/Makefile index a63d94542..b4dd64678 100644 --- a/stable/tools/xml-rpc-api2txt/Makefile +++ b/stable/tools/xml-rpc-api2txt/Makefile @@ -25,6 +25,12 @@ $(SRCDIR)/tools/common.mk: srcdir blddir include depend.mk +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean clean: clean-common rm -f $(PROGS) diff --git a/stable/tools/xml/Makefile b/stable/tools/xml/Makefile index 2bc54e395..70e05e8a3 100644 --- a/stable/tools/xml/Makefile +++ b/stable/tools/xml/Makefile @@ -54,6 +54,12 @@ include depend.mk .PHONY: dep dep: dep-common +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean clean: clean-common rm -f $(PROGS) diff --git a/stable/tools/xml/xmlrpc_parsecall.c b/stable/tools/xml/xmlrpc_parsecall.c index fbc0e8965..ac576f212 100644 --- a/stable/tools/xml/xmlrpc_parsecall.c +++ b/stable/tools/xml/xmlrpc_parsecall.c @@ -3,6 +3,7 @@ #include #include +#include #include #include "casprintf.h" diff --git a/stable/tools/xmlrpc/Makefile b/stable/tools/xmlrpc/Makefile index 71095c5f9..3e322ce66 100644 --- a/stable/tools/xmlrpc/Makefile +++ b/stable/tools/xmlrpc/Makefile @@ -54,6 +54,12 @@ include depend.mk .PHONY: dep dep: dep-common +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean clean: clean-common rm -f xmlrpc diff --git a/stable/tools/xmlrpc/xmlrpc.c b/stable/tools/xmlrpc/xmlrpc.c index 3df147edf..3141398c0 100644 --- a/stable/tools/xmlrpc/xmlrpc.c +++ b/stable/tools/xmlrpc/xmlrpc.c @@ -104,7 +104,7 @@ processArguments(xmlrpc_env * const envP, cmdlineP->url = cmd_getArgument(cp, 0); cmdlineP->methodName = cmd_getArgument(cp, 1); cmdlineP->paramCount = cmd_argumentCount(cp) - 2; - MALLOCARRAY(cmdlineP->params, cmdlineP->paramCount); + MALLOCARRAY_NOFAIL(cmdlineP->params, cmdlineP->paramCount); for (i = 0; i < cmdlineP->paramCount; ++i) cmdlineP->params[i] = cmd_getArgument(cp, i+2); } @@ -285,39 +285,52 @@ getCdata(xmlrpc_env * const envP, const char ** const cursorP, const char ** const cdataP) { - char text[strlen(*cursorP)+1]; - unsigned int textCursor; - bool end; - const char * cursor; + size_t const cdataSizeBound = strlen(*cursorP) + 1; - cursor = *cursorP; /* initial value */ - - for (textCursor = 0, end = false; !end; ) { - switch (*cursor) { - case ',': - case ':': - case '(': - case ')': - case '{': - case '}': - case '\0': - end = true; - break; - case '\\': { - ++cursor; // skip backslash escape character - if (!*cursor) - setError(envP, "Nothing after escape character ('\\')"); - else - text[textCursor++] = *cursor++; - }; break; - default: - text[textCursor++]= *cursor++; + char * text; + + MALLOCARRAY(text, cdataSizeBound); + + if (text == NULL) + setError(envP, "Failed to allocate a buffer of size %u " + "to compute cdata", (unsigned)cdataSizeBound); + else { + unsigned int textCursor; + bool end; + const char * cursor; + + cursor = *cursorP; /* initial value */ + + for (textCursor = 0, end = false; !end; ) { + switch (*cursor) { + case ',': + case ':': + case '(': + case ')': + case '{': + case '}': + case '\0': + end = true; + break; + case '\\': { + ++cursor; // skip backslash escape character + if (!*cursor) + setError(envP, "Nothing after escape character ('\\')"); + else + text[textCursor++] = *cursor++; + }; break; + default: + text[textCursor++]= *cursor++; + } + assert(textCursor <= cdataSizeBound); } - } - text[textCursor++] = '\0'; + text[textCursor++] = '\0'; - *cdataP = strdup(text); - *cursorP = cursor; + assert(textCursor <= cdataSizeBound); + + *cdataP = text; + *cursorP = cursor; + } } diff --git a/stable/tools/xmlrpc_cpp_proxy/Makefile b/stable/tools/xmlrpc_cpp_proxy/Makefile index 22529a877..8bf1f7f23 100644 --- a/stable/tools/xmlrpc_cpp_proxy/Makefile +++ b/stable/tools/xmlrpc_cpp_proxy/Makefile @@ -53,6 +53,12 @@ $(SRCDIR)/tools/common.mk: srcdir blddir include depend.mk +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean clean: clean-common rm -f xmlrpc_cpp_proxy diff --git a/stable/tools/xmlrpc_dumpserver/Makefile b/stable/tools/xmlrpc_dumpserver/Makefile new file mode 100644 index 000000000..c5cbf0098 --- /dev/null +++ b/stable/tools/xmlrpc_dumpserver/Makefile @@ -0,0 +1,72 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/xmlrpc_dumpserver + +default: all + +include $(BLDDIR)/config.mk + +PROGS := xmlrpc_dumpserver + +PROGRAMS_TO_INSTALL = $(PROGS) + +include $(SRCDIR)/tools/common.mk + +INCLUDES = \ + -I../lib/include \ + -Iblddir \ + -Iblddir/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include + +all: xmlrpc_dumpserver + +# cmdline.parser.o references getoptx.o and string_parser.o. +# string_parser.o references stripcaseeq.o + +UTIL_OBJS = \ + casprintf.o \ + cmdline_parser.o \ + getoptx.o \ + string_parser.o \ + stripcaseeq.o \ + +UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) + +DUMPVALUE = blddir/tools/lib/dumpvalue.o + +XMLRPC_OBJS = xmlrpc_dumpserver.o $(DUMPVALUE) + +xmlrpc_dumpserver: $(XMLRPC_OBJS) $(SERVER_ABYSS_LIBS_DEP) $(UTILS) + $(CCLD) -o $@ $(LDFLAGS_ALL) $(XMLRPC_OBJS) $(UTILS) \ + $(SERVER_ABYSS_LDLIBS) + +%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h + $(CC) -c $(CFLAGS_ALL) $< + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: dep +dep: dep-common + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean +clean: clean-common + rm -f $(PROGS) + +.PHONY: distclean +distclean: clean distclean-common diff --git a/stable/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c b/stable/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c new file mode 100644 index 000000000..562fd3e93 --- /dev/null +++ b/stable/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c @@ -0,0 +1,269 @@ +/*============================================================================= + xmlrpc_dumpserver +=============================================================================== + + This program runs an XML-RPC server that does nothing but print to Standard + Output the contents of every call it receives, and send a failure response. + + You use this to test a client or to learn about XML-RPC. + + Example: + + $ xmlrpc_dumpserver -port=8080 & + + $ xmlrpc localhost:8080 dummymethod s/hello i/5 + +=============================================================================*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" /* information about this build environment */ +#include "bool.h" +#include "int.h" +#include "mallocvar.h" +#include "girstring.h" +#include "casprintf.h" +#include "cmdline_parser.h" +#include "dumpvalue.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server_abyss.h" + +#define NAME "xmlrpc command line program" +#define VERSION "1.0" + +struct CmdlineInfo { + unsigned int port; +}; + + + +static void +parseCommandLine(int const argc, + const char ** const argv, + struct CmdlineInfo * const cmdlineP, + const char ** const errorP) { + + cmdlineParser const cp = cmd_createOptionParser(); + + const char * error; + + cmd_defineOption(cp, "port", OPTTYPE_UINT); + + cmd_processOptions(cp, argc, argv, &error); + + if (error) { + casprintf(errorP, "Command syntax error. %s", error); + strfree(error); + } else { + *errorP = NULL; /* initial assumption */ + + if (cmd_argumentCount(cp) > 0) + casprintf(errorP, "No non-option arguments are possible. " + "You specified %u", cmd_argumentCount(cp)); + + if (!*errorP) { + if (cmd_optionIsPresent(cp, "port")) { + cmdlineP->port = cmd_getOptionValueUint(cp, "port"); + } else { + casprintf(errorP, "You must specify the TCP port number " + "on which to listen for XML-RPC calls with -port"); + } + } + } + cmd_destroyOptionParser(cp); +} + + + +static void +freeCmdline(struct CmdlineInfo const cmdline ATTR_UNUSED) { + +} + + + +static void +dumpParameters(xmlrpc_value * const paramArrayP) { + + xmlrpc_env env; + int arraySize; + unsigned int paramSeq; + + xmlrpc_env_init(&env); + + arraySize = xmlrpc_array_size(&env, paramArrayP); + + assert(!env.fault_occurred); + assert(arraySize >= 0); + + { + unsigned int const paramCt = arraySize; + + printf("Number of parameters: %u\n", paramCt); + + printf("\n"); + + for (paramSeq = 0; paramSeq < paramCt; ++paramSeq) { + + xmlrpc_value * paramValueP; + + xmlrpc_array_read_item(&env, paramArrayP, paramSeq, ¶mValueP); + + assert(!env.fault_occurred); + + printf("Parameter %u:\n", paramSeq); + printf("\n"); + + dumpValue(" ", paramValueP); + + xmlrpc_DECREF(paramValueP); + + printf("\n"); + } + } + xmlrpc_env_clean(&env); +} + + + +static xmlrpc_value * +defaultMethod(xmlrpc_env * const envP, + const char * const callInfoP ATTR_UNUSED, + const char * const methodName, + xmlrpc_value * const paramArrayP, + void * const serverInfo ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + This is a *xmlrpc_default_method, i.e. a default method for an Xmlrpc-c + registry, which is meant to be called by an XML-RPC server when it receives + a call for a method that is not registered by name. +-----------------------------------------------------------------------------*/ + printf("Server has received a call of method '%s'\n", methodName); + + printf("\n"); + + assert(xmlrpc_value_type(paramArrayP) == XMLRPC_TYPE_ARRAY); + + dumpParameters(paramArrayP); + + xmlrpc_faultf(envP, + "This XML-RPC server is a test server that fails all " + "RPCs. But the fact that it failed this way tells you that " + "the call _was_ valid in XML-RPC terms. The server " + "printed to Standard Output a description of the valid " + "call."); + + /* Return value is irrelevant because we failed the RPC, but to prevent + a compiler warning: + */ + return NULL; +} + + + +static void +setServerParm(xmlrpc_server_abyss_parms * const serverparmP, + xmlrpc_registry * const registryP, + unsigned int const portNum, + size_t * const lengthP) { + + serverparmP->config_file_name = NULL; + serverparmP->registryP = registryP; + serverparmP->port_number = portNum; + serverparmP->log_file_name = NULL; + serverparmP->keepalive_timeout = 0; + serverparmP->keepalive_max_conn = 0; + serverparmP->timeout = 0; + serverparmP->dont_advertise = false; + serverparmP->socket_bound = false; + serverparmP->uri_path = NULL; + serverparmP->chunk_response = false; + serverparmP->enable_shutdown = true; + + *lengthP = XMLRPC_APSIZE(enable_shutdown); +} + + + +static void +runServer(unsigned int const portNum, + const char ** const errorP) { + + xmlrpc_registry * registryP; + xmlrpc_env env; + + xmlrpc_env_init(&env); + + registryP = xmlrpc_registry_new(&env); + if (env.fault_occurred) + casprintf(errorP, "xmlrpc_registry_new() failed. %s", + env.fault_string); + else { + xmlrpc_registry_set_default_method(&env, registryP, + &defaultMethod, NULL); + + if (env.fault_occurred) + casprintf(errorP, "xmlrpc_registry_add_method3() failed. %s", + env.fault_string); + else { + xmlrpc_server_abyss_parms serverparm; + size_t parmLength; + + setServerParm(&serverparm, registryP, portNum, &parmLength); + + printf("Running XML-RPC server on TCP Port %u...\n", portNum); + + xmlrpc_server_abyss(&env, &serverparm, parmLength); + + if (env.fault_occurred) + casprintf(errorP, "xmlrpc_server_abyss() failed. %s", + env.fault_string); + + /* xmlrpc_server_abyss() never returns unless it fails */ + *errorP = NULL; + } + } +} + + + +int +main(int const argc, + const char ** const argv) { + + int exitCode; + struct CmdlineInfo cmdline; + const char * error; + + parseCommandLine(argc, argv, &cmdline, &error); + + if (error) { + fprintf(stderr, "Command syntax error. %s\n", error); + strfree(error); + exitCode = 10; + } else { + const char * error; + + runServer(cmdline.port, &error); + + if (error) { + fprintf(stderr, "Server on port %u failed. %s\n", + cmdline.port, error); + strfree(error); + exitCode = 1; + } else + exitCode = 0; + + freeCmdline(cmdline); + } + return exitCode; +} + + + diff --git a/stable/tools/xmlrpc_pstream/Makefile b/stable/tools/xmlrpc_pstream/Makefile index 251c7f28f..869a7f6b9 100644 --- a/stable/tools/xmlrpc_pstream/Makefile +++ b/stable/tools/xmlrpc_pstream/Makefile @@ -62,6 +62,12 @@ $(SRCDIR)/tools/common.mk: srcdir blddir include depend.mk +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: clean clean: clean-common rm -f xmlrpc_pstream diff --git a/stable/tools/xmlrpc_transport/Makefile b/stable/tools/xmlrpc_transport/Makefile index 4c930373f..59c56b691 100644 --- a/stable/tools/xmlrpc_transport/Makefile +++ b/stable/tools/xmlrpc_transport/Makefile @@ -46,6 +46,12 @@ $(SRCDIR)/tools/common.mk: srcdir blddir include depend.mk +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + .PHONY: dep dep: dep-common diff --git a/stable/tools/xmlrpc_transport/xmlrpc_transport.c b/stable/tools/xmlrpc_transport/xmlrpc_transport.c index 39697b416..80770e905 100644 --- a/stable/tools/xmlrpc_transport/xmlrpc_transport.c +++ b/stable/tools/xmlrpc_transport/xmlrpc_transport.c @@ -13,6 +13,7 @@ #include "mallocvar.h" #include "cmdline_parser.h" +#include "xmlrpc-c/util_int.h" #include "xmlrpc-c/base.h" #include "xmlrpc-c/client.h" diff --git a/stable/unix-common.mk b/stable/unix-common.mk index 69c0df62a..6954faf52 100644 --- a/stable/unix-common.mk +++ b/stable/unix-common.mk @@ -45,6 +45,9 @@ # install-shared-libraries: install all shared libraries and the necessary # symbolic links. +# uninstall-shared-libraries: remove what would be installed by +# install-shared-libraries + # SONAME is to be referenced by $(LDFLAGS_SHLIB) in the rule to make # a shared library (in common.mk). I.e. $@ is the name of the shared # library file. @@ -77,12 +80,25 @@ SHLIB_INSTALL_TARGETS = $(SHARED_LIBS_TO_INSTALL:%=%/install) install-shared-libraries: $(SHLIB_INSTALL_TARGETS) +LIBDESTDIR = $(DESTDIR)$(LIBINST_DIR) + $(SHLIB_INSTALL_TARGETS):%/install:%.$(SHLIB_SUFFIX).$(MAJ).$(MIN) # $< is a library file name, e.g. libfoo.so.3.1 . - $(INSTALL_SHLIB) $< $(DESTDIR)$(LIBINST_DIR)/$< - cd $(DESTDIR)$(LIBINST_DIR); \ + $(INSTALL_SHLIB) $< $(LIBDESTDIR)/$< + cd $(LIBDESTDIR); \ rm -f $(<:%.$(MIN)=%); \ $(LN_S) $< $(<:%.$(MIN)=%) - cd $(DESTDIR)$(LIBINST_DIR); \ + cd $(LIBDESTDIR); \ rm -f $(<:%.$(MAJ).$(MIN)=%); \ $(LN_S) $(<:%.$(MIN)=%) $(<:%.$(MAJ).$(MIN)=%) + +.PHONY: uninstall-shared-libraries +uninstall-shared-libraries: + @list='$(SHARED_LIBS_TO_INSTALL)'; \ + for p in $$list; do \ + echo "Uninstalling $$p shared library"; \ + cd $(LIBDESTDIR); \ + rm -f $$p.$(SHLIB_SUFFIX); \ + rm -f $$p.$(SHLIB_SUFFIX).$(MAJ); \ + rm -f $$p.$(SHLIB_SUFFIX).$(MAJ).$(MIN); \ + done diff --git a/stable/version.mk b/stable/version.mk index e34e3af7d..74913a769 100644 --- a/stable/version.mk +++ b/stable/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 43 -XMLRPC_POINT_RELEASE = 7 +XMLRPC_MINOR_RELEASE = 51 +XMLRPC_POINT_RELEASE = 1 diff --git a/stable/xmlrpc-c-config.main b/stable/xmlrpc-c-config.main index 6080e9dcd..d37be4eaf 100644 --- a/stable/xmlrpc-c-config.main +++ b/stable/xmlrpc-c-config.main @@ -9,6 +9,7 @@ The features are: pstream-server pstream-based server functions server-util basic server functions (implied by *-server) abyss Abyss HTTP server (not necessary with abyss-server) + openssl Openssl convenience functions Options are: --version The version number of the package @@ -74,6 +75,10 @@ while test $# -gt 0; do the_libs="-lxmlrpc_util++ $the_libs" the_libs="-l$LIBXMLRPCPP_NAME $the_libs" ;; + openssl) + the_libs="${OPENSSL_LDADD} $the_libs" + the_libs="-lxmlrpc_openssl $the_libs" + ;; server-util) the_libs="-lxmlrpc_server $the_libs" if test "${needCpp}" = "yes"; then @@ -91,6 +96,10 @@ while test $# -gt 0; do ;; abyss-server) the_libs="${SOCKETLIBOPT} $the_libs" + if test "${ABYSS_DOES_OPENSSL}" = "yes"; then + the_libs="${OPENSSL_LDADD} $the_libs" + cflags="${cflags} ${OPENSSL_CFLAGS}" + fi the_libs="-lxmlrpc_abyss $the_libs" the_libs="-lxmlrpc_server $the_libs" the_libs="-lxmlrpc_server_abyss $the_libs" diff --git a/stable/xmlrpc-c-config.test.main b/stable/xmlrpc-c-config.test.main index cf72f9ff1..d184534ab 100644 --- a/stable/xmlrpc-c-config.test.main +++ b/stable/xmlrpc-c-config.test.main @@ -55,6 +55,10 @@ while test $# -gt 0; do the_libs="${BLDDIR}/lib/libutil++/libxmlrpc_util++.a $the_libs" the_libs="${BLDDIR}/src/cpp/lib$LIBXMLRPCPP_NAME.a $the_libs" ;; + openssl) + the_libs="${OPENSSL_LDADD} $the_libs" + the_libs="${BLDDIR}/lib/openssl/libxmlrpc_openssl.a $the_libs" + ;; server-util) the_libs="${BLDDIR}/src/libxmlrpc_server.a $the_libs" if test "${needCpp}" = "yes"; then @@ -72,6 +76,10 @@ while test $# -gt 0; do ;; abyss-server) the_libs="${SOCKETLIBOPT} $the_libs" + if test "${ABYSS_DOES_OPENSSL}" = "yes"; then + the_libs="${OPENSSL_LDADD} $the_libs" + cflags="${cflags} ${OPENSSL_CFLAGS}" + fi the_libs="${BLDDIR}/lib/abyss/src/libxmlrpc_abyss.a $the_libs" the_libs="${BLDDIR}/src/libxmlrpc_server.a $the_libs" the_libs="${BLDDIR}/src/libxmlrpc_server_abyss.a $the_libs" diff --git a/stable/xmlrpc_amconfig.h.in b/stable/xmlrpc_amconfig.h.in deleted file mode 100644 index 6f3f2aecf..000000000 --- a/stable/xmlrpc_amconfig.h.in +++ /dev/null @@ -1,37 +0,0 @@ -/* xmlrpc_amconfig.h is generated by 'configure' from the template - xmlrpc_amconfig.h.in, by virtue of the AM_CONFIG_HEADER() macro in - configure.in. - - In the future, we plan to eliminate this file, because it is a special - tool that requires extra learning. Instead, we will just put logic - directly in configure.in like that for wchar.h, etc. -*/ - -/* The following are related to AC_CHECK_FUNCS macro calls in - configure.in -*/ - -#undef HAVE_SETGROUPS -#undef HAVE_ASPRINTF -#undef HAVE_SETENV -#undef HAVE_PSELECT -#undef HAVE_WCSNCMP -#undef HAVE_GETTIMEOFDAY -#undef HAVE_LOCALTIME_R -#undef HAVE_GMTIME_R -#undef HAVE_STRCASECMP -#undef HAVE_STRICMP -#undef HAVE__STRICMP -#undef HAVE_STRTOLL -#undef HAVE_STRTOQ -#undef HAVE___STRTOLL -#undef HAVE_STRTOULL -#undef HAVE_STRTOUQ -#undef HAVE___STRTOULL - - -/* Define if you have the socket library (-lsocket). */ -#undef HAVE_LIBSOCKET - -/* Name of package */ -#undef PACKAGE diff --git a/stable/xmlrpc_config.h.in b/stable/xmlrpc_config.h.in index 3fb24c01e..968c27396 100644 --- a/stable/xmlrpc_config.h.in +++ b/stable/xmlrpc_config.h.in @@ -26,69 +26,30 @@ #ifndef XMLRPC_CONFIG_H_INCLUDED #define XMLRPC_CONFIG_H_INCLUDED -/* We hope to replace xmlrpc_amconfig.h some day with something that - doesn't require a whole special set of software to build, to make - Xmlrpc-c approachable by dumber developers. -*/ -#include "xmlrpc_amconfig.h" - -#ifndef HAVE_SETGROUPS -#define HAVE_SETGROUPS 0 -#endif -#ifndef HAVE_ASPRINTF -#define HAVE_ASPRINTF 0 -#endif -#ifndef HAVE_SETENV -#define HAVE_SETENV 0 -#endif -#ifndef HAVE_PSELECT -#define HAVE_PSELECT 0 -#endif -#ifndef HAVE_WCSNCMP -#define HAVE_WCSNCMP 1 -#endif -#ifndef HAVE_GETTIMEOFDAY -#define HAVE_GETTIMEOFDAY 0 -#endif -#ifndef HAVE_LOCALTIME_R -#define HAVE_LOCALTIME_R 0 -#endif -#ifndef HAVE_GMTIME_R -#define HAVE_GMTIME_R 0 -#endif -#ifndef HAVE_STRCASECMP -#define HAVE_STRCASECMP 0 -#endif -#ifndef HAVE_STRICMP -#define HAVE_STRICMP 0 -#endif -#ifndef HAVE__STRICMP -#define HAVE__STRICMP 0 -#endif -#ifndef HAVE_STRTOLL -#define HAVE_STRTOLL 0 -#endif -#ifndef HAVE_STRTOQ -#define HAVE_STRTOQ 0 -#endif -#ifndef HAVE___STRTOLL -#define HAVE___STRTOLL 0 -#endif -#ifndef HAVE_STRTOUQ -#define HAVE_STRTOUQ 0 -#endif -#ifndef HAVE___STRTOULL -#define HAVE___STRTOULL 0 -#endif -#ifndef HAVE__STRTOUI64 -#define HAVE__STRTOUI64 0 -#endif - #define HAVE_WCHAR_H @HAVE_WCHAR_H_DEFINE@ #define HAVE_SYS_FILIO_H @HAVE_SYS_FILIO_H_DEFINE@ #define HAVE_SYS_IOCTL_H @HAVE_SYS_IOCTL_H_DEFINE@ #define HAVE_SYS_SELECT_H @HAVE_SYS_SELECT_H_DEFINE@ +#define HAVE_WCSNCMP @HAVE_WCSNCMP_DEFINE@ +#define HAVE_SETGROUPS @HAVE_SETGROUPS_DEFINE@ +#define HAVE_ASPRINTF @HAVE_ASPRINTF_DEFINE@ +#define HAVE_SETENV @HAVE_SETENV_DEFINE@ +#define HAVE_STRTOLL @HAVE_STRTOLL_DEFINE@ +#define HAVE_STRTOULL @HAVE_STRTOULL_DEFINE@ +#define HAVE_STRTOQ @HAVE_STRTOQ_DEFINE@ +#define HAVE_STRTOUQ @HAVE_STRTOUQ_DEFINE@ +#define HAVE___STRTOLL @HAVE___STRTOLL_DEFINE@ +#define HAVE___STRTOULL @HAVE___STRTOULL_DEFINE@ +#define HAVE__STRTOUI64 @HAVE__STRTOUI64_DEFINE@ +#define HAVE_PSELECT @HAVE_PSELECT_DEFINE@ +#define HAVE_GETTIMEOFDAY @HAVE_GETTIMEOFDAY_DEFINE@ +#define HAVE_LOCALTIME_R @HAVE_LOCALTIME_R_DEFINE@ +#define HAVE_GMTIME_R @HAVE_GMTIME_R_DEFINE@ +#define HAVE_STRCASECMP @HAVE_STRCASECMP_DEFINE@ +#define HAVE_STRICMP @HAVE_STRICMP_DEFINE@ +#define HAVE__STRICMP @HAVE__STRICMP_DEFINE@ + #define VA_LIST_IS_ARRAY @VA_LIST_IS_ARRAY_DEFINE@ #define HAVE_LIBWWW_SSL @HAVE_LIBWWW_SSL_DEFINE@ @@ -122,10 +83,16 @@ msvcrt.dll. Note that there are other DLLs in the suite, but only the basic msvcrt.dll comes with Windows. - _WIN32, defined by the compiler, means we're using som Microsoft C runtime + _WIN32, defined by the compiler, means we're using some Microsoft C runtime library - it could be either the Microsoft Visual C++ runtime library or an older one. Note that Xmlrpc-c is not supposed to be buildable with an older one, so we have no use for _WIN32. + + WIN32 is a macro that some older compilers predefine (compilers aren't + supposed to because it doesn't start with an underscore, hence the change). + Many build systems (project files, etc.) set WIN32 explicitly for backward + compatibility. Xmlrpc-c has some vestigial uses of it, but we should + remove those. */ #if defined(_MSC_VER) @@ -256,4 +223,20 @@ #define XMLRPC_CHDIR chdir #endif +#if MSVCRT + #define XMLRPC_GETPID _getpid +#else + #define XMLRPC_GETPID getpid +#endif + +#define HAVE_ABYSS_OPENSSL @HAVE_ABYSS_OPENSSL_DEFINE@ + +#if MSVCRT + #define XMLRPC_FINITE _finite +#else + #define XMLRPC_FINITE finite +#endif + + + #endif From c906641ffa3bdc132297db660d04d692f089e6c3 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 02:20:09 +0000 Subject: [PATCH 018/154] Change release number to 1.52.00 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3003 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/version.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/version.mk b/trunk/version.mk index fd6edbade..8faf5b0d1 100644 --- a/trunk/version.mk +++ b/trunk/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 51 +XMLRPC_MINOR_RELEASE = 52 XMLRPC_POINT_RELEASE = 0 From 6c73b19cddd1a824c81cc3af6b1dc5869381ab2d Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 22:33:25 +0000 Subject: [PATCH 019/154] Promote Development to Advanced git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3004 98333e67-4a24-44d7-a75c-e53540dd3050 --- advanced/GNUmakefile | 1 + .../examples/cpp/pstream_serial_server.cpp | 10 +- .../include/xmlrpc-c/client_transport.hpp | 20 +- advanced/lib/abyss/src/http.c | 84 +- advanced/lib/abyss/src/sessionReadRequest.c | 50 +- advanced/lib/expat/Makefile | 2 +- advanced/lib/expat/xmltok/xmltok_impl.c | 1039 +++++++++-------- .../xmlrpc_wininet_transport.c | 108 +- advanced/src/cpp/client.cpp | 44 +- advanced/src/cpp/client_simple.cpp | 16 +- advanced/src/cpp/packetsocket.cpp | 23 +- advanced/src/cpp/value.cpp | 8 - advanced/src/xmlrpc_string.c | 5 - advanced/tools/lib/Makefile | 2 +- advanced/version.mk | 4 +- 15 files changed, 721 insertions(+), 695 deletions(-) diff --git a/advanced/GNUmakefile b/advanced/GNUmakefile index 7d3aff019..ea6ef12c9 100644 --- a/advanced/GNUmakefile +++ b/advanced/GNUmakefile @@ -148,6 +148,7 @@ distclean-local: clean-local rm -f config.log config.status config.mk srcdir.mk rm -f xmlrpc_config.h xmlrpc_amconfig.h stamp-h rm -f shell_config xmlrpc-c-config xmlrpc-c-config.test + rm -rf autom4te.cache # gets created by 'autoconf' rm -f TAGS check: $(SUBDIRS:%=%/check) diff --git a/advanced/examples/cpp/pstream_serial_server.cpp b/advanced/examples/cpp/pstream_serial_server.cpp index 73d96c282..ae73a819b 100644 --- a/advanced/examples/cpp/pstream_serial_server.cpp +++ b/advanced/examples/cpp/pstream_serial_server.cpp @@ -42,20 +42,20 @@ class sampleAddMethod : public xmlrpc_c::method { void execute(xmlrpc_c::paramList const& paramList, xmlrpc_c::value * const retvalP) { - + int const addend(paramList.getInt(0)); int const adder(paramList.getInt(1)); - + paramList.verifyEnd(2); - + *retvalP = xmlrpc_c::value_int(addend + adder); } }; -int -main(int const, +int +main(int const, const char ** const) { #ifndef _WIN32 diff --git a/advanced/include/xmlrpc-c/client_transport.hpp b/advanced/include/xmlrpc-c/client_transport.hpp index 4c6c87e1f..9b1bdd9e4 100644 --- a/advanced/include/xmlrpc-c/client_transport.hpp +++ b/advanced/include/xmlrpc-c/client_transport.hpp @@ -86,7 +86,7 @@ class XMLRPC_CLIENTPP_EXPORTED xmlTransactionPtr : public girmem::autoObjectPtr xmlTransactionPtr(); xmlTransactionPtr(xmlTransaction * xmlTransP); - + xmlrpc_c::xmlTransaction * operator->() const; }; @@ -133,7 +133,7 @@ class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport : public girmem::autoObject { }; class XMLRPC_CLIENTPP_EXPORTED clientXmlTransportPtr : public girmem::autoObjectPtr { - + public: clientXmlTransportPtr(); @@ -166,25 +166,25 @@ class XMLRPC_CLIENTPP_EXPORTED carriageParm_http0 : public xmlrpc_c::carriagePar void disallowAuthBasic(); - + void allowAuthDigest(); void disallowAuthDigest(); - + void allowAuthNegotiate(); void disallowAuthNegotiate(); - + void allowAuthNtlm(); void disallowAuthNtlm(); - + void setBasicAuth(std::string const userid, std::string const password); @@ -219,17 +219,17 @@ class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_http : public xmlrpc_c::client -----------------------------------------------------------------------------*/ 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); @@ -350,7 +350,7 @@ class XMLRPC_CLIENTPP_EXPORTED carriageParm_libwww0Ptr : public xmlrpc_c::carria }; class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_libwww : public xmlrpc_c::clientXmlTransport_http { - + public: clientXmlTransport_libwww(std::string const appname = "", std::string const appversion = ""); diff --git a/advanced/lib/abyss/src/http.c b/advanced/lib/abyss/src/http.c index 815906e45..f61c9928c 100644 --- a/advanced/lib/abyss/src/http.c +++ b/advanced/lib/abyss/src/http.c @@ -63,7 +63,7 @@ HTTPRequestHasValidUri(TSession * const sessionP) { if (!sessionP->requestInfo.uri) return false; - + if (xmlrpc_streq(sessionP->requestInfo.uri, "*")) return (sessionP->requestInfo.method != m_options); @@ -154,13 +154,13 @@ RequestAuth(TSession * const sessionP, if (xmlrpc_strcaseeq(authType, "basic")) { const char * userPass; char userPassEncoded[80]; - + NextToken((const char **)&authHdrPtr); - + xmlrpc_asprintf(&userPass, "%s:%s", user, pass); xmlrpc_base64Encode(userPass, userPassEncoded); xmlrpc_strfree(userPass); - + if (xmlrpc_streq(authHdrPtr, userPassEncoded)) { sessionP->requestInfo.user = xmlrpc_strdupsol(user); authorized = true; @@ -245,42 +245,42 @@ HTTPReasonByStatus(uint16_t const code) { }; static struct _HTTPReasons const reasons[] = { - { 100,"Continue" }, - { 101,"Switching Protocols" }, - { 200,"OK" }, - { 201,"Created" }, - { 202,"Accepted" }, - { 203,"Non-Authoritative Information" }, - { 204,"No Content" }, - { 205,"Reset Content" }, - { 206,"Partial Content" }, - { 300,"Multiple Choices" }, - { 301,"Moved Permanently" }, - { 302,"Moved Temporarily" }, - { 303,"See Other" }, - { 304,"Not Modified" }, - { 305,"Use Proxy" }, - { 400,"Bad Request" }, - { 401,"Unauthorized" }, - { 402,"Payment Required" }, - { 403,"Forbidden" }, - { 404,"Not Found" }, - { 405,"Method Not Allowed" }, - { 406,"Not Acceptable" }, - { 407,"Proxy Authentication Required" }, - { 408,"Request Timeout" }, - { 409,"Conflict" }, - { 410,"Gone" }, - { 411,"Length Required" }, - { 412,"Precondition Failed" }, - { 413,"Request Entity Too Large" }, - { 414,"Request-URI Too Long" }, - { 415,"Unsupported Media Type" }, - { 500,"Internal Server Error" }, - { 501,"Not Implemented" }, - { 502,"Bad Gateway" }, - { 503,"Service Unavailable" }, - { 504,"Gateway Timeout" }, + { 100,"Continue" }, + { 101,"Switching Protocols" }, + { 200,"OK" }, + { 201,"Created" }, + { 202,"Accepted" }, + { 203,"Non-Authoritative Information" }, + { 204,"No Content" }, + { 205,"Reset Content" }, + { 206,"Partial Content" }, + { 300,"Multiple Choices" }, + { 301,"Moved Permanently" }, + { 302,"Moved Temporarily" }, + { 303,"See Other" }, + { 304,"Not Modified" }, + { 305,"Use Proxy" }, + { 400,"Bad Request" }, + { 401,"Unauthorized" }, + { 402,"Payment Required" }, + { 403,"Forbidden" }, + { 404,"Not Found" }, + { 405,"Method Not Allowed" }, + { 406,"Not Acceptable" }, + { 407,"Proxy Authentication Required" }, + { 408,"Request Timeout" }, + { 409,"Conflict" }, + { 410,"Gone" }, + { 411,"Length Required" }, + { 412,"Precondition Failed" }, + { 413,"Request Entity Too Large" }, + { 414,"Request-URI Too Long" }, + { 415,"Unsupported Media Type" }, + { 500,"Internal Server Error" }, + { 501,"Not Implemented" }, + { 502,"Bad Gateway" }, + { 503,"Service Unavailable" }, + { 504,"Gateway Timeout" }, { 505,"HTTP Version Not Supported" }, { 000, NULL } }; @@ -360,7 +360,7 @@ bool HTTPWriteContinue(TSession * const sessionP) { char const continueStatus[] = "HTTP/1.1 100 continue\r\n\r\n"; - /* This is a status line plus an end-of-headers empty line */ + /* This is a status line plus an end-of-header empty line */ return ConnWrite(sessionP->connP, continueStatus, strlen(continueStatus)); } @@ -384,7 +384,7 @@ HTTPWriteContinue(TSession * const sessionP) { ** 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 diff --git a/advanced/lib/abyss/src/sessionReadRequest.c b/advanced/lib/abyss/src/sessionReadRequest.c index 0b77d3ff7..bad3f06f8 100644 --- a/advanced/lib/abyss/src/sessionReadRequest.c +++ b/advanced/lib/abyss/src/sessionReadRequest.c @@ -133,7 +133,7 @@ getLineInBuffer(TConn * const connectionP, } } } - } + } *lineEndP = lfPos + 1; *timedOutP = timedOut; } @@ -206,7 +206,7 @@ getRestOfField(TConn * const connectionP, bool timedOut; fieldEnd = lineEnd; /* initial value - end of 1st line */ - + for (gotWholeField = false, timedOut = false, *errorP = NULL; !gotWholeField && !timedOut && !*errorP;) { @@ -214,7 +214,7 @@ getRestOfField(TConn * const connectionP, /* Note that we are guaranteed, assuming the HTTP stream is valid, that there is at least one more line in it. Worst - case, it's the empty line that marks the end of the headers. + case, it's the empty line that marks the end of the header. */ getLineInBuffer(connectionP, fieldEnd, deadline, &nextLineEnd, &timedOut, errorP); @@ -258,7 +258,7 @@ readField(TConn * const connectionP, call that empty line the EOH mark. We assume the connection is positioned to a header or EOH mark. - + In the course of reading, we read at least one character past the line delimiter at the end of the field or EOH mark; we may read much more. But we leave everything after the field or EOH (and @@ -340,7 +340,7 @@ skipToNonemptyLine(TConn * const connectionP, bool gotNonEmptyLine; char * lineStart; - + for (lineStart = bufferStart, gotNonEmptyLine = false, *timedOutP = false, *errorP = NULL; !gotNonEmptyLine && !*timedOutP && !*errorP; ) { @@ -380,7 +380,7 @@ readRequestField(TSession * const sessionP, We assume the connection is presently positioned to the beginning of the HTTP document. We leave it positioned after the request field. - + We ignore any empty lines at the beginning of the stream, per RFC2616 Section 4.1. @@ -418,7 +418,7 @@ readRequestField(TSession * const sessionP, encountered EOH: */ assert(!endOfHeader); - + *requestLineP = line; } } @@ -475,15 +475,15 @@ parsePerCentEscape(const char ** const srcP, *errorP = NULL; /* initial assumption */ hexDigitValue(*src++, &digit0, errorP); - + if (!*errorP) { unsigned int digit1; - + if (!*src) xmlrpc_asprintf(errorP, "URI ends after the first digit"); else { hexDigitValue(*src++, &digit1, errorP); - + if (!*errorP) *unescapedP = ((digit0 << 4) | digit1); } @@ -516,7 +516,7 @@ unescapeUri(const char * const uriComponent, char * dst; src = dst = buffer; - + *errorP = NULL; /* initial value */ while (*src && !*errorP) { @@ -588,7 +588,7 @@ parseHostPort(const char * const hostport, for (p = colonPos + 1, port = 0; isdigit(*p) && port < 65535; (port = port * 10 + (*p - '0')), ++p); - + if (*p || port == 0) { xmlrpc_asprintf(errorP, "There is nothing, or something " "non-numeric for the port number after the " @@ -626,7 +626,7 @@ splitUriQuery(const char * const requestUri, xmlrpc_asprintf(errorP, "Couldn't get memory for URI buffer"); else { char * const qmark = strchr(buffer, '?'); - + if (qmark) { *qmark = '\0'; *queryP = xmlrpc_strdupsol(qmark + 1); @@ -660,7 +660,7 @@ parseHttpHostPortPath(const char * const hostportpath, char * const slashPos = strchr(buffer, '/'); char * hostport; - + if (slashPos) { path = xmlrpc_strdupsol(slashPos); /* Includes the initial slash */ @@ -897,9 +897,9 @@ parseRequestLine(char * const requestLine, const char * httpVersion; NextToken((const char **)&p); - + /* HTTP Version Decoding */ - + httpVersion = GetToken(&p); if (httpVersion) { const char * error; @@ -972,7 +972,7 @@ getFieldNameToken(char ** const pP, char * fieldName; NextToken((const char **)pP); - + fieldName = GetToken(pP); if (!fieldName) { xmlrpc_asprintf(errorP, "The header has no field name token"); @@ -987,7 +987,7 @@ getFieldNameToken(char ** const pP, fieldName[strlen(fieldName)-1] = '\0'; /* remove trailing colon */ strtolower(fieldName); - + *errorP = NULL; } } @@ -1112,14 +1112,14 @@ readAndProcessHeaderFields(TSession * const sessionP, getFieldNameToken(&p, &fieldName, errorP, httpErrorCodeP); if (!*errorP) { char * fieldValue; - + NextToken((const char **)&p); - + fieldValue = p; TableAdd(&sessionP->requestHeaderFields, fieldName, fieldValue); - + processField(fieldName, fieldValue, sessionP, errorP, httpErrorCodeP); } @@ -1136,19 +1136,19 @@ SessionReadRequest(TSession * const sessionP, const char ** const errorP, uint16_t * const httpErrorCodeP) { /*---------------------------------------------------------------------------- - Read the headers of a new HTTP request (assuming nothing has yet been + Read the header of a new HTTP request (assuming nothing has yet been read on the session). - Update *sessionP with the information from the headers. + Update *sessionP with the information from the header. Leave the connection positioned to the body of the request, ready to be read by an HTTP request handler (via SessionRefillBuffer() and SessionGetReadData()). - If we are unable to read the headers, we return a text description as + If we are unable to read the header, we return a text description as *errorP and a suitable HTTP status code as *httpErrorCodeP. - If we successfully read the headers, we return *errorP == NULL and + If we successfully read the header, we return *errorP == NULL and nothing as *httpErrorCodeP. -----------------------------------------------------------------------------*/ time_t const deadline = time(NULL) + timeout; diff --git a/advanced/lib/expat/Makefile b/advanced/lib/expat/Makefile index cf2355302..d8828ff2a 100644 --- a/advanced/lib/expat/Makefile +++ b/advanced/lib/expat/Makefile @@ -46,7 +46,7 @@ xmlrpc_expat.pc: clean: $(SUBDIRS:%=%/clean) clean-common .PHONY: distclean -distclean: $(SUBDIRS:%=%/distclean) distclean-common +distclean: $(SUBDIRS:%=%/distclean) clean-common distclean-common .PHONY: tags tags: $(SUBDIRS:%=%/tags) TAGS diff --git a/advanced/lib/expat/xmltok/xmltok_impl.c b/advanced/lib/expat/xmltok/xmltok_impl.c index d0355275f..cf0091d1d 100644 --- a/advanced/lib/expat/xmltok/xmltok_impl.c +++ b/advanced/lib/expat/xmltok/xmltok_impl.c @@ -21,7 +21,7 @@ See the file copying.txt for copying permission. #define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ case BT_LEAD ## n: \ if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ + return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n)) { \ *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; \ @@ -100,7 +100,7 @@ See the file copying.txt for copying permission. static int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr != end) { if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { @@ -110,24 +110,24 @@ int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); case BT_MINUS: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_COMMENT; - } - break; + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_COMMENT; + } + break; default: - ptr += MINBPC(enc); - break; + ptr += MINBPC(enc); + break; } } } @@ -138,7 +138,7 @@ int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; @@ -160,14 +160,16 @@ int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, switch (BYTE_TYPE(enc, ptr)) { case BT_PERCNT: if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; /* don't allow */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } - /* fall through */ + *nextTokPtr = ptr; + return XML_TOK_DECL_OPEN; + break; case BT_S: case BT_CR: case BT_LF: *nextTokPtr = ptr; return XML_TOK_DECL_OPEN; @@ -184,9 +186,9 @@ int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, } static -int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, - const char * end, +int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, + const char * end, int * tokPtr) { int upper = 0; @@ -232,58 +234,60 @@ int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, static int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int tok; const char *target = ptr; if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } ptr += MINBPC(enc); while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); - case BT_QUEST: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr + MINBPC(enc); - return tok; - } - break; - default: - ptr += MINBPC(enc); - break; - } + INVALID_CASES(ptr, nextTokPtr); + case BT_QUEST: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + *nextTokPtr = ptr + MINBPC(enc); + return tok; + } + break; + default: + ptr += MINBPC(enc); + break; + } } return XML_TOK_PARTIAL; case BT_QUEST: if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr + MINBPC(enc); - return tok; + *nextTokPtr = ptr + MINBPC(enc); + return tok; } - /* fall through */ + *nextTokPtr = ptr; + return XML_TOK_INVALID; + break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; @@ -294,8 +298,8 @@ int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end, static -int PREFIX(scanCdataSection)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, +int PREFIX(scanCdataSection)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, const char * end, const char ** nextTokPtr) { @@ -316,7 +320,7 @@ int PREFIX(scanCdataSection)(const ENCODING * enc ATTR_UNUSED, static int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_NONE; @@ -325,7 +329,7 @@ int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *en if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; end = ptr + n; } } @@ -356,22 +360,22 @@ int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *en case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); default: ptr += MINBPC(enc); break; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NONXML: case BT_MALFORM: @@ -394,35 +398,35 @@ int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *en static int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_CR: case BT_LF: - break; - case BT_GT: - *nextTokPtr = ptr + MINBPC(enc); + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: case BT_CR: case BT_LF: + break; + case BT_GT: + *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_END_TAG; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } } return XML_TOK_PARTIAL; case BT_COLON: - /* no need to check qname syntax here, since end-tag must match exactly */ + /* no need to check qname syntax here, since end-tag must match exactly*/ ptr += MINBPC(enc); break; case BT_GT: @@ -440,7 +444,7 @@ int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { @@ -455,13 +459,13 @@ int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: - break; + break; case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CHAR_REF; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CHAR_REF; default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } } } @@ -472,7 +476,7 @@ int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end static int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr != end) { if (CHAR_MATCHES(enc, ptr, ASCII_x)) @@ -487,13 +491,13 @@ int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: - break; + break; case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CHAR_REF; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CHAR_REF; default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } } } @@ -504,12 +508,12 @@ int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_NUM: return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); default: @@ -518,7 +522,7 @@ int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_ENTITY_REF; @@ -534,148 +538,148 @@ int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int hadColon = 0; while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_COLON: if (hadColon) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } hadColon = 1; ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } break; case BT_S: case BT_CR: case BT_LF: for (;;) { - int t; - - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - t = BYTE_TYPE(enc, ptr); - if (t == BT_EQUALS) - break; - switch (t) { - case BT_S: - case BT_LF: - case BT_CR: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } + int t; + + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + t = BYTE_TYPE(enc, ptr); + if (t == BT_EQUALS) + break; + switch (t) { + case BT_S: + case BT_LF: + case BT_CR: + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } } - /* fall through */ + /* fall through */ case BT_EQUALS: - { - int open; - hadColon = 0; - for (;;) { - - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - open = BYTE_TYPE(enc, ptr); - if (open == BT_QUOT || open == BT_APOS) - break; - switch (open) { - case BT_S: - case BT_LF: - case BT_CR: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - ptr += MINBPC(enc); - /* in attribute value */ - for (;;) { - int t; - if (ptr == end) - return XML_TOK_PARTIAL; - t = BYTE_TYPE(enc, ptr); - if (t == open) - break; - switch (t) { - INVALID_CASES(ptr, nextTokPtr); - case BT_AMP: - { - int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr); - if (tok <= 0) { - if (tok == XML_TOK_INVALID) - *nextTokPtr = ptr; - return tok; - } - break; - } - case BT_LT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - default: - ptr += MINBPC(enc); - break; - } - } - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: - case BT_CR: - case BT_LF: - break; - case BT_SOL: - goto sol; - case BT_GT: - goto gt; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - /* ptr points to closing quote */ - for (;;) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_CR: case BT_LF: - continue; - case BT_GT: - gt: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_START_TAG_WITH_ATTS; - case BT_SOL: - sol: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - break; - } - break; + { + int open; + hadColon = 0; + for (;;) { + + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + open = BYTE_TYPE(enc, ptr); + if (open == BT_QUOT || open == BT_APOS) + break; + switch (open) { + case BT_S: + case BT_LF: + case BT_CR: + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + ptr += MINBPC(enc); + /* in attribute value */ + for (;;) { + int t; + if (ptr == end) + return XML_TOK_PARTIAL; + t = BYTE_TYPE(enc, ptr); + if (t == open) + break; + switch (t) { + INVALID_CASES(ptr, nextTokPtr); + case BT_AMP: + { + int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr); + if (tok <= 0) { + if (tok == XML_TOK_INVALID) + *nextTokPtr = ptr; + return tok; + } + break; + } + case BT_LT: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + default: + ptr += MINBPC(enc); + break; + } } + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: + case BT_CR: + case BT_LF: + break; + case BT_SOL: + goto sol; + case BT_GT: + goto gt; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + /* ptr points to closing quote */ + for (;;) { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_S: case BT_CR: case BT_LF: + continue; + case BT_GT: + gt: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_START_TAG_WITH_ATTS; + case BT_SOL: + sol: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + break; + } + break; + } default: *nextTokPtr = ptr; return XML_TOK_INVALID; @@ -688,13 +692,13 @@ int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int hadColon; if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_EXCL: if ((ptr += MINBPC(enc)) == end) return XML_TOK_PARTIAL; @@ -718,44 +722,44 @@ int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, /* we have a start-tag */ while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_COLON: if (hadColon) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } hadColon = 1; ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } break; case BT_S: case BT_CR: case BT_LF: - { - ptr += MINBPC(enc); - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: - goto gt; - case BT_SOL: - goto sol; - case BT_S: case BT_CR: case BT_LF: - ptr += MINBPC(enc); - continue; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); - } - return XML_TOK_PARTIAL; + { + ptr += MINBPC(enc); + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: + goto gt; + case BT_SOL: + goto sol; + case BT_S: case BT_CR: case BT_LF: + ptr += MINBPC(enc); + continue; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); } + return XML_TOK_PARTIAL; + } case BT_GT: gt: *nextTokPtr = ptr + MINBPC(enc); @@ -764,10 +768,10 @@ int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, sol: ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_EMPTY_ELEMENT_NO_ATTS; @@ -927,8 +931,9 @@ PREFIX(contentTok)(const ENCODING * const enc, *nextTokPtr = ptr; return XML_TOK_INVALID; } - } - /* fall through */ + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + } break; case BT_AMP: case BT_LT: case BT_NONXML: @@ -956,12 +961,12 @@ PREFIX(contentTok)(const ENCODING * const enc, static int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_PERCENT; @@ -971,7 +976,7 @@ int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_PARAM_ENTITY_REF; @@ -985,19 +990,19 @@ int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_CR: case BT_LF: case BT_S: case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: *nextTokPtr = ptr; @@ -1012,27 +1017,27 @@ int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanLit)(int open, const ENCODING *enc, - const char *ptr, const char *end, - const char **nextTokPtr) + const char *ptr, const char *end, + const char **nextTokPtr) { while (ptr != end) { int t = BYTE_TYPE(enc, ptr); switch (t) { - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); case BT_QUOT: case BT_APOS: ptr += MINBPC(enc); if (t != open) - break; + break; if (ptr == end) - return -XML_TOK_LITERAL; + return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: case BT_GT: case BT_PERCNT: case BT_LSQB: - return XML_TOK_LITERAL; + return XML_TOK_LITERAL; default: - return XML_TOK_INVALID; + return XML_TOK_INVALID; } default: ptr += MINBPC(enc); @@ -1044,7 +1049,7 @@ int PREFIX(scanLit)(int open, const ENCODING *enc, static int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int tok; if (ptr == end) @@ -1054,7 +1059,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; end = ptr + n; } } @@ -1064,27 +1069,27 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_APOS: return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_LT: - { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_EXCL: - return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_QUEST: - return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_NMSTRT: - case BT_HEX: - case BT_NONASCII: - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - *nextTokPtr = ptr - MINBPC(enc); - return XML_TOK_INSTANCE_START; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; + { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_EXCL: + return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_QUEST: + return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_NMSTRT: + case BT_HEX: + case BT_NONASCII: + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + *nextTokPtr = ptr - MINBPC(enc); + return XML_TOK_INSTANCE_START; } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } case BT_CR: if (ptr + MINBPC(enc) == end) return -XML_TOK_PROLOG_S; @@ -1093,18 +1098,20 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, for (;;) { ptr += MINBPC(enc); if (ptr == end) - break; + break; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_LF: - break; + break; case BT_CR: - /* don't split CR/LF pair */ - if (ptr + MINBPC(enc) != end) - break; - /* fall through */ + /* don't split CR/LF pair */ + if (ptr + MINBPC(enc) == end) { + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + } + break; default: - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; } } *nextTokPtr = ptr; @@ -1123,10 +1130,10 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { - *nextTokPtr = ptr + 2*MINBPC(enc); - return XML_TOK_COND_SECT_CLOSE; + *nextTokPtr = ptr + 2*MINBPC(enc); + return XML_TOK_COND_SECT_CLOSE; } } *nextTokPtr = ptr; @@ -1164,22 +1171,22 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_DECL_CLOSE; case BT_NUM: return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NAME; \ - break; \ - } \ - if (IS_NAME_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NMTOKEN; \ - break; \ - } \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ + break; \ + } \ + if (IS_NAME_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NMTOKEN; \ + break; \ + } \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NMSTRT: @@ -1203,72 +1210,74 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, if (IS_NAME_CHAR_MINBPC(enc, ptr)) { ptr += MINBPC(enc); tok = XML_TOK_NMTOKEN; - break; + } else { + *nextTokPtr = ptr; + return XML_TOK_INVALID; } - /* fall through */ + break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } - while (ptr != end) { + while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: case BT_RPAR: case BT_COMMA: - case BT_VERBAR: case BT_LSQB: case BT_PERCNT: - case BT_S: case BT_CR: case BT_LF: - *nextTokPtr = ptr; - return tok; - case BT_COLON: - ptr += MINBPC(enc); - switch (tok) { - case XML_TOK_NAME: - if (ptr == end) - return XML_TOK_PARTIAL; - tok = XML_TOK_PREFIXED_NAME; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - default: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case XML_TOK_PREFIXED_NAME: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case BT_PLUS: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_PLUS; - case BT_AST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_ASTERISK; - case BT_QUEST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_QUESTION; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } + case BT_GT: case BT_RPAR: case BT_COMMA: + case BT_VERBAR: case BT_LSQB: case BT_PERCNT: + case BT_S: case BT_CR: case BT_LF: + *nextTokPtr = ptr; + return tok; + case BT_COLON: + ptr += MINBPC(enc); + switch (tok) { + case XML_TOK_NAME: + if (ptr == end) + return XML_TOK_PARTIAL; + tok = XML_TOK_PREFIXED_NAME; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + default: + tok = XML_TOK_NMTOKEN; + break; } - return -tok; + break; + case XML_TOK_PREFIXED_NAME: + tok = XML_TOK_NMTOKEN; + break; + } + break; + case BT_PLUS: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_PLUS; + case BT_AST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_ASTERISK; + case BT_QUEST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_QUESTION; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -tok; } static int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { const char *start; if (ptr == end) @@ -1282,7 +1291,7 @@ int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char * #undef LEAD_CASE case BT_AMP: if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LT: @@ -1291,27 +1300,27 @@ int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char * return XML_TOK_INVALID; case BT_LF: if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_S: if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_ATTRIBUTE_VALUE_S; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_ATTRIBUTE_VALUE_S; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; @@ -1326,7 +1335,7 @@ int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char * static int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { const char *start; if (ptr == end) @@ -1340,30 +1349,30 @@ int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end #undef LEAD_CASE case BT_AMP: if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_PERCNT: if (ptr == start) - return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LF: if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; @@ -1380,7 +1389,7 @@ int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end static int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int level = 0; if (MINBPC(enc) > 1) { @@ -1392,33 +1401,33 @@ int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *e } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); case BT_LT: if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { - ++level; - ptr += MINBPC(enc); - } + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { + ++level; + ptr += MINBPC(enc); + } } break; case BT_RSQB: if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr += MINBPC(enc); - if (level == 0) { - *nextTokPtr = ptr; - return XML_TOK_IGNORE_SECT; - } - --level; - } + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr += MINBPC(enc); + if (level == 0) { + *nextTokPtr = ptr; + return XML_TOK_IGNORE_SECT; + } + --level; + } } break; default: @@ -1431,9 +1440,23 @@ int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *e +static bool +PREFIX(isSpecialChar)(char const c) { + + switch (c) { + case 0x24: /* $ */ + case 0x40: /* @ */ + return true; + default: + return false; + } +} + + + static int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, - const char **badPtr) + const char **badPtr) { ptr += MINBPC(enc); end -= MINBPC(enc); @@ -1461,51 +1484,51 @@ int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, break; case BT_S: if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { - *badPtr = ptr; - return 0; + *badPtr = ptr; + return 0; } break; case BT_NAME: case BT_NMSTRT: - if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) - break; - default: - switch (BYTE_TO_ASCII(enc, ptr)) { - case 0x24: /* $ */ - case 0x40: /* @ */ - break; - default: - *badPtr = ptr; - return 0; + if (BYTE_TO_ASCII(enc, ptr) & ~0x7f) { + if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { + *badPtr = ptr; + return 0; + } } break; + default: + if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { + *badPtr = ptr; + return 0; + } } } return 1; } /* This must only be called for a well-formed start-tag or empty element tag. -Returns the number of attributes. Pointers to the first attsMax attributes +Returns the number of attributes. Pointers to the first attsMax attributes are stored in atts. */ static int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, - int attsMax, ATTRIBUTE *atts) + int attsMax, ATTRIBUTE *atts) { enum { other, inName, inValue } state = inName; int nAtts = 0; int open = 0; /* defined when state == inValue; - initialization just to shut up compilers */ + initialization just to shut up compilers */ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { #define START_NAME \ if (state == other) { \ - if (nAtts < attsMax) { \ - atts[nAtts].name = ptr; \ - atts[nAtts].normalized = 1; \ - } \ - state = inName; \ + if (nAtts < attsMax) { \ + atts[nAtts].name = ptr; \ + atts[nAtts].normalized = 1; \ + } \ + state = inName; \ } #define LEAD_CASE(n) \ case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; @@ -1519,47 +1542,47 @@ int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, #undef START_NAME case BT_QUOT: if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_QUOT; } else if (open == BT_QUOT) { state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; } break; case BT_APOS: if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_APOS; } else if (open == BT_APOS) { state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; } break; case BT_AMP: if (nAtts < attsMax) - atts[nAtts].normalized = 0; + atts[nAtts].normalized = 0; break; case BT_S: if (state == inName) state = other; else if (state == inValue - && nAtts < attsMax - && atts[nAtts].normalized - && (ptr == atts[nAtts].valuePtr - || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE - || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE - || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) - atts[nAtts].normalized = 0; + && nAtts < attsMax + && atts[nAtts].normalized + && (ptr == atts[nAtts].valuePtr + || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE + || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE + || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) + atts[nAtts].normalized = 0; break; case BT_CR: case BT_LF: /* This case ensures that the first attribute name is counted @@ -1567,12 +1590,12 @@ int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, if (state == inName) state = other; else if (state == inValue && nAtts < attsMax) - atts[nAtts].normalized = 0; + atts[nAtts].normalized = 0; break; case BT_GT: case BT_SOL: if (state != inValue) - return nAtts; + return nAtts; break; default: break; @@ -1593,20 +1616,20 @@ int PREFIX(charRefNumber)(const ENCODING *enc ATTR_UNUSED, const char *ptr) switch (c) { case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: - result <<= 4; - result |= (c - ASCII_0); - break; + result <<= 4; + result |= (c - ASCII_0); + break; case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F: - result <<= 4; - result += 10 + (c - ASCII_A); - break; + result <<= 4; + result += 10 + (c - ASCII_A); + break; case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f: - result <<= 4; - result += 10 + (c - ASCII_a); - break; + result <<= 4; + result += 10 + (c - ASCII_a); + break; } if (result >= 0x110000) - return -1; + return -1; } } else { @@ -1615,15 +1638,15 @@ int PREFIX(charRefNumber)(const ENCODING *enc ATTR_UNUSED, const char *ptr) result *= 10; result += (c - ASCII_0); if (result >= 0x110000) - return -1; + return -1; } } return checkCharRefNumber(result); } static -int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, +int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, const char * end) { switch ((end - ptr)/MINBPC(enc)) { @@ -1631,9 +1654,9 @@ int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_l: - return ASCII_LT; + return ASCII_LT; case ASCII_g: - return ASCII_GT; + return ASCII_GT; } } break; @@ -1641,9 +1664,9 @@ int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, if (CHAR_MATCHES(enc, ptr, ASCII_a)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_m)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_p)) - return ASCII_AMP; + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) + return ASCII_AMP; } } break; @@ -1652,23 +1675,23 @@ int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, case ASCII_q: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_u)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_t)) - return ASCII_QUOT; - } + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_t)) + return ASCII_QUOT; + } } break; case ASCII_a: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_p)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_s)) - return ASCII_APOS; - } + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_s)) + return ASCII_APOS; + } } break; } @@ -1681,15 +1704,29 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) { for (;;) { switch (BYTE_TYPE(enc, ptr1)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (*ptr1++ != *ptr2++) \ - return 0; - LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) -#undef LEAD_CASE - /* fall through */ + case BT_LEAD4: if (*ptr1++ != *ptr2++) - return 0; + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_LEAD3: + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_LEAD2: + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; break; case BT_NONASCII: case BT_NMSTRT: @@ -1699,23 +1736,23 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) case BT_NAME: case BT_MINUS: if (*ptr2++ != *ptr1++) - return 0; + return 0; if (MINBPC(enc) > 1) { - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 2) { - if (*ptr2++ != *ptr1++) - return 0; + if (*ptr2++ != *ptr1++) + return 0; + if (MINBPC(enc) > 2) { + if (*ptr2++ != *ptr1++) + return 0; if (MINBPC(enc) > 3) { - if (*ptr2++ != *ptr1++) - return 0; - } - } + if (*ptr2++ != *ptr1++) + return 0; + } + } } break; default: if (MINBPC(enc) == 1 && *ptr1 == *ptr2) - return 1; + return 1; switch (BYTE_TYPE(enc, ptr2)) { case BT_LEAD2: case BT_LEAD3: @@ -1727,9 +1764,9 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) case BT_DIGIT: case BT_NAME: case BT_MINUS: - return 0; + return 0; default: - return 1; + return 1; } } } @@ -1737,9 +1774,9 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) } static -int PREFIX(nameMatchesAscii)(const ENCODING * enc ATTR_UNUSED, +int PREFIX(nameMatchesAscii)(const ENCODING * enc ATTR_UNUSED, const char * ptr1, - const char * end1, + const char * end1, const char * ptr2) { for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { diff --git a/advanced/lib/wininet_transport/xmlrpc_wininet_transport.c b/advanced/lib/wininet_transport/xmlrpc_wininet_transport.c index f990afb7b..858a7b461 100644 --- a/advanced/lib/wininet_transport/xmlrpc_wininet_transport.c +++ b/advanced/lib/wininet_transport/xmlrpc_wininet_transport.c @@ -3,7 +3,7 @@ =============================================================================== WinInet-based client transport for Xmlrpc-c. Copyright information at the bottom of this file. - + =============================================================================*/ #include "xmlrpc_config.h" @@ -55,14 +55,14 @@ struct xmlrpc_client_transport { struct lock * listLockP; struct list_head rpcList; /* List of all RPCs that exist for this transport. An RPC exists - from the time the user requests it until the time the user + from the time the user requests it until the time the user acknowledges it is done. */ int allowInvalidSSLCerts; /* Flag to specify if we ignore invalid SSL Certificates. If this is set to zero, calling a XMLRPC server with an invalid SSL certificate will fail. This is the default behavior of the other - transports, but invalid certificates were allowed in pre 1.2 + transports, but invalid certificates were allowed in pre 1.2 wininet xmlrpc-c transports. */ }; @@ -72,7 +72,7 @@ typedef struct { HINTERNET hHttpRequest; HINTERNET hURL; INTERNET_PORT nPort; - char szHostName[255]; + char szHostName[255]; char szUrlPath[255]; BOOL bUseSSL; char * headerList; @@ -115,7 +115,7 @@ createWinInetHeaderList(xmlrpc_env * const envP, /* NOTE: A newline is required between each added header */ szHeaderList = malloc(strlen(szContentType) + 17 + strlen(serverP->basicAuthHdrValue) + 1); - + if (szHeaderList == NULL) xmlrpc_faultf(envP, "Couldn't allocate memory for authorization header"); @@ -130,11 +130,11 @@ createWinInetHeaderList(xmlrpc_env * const envP, } else { /* Just the content type header is needed */ szHeaderList = malloc(strlen(szContentType) + 1); - + if (szHeaderList == NULL) xmlrpc_faultf(envP, "Couldn't allocate memory for standard header"); - else + else memcpy(szHeaderList, szContentType, strlen(szContentType) + 1); } *headerListP = szHeaderList; @@ -201,7 +201,7 @@ createWinInetTransaction(xmlrpc_env * const envP, XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP); } } - + if (envP->fault_occurred) free(winInetTransactionP); } @@ -236,7 +236,7 @@ get_wininet_response(xmlrpc_env * const envP, unsigned long dwLen; INTERNET_BUFFERS inetBuffer; unsigned long dwFlags; - unsigned long dwErr; + unsigned long dwErr; unsigned long nExpected; void * body; BOOL bOK; @@ -260,14 +260,14 @@ get_wininet_response(xmlrpc_env * const envP, required by XML-RPC. Following fails if server didn't send it. */ - bOK = HttpQueryInfo(winInetTransactionP->hHttpRequest, - HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, + bOK = HttpQueryInfo(winInetTransactionP->hHttpRequest, + HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, &inetBuffer.dwBufferTotal, &dwLen, NULL); if (!bOK) { LPTSTR pMsg; dwErr = GetLastError (); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -288,7 +288,7 @@ get_wininet_response(xmlrpc_env * const envP, inetBuffer.dwBufferLength = nExpected; InternetQueryDataAvailable(winInetTransactionP->hHttpRequest, &inetBuffer.dwBufferLength, 0, 0); - + /* Read Response from InternetFile */ do { if (inetBuffer.dwBufferLength != 0) @@ -306,8 +306,8 @@ get_wininet_response(xmlrpc_env * const envP, dwErr = 0; } else { LPTSTR pMsg; - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -318,7 +318,7 @@ get_wininet_response(xmlrpc_env * const envP, XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); } } - + if (inetBuffer.dwBufferLength) { TCHAR * const oldBufptr = inetBuffer.lpvBuffer; @@ -327,14 +327,14 @@ get_wininet_response(xmlrpc_env * const envP, /* Adjust inetBuffer.dwBufferLength when it is greater than the */ /* expected end of file */ if (inetBuffer.dwBufferLength > nExpected) - inetBuffer.dwBufferLength = nExpected; + inetBuffer.dwBufferLength = nExpected; } else inetBuffer.dwBufferLength = nExpected; dwErr = 0; } while (nExpected != 0); - /* Add to the response buffer. */ + /* Add to the response buffer. */ xmlrpc_mem_block_append(envP, winInetTransactionP->pResponseData, body, inetBuffer.dwBufferTotal); XMLRPC_FAIL_IF_FAULT(envP); @@ -369,11 +369,11 @@ performWinInetTransaction( pMsgMem = NULL; /* initial value */ reqFlags = INTERNET_FLAG_NO_UI; /* initial value */ - + winInetTransactionP->hURL = - InternetConnect(hSyncInternetSession, + InternetConnect(hSyncInternetSession, winInetTransactionP->szHostName, - winInetTransactionP->nPort, + winInetTransactionP->nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); /* Start our request running. */ @@ -386,14 +386,14 @@ performWinInetTransaction( winInetTransactionP->szUrlPath, "HTTP/1.1", NULL, (const char **)&acceptTypes, reqFlags, 1); - + XMLRPC_FAIL_IF_NULL(winInetTransactionP->hHttpRequest, envP, XMLRPC_INTERNAL_ERROR, "Unable to open the requested URL."); succeeded = HttpAddRequestHeaders(winInetTransactionP->hHttpRequest, - winInetTransactionP->headerList, + winInetTransactionP->headerList, strlen (winInetTransactionP->headerList), HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); @@ -411,9 +411,9 @@ performWinInetTransaction( &dwTimeOut, sizeof(dwTimeOut)); } Again: - /* Send the requested XML remote procedure command */ - succeeded = HttpSendRequest(winInetTransactionP->hHttpRequest, NULL, 0, - winInetTransactionP->pSendData, + /* Send the requested XML remote procedure command */ + succeeded = HttpSendRequest(winInetTransactionP->hHttpRequest, NULL, 0, + winInetTransactionP->pSendData, strlen(winInetTransactionP->pSendData)); if (!succeeded) { LPTSTR pMsg; @@ -422,7 +422,7 @@ performWinInetTransaction( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS, + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -473,13 +473,13 @@ performWinInetTransaction( "for example, if you entered www.server.com " "and the common name " "on the certificate says www.different.com. "); - + reqFlags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID; InternetSetOption(winInetTransactionP->hHttpRequest, INTERNET_OPTION_SECURITY_FLAGS, &reqFlags, sizeof(reqFlags)); - + goto Again; } else pMsg = "The SSL certificate common name " @@ -533,14 +533,14 @@ performWinInetTransaction( } } else - pMsg = (LPTSTR)pMsgMem; + pMsg = (LPTSTR)pMsgMem; XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); } queryLen = sizeof(unsigned long); /* initial value */ - succeeded = HttpQueryInfo(winInetTransactionP->hHttpRequest, + succeeded = HttpQueryInfo(winInetTransactionP->hHttpRequest, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, &winInetTransactionP->http_status, &queryLen, NULL); @@ -548,8 +548,8 @@ performWinInetTransaction( LPTSTR pMsg; lastErr = GetLastError(); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -576,7 +576,7 @@ performWinInetTransaction( winInetTransactionP->http_status, errMsg); goto cleanup; } - /* Read the response. */ + /* Read the response. */ get_wininet_response(envP, winInetTransactionP); XMLRPC_FAIL_IF_FAULT(envP); @@ -618,7 +618,7 @@ createRpcThread(xmlrpc_env * const envP, rc = pthread_create(threadP, NULL, doAsyncRpc, rpcP); switch (rc) { - case 0: + case 0: break; case EAGAIN: xmlrpc_faultf(envP, "pthread_create() failed: " @@ -647,7 +647,7 @@ rpcCreate(xmlrpc_env * const envP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, xmlrpc_mem_block * const responseXmlP, - xmlrpc_transport_asynch_complete complete, + xmlrpc_transport_asynch_complete complete, struct xmlrpc_call_info * const callInfoP, rpc ** const rpcPP) { @@ -662,7 +662,7 @@ rpcCreate(xmlrpc_env * const envP, rpcP->responseXmlP = responseXmlP; rpcP->threadExists = FALSE; - createWinInetTransaction(envP, serverP, callXmlP, responseXmlP, + createWinInetTransaction(envP, serverP, callXmlP, responseXmlP, &rpcP->winInetTransactionP); if (!envP->fault_occurred) { if (complete) { @@ -689,7 +689,7 @@ rpcCreate(xmlrpc_env * const envP, -static void +static void rpcDestroy(rpc * const rpcP) { XMLRPC_ASSERT_PTR_OK(rpcP); @@ -704,10 +704,10 @@ rpcDestroy(rpc * const rpcP) { -static void * -finishRpc(struct list_head * const headerP, +static void * +finishRpc(struct list_head * const headerP, void * const context ATTR_UNUSED) { - + rpc * const rpcP = headerP->itemP; if (rpcP->threadExists) { @@ -715,7 +715,7 @@ finishRpc(struct list_head * const headerP, int result; result = pthread_join(rpcP->thread, &status); - + rpcP->threadExists = FALSE; } @@ -807,7 +807,7 @@ statusCallback (HINTERNET const hInternet, -static void +static void create(xmlrpc_env * const envP, int const flags ATTR_UNUSED, const char * const appname ATTR_UNUSED, @@ -818,7 +818,7 @@ create(xmlrpc_env * const envP, /*---------------------------------------------------------------------------- This does the 'create' operation for a WinInet client transport. -----------------------------------------------------------------------------*/ - const struct xmlrpc_wininet_xportparms * const wininetXportParmsP = + const struct xmlrpc_wininet_xportparms * const wininetXportParmsP = transportparmsP; struct xmlrpc_client_transport * transportP; @@ -828,7 +828,7 @@ create(xmlrpc_env * const envP, xmlrpc_faultf(envP, "Unable to allocate transport descriptor."); else { transportP->listLockP = xmlrpc_lock_create(); - + list_make_empty(&transportP->rpcList); if (hSyncInternetSession == NULL) @@ -849,7 +849,7 @@ create(xmlrpc_env * const envP, -static void +static void destroy(struct xmlrpc_client_transport * const clientTransportP) { /*---------------------------------------------------------------------------- This does the 'destroy' operation for a WinInet client transport. @@ -869,8 +869,8 @@ destroy(struct xmlrpc_client_transport * const clientTransportP) { -static void -sendRequest(xmlrpc_env * const envP, +static void +sendRequest(xmlrpc_env * const envP, struct xmlrpc_client_transport * const clientTransportP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, @@ -905,7 +905,7 @@ sendRequest(xmlrpc_env * const envP, -static void +static void finishAsynch(struct xmlrpc_client_transport * const clientTransportP, xmlrpc_timeoutType const timeoutType ATTR_UNUSED, xmlrpc_timeout const timeout ATTR_UNUSED) { @@ -950,9 +950,9 @@ call(xmlrpc_env * const envP, if (!envP->fault_occurred) { performWinInetTransaction(envP, rpcP->winInetTransactionP, clientTransportP); - + *responsePP = responseXmlP; - + rpcDestroy(rpcP); } if (envP->fault_occurred) @@ -986,8 +986,8 @@ struct xmlrpc_client_transport_ops xmlrpc_wininet_transport_ops = { ** 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. -** +** 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 diff --git a/advanced/src/cpp/client.cpp b/advanced/src/cpp/client.cpp index 6b7d27a50..0e8184c14 100644 --- a/advanced/src/cpp/client.cpp +++ b/advanced/src/cpp/client.cpp @@ -48,7 +48,7 @@ throwIfError(env_wrap const& env) { class memblockStringWrapper { -public: +public: memblockStringWrapper(string const value) { env_wrap env; @@ -60,7 +60,7 @@ class memblockStringWrapper { value.c_str(), value.size()); throwIfError(env); } - + memblockStringWrapper(xmlrpc_mem_block * const memblockP) : memblockP(memblockP) {}; @@ -96,7 +96,7 @@ struct client_xml_impl { transportPtr(transportPtr), dialect(dialect) {} }; - + carriageParm::carriageParm() {} @@ -160,7 +160,7 @@ carriageParm_http0::instantiate(string const serverUrl) { if (c_serverInfoP) throw(error("object already instantiated")); - + env_wrap env; this->c_serverInfoP = @@ -323,7 +323,7 @@ carriageParm_http0::setBasicAuth(string const username, if (!this->c_serverInfoP) throw(error("object not instantiated")); - + env_wrap env; xmlrpc_server_info_set_basic_auth( @@ -388,7 +388,7 @@ xmlTransactionPtr::xmlTransactionPtr() {} xmlTransactionPtr::xmlTransactionPtr(xmlTransaction * xmlTransP) : autoObjectPtr(xmlTransP) {} - + xmlTransaction * @@ -428,7 +428,7 @@ struct xmlTranCtl { callXml.c_str(), callXml.size()); throwIfError(env); } - + ~xmlTranCtl() { XMLRPC_MEMBLOCK_FREE(char, this->callXmlP); } @@ -455,7 +455,7 @@ clientXmlTransport::start(carriageParm * const carriageParmP, // Note: derived class clientXmlTransport_http overrides this, // so it doesn't normally get used. - + string responseXml; this->call(carriageParmP, callXml, &responseXml); @@ -593,7 +593,7 @@ clientXmlTransport_http::call( memblockStringWrapper responseHolder(responseXmlMP); // Makes responseXmlMP get freed at end of scope - + *responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlMP), XMLRPC_MEMBLOCK_SIZE(char, responseXmlMP)); } @@ -869,7 +869,7 @@ client_xml::call(carriageParm * const carriageParmP, string responseXml; xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); - + xml::trace("XML-RPC CALL", callXml); try { @@ -879,7 +879,7 @@ client_xml::call(carriageParm * const carriageParmP, "get XML response back. %s", e.what()); } xml::trace("XML-RPC RESPONSE", responseXml); - + try { xml::parseResponse(responseXml, outcomeP); } catch (exception const& e) { @@ -887,7 +887,7 @@ client_xml::call(carriageParm * const carriageParmP, e.what()); } } - + void @@ -899,14 +899,14 @@ client_xml::start(carriageParm * const carriageParmP, string callXml; xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); - + xml::trace("XML-RPC CALL", callXml); xmlTransaction_clientPtr const xmlTranP(tranP); this->implP->transportP->start(carriageParmP, callXml, xmlTranP); } - + void @@ -1008,14 +1008,14 @@ struct rpc_impl { rpc::rpc(string const methodName, paramList const& paramList) { - + this->implP = new rpc_impl(methodName, paramList); } rpc::~rpc() { - + if (this->implP->state == rpc_impl::STATE_ERROR) delete(this->implP->errorP); @@ -1051,11 +1051,11 @@ rpc::call(connection const& connection) { } - + void rpc::start(client * const clientP, carriageParm * const carriageParmP) { - + if (this->implP->state != rpc_impl::STATE_UNFINISHED) throw(error("Attempt to execute an RPC that has already been " "executed")); @@ -1067,10 +1067,10 @@ rpc::start(client * const clientP, } - + void rpc::start(xmlrpc_c::connection const& connection) { - + this->start(connection.clientP, connection.carriageParmP); } @@ -1129,7 +1129,7 @@ rpc::progress(struct xmlrpc_progress_data const&) const { -----------------------------------------------------------------------------*/ } - + value @@ -1230,7 +1230,7 @@ xmlTransaction_client::finish(string const& responseXml) const { try { rpcOutcome outcome; - + xml::parseResponse(responseXml, &outcome); this->tranP->finish(outcome); diff --git a/advanced/src/cpp/client_simple.cpp b/advanced/src/cpp/client_simple.cpp index 2bb2ec6ed..abd198452 100644 --- a/advanced/src/cpp/client_simple.cpp +++ b/advanced/src/cpp/client_simple.cpp @@ -36,7 +36,7 @@ class cValueWrapper { clientSimple::clientSimple() { - + clientXmlTransportPtr const transportP(clientXmlTransport_http::create()); this->clientP = clientPtr(new client_xml(transportP)); @@ -54,7 +54,7 @@ clientSimple::call(string const serverUrl, rpcPtr rpcPtr(methodName, paramList()); rpcPtr->call(this->clientP.get(), &carriageParm); - + *resultP = rpcPtr->getResult(); } @@ -65,7 +65,7 @@ void makeParamArray(string const format, xmlrpc_value ** const paramArrayPP, va_list args) { - + env_wrap env; /* The format is a sequence of parameter specifications, such as @@ -120,10 +120,10 @@ clientSimple::call(string const serverUrl, cValueWrapper paramArrayWrapper(paramArrayP); // ensure destruction unsigned int const paramCount( xmlrpc_array_size(&env.env_c, paramArrayP)); - + if (env.env_c.fault_occurred) throw(error(env.env_c.fault_string)); - + paramList paramList; for (unsigned int i = 0; i < paramCount; ++i) { xmlrpc_value * paramP; @@ -148,13 +148,13 @@ clientSimple::call(string const serverUrl, string const methodName, paramList const& paramList, value * const resultP) { - + carriageParm_http0 carriageParm(serverUrl); - + rpcPtr rpcPtr(methodName, paramList); rpcPtr->call(this->clientP.get(), &carriageParm); - + *resultP = rpcPtr->getResult(); } diff --git a/advanced/src/cpp/packetsocket.cpp b/advanced/src/cpp/packetsocket.cpp index 328e2c477..3719357a2 100644 --- a/advanced/src/cpp/packetsocket.cpp +++ b/advanced/src/cpp/packetsocket.cpp @@ -33,7 +33,7 @@ A stream is all the data transmitted during a single socket connection. - End of stream in the middle of a packet is a protocol error. + End of stream in the middle of a packet is a protocol error. All bytes not part of a control word are literal bytes of a packet. @@ -119,7 +119,7 @@ class XMLRPC_DLLEXPORT socketx { */ socketx::socketx(int const sockFd) { -#if MSVCRT +#if MSVCRT // We don't have any way to duplicate; we'll just have to borrow. this->fdIsBorrowed = true; this->fd = sockFd; @@ -196,10 +196,10 @@ socketx::waitForWritable() const { select(this->fd + 1, 0, &wr_set, 0, 0); #else struct pollfd pollfds[1]; - + pollfds[0].fd = this->fd; pollfds[0].events = POLLOUT; - + poll(pollfds, ARRAY_SIZE(pollfds), -1); #endif } @@ -302,7 +302,7 @@ socketx::read(unsigned char * const buffer, arrive later. Return as *bytesReadP the number of bytes put into 'buffer'. - + Throw a BrokenConnectionEx exception if the connection has been broken. -----------------------------------------------------------------------------*/ int rc; @@ -410,7 +410,7 @@ namespace xmlrpc_c { packet::packet() : bytes(NULL), length(0), allocSize(0) {} - + void @@ -673,7 +673,7 @@ packetSocket_impl::writeWait(packetPtr const& packetP) const { if (this->mustTrace) traceWrite(packetP->getBytes(), packetP->getLength()); - + this->sock.writeWait(packetStart, 4); const unsigned char * const end( @@ -769,7 +769,7 @@ packetSocket_impl::takeSomeEscapeSeq(const unsigned char * const buffer, this->escAccum.bytes[0], this->escAccum.bytes[1], this->escAccum.bytes[2]); - + this->inEscapeSeq = false; this->escAccum.len = 0; } @@ -822,7 +822,7 @@ packetSocket_impl::verifyNothingAccumulated() { if (this->inEscapeSeq) throwf("Streams socket closed in the middle of an " "escape sequence"); - + if (this->inPacket) throwf("Stream socket closed in the middle of a packet " "(%u bytes of packet received; no END marker to mark " @@ -855,7 +855,7 @@ packetSocket_impl::processBytesRead(const unsigned char * const buffer, throwf("Byte 0x%02x is not in a packet or escape sequence. " "Sender is probably not using packet socket protocol", buffer[cursor]); - + cursor += bytesTaken; } } @@ -909,10 +909,11 @@ packetSocket_impl::readFromFile() { fprintf(stderr, "EOF on read\n"); this->eof = true; this->verifyNothingAccumulated(); - } else + } else { if (this->mustTrace) traceBytesRead(buffer, bytesRead); this->processBytesRead(buffer, bytesRead); + } } } } diff --git a/advanced/src/cpp/value.cpp b/advanced/src/cpp/value.cpp index e2c123729..b319430ea 100644 --- a/advanced/src/cpp/value.cpp +++ b/advanced/src/cpp/value.cpp @@ -1,4 +1,3 @@ -#include /***************************************************************************** value.cpp ****************************************************************************** @@ -622,13 +621,9 @@ class cNewStringWrapper { switch (nlCode) { case value_string::nlCode_all: - cerr << "Going to call xmlrpc_string_new_lp" << endl; - cerr << "length = " << cppvalue.length() << ", value = " - << cppvalue.c_str() << endl; this->valueP = xmlrpc_string_new_lp(&env.env_c, cppvalue.length(), cppvalue.c_str()); - cerr << "Back from xmlrpc_string_new_lp" << endl; break; case value_string::nlCode_lf: this->valueP = xmlrpc_string_new_lp_cr(&env.env_c, @@ -661,12 +656,9 @@ value_string::value_string(std::string const& cppvalue, value_string::value_string(std::string const& cppvalue) { - cerr << "value_string constructor entered" << endl; cNewStringWrapper wrapper(cppvalue, nlCode_all); - cerr << "wrapper constructed" << endl; this->instantiate(wrapper.valueP); - cerr << "value_string constructor exiting" << endl; } diff --git a/advanced/src/xmlrpc_string.c b/advanced/src/xmlrpc_string.c index 2da61e4ee..e6e007166 100644 --- a/advanced/src/xmlrpc_string.c +++ b/advanced/src/xmlrpc_string.c @@ -1,4 +1,3 @@ -#include /*============================================================================= xmlrpc_string =============================================================================== @@ -746,15 +745,12 @@ stringNew(xmlrpc_env * const envP, enum crTreatment const crTreatment, xmlrpc_value ** const valPP) { - fprintf(stderr, "stringNew entered\n"); xmlrpc_value * valP; xmlrpc_validate_utf8(envP, value, length); if (!envP->fault_occurred) { - fprintf(stderr, "Going to xmlrpc_createXmlrpcValue\n"); xmlrpc_createXmlrpcValue(envP, &valP); - fprintf(stderr, "Back from createXmlrpcValue\n"); if (!envP->fault_occurred) { valP->_type = XMLRPC_TYPE_STRING; @@ -774,7 +770,6 @@ stringNew(xmlrpc_env * const envP, *valPP = valP; } } - fprintf(stderr, "stringNew exiting\n"); } diff --git a/advanced/tools/lib/Makefile b/advanced/tools/lib/Makefile index 836d9c97c..39d34b844 100644 --- a/advanced/tools/lib/Makefile +++ b/advanced/tools/lib/Makefile @@ -26,7 +26,7 @@ LIBOBJS = \ .PHONY: all all: $(LIBOBJS) -%.o:%.c +%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h $(CC) -c $(CFLAGS_ALL) $< # This common.mk dependency makes sure the symlinks get built before diff --git a/advanced/version.mk b/advanced/version.mk index 74913a769..8faf5b0d1 100644 --- a/advanced/version.mk +++ b/advanced/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 51 -XMLRPC_POINT_RELEASE = 1 +XMLRPC_MINOR_RELEASE = 52 +XMLRPC_POINT_RELEASE = 0 From b9289af6fc501c8d1baf8e0fac51ac24b74fe9a8 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 22:39:59 +0000 Subject: [PATCH 020/154] Last 1.51 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3005 98333e67-4a24-44d7-a75c-e53540dd3050 From 1b0b6e4974b57da47f47cf7ac295f41e332ff366 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 22:40:32 +0000 Subject: [PATCH 021/154] First 1.52 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3006 98333e67-4a24-44d7-a75c-e53540dd3050 From 7c88d76eacb0950906e0ce363f6438e060e8ab39 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 26 Jun 2018 22:41:06 +0000 Subject: [PATCH 022/154] Prepare to work on release 1.53 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3007 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/version.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/version.mk b/trunk/version.mk index 8faf5b0d1..9367b2e09 100644 --- a/trunk/version.mk +++ b/trunk/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 52 -XMLRPC_POINT_RELEASE = 0 +XMLRPC_POINT_RELEASE = 99 From dd509f0da8ea44b22b9b3fd3e6bb2d14410d9296 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 2 Sep 2018 22:05:02 +0000 Subject: [PATCH 023/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3008 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/test/cpp/value.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/trunk/test/cpp/value.cpp b/trunk/test/cpp/value.cpp index 30e758c78..a24e271c0 100644 --- a/trunk/test/cpp/value.cpp +++ b/trunk/test/cpp/value.cpp @@ -91,7 +91,7 @@ class booleanTestSuite : public testSuite { return "booleanTestSuite"; } virtual void runtests(unsigned int const) { - value_boolean boolean1(true); + value_boolean boolean1(true); TEST(static_cast(boolean1) == true); value_boolean boolean2(false); TEST(static_cast(boolean2) == false); @@ -291,7 +291,7 @@ class stringTestSuite : public testSuite { badString.validate(); TEST_FAILED("'validate' of string containging a control " "character succeeded"); - } catch (error const&) {} + } catch (error const&) {} } }; @@ -397,7 +397,7 @@ class structTestSuite : public testSuite { cstruct structData; pair member("the_integer", value_int(9)); structData.insert(member); - + value_struct struct1(structData); map dataReadBack(struct1); @@ -450,7 +450,7 @@ class arrayTestSuite : public testSuite { TEST(dataReadBack1[1].type() == value::TYPE_DOUBLE); TEST(static_cast(value_double(dataReadBack1[1])) == 2.78); TEST(dataReadBack1[2].type() == value::TYPE_STRING); - TEST(static_cast(value_string(dataReadBack1[2])) == + TEST(static_cast(value_string(dataReadBack1[2])) == "hello world"); value val1(array1); From 0cec831dfedc7885cfce5a65d0354d76afa2ad4b Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 2 Sep 2018 22:25:45 +0000 Subject: [PATCH 024/154] Make 'toValue' work for vector of vectors or map of vectors git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3009 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/include/xmlrpc-c/base.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/trunk/include/xmlrpc-c/base.hpp b/trunk/include/xmlrpc-c/base.hpp index 0a1923e57..fa7ca31a6 100644 --- a/trunk/include/xmlrpc-c/base.hpp +++ b/trunk/include/xmlrpc-c/base.hpp @@ -320,6 +320,16 @@ toValue(xmlrpc_c::value const& v) { return v; } +/* Forward declarations to make it possible to do 'toValue' of a vector of + vectors, map of vectors, etc. +*/ + +template inline xmlrpc_c::value_array +toValue(std::vector const& in); + +template xmlrpc_c::value_struct +toValue(std::map const& in); + template xmlrpc_c::value_struct toValue(std::map const& in) { /*---------------------------------------------------------------------------- From 1783489579c1d26eef8adc1f25b154c7efb361a5 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 2 Sep 2018 22:31:34 +0000 Subject: [PATCH 025/154] Release 1.52.01 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3010 98333e67-4a24-44d7-a75c-e53540dd3050 --- advanced/include/xmlrpc-c/base.hpp | 10 ++++++++++ advanced/version.mk | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/advanced/include/xmlrpc-c/base.hpp b/advanced/include/xmlrpc-c/base.hpp index 0a1923e57..fa7ca31a6 100644 --- a/advanced/include/xmlrpc-c/base.hpp +++ b/advanced/include/xmlrpc-c/base.hpp @@ -320,6 +320,16 @@ toValue(xmlrpc_c::value const& v) { return v; } +/* Forward declarations to make it possible to do 'toValue' of a vector of + vectors, map of vectors, etc. +*/ + +template inline xmlrpc_c::value_array +toValue(std::vector const& in); + +template xmlrpc_c::value_struct +toValue(std::map const& in); + template xmlrpc_c::value_struct toValue(std::map const& in) { /*---------------------------------------------------------------------------- diff --git a/advanced/version.mk b/advanced/version.mk index 8faf5b0d1..5eb204f32 100644 --- a/advanced/version.mk +++ b/advanced/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 52 -XMLRPC_POINT_RELEASE = 0 +XMLRPC_POINT_RELEASE = 1 From 9eecb3502d62283c6d21d93f3370fa569bc4da0a Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 2 Sep 2018 22:33:24 +0000 Subject: [PATCH 026/154] Release 1.51.02 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3011 98333e67-4a24-44d7-a75c-e53540dd3050 --- stable/include/xmlrpc-c/base.hpp | 10 ++++++++++ stable/version.mk | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/stable/include/xmlrpc-c/base.hpp b/stable/include/xmlrpc-c/base.hpp index 0a1923e57..fa7ca31a6 100644 --- a/stable/include/xmlrpc-c/base.hpp +++ b/stable/include/xmlrpc-c/base.hpp @@ -320,6 +320,16 @@ toValue(xmlrpc_c::value const& v) { return v; } +/* Forward declarations to make it possible to do 'toValue' of a vector of + vectors, map of vectors, etc. +*/ + +template inline xmlrpc_c::value_array +toValue(std::vector const& in); + +template xmlrpc_c::value_struct +toValue(std::map const& in); + template xmlrpc_c::value_struct toValue(std::map const& in) { /*---------------------------------------------------------------------------- diff --git a/stable/version.mk b/stable/version.mk index 74913a769..79dc5b4ea 100644 --- a/stable/version.mk +++ b/stable/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 51 -XMLRPC_POINT_RELEASE = 1 +XMLRPC_POINT_RELEASE = 2 From d1cd75b5e9ace492a05de516fef9b2ad4c93933d Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 2 Sep 2018 22:33:58 +0000 Subject: [PATCH 027/154] Add test for array of arrays git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3012 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/test/cpp/value.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/trunk/test/cpp/value.cpp b/trunk/test/cpp/value.cpp index a24e271c0..3e403c9c1 100644 --- a/trunk/test/cpp/value.cpp +++ b/trunk/test/cpp/value.cpp @@ -485,6 +485,38 @@ class arrayTestSuite : public testSuite { }; +class arrayArrayTestSuite : public testSuite { +public: + virtual string suiteName() { + return "arrayArrayTestSuite"; + } + virtual void runtests(unsigned int const) { + + /* Empty array of arrays */ + vector > arrayArrayDataVec; + + value const arrayArray1(toValue(arrayArrayDataVec)); + TEST(arrayArray1.type() == value::TYPE_ARRAY); + TEST(value_array(arrayArray1).size() == 0); + + /* Array of 1 empty array */ + vector innerArray; + arrayArrayDataVec.push_back(innerArray); + value const arrayArray2(toValue(arrayArrayDataVec)); + + TEST(arrayArray2.type() == value::TYPE_ARRAY); + TEST(value_array(arrayArray2).size() == 1); + vector dataReadBackx( + value_array(arrayArray2).vectorValueValue()); + TEST(dataReadBackx.size() == 1); + TEST(dataReadBackx[0].type() == value::TYPE_ARRAY); + vector dataReadBackx2( + value_array(dataReadBackx[0]).vectorValueValue()); + TEST(dataReadBackx2.size() == 0); + } +}; + + } // unnamed namespace @@ -508,4 +540,5 @@ valueTestSuite::runtests(unsigned int const indentation) { i8TestSuite().run(indentation+1); structTestSuite().run(indentation+1); arrayTestSuite().run(indentation+1); + arrayArrayTestSuite().run(indentation+1); } From 55b0e59d15434839795b99e41cb304c684f9f846 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 2 Sep 2018 22:34:58 +0000 Subject: [PATCH 028/154] miscellaneous update git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3013 98333e67-4a24-44d7-a75c-e53540dd3050 From 34a41aaf96e23387a93c285a755ef42ea7928d60 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 14 Sep 2018 15:55:54 +0000 Subject: [PATCH 029/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3014 98333e67-4a24-44d7-a75c-e53540dd3050 --- .../curl_transport/xmlrpc_curl_transport.c | 120 +++++++++--------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/trunk/lib/curl_transport/xmlrpc_curl_transport.c b/trunk/lib/curl_transport/xmlrpc_curl_transport.c index 245300c3f..70ebc6765 100644 --- a/trunk/lib/curl_transport/xmlrpc_curl_transport.c +++ b/trunk/lib/curl_transport/xmlrpc_curl_transport.c @@ -169,7 +169,7 @@ static void addMilliseconds(xmlrpc_timespec const addend, unsigned int const adder, xmlrpc_timespec * const sumP) { - + unsigned int const million = 1000000; unsigned int const billion = 1000000000; @@ -211,7 +211,7 @@ struct xmlrpc_client_transport { the transaction with proper interruptibility. The only Curl transaction ever attached to this multi manager is 'syncCurlSessionP'. - + This is constant (the handle, not the object). */ curlMulti * asyncCurlMultiP; @@ -220,7 +220,7 @@ struct xmlrpc_client_transport { interface. Note that there may be multiple such Curl transactions simultaneously and one can't wait for a particular one to finish; the collection of asynchronous RPCs are an indivisible mass. - + This is constant (the handle, not the object). */ bool dontAdvertise; @@ -234,7 +234,7 @@ struct xmlrpc_client_transport { */ const char * userAgent; /* Information to include in a User-Agent HTTP header, reflecting - facilities outside of Xmlrpc-c. + facilities outside of Xmlrpc-c. Null means none. @@ -307,7 +307,7 @@ initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { #if MSVCRT /* This is CRITICAL so that cURL-Win32 works properly! */ - + /* So this commenter says, but I wonder why. libcurl should do the required WSAStartup() itself, and it looks to me like it does. -Bryan 06.01.01 @@ -316,7 +316,7 @@ initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); - + err = WSAStartup(wVersionRequested, &wsaData); if (err) xmlrpc_env_set_fault_formatted( @@ -324,8 +324,8 @@ initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { "Winsock startup failed. WSAStartup returned rc %d", err); else { if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { - /* Tell the user that we couldn't find a useable */ - /* winsock.dll. */ + /* Tell the user that we couldn't find a useable */ + /* winsock.dll. */ xmlrpc_env_set_fault_formatted( envP, XMLRPC_INTERNAL_ERROR, "Winsock reported that " "it does not implement the requested version 1.1."); @@ -402,14 +402,14 @@ pselectTimeout(xmlrpc_timeoutType const timeoutType, retval.tv_nsec = (uint32_t)((selectTimeoutMillisec % 1000) * million); return retval; -} +} static void processCurlMessages(xmlrpc_env * const envP, curlMulti * const curlMultiP) { - + bool endOfMessages; endOfMessages = false; /* initial assumption */ @@ -457,7 +457,7 @@ waitForWork(xmlrpc_env * const envP, checked, we will return immediately and if it arrives while we're waiting, we will return then. Note that we can provide this service only because pselect() has the same atomic unblock/wait feature. - + If sigmaskP is NULL, wait under whatever the current signal mask is. -----------------------------------------------------------------------------*/ fd_set readFdSet; @@ -487,7 +487,7 @@ waitForWork(xmlrpc_env * const envP, rc = xmlrpc_pselect(maxFd+1, &readFdSet, &writeFdSet, &exceptFdSet, &pselectTimeoutArg, sigmaskP); - + if (rc < 0 && errno != EINTR) xmlrpc_faultf(envP, "Impossible failure of pselect() " "with errno %d (%s)", @@ -532,7 +532,7 @@ waitForWorkInt(xmlrpc_env * const envP, sigfillset(&allSignals); sigprocmask(SIG_BLOCK, &allSignals, &callerBlockSet); - + if (*interruptP == 0) waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); else @@ -637,13 +637,13 @@ finishCurlMulti(xmlrpc_env * const envP, rpcStillRunning = true; /* initial assumption */ timedOut = false; curlCalledSinceInterrupt = false; - + while (rpcStillRunning && !timedOut && !envP->fault_occurred) { if (interruptP && !curlCalledSinceInterrupt) { waitForWorkInt(envP, curlMultiP, timeoutType, deadline, interruptP); - } else + } else waitForWork(envP, curlMultiP, timeoutType, deadline, NULL); if (!envP->fault_occurred) { @@ -660,7 +660,7 @@ finishCurlMulti(xmlrpc_env * const envP, doCurlWork(envP, curlMultiP, &rpcStillRunning); xmlrpc_gettimeofday(&nowTime); - + timedOut = (timeoutType == timeout_yes && timeIsAfter(nowTime, deadline)); } @@ -674,7 +674,7 @@ getTimeoutParm(xmlrpc_env * const envP, const struct xmlrpc_curl_xportparms * const curlXportParmsP, size_t const parmSize, unsigned int * const timeoutP) { - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(timeout)) *timeoutP = 0; else { @@ -702,7 +702,7 @@ getConnectTimeoutParm( const struct xmlrpc_curl_xportparms * const curlXportParmsP, size_t const parmSize, unsigned int * const timeoutP) { - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(connect_timeout)) *timeoutP = 0; else { @@ -777,12 +777,12 @@ getXportParms(xmlrpc_env * const envP, transportP->userAgent = NULL; else transportP->userAgent = strdup(curlXportParmsP->user_agent); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(dont_advertise)) transportP->dontAdvertise = false; else transportP->dontAdvertise = curlXportParmsP->dont_advertise; - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(network_interface)) curlSetupP->networkInterface = NULL; else if (curlXportParmsP->network_interface == NULL) @@ -795,8 +795,8 @@ getXportParms(xmlrpc_env * const envP, curlSetupP->sslVerifyPeer = true; else curlSetupP->sslVerifyPeer = !curlXportParmsP->no_ssl_verifypeer; - - if (!curlXportParmsP || + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(no_ssl_verifyhost)) curlSetupP->sslVerifyHost = true; else @@ -808,87 +808,87 @@ getXportParms(xmlrpc_env * const envP, curlSetupP->sslCert = NULL; else curlSetupP->sslCert = strdup(curlXportParmsP->ssl_cert); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcerttype)) curlSetupP->sslCertType = NULL; else if (curlXportParmsP->sslcerttype == NULL) curlSetupP->sslCertType = NULL; else curlSetupP->sslCertType = strdup(curlXportParmsP->sslcerttype); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcertpasswd)) curlSetupP->sslCertPasswd = NULL; else if (curlXportParmsP->sslcertpasswd == NULL) curlSetupP->sslCertPasswd = NULL; else curlSetupP->sslCertPasswd = strdup(curlXportParmsP->sslcertpasswd); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkey)) curlSetupP->sslKey = NULL; else if (curlXportParmsP->sslkey == NULL) curlSetupP->sslKey = NULL; else curlSetupP->sslKey = strdup(curlXportParmsP->sslkey); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeytype)) curlSetupP->sslKeyType = NULL; else if (curlXportParmsP->sslkeytype == NULL) curlSetupP->sslKeyType = NULL; else curlSetupP->sslKeyType = strdup(curlXportParmsP->sslkeytype); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeypasswd)) curlSetupP->sslKeyPasswd = NULL; else if (curlXportParmsP->sslkeypasswd == NULL) curlSetupP->sslKeyPasswd = NULL; else curlSetupP->sslKeyPasswd = strdup(curlXportParmsP->sslkeypasswd); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine)) curlSetupP->sslEngine = NULL; else if (curlXportParmsP->sslengine == NULL) curlSetupP->sslEngine = NULL; else curlSetupP->sslEngine = strdup(curlXportParmsP->sslengine); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine_default)) curlSetupP->sslEngineDefault = false; else curlSetupP->sslEngineDefault = !!curlXportParmsP->sslengine_default; - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslversion)) curlSetupP->sslVersion = XMLRPC_SSLVERSION_DEFAULT; else curlSetupP->sslVersion = curlXportParmsP->sslversion; - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(cainfo)) curlSetupP->caInfo = NULL; else if (curlXportParmsP->cainfo == NULL) curlSetupP->caInfo = NULL; else curlSetupP->caInfo = strdup(curlXportParmsP->cainfo); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(capath)) curlSetupP->caPath = NULL; else if (curlXportParmsP->capath == NULL) curlSetupP->caPath = NULL; else curlSetupP->caPath = strdup(curlXportParmsP->capath); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(randomfile)) curlSetupP->randomFile = NULL; else if (curlXportParmsP->randomfile == NULL) curlSetupP->randomFile = NULL; else curlSetupP->randomFile = strdup(curlXportParmsP->randomfile); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(egdsocket)) curlSetupP->egdSocket = NULL; else if (curlXportParmsP->egdsocket == NULL) curlSetupP->egdSocket = NULL; else curlSetupP->egdSocket = strdup(curlXportParmsP->egdsocket); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(ssl_cipher_list)) curlSetupP->sslCipherList = NULL; else if (curlXportParmsP->ssl_cipher_list == NULL) @@ -1054,7 +1054,7 @@ makeSyncCurlSession(xmlrpc_env * const envP, if (!envP->fault_occurred) { /* We'll need a multi manager to actually execute this session: */ transportP->syncCurlMultiP = curlMulti_create(); - + if (transportP->syncCurlMultiP == NULL) xmlrpc_faultf(envP, "Unable to create Curl multi manager for " "synchronous RPCs"); @@ -1064,7 +1064,7 @@ makeSyncCurlSession(xmlrpc_env * const envP, } if (envP->fault_occurred) transportP->syncCurlSessionLockP->destroy( - transportP->syncCurlSessionLockP); + transportP->syncCurlSessionLockP); } } @@ -1078,12 +1078,12 @@ unmakeSyncCurlSession(struct xmlrpc_client_transport * const transportP) { destroySyncCurlSession(transportP->syncCurlSessionP); transportP->syncCurlSessionLockP->destroy( - transportP->syncCurlSessionLockP); + transportP->syncCurlSessionLockP); } -static void +static void create(xmlrpc_env * const envP, int const flags ATTR_UNUSED, const char * const appname ATTR_UNUSED, @@ -1094,7 +1094,7 @@ create(xmlrpc_env * const envP, /*---------------------------------------------------------------------------- This does the 'create' operation for a Curl client transport. -----------------------------------------------------------------------------*/ - const struct xmlrpc_curl_xportparms * const curlXportParmsP = + const struct xmlrpc_curl_xportparms * const curlXportParmsP = transportparmsP; struct xmlrpc_client_transport * transportP; @@ -1108,16 +1108,16 @@ create(xmlrpc_env * const envP, transportP->interruptP = NULL; transportP->asyncCurlMultiP = curlMulti_create(); - + if (transportP->asyncCurlMultiP == NULL) xmlrpc_faultf(envP, "Unable to create Curl multi manager for " "asynchronous RPCs"); else { getXportParms(envP, curlXportParmsP, parm_size, transportP); - + if (!envP->fault_occurred) { makeSyncCurlSession(envP, transportP); - + if (envP->fault_occurred) freeXportParms(transportP); } @@ -1147,11 +1147,11 @@ assertNoOutstandingCurlWork(curlMulti * const curlMultiP) { xmlrpc_env env; bool immediateWorkToDo; int runningHandles; - + xmlrpc_env_init(&env); - + curlMulti_perform(&env, curlMultiP, &immediateWorkToDo, &runningHandles); - + /* We know the above was a no-op, since we're asserting that there is no outstanding work. */ @@ -1163,7 +1163,7 @@ assertNoOutstandingCurlWork(curlMulti * const curlMultiP) { -static void +static void destroy(struct xmlrpc_client_transport * const clientTransportP) { /*---------------------------------------------------------------------------- This does the 'destroy' operation for a Curl client transport. @@ -1265,7 +1265,7 @@ createRpc(xmlrpc_env * const envP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, xmlrpc_mem_block * const responseXmlP, - xmlrpc_transport_asynch_complete complete, + xmlrpc_transport_asynch_complete complete, xmlrpc_transport_progress progress, struct xmlrpc_call_info * const callInfoP, rpc ** const rpcPP) { @@ -1296,7 +1296,7 @@ createRpc(xmlrpc_env * const envP, curlTransaction_create(envP, curlSessionP, serverP, - callXmlP, responseXmlP, + callXmlP, responseXmlP, clientTransportP->dontAdvertise, clientTransportP->userAgent, &clientTransportP->curlSetupStuff, @@ -1316,7 +1316,7 @@ createRpc(xmlrpc_env * const envP, -static void +static void destroyRpc(rpc * const rpcP) { XMLRPC_ASSERT_PTR_OK(rpcP); @@ -1397,7 +1397,7 @@ curlTransactionProgress(void * const context, The curlTransaction calls this once a second telling us how much data has transferred. If the transport user has set up a progress - function, we call that with this progress information. That + function, we call that with this progress information. That function might e.g. display a progress bar. Additionally, the curlTransaction gives us the opportunity to tell it @@ -1436,8 +1436,8 @@ curlTransactionProgress(void * const context, -static void -sendRequest(xmlrpc_env * const envP, +static void +sendRequest(xmlrpc_env * const envP, struct xmlrpc_client_transport * const clientTransportP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, @@ -1459,7 +1459,7 @@ sendRequest(xmlrpc_env * const envP, responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); if (!envP->fault_occurred) { CURL * const curlSessionP = curl_easy_init(); - + if (curlSessionP == NULL) xmlrpc_faultf(envP, "Could not create Curl session. " "curl_easy_init() failed."); @@ -1467,10 +1467,10 @@ sendRequest(xmlrpc_env * const envP, createRpc(envP, clientTransportP, curlSessionP, serverP, callXmlP, responseXmlP, complete, progress, callInfoP, &rpcP); - + if (!envP->fault_occurred) { startRpc(envP, rpcP); - + if (envP->fault_occurred) destroyRpc(rpcP); } @@ -1489,7 +1489,7 @@ sendRequest(xmlrpc_env * const envP, -static void +static void finishAsynch( struct xmlrpc_client_transport * const clientTransportP, xmlrpc_timeoutType const timeoutType, @@ -1524,7 +1524,7 @@ finishAsynch( /* The datetime after which we should quit waiting */ xmlrpc_env_init(&env); - + if (timeoutType == timeout_yes) { xmlrpc_timespec waitStartTime; xmlrpc_gettimeofday(&waitStartTime); @@ -1545,7 +1545,7 @@ finishAsynch( Note that a failure of finish_curlMulti() does not mean that a session completed with an error or an RPC completed with an - error. Those things are reported up through the user's + error. Those things are reported up through the user's xmlrpc_transport_asynch_complete routine. A failure here is something that stopped us from calling that. @@ -1619,7 +1619,7 @@ setupGlobalConstants(xmlrpc_env * const envP) { CURLcode rc; rc = curl_global_init(CURL_GLOBAL_ALL); - + if (rc != CURLE_OK) xmlrpc_faultf(envP, "curl_global_init() failed with code %d", rc); } From 14ae3ed8e7f4b46b3245df015447f7e20fc0656d Mon Sep 17 00:00:00 2001 From: giraffedata Date: Mon, 17 Sep 2018 15:37:12 +0000 Subject: [PATCH 030/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3015 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/libutil/error.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/trunk/lib/libutil/error.c b/trunk/lib/libutil/error.c index ff3bbe16d..473755773 100644 --- a/trunk/lib/libutil/error.c +++ b/trunk/lib/libutil/error.c @@ -28,8 +28,8 @@ xmlrpc_assertion_failed(const char * const fileName, static const char * const default_fault_string = "Not enough memory for error message"; -void xmlrpc_env_init (xmlrpc_env* env) -{ +void +xmlrpc_env_init (xmlrpc_env* env) { XMLRPC_ASSERT(env != NULL); env->fault_occurred = 0; @@ -37,6 +37,8 @@ void xmlrpc_env_init (xmlrpc_env* env) env->fault_string = NULL; } + + void xmlrpc_env_clean(xmlrpc_env * const envP) { @@ -55,14 +57,14 @@ xmlrpc_env_clean(xmlrpc_env * const envP) { -void +void xmlrpc_env_set_fault(xmlrpc_env * const envP, - int const faultCode, + int const faultCode, const char * const faultDescription) { char * buffer; - XMLRPC_ASSERT(envP != NULL); + XMLRPC_ASSERT(envP != NULL); XMLRPC_ASSERT(faultDescription != NULL); /* Clean up any leftover pointers. */ @@ -101,10 +103,10 @@ xmlrpc_set_fault_formatted_v(xmlrpc_env * const envP, -void -xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP, +void +xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP, int const code, - const char * const format, + const char * const format, ...) { va_list args; @@ -149,8 +151,8 @@ xmlrpc_faultf(xmlrpc_env * const envP, ** 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. -** +** 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 From bb60c3b6d3d6064c0b00ef3a11e5468dbb9f66e7 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Wed, 19 Sep 2018 02:40:17 +0000 Subject: [PATCH 031/154] Fix memory leak git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3016 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/src/xmlrpc_data.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/trunk/src/xmlrpc_data.c b/trunk/src/xmlrpc_data.c index b0517f9f0..605cac1eb 100644 --- a/trunk/src/xmlrpc_data.c +++ b/trunk/src/xmlrpc_data.c @@ -379,6 +379,11 @@ xmlrpc_createXmlrpcValue(xmlrpc_env * const envP, "xmlrpc_value"); else valP->refcount = 1; + + if (envP->fault_occurred) { + free(valP); + valP = NULL; + } } *valPP = valP; } From d2f34818ca515edb9227cff87760e31efabb834c Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 30 Sep 2018 15:17:51 +0000 Subject: [PATCH 032/154] Release 1.43.08 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3017 98333e67-4a24-44d7-a75c-e53540dd3050 From 343a3b98e54999d67edb644bcd395aa9784fb16e Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 30 Sep 2018 15:18:25 +0000 Subject: [PATCH 033/154] Release 1.51.03 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3018 98333e67-4a24-44d7-a75c-e53540dd3050 --- stable/src/xmlrpc_data.c | 5 +++++ stable/version.mk | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/stable/src/xmlrpc_data.c b/stable/src/xmlrpc_data.c index b0517f9f0..605cac1eb 100644 --- a/stable/src/xmlrpc_data.c +++ b/stable/src/xmlrpc_data.c @@ -379,6 +379,11 @@ xmlrpc_createXmlrpcValue(xmlrpc_env * const envP, "xmlrpc_value"); else valP->refcount = 1; + + if (envP->fault_occurred) { + free(valP); + valP = NULL; + } } *valPP = valP; } diff --git a/stable/version.mk b/stable/version.mk index 79dc5b4ea..7b0a4c426 100644 --- a/stable/version.mk +++ b/stable/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 51 -XMLRPC_POINT_RELEASE = 2 +XMLRPC_POINT_RELEASE = 3 From 1790bb6437c7a93bb5e44173639c370b6aad1fbe Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 30 Sep 2018 15:19:54 +0000 Subject: [PATCH 034/154] Last 1.52 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3019 98333e67-4a24-44d7-a75c-e53540dd3050 From 17de059dccc809ca55a5dc85fe2b4fa436df5a7d Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 30 Sep 2018 15:28:07 +0000 Subject: [PATCH 035/154] Change release number to 1.53.00 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3020 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/version.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trunk/version.mk b/trunk/version.mk index 9367b2e09..7ed5663b3 100644 --- a/trunk/version.mk +++ b/trunk/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 52 -XMLRPC_POINT_RELEASE = 99 +XMLRPC_MINOR_RELEASE = 53 +XMLRPC_POINT_RELEASE = 0 From 969b6357644051b30e67c647a87dcf4e22dcc918 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 30 Sep 2018 15:28:46 +0000 Subject: [PATCH 036/154] First 1.53 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3021 98333e67-4a24-44d7-a75c-e53540dd3050 From 50d1e4c615e96e7a4165fd6bcebe70c82a8850aa Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 30 Sep 2018 15:31:55 +0000 Subject: [PATCH 037/154] Promote Development to Advanced git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3022 98333e67-4a24-44d7-a75c-e53540dd3050 --- .../curl_transport/xmlrpc_curl_transport.c | 120 +++++++++--------- advanced/lib/libutil/error.c | 22 ++-- advanced/src/xmlrpc_data.c | 5 + advanced/test/cpp/value.cpp | 41 +++++- advanced/version.mk | 4 +- 5 files changed, 116 insertions(+), 76 deletions(-) diff --git a/advanced/lib/curl_transport/xmlrpc_curl_transport.c b/advanced/lib/curl_transport/xmlrpc_curl_transport.c index 245300c3f..70ebc6765 100644 --- a/advanced/lib/curl_transport/xmlrpc_curl_transport.c +++ b/advanced/lib/curl_transport/xmlrpc_curl_transport.c @@ -169,7 +169,7 @@ static void addMilliseconds(xmlrpc_timespec const addend, unsigned int const adder, xmlrpc_timespec * const sumP) { - + unsigned int const million = 1000000; unsigned int const billion = 1000000000; @@ -211,7 +211,7 @@ struct xmlrpc_client_transport { the transaction with proper interruptibility. The only Curl transaction ever attached to this multi manager is 'syncCurlSessionP'. - + This is constant (the handle, not the object). */ curlMulti * asyncCurlMultiP; @@ -220,7 +220,7 @@ struct xmlrpc_client_transport { interface. Note that there may be multiple such Curl transactions simultaneously and one can't wait for a particular one to finish; the collection of asynchronous RPCs are an indivisible mass. - + This is constant (the handle, not the object). */ bool dontAdvertise; @@ -234,7 +234,7 @@ struct xmlrpc_client_transport { */ const char * userAgent; /* Information to include in a User-Agent HTTP header, reflecting - facilities outside of Xmlrpc-c. + facilities outside of Xmlrpc-c. Null means none. @@ -307,7 +307,7 @@ initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { #if MSVCRT /* This is CRITICAL so that cURL-Win32 works properly! */ - + /* So this commenter says, but I wonder why. libcurl should do the required WSAStartup() itself, and it looks to me like it does. -Bryan 06.01.01 @@ -316,7 +316,7 @@ initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); - + err = WSAStartup(wVersionRequested, &wsaData); if (err) xmlrpc_env_set_fault_formatted( @@ -324,8 +324,8 @@ initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { "Winsock startup failed. WSAStartup returned rc %d", err); else { if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { - /* Tell the user that we couldn't find a useable */ - /* winsock.dll. */ + /* Tell the user that we couldn't find a useable */ + /* winsock.dll. */ xmlrpc_env_set_fault_formatted( envP, XMLRPC_INTERNAL_ERROR, "Winsock reported that " "it does not implement the requested version 1.1."); @@ -402,14 +402,14 @@ pselectTimeout(xmlrpc_timeoutType const timeoutType, retval.tv_nsec = (uint32_t)((selectTimeoutMillisec % 1000) * million); return retval; -} +} static void processCurlMessages(xmlrpc_env * const envP, curlMulti * const curlMultiP) { - + bool endOfMessages; endOfMessages = false; /* initial assumption */ @@ -457,7 +457,7 @@ waitForWork(xmlrpc_env * const envP, checked, we will return immediately and if it arrives while we're waiting, we will return then. Note that we can provide this service only because pselect() has the same atomic unblock/wait feature. - + If sigmaskP is NULL, wait under whatever the current signal mask is. -----------------------------------------------------------------------------*/ fd_set readFdSet; @@ -487,7 +487,7 @@ waitForWork(xmlrpc_env * const envP, rc = xmlrpc_pselect(maxFd+1, &readFdSet, &writeFdSet, &exceptFdSet, &pselectTimeoutArg, sigmaskP); - + if (rc < 0 && errno != EINTR) xmlrpc_faultf(envP, "Impossible failure of pselect() " "with errno %d (%s)", @@ -532,7 +532,7 @@ waitForWorkInt(xmlrpc_env * const envP, sigfillset(&allSignals); sigprocmask(SIG_BLOCK, &allSignals, &callerBlockSet); - + if (*interruptP == 0) waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); else @@ -637,13 +637,13 @@ finishCurlMulti(xmlrpc_env * const envP, rpcStillRunning = true; /* initial assumption */ timedOut = false; curlCalledSinceInterrupt = false; - + while (rpcStillRunning && !timedOut && !envP->fault_occurred) { if (interruptP && !curlCalledSinceInterrupt) { waitForWorkInt(envP, curlMultiP, timeoutType, deadline, interruptP); - } else + } else waitForWork(envP, curlMultiP, timeoutType, deadline, NULL); if (!envP->fault_occurred) { @@ -660,7 +660,7 @@ finishCurlMulti(xmlrpc_env * const envP, doCurlWork(envP, curlMultiP, &rpcStillRunning); xmlrpc_gettimeofday(&nowTime); - + timedOut = (timeoutType == timeout_yes && timeIsAfter(nowTime, deadline)); } @@ -674,7 +674,7 @@ getTimeoutParm(xmlrpc_env * const envP, const struct xmlrpc_curl_xportparms * const curlXportParmsP, size_t const parmSize, unsigned int * const timeoutP) { - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(timeout)) *timeoutP = 0; else { @@ -702,7 +702,7 @@ getConnectTimeoutParm( const struct xmlrpc_curl_xportparms * const curlXportParmsP, size_t const parmSize, unsigned int * const timeoutP) { - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(connect_timeout)) *timeoutP = 0; else { @@ -777,12 +777,12 @@ getXportParms(xmlrpc_env * const envP, transportP->userAgent = NULL; else transportP->userAgent = strdup(curlXportParmsP->user_agent); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(dont_advertise)) transportP->dontAdvertise = false; else transportP->dontAdvertise = curlXportParmsP->dont_advertise; - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(network_interface)) curlSetupP->networkInterface = NULL; else if (curlXportParmsP->network_interface == NULL) @@ -795,8 +795,8 @@ getXportParms(xmlrpc_env * const envP, curlSetupP->sslVerifyPeer = true; else curlSetupP->sslVerifyPeer = !curlXportParmsP->no_ssl_verifypeer; - - if (!curlXportParmsP || + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(no_ssl_verifyhost)) curlSetupP->sslVerifyHost = true; else @@ -808,87 +808,87 @@ getXportParms(xmlrpc_env * const envP, curlSetupP->sslCert = NULL; else curlSetupP->sslCert = strdup(curlXportParmsP->ssl_cert); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcerttype)) curlSetupP->sslCertType = NULL; else if (curlXportParmsP->sslcerttype == NULL) curlSetupP->sslCertType = NULL; else curlSetupP->sslCertType = strdup(curlXportParmsP->sslcerttype); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcertpasswd)) curlSetupP->sslCertPasswd = NULL; else if (curlXportParmsP->sslcertpasswd == NULL) curlSetupP->sslCertPasswd = NULL; else curlSetupP->sslCertPasswd = strdup(curlXportParmsP->sslcertpasswd); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkey)) curlSetupP->sslKey = NULL; else if (curlXportParmsP->sslkey == NULL) curlSetupP->sslKey = NULL; else curlSetupP->sslKey = strdup(curlXportParmsP->sslkey); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeytype)) curlSetupP->sslKeyType = NULL; else if (curlXportParmsP->sslkeytype == NULL) curlSetupP->sslKeyType = NULL; else curlSetupP->sslKeyType = strdup(curlXportParmsP->sslkeytype); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeypasswd)) curlSetupP->sslKeyPasswd = NULL; else if (curlXportParmsP->sslkeypasswd == NULL) curlSetupP->sslKeyPasswd = NULL; else curlSetupP->sslKeyPasswd = strdup(curlXportParmsP->sslkeypasswd); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine)) curlSetupP->sslEngine = NULL; else if (curlXportParmsP->sslengine == NULL) curlSetupP->sslEngine = NULL; else curlSetupP->sslEngine = strdup(curlXportParmsP->sslengine); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine_default)) curlSetupP->sslEngineDefault = false; else curlSetupP->sslEngineDefault = !!curlXportParmsP->sslengine_default; - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslversion)) curlSetupP->sslVersion = XMLRPC_SSLVERSION_DEFAULT; else curlSetupP->sslVersion = curlXportParmsP->sslversion; - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(cainfo)) curlSetupP->caInfo = NULL; else if (curlXportParmsP->cainfo == NULL) curlSetupP->caInfo = NULL; else curlSetupP->caInfo = strdup(curlXportParmsP->cainfo); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(capath)) curlSetupP->caPath = NULL; else if (curlXportParmsP->capath == NULL) curlSetupP->caPath = NULL; else curlSetupP->caPath = strdup(curlXportParmsP->capath); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(randomfile)) curlSetupP->randomFile = NULL; else if (curlXportParmsP->randomfile == NULL) curlSetupP->randomFile = NULL; else curlSetupP->randomFile = strdup(curlXportParmsP->randomfile); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(egdsocket)) curlSetupP->egdSocket = NULL; else if (curlXportParmsP->egdsocket == NULL) curlSetupP->egdSocket = NULL; else curlSetupP->egdSocket = strdup(curlXportParmsP->egdsocket); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(ssl_cipher_list)) curlSetupP->sslCipherList = NULL; else if (curlXportParmsP->ssl_cipher_list == NULL) @@ -1054,7 +1054,7 @@ makeSyncCurlSession(xmlrpc_env * const envP, if (!envP->fault_occurred) { /* We'll need a multi manager to actually execute this session: */ transportP->syncCurlMultiP = curlMulti_create(); - + if (transportP->syncCurlMultiP == NULL) xmlrpc_faultf(envP, "Unable to create Curl multi manager for " "synchronous RPCs"); @@ -1064,7 +1064,7 @@ makeSyncCurlSession(xmlrpc_env * const envP, } if (envP->fault_occurred) transportP->syncCurlSessionLockP->destroy( - transportP->syncCurlSessionLockP); + transportP->syncCurlSessionLockP); } } @@ -1078,12 +1078,12 @@ unmakeSyncCurlSession(struct xmlrpc_client_transport * const transportP) { destroySyncCurlSession(transportP->syncCurlSessionP); transportP->syncCurlSessionLockP->destroy( - transportP->syncCurlSessionLockP); + transportP->syncCurlSessionLockP); } -static void +static void create(xmlrpc_env * const envP, int const flags ATTR_UNUSED, const char * const appname ATTR_UNUSED, @@ -1094,7 +1094,7 @@ create(xmlrpc_env * const envP, /*---------------------------------------------------------------------------- This does the 'create' operation for a Curl client transport. -----------------------------------------------------------------------------*/ - const struct xmlrpc_curl_xportparms * const curlXportParmsP = + const struct xmlrpc_curl_xportparms * const curlXportParmsP = transportparmsP; struct xmlrpc_client_transport * transportP; @@ -1108,16 +1108,16 @@ create(xmlrpc_env * const envP, transportP->interruptP = NULL; transportP->asyncCurlMultiP = curlMulti_create(); - + if (transportP->asyncCurlMultiP == NULL) xmlrpc_faultf(envP, "Unable to create Curl multi manager for " "asynchronous RPCs"); else { getXportParms(envP, curlXportParmsP, parm_size, transportP); - + if (!envP->fault_occurred) { makeSyncCurlSession(envP, transportP); - + if (envP->fault_occurred) freeXportParms(transportP); } @@ -1147,11 +1147,11 @@ assertNoOutstandingCurlWork(curlMulti * const curlMultiP) { xmlrpc_env env; bool immediateWorkToDo; int runningHandles; - + xmlrpc_env_init(&env); - + curlMulti_perform(&env, curlMultiP, &immediateWorkToDo, &runningHandles); - + /* We know the above was a no-op, since we're asserting that there is no outstanding work. */ @@ -1163,7 +1163,7 @@ assertNoOutstandingCurlWork(curlMulti * const curlMultiP) { -static void +static void destroy(struct xmlrpc_client_transport * const clientTransportP) { /*---------------------------------------------------------------------------- This does the 'destroy' operation for a Curl client transport. @@ -1265,7 +1265,7 @@ createRpc(xmlrpc_env * const envP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, xmlrpc_mem_block * const responseXmlP, - xmlrpc_transport_asynch_complete complete, + xmlrpc_transport_asynch_complete complete, xmlrpc_transport_progress progress, struct xmlrpc_call_info * const callInfoP, rpc ** const rpcPP) { @@ -1296,7 +1296,7 @@ createRpc(xmlrpc_env * const envP, curlTransaction_create(envP, curlSessionP, serverP, - callXmlP, responseXmlP, + callXmlP, responseXmlP, clientTransportP->dontAdvertise, clientTransportP->userAgent, &clientTransportP->curlSetupStuff, @@ -1316,7 +1316,7 @@ createRpc(xmlrpc_env * const envP, -static void +static void destroyRpc(rpc * const rpcP) { XMLRPC_ASSERT_PTR_OK(rpcP); @@ -1397,7 +1397,7 @@ curlTransactionProgress(void * const context, The curlTransaction calls this once a second telling us how much data has transferred. If the transport user has set up a progress - function, we call that with this progress information. That + function, we call that with this progress information. That function might e.g. display a progress bar. Additionally, the curlTransaction gives us the opportunity to tell it @@ -1436,8 +1436,8 @@ curlTransactionProgress(void * const context, -static void -sendRequest(xmlrpc_env * const envP, +static void +sendRequest(xmlrpc_env * const envP, struct xmlrpc_client_transport * const clientTransportP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, @@ -1459,7 +1459,7 @@ sendRequest(xmlrpc_env * const envP, responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); if (!envP->fault_occurred) { CURL * const curlSessionP = curl_easy_init(); - + if (curlSessionP == NULL) xmlrpc_faultf(envP, "Could not create Curl session. " "curl_easy_init() failed."); @@ -1467,10 +1467,10 @@ sendRequest(xmlrpc_env * const envP, createRpc(envP, clientTransportP, curlSessionP, serverP, callXmlP, responseXmlP, complete, progress, callInfoP, &rpcP); - + if (!envP->fault_occurred) { startRpc(envP, rpcP); - + if (envP->fault_occurred) destroyRpc(rpcP); } @@ -1489,7 +1489,7 @@ sendRequest(xmlrpc_env * const envP, -static void +static void finishAsynch( struct xmlrpc_client_transport * const clientTransportP, xmlrpc_timeoutType const timeoutType, @@ -1524,7 +1524,7 @@ finishAsynch( /* The datetime after which we should quit waiting */ xmlrpc_env_init(&env); - + if (timeoutType == timeout_yes) { xmlrpc_timespec waitStartTime; xmlrpc_gettimeofday(&waitStartTime); @@ -1545,7 +1545,7 @@ finishAsynch( Note that a failure of finish_curlMulti() does not mean that a session completed with an error or an RPC completed with an - error. Those things are reported up through the user's + error. Those things are reported up through the user's xmlrpc_transport_asynch_complete routine. A failure here is something that stopped us from calling that. @@ -1619,7 +1619,7 @@ setupGlobalConstants(xmlrpc_env * const envP) { CURLcode rc; rc = curl_global_init(CURL_GLOBAL_ALL); - + if (rc != CURLE_OK) xmlrpc_faultf(envP, "curl_global_init() failed with code %d", rc); } diff --git a/advanced/lib/libutil/error.c b/advanced/lib/libutil/error.c index ff3bbe16d..473755773 100644 --- a/advanced/lib/libutil/error.c +++ b/advanced/lib/libutil/error.c @@ -28,8 +28,8 @@ xmlrpc_assertion_failed(const char * const fileName, static const char * const default_fault_string = "Not enough memory for error message"; -void xmlrpc_env_init (xmlrpc_env* env) -{ +void +xmlrpc_env_init (xmlrpc_env* env) { XMLRPC_ASSERT(env != NULL); env->fault_occurred = 0; @@ -37,6 +37,8 @@ void xmlrpc_env_init (xmlrpc_env* env) env->fault_string = NULL; } + + void xmlrpc_env_clean(xmlrpc_env * const envP) { @@ -55,14 +57,14 @@ xmlrpc_env_clean(xmlrpc_env * const envP) { -void +void xmlrpc_env_set_fault(xmlrpc_env * const envP, - int const faultCode, + int const faultCode, const char * const faultDescription) { char * buffer; - XMLRPC_ASSERT(envP != NULL); + XMLRPC_ASSERT(envP != NULL); XMLRPC_ASSERT(faultDescription != NULL); /* Clean up any leftover pointers. */ @@ -101,10 +103,10 @@ xmlrpc_set_fault_formatted_v(xmlrpc_env * const envP, -void -xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP, +void +xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP, int const code, - const char * const format, + const char * const format, ...) { va_list args; @@ -149,8 +151,8 @@ xmlrpc_faultf(xmlrpc_env * const envP, ** 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. -** +** 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 diff --git a/advanced/src/xmlrpc_data.c b/advanced/src/xmlrpc_data.c index b0517f9f0..605cac1eb 100644 --- a/advanced/src/xmlrpc_data.c +++ b/advanced/src/xmlrpc_data.c @@ -379,6 +379,11 @@ xmlrpc_createXmlrpcValue(xmlrpc_env * const envP, "xmlrpc_value"); else valP->refcount = 1; + + if (envP->fault_occurred) { + free(valP); + valP = NULL; + } } *valPP = valP; } diff --git a/advanced/test/cpp/value.cpp b/advanced/test/cpp/value.cpp index 30e758c78..3e403c9c1 100644 --- a/advanced/test/cpp/value.cpp +++ b/advanced/test/cpp/value.cpp @@ -91,7 +91,7 @@ class booleanTestSuite : public testSuite { return "booleanTestSuite"; } virtual void runtests(unsigned int const) { - value_boolean boolean1(true); + value_boolean boolean1(true); TEST(static_cast(boolean1) == true); value_boolean boolean2(false); TEST(static_cast(boolean2) == false); @@ -291,7 +291,7 @@ class stringTestSuite : public testSuite { badString.validate(); TEST_FAILED("'validate' of string containging a control " "character succeeded"); - } catch (error const&) {} + } catch (error const&) {} } }; @@ -397,7 +397,7 @@ class structTestSuite : public testSuite { cstruct structData; pair member("the_integer", value_int(9)); structData.insert(member); - + value_struct struct1(structData); map dataReadBack(struct1); @@ -450,7 +450,7 @@ class arrayTestSuite : public testSuite { TEST(dataReadBack1[1].type() == value::TYPE_DOUBLE); TEST(static_cast(value_double(dataReadBack1[1])) == 2.78); TEST(dataReadBack1[2].type() == value::TYPE_STRING); - TEST(static_cast(value_string(dataReadBack1[2])) == + TEST(static_cast(value_string(dataReadBack1[2])) == "hello world"); value val1(array1); @@ -485,6 +485,38 @@ class arrayTestSuite : public testSuite { }; +class arrayArrayTestSuite : public testSuite { +public: + virtual string suiteName() { + return "arrayArrayTestSuite"; + } + virtual void runtests(unsigned int const) { + + /* Empty array of arrays */ + vector > arrayArrayDataVec; + + value const arrayArray1(toValue(arrayArrayDataVec)); + TEST(arrayArray1.type() == value::TYPE_ARRAY); + TEST(value_array(arrayArray1).size() == 0); + + /* Array of 1 empty array */ + vector innerArray; + arrayArrayDataVec.push_back(innerArray); + value const arrayArray2(toValue(arrayArrayDataVec)); + + TEST(arrayArray2.type() == value::TYPE_ARRAY); + TEST(value_array(arrayArray2).size() == 1); + vector dataReadBackx( + value_array(arrayArray2).vectorValueValue()); + TEST(dataReadBackx.size() == 1); + TEST(dataReadBackx[0].type() == value::TYPE_ARRAY); + vector dataReadBackx2( + value_array(dataReadBackx[0]).vectorValueValue()); + TEST(dataReadBackx2.size() == 0); + } +}; + + } // unnamed namespace @@ -508,4 +540,5 @@ valueTestSuite::runtests(unsigned int const indentation) { i8TestSuite().run(indentation+1); structTestSuite().run(indentation+1); arrayTestSuite().run(indentation+1); + arrayArrayTestSuite().run(indentation+1); } diff --git a/advanced/version.mk b/advanced/version.mk index 5eb204f32..7ed5663b3 100644 --- a/advanced/version.mk +++ b/advanced/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 52 -XMLRPC_POINT_RELEASE = 1 +XMLRPC_MINOR_RELEASE = 53 +XMLRPC_POINT_RELEASE = 0 From 51922c28af1f39dd3981ced32e1455b0250b8912 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 30 Sep 2018 15:35:51 +0000 Subject: [PATCH 038/154] prepare to work on 1.54 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3023 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/version.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/version.mk b/trunk/version.mk index 7ed5663b3..a97ecdf94 100644 --- a/trunk/version.mk +++ b/trunk/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 53 -XMLRPC_POINT_RELEASE = 0 +XMLRPC_POINT_RELEASE = 99 From cedac358f039c6ccb298aea39fa403ae3d48eb11 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Mon, 29 Oct 2018 03:09:49 +0000 Subject: [PATCH 039/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3024 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/src/json.c | 86 ++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/trunk/src/json.c b/trunk/src/json.c index 394202b8e..be0257722 100644 --- a/trunk/src/json.c +++ b/trunk/src/json.c @@ -203,7 +203,7 @@ finishStringToken(xmlrpc_env * const envP, while (isxdigit(*cur) && cur - tokP->end < 4) ++cur; - + if (cur - tokP->end < 4) setParseErr(envP, tokP, "hex unicode must contain 4 digits. " @@ -268,7 +268,7 @@ isFloat(const char * const token, point number. N.B. This is true of any integer. - + We don't accept plus signs. Examples of valid floating point: 0, 32, 32.5, , 32.500, @@ -385,7 +385,7 @@ advanceToNextToken(Tokenizer * const tokP) { while (*tokP->begin != '\0' && (isspace(*tokP->begin) || atComment(tokP))) { - + advancePastWhiteSpace(tokP); advancePastComments(tokP); @@ -410,7 +410,7 @@ getToken(xmlrpc_env * const envP, tokP->size = tokP->end - tokP->begin; } else { tokP->end = tokP->begin; /* initial value */ - + if (*tokP->begin == '{') { finishDelimiterToken(tokP); tokP->type = typeOpenBrace; @@ -550,7 +550,7 @@ getBackslashSequence(xmlrpc_env * const envP, buffer[0] = '\t'; tsize = 1; *nBytesConsumedP = 1; - break; + break; case 'u': { long digit; strncpy(buffer, cur + 1, 4); @@ -587,7 +587,7 @@ unescapeString(xmlrpc_env * const envP, cur = begin; last = cur; - + while (cur != end && !envP->fault_occurred) { if (*cur == '\\') { if (cur != last) { @@ -634,7 +634,7 @@ static xmlrpc_value * makeUtf8String(xmlrpc_env * const envP, const char * const begin, const char * const end) { -/*---------------------------------------------------------------------------- +/*---------------------------------------------------------------------------- Copy a json string directly into a string value, and convert any json escaping (\uXXXX) to something acceptable to the internal string handling. @@ -671,7 +671,7 @@ stringTokenValue(xmlrpc_env * const envP, assert(tokP->end >= tokP->begin + 2); assert(*tokP->begin == '"'); assert(*(tokP->end-1) == '"'); - + valP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); if (env.fault_occurred) { @@ -706,7 +706,7 @@ integerTokenValue(xmlrpc_env * const envP, tokP->begin, env.fault_string); else valP = xmlrpc_i8_new(envP, value); - + xmlrpc_env_clean(&env); return valP; @@ -772,7 +772,7 @@ parseList(xmlrpc_env * const envP, XMLRPC_ASSERT_ENV_OK(envP); retval = xmlrpc_array_new(envP); - + if (!envP->fault_occurred) { bool endOfList; for (endOfList = false; !endOfList && !envP->fault_occurred; ) { @@ -833,9 +833,9 @@ parseObjectMember(xmlrpc_env * const envP, assert(tokP->end >= tokP->begin + 2); assert(*tokP->begin == '"'); assert(*(tokP->end-1) == '"'); - + keyP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); - + if (env.fault_occurred) setParseErr(envP, tokP, "Error in what is supposed to be " "the key of a member of an object: %s", @@ -858,7 +858,7 @@ parseObjectMember(xmlrpc_env * const envP, } - + static xmlrpc_value * parseObject(xmlrpc_env * const envP, Tokenizer * const tokP) { @@ -884,7 +884,7 @@ parseObject(xmlrpc_env * const envP, if (!envP->fault_occurred) { getToken(envP, tokP); - + if (!envP->fault_occurred) { if (tokP->type == typeComma) { /* member separator; keep going */ @@ -924,9 +924,9 @@ parseValue(xmlrpc_env * const envP, Tokenizer * const tokP) { xmlrpc_value * retval; - + XMLRPC_ASSERT_ENV_OK(envP); - + switch (tokP->type) { case typeOpenBracket: @@ -936,7 +936,7 @@ parseValue(xmlrpc_env * const envP, case typeOpenBrace: retval = parseObject(envP, tokP); break; - + case typeNull: retval = xmlrpc_nil_new(envP); break; @@ -956,7 +956,7 @@ parseValue(xmlrpc_env * const envP, case typeInteger: retval = integerTokenValue(envP, tokP); break; - + case typeFloat: retval = xmlrpc_double_new(envP, strtod(tokP->begin, NULL)); break; @@ -964,7 +964,7 @@ parseValue(xmlrpc_env * const envP, case typeString: retval = stringTokenValue(envP, tokP); break; - + default: retval = NULL; setParseErr(envP, tokP, "Invalid token " @@ -984,9 +984,9 @@ xmlrpc_parse_json(xmlrpc_env * const envP, xmlrpc_value * retval = retval; Tokenizer tok; - + XMLRPC_ASSERT_ENV_OK(envP); - + initializeTokenizer(&tok, str); getToken(envP, &tok); @@ -1093,7 +1093,7 @@ appendEscapeSeq(xmlrpc_env * const envP, char buffer[6+1]; char slashChar; /* Character that goes after the backslash, including 'u' for \uHHHH */ - + switch (c) { case '"' : slashChar = '"'; break; /* U+0022 */ case '\\': slashChar = '\\'; break; /* U+005C */ @@ -1108,7 +1108,7 @@ appendEscapeSeq(xmlrpc_env * const envP, buffer[0] = '\\'; buffer[1] = slashChar; - + if (slashChar == 'u') { sprintf(&buffer[2], "%04x", c); size = 6; /* \u1234 */ @@ -1135,7 +1135,7 @@ makeJsonString(xmlrpc_env * const envP, const char * last; last = cur = begin; - + while (cur != end && !envP->fault_occurred) { unsigned char const c = *cur; @@ -1145,7 +1145,7 @@ makeJsonString(xmlrpc_env * const envP, the characters before it to the output. */ XMLRPC_MEMBLOCK_APPEND(char, envP, outP, last, cur - last); - + if (!envP->fault_occurred) { appendEscapeSeq(envP, outP, c); @@ -1205,7 +1205,7 @@ serializeI8(xmlrpc_env * const envP, xmlrpc_int64 value; xmlrpc_read_i8(envP, valP, &value); - + formatOut(envP, outP, "%" XMLRPC_PRId64, value); } @@ -1215,7 +1215,7 @@ static void serializeBool(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - + xmlrpc_bool value; xmlrpc_read_bool(envP, valP, &value); @@ -1228,7 +1228,7 @@ static void serializeDouble(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - + xmlrpc_double value; xmlrpc_read_double(envP, valP, &value); @@ -1254,16 +1254,16 @@ serializeDatetime(xmlrpc_env * const envP, } - + static void serializeString(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - + formatOut(envP, outP, "\""); - + makeJsonStringFromXmlRpc(envP, valP, outP); - + formatOut(envP, outP, "\""); } @@ -1289,12 +1289,12 @@ serializeBitstring(xmlrpc_env * const envP, if (!envP->fault_occurred) { formatOut(envP, outP, "\""); - + XMLRPC_MEMBLOCK_APPEND( char, envP, outP, XMLRPC_MEMBLOCK_CONTENTS(char, base64P), XMLRPC_MEMBLOCK_SIZE(char, base64P)); - + if (!envP->fault_occurred) formatOut(envP, outP, "\""); @@ -1322,7 +1322,7 @@ serializeArray(xmlrpc_env * const envP, for (i = 0; i < size && !envP->fault_occurred; ++i) { xmlrpc_value * const itemP = xmlrpc_array_get_item(envP, valP, i); - + if (!envP->fault_occurred) { if (!envP->fault_occurred) { serializeValue(envP, itemP, level + 1, outP); @@ -1340,7 +1340,7 @@ serializeArray(xmlrpc_env * const envP, } } } -} +} @@ -1352,17 +1352,17 @@ serializeStructMember(xmlrpc_env * const envP, xmlrpc_mem_block * const outP) { serializeValue(envP, memberKeyP, level, outP); - + if (!envP->fault_occurred) { formatOut(envP, outP, ":"); - + if (!envP->fault_occurred) serializeValue(envP, memberValueP, level, outP); } } - + static void serializeStruct(xmlrpc_env * const envP, xmlrpc_value * const valP, @@ -1373,7 +1373,7 @@ serializeStruct(xmlrpc_env * const envP, formatOut(envP, outP, "{\n"); if (!envP->fault_occurred) { unsigned int const size = xmlrpc_struct_size(envP, valP); - + if (!envP->fault_occurred) { unsigned int i; for (i = 0; i < size && !envP->fault_occurred; ++i) { @@ -1386,7 +1386,7 @@ serializeStruct(xmlrpc_env * const envP, if (!envP->fault_occurred) { serializeStructMember(envP, memberKeyP, memberValueP, level + 1, outP); - + if (!envP->fault_occurred && i < size - 1) XMLRPC_MEMBLOCK_APPEND(char, envP, outP, ",\n", 2); } @@ -1416,7 +1416,7 @@ serializeValue(xmlrpc_env * const envP, XMLRPC_ASSERT_ENV_OK(envP); indent(envP, level, outP); - + switch (xmlrpc_value_type(valP)) { case XMLRPC_TYPE_INT: serializeInt(envP, valP, outP); @@ -1444,7 +1444,7 @@ serializeValue(xmlrpc_env * const envP, case XMLRPC_TYPE_BASE64: serializeBitstring(envP, valP, outP); - break; + break; case XMLRPC_TYPE_ARRAY: serializeArray(envP, valP, level, outP); From 8fcaa2b0b833ae912407f6f8f4d51f6c02490db3 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 3 Nov 2018 19:03:06 +0000 Subject: [PATCH 040/154] Use 'curl-config' found at configure time, not make time git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3025 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/config.mk.in | 1 + trunk/configure | 2 ++ trunk/configure.in | 2 ++ trunk/lib/curl_transport/Makefile | 4 ++-- trunk/src/Makefile | 2 +- 5 files changed, 8 insertions(+), 3 deletions(-) diff --git a/trunk/config.mk.in b/trunk/config.mk.in index f19ead43e..725c0632f 100644 --- a/trunk/config.mk.in +++ b/trunk/config.mk.in @@ -32,6 +32,7 @@ BUILD_TOOLS = @BUILD_TOOLS@ BUILD_XMLRPC_PSTREAM = @BUILD_XMLRPC_PSTREAM@ WININET_LDADD = @WININET_LDADD@ WININET_LIBDIR = @WININET_LIBDIR@ +CURL_CONFIG = @CURL_CONFIG@ CURL_LDADD = @CURL_LDADD@ CURL_LIBDIR = @CURL_LIBDIR@ LIBWWW_LDADD = @LIBWWW_LDADD@ diff --git a/trunk/configure b/trunk/configure index c1b3138d9..472723a4d 100755 --- a/trunk/configure +++ b/trunk/configure @@ -5956,6 +5956,8 @@ test -n "$CURL_CONFIG" || CURL_CONFIG="no" fi + + CURL_LDADD=$($CURL_CONFIG --libs) diff --git a/trunk/configure.in b/trunk/configure.in index bb0e6432e..3b71efe5c 100644 --- a/trunk/configure.in +++ b/trunk/configure.in @@ -676,6 +676,8 @@ if test $MUST_BUILD_CURL_CLIENT = yes; then dnl So we don't do any check now. If we find out there's a problem with dnl older Curls, we will revisit that. + AC_SUBST(CURL_CONFIG) + CURL_LDADD=$($CURL_CONFIG --libs) AC_SUBST(CURL_LDADD) diff --git a/trunk/lib/curl_transport/Makefile b/trunk/lib/curl_transport/Makefile index 499ab7893..03a1973c0 100644 --- a/trunk/lib/curl_transport/Makefile +++ b/trunk/lib/curl_transport/Makefile @@ -29,7 +29,7 @@ include $(SRCDIR)/common.mk $(SRCDIR)/common.mk: srcdir blddir -CURL_VERSION := $(shell curl-config --vernum) +CURL_VERSION := $(shell $(CURL_CONFIG) --vernum) # Some time at or before Curl 7.12, became an empty file # (no-op). Some time after Curl 7.18, ceased to exist. @@ -43,7 +43,7 @@ ifeq ($(NEED_CURL_TYPES_H),Y) CFLAGS_LOCAL += -DNEED_CURL_TYPES_H endif -CURL_INCLUDES := $(shell curl-config --cflags) +CURL_INCLUDES := $(shell $(CURL_CONFIG) --cflags) # We expect that curl-config --cflags just gives us -I options, because # we need just the -I options for 'make dep'. Plus, it's scary to think # of what any other compiler flag would do to our compile. diff --git a/trunk/src/Makefile b/trunk/src/Makefile index 315097c64..1cdf8b021 100644 --- a/trunk/src/Makefile +++ b/trunk/src/Makefile @@ -57,7 +57,7 @@ ifeq ($(MUST_BUILD_CURL_CLIENT),yes) TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curltransaction TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curlmulti - TRANSPORT_LIBDEP += $(shell curl-config --libs) + TRANSPORT_LIBDEP += $(shell $CURL_CONFIG --libs) TRANSPORT_INCLUDES += -Isrcdir/lib/curl_transport endif ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) From 63e259d849caf1ef2c1db04997c582c9c2a13027 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 29 Dec 2018 03:48:10 +0000 Subject: [PATCH 041/154] Change release number to 1.54 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3026 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/version.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trunk/version.mk b/trunk/version.mk index a97ecdf94..311603ad2 100644 --- a/trunk/version.mk +++ b/trunk/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 53 -XMLRPC_POINT_RELEASE = 99 +XMLRPC_MINOR_RELEASE = 54 +XMLRPC_POINT_RELEASE = 0 From b86e39afb8e1b15c35861c8413e392c405e2fa95 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 29 Dec 2018 03:51:10 +0000 Subject: [PATCH 042/154] First 1.54 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3027 98333e67-4a24-44d7-a75c-e53540dd3050 From bb8223dc1ff3d924febba1176857947b2355a22c Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 29 Dec 2018 03:56:46 +0000 Subject: [PATCH 043/154] Promote Development as new Advanced: Release 1.54.00 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3028 98333e67-4a24-44d7-a75c-e53540dd3050 --- advanced/config.mk.in | 1 + advanced/configure | 2 + advanced/configure.in | 2 + advanced/lib/curl_transport/Makefile | 4 +- advanced/src/Makefile | 2 +- advanced/src/json.c | 86 ++++++++++++++-------------- advanced/version.mk | 2 +- 7 files changed, 52 insertions(+), 47 deletions(-) diff --git a/advanced/config.mk.in b/advanced/config.mk.in index f19ead43e..725c0632f 100644 --- a/advanced/config.mk.in +++ b/advanced/config.mk.in @@ -32,6 +32,7 @@ BUILD_TOOLS = @BUILD_TOOLS@ BUILD_XMLRPC_PSTREAM = @BUILD_XMLRPC_PSTREAM@ WININET_LDADD = @WININET_LDADD@ WININET_LIBDIR = @WININET_LIBDIR@ +CURL_CONFIG = @CURL_CONFIG@ CURL_LDADD = @CURL_LDADD@ CURL_LIBDIR = @CURL_LIBDIR@ LIBWWW_LDADD = @LIBWWW_LDADD@ diff --git a/advanced/configure b/advanced/configure index c1b3138d9..472723a4d 100755 --- a/advanced/configure +++ b/advanced/configure @@ -5956,6 +5956,8 @@ test -n "$CURL_CONFIG" || CURL_CONFIG="no" fi + + CURL_LDADD=$($CURL_CONFIG --libs) diff --git a/advanced/configure.in b/advanced/configure.in index bb0e6432e..3b71efe5c 100644 --- a/advanced/configure.in +++ b/advanced/configure.in @@ -676,6 +676,8 @@ if test $MUST_BUILD_CURL_CLIENT = yes; then dnl So we don't do any check now. If we find out there's a problem with dnl older Curls, we will revisit that. + AC_SUBST(CURL_CONFIG) + CURL_LDADD=$($CURL_CONFIG --libs) AC_SUBST(CURL_LDADD) diff --git a/advanced/lib/curl_transport/Makefile b/advanced/lib/curl_transport/Makefile index 499ab7893..03a1973c0 100644 --- a/advanced/lib/curl_transport/Makefile +++ b/advanced/lib/curl_transport/Makefile @@ -29,7 +29,7 @@ include $(SRCDIR)/common.mk $(SRCDIR)/common.mk: srcdir blddir -CURL_VERSION := $(shell curl-config --vernum) +CURL_VERSION := $(shell $(CURL_CONFIG) --vernum) # Some time at or before Curl 7.12, became an empty file # (no-op). Some time after Curl 7.18, ceased to exist. @@ -43,7 +43,7 @@ ifeq ($(NEED_CURL_TYPES_H),Y) CFLAGS_LOCAL += -DNEED_CURL_TYPES_H endif -CURL_INCLUDES := $(shell curl-config --cflags) +CURL_INCLUDES := $(shell $(CURL_CONFIG) --cflags) # We expect that curl-config --cflags just gives us -I options, because # we need just the -I options for 'make dep'. Plus, it's scary to think # of what any other compiler flag would do to our compile. diff --git a/advanced/src/Makefile b/advanced/src/Makefile index 315097c64..1cdf8b021 100644 --- a/advanced/src/Makefile +++ b/advanced/src/Makefile @@ -57,7 +57,7 @@ ifeq ($(MUST_BUILD_CURL_CLIENT),yes) TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curltransaction TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curlmulti - TRANSPORT_LIBDEP += $(shell curl-config --libs) + TRANSPORT_LIBDEP += $(shell $CURL_CONFIG --libs) TRANSPORT_INCLUDES += -Isrcdir/lib/curl_transport endif ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) diff --git a/advanced/src/json.c b/advanced/src/json.c index 394202b8e..be0257722 100644 --- a/advanced/src/json.c +++ b/advanced/src/json.c @@ -203,7 +203,7 @@ finishStringToken(xmlrpc_env * const envP, while (isxdigit(*cur) && cur - tokP->end < 4) ++cur; - + if (cur - tokP->end < 4) setParseErr(envP, tokP, "hex unicode must contain 4 digits. " @@ -268,7 +268,7 @@ isFloat(const char * const token, point number. N.B. This is true of any integer. - + We don't accept plus signs. Examples of valid floating point: 0, 32, 32.5, , 32.500, @@ -385,7 +385,7 @@ advanceToNextToken(Tokenizer * const tokP) { while (*tokP->begin != '\0' && (isspace(*tokP->begin) || atComment(tokP))) { - + advancePastWhiteSpace(tokP); advancePastComments(tokP); @@ -410,7 +410,7 @@ getToken(xmlrpc_env * const envP, tokP->size = tokP->end - tokP->begin; } else { tokP->end = tokP->begin; /* initial value */ - + if (*tokP->begin == '{') { finishDelimiterToken(tokP); tokP->type = typeOpenBrace; @@ -550,7 +550,7 @@ getBackslashSequence(xmlrpc_env * const envP, buffer[0] = '\t'; tsize = 1; *nBytesConsumedP = 1; - break; + break; case 'u': { long digit; strncpy(buffer, cur + 1, 4); @@ -587,7 +587,7 @@ unescapeString(xmlrpc_env * const envP, cur = begin; last = cur; - + while (cur != end && !envP->fault_occurred) { if (*cur == '\\') { if (cur != last) { @@ -634,7 +634,7 @@ static xmlrpc_value * makeUtf8String(xmlrpc_env * const envP, const char * const begin, const char * const end) { -/*---------------------------------------------------------------------------- +/*---------------------------------------------------------------------------- Copy a json string directly into a string value, and convert any json escaping (\uXXXX) to something acceptable to the internal string handling. @@ -671,7 +671,7 @@ stringTokenValue(xmlrpc_env * const envP, assert(tokP->end >= tokP->begin + 2); assert(*tokP->begin == '"'); assert(*(tokP->end-1) == '"'); - + valP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); if (env.fault_occurred) { @@ -706,7 +706,7 @@ integerTokenValue(xmlrpc_env * const envP, tokP->begin, env.fault_string); else valP = xmlrpc_i8_new(envP, value); - + xmlrpc_env_clean(&env); return valP; @@ -772,7 +772,7 @@ parseList(xmlrpc_env * const envP, XMLRPC_ASSERT_ENV_OK(envP); retval = xmlrpc_array_new(envP); - + if (!envP->fault_occurred) { bool endOfList; for (endOfList = false; !endOfList && !envP->fault_occurred; ) { @@ -833,9 +833,9 @@ parseObjectMember(xmlrpc_env * const envP, assert(tokP->end >= tokP->begin + 2); assert(*tokP->begin == '"'); assert(*(tokP->end-1) == '"'); - + keyP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); - + if (env.fault_occurred) setParseErr(envP, tokP, "Error in what is supposed to be " "the key of a member of an object: %s", @@ -858,7 +858,7 @@ parseObjectMember(xmlrpc_env * const envP, } - + static xmlrpc_value * parseObject(xmlrpc_env * const envP, Tokenizer * const tokP) { @@ -884,7 +884,7 @@ parseObject(xmlrpc_env * const envP, if (!envP->fault_occurred) { getToken(envP, tokP); - + if (!envP->fault_occurred) { if (tokP->type == typeComma) { /* member separator; keep going */ @@ -924,9 +924,9 @@ parseValue(xmlrpc_env * const envP, Tokenizer * const tokP) { xmlrpc_value * retval; - + XMLRPC_ASSERT_ENV_OK(envP); - + switch (tokP->type) { case typeOpenBracket: @@ -936,7 +936,7 @@ parseValue(xmlrpc_env * const envP, case typeOpenBrace: retval = parseObject(envP, tokP); break; - + case typeNull: retval = xmlrpc_nil_new(envP); break; @@ -956,7 +956,7 @@ parseValue(xmlrpc_env * const envP, case typeInteger: retval = integerTokenValue(envP, tokP); break; - + case typeFloat: retval = xmlrpc_double_new(envP, strtod(tokP->begin, NULL)); break; @@ -964,7 +964,7 @@ parseValue(xmlrpc_env * const envP, case typeString: retval = stringTokenValue(envP, tokP); break; - + default: retval = NULL; setParseErr(envP, tokP, "Invalid token " @@ -984,9 +984,9 @@ xmlrpc_parse_json(xmlrpc_env * const envP, xmlrpc_value * retval = retval; Tokenizer tok; - + XMLRPC_ASSERT_ENV_OK(envP); - + initializeTokenizer(&tok, str); getToken(envP, &tok); @@ -1093,7 +1093,7 @@ appendEscapeSeq(xmlrpc_env * const envP, char buffer[6+1]; char slashChar; /* Character that goes after the backslash, including 'u' for \uHHHH */ - + switch (c) { case '"' : slashChar = '"'; break; /* U+0022 */ case '\\': slashChar = '\\'; break; /* U+005C */ @@ -1108,7 +1108,7 @@ appendEscapeSeq(xmlrpc_env * const envP, buffer[0] = '\\'; buffer[1] = slashChar; - + if (slashChar == 'u') { sprintf(&buffer[2], "%04x", c); size = 6; /* \u1234 */ @@ -1135,7 +1135,7 @@ makeJsonString(xmlrpc_env * const envP, const char * last; last = cur = begin; - + while (cur != end && !envP->fault_occurred) { unsigned char const c = *cur; @@ -1145,7 +1145,7 @@ makeJsonString(xmlrpc_env * const envP, the characters before it to the output. */ XMLRPC_MEMBLOCK_APPEND(char, envP, outP, last, cur - last); - + if (!envP->fault_occurred) { appendEscapeSeq(envP, outP, c); @@ -1205,7 +1205,7 @@ serializeI8(xmlrpc_env * const envP, xmlrpc_int64 value; xmlrpc_read_i8(envP, valP, &value); - + formatOut(envP, outP, "%" XMLRPC_PRId64, value); } @@ -1215,7 +1215,7 @@ static void serializeBool(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - + xmlrpc_bool value; xmlrpc_read_bool(envP, valP, &value); @@ -1228,7 +1228,7 @@ static void serializeDouble(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - + xmlrpc_double value; xmlrpc_read_double(envP, valP, &value); @@ -1254,16 +1254,16 @@ serializeDatetime(xmlrpc_env * const envP, } - + static void serializeString(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - + formatOut(envP, outP, "\""); - + makeJsonStringFromXmlRpc(envP, valP, outP); - + formatOut(envP, outP, "\""); } @@ -1289,12 +1289,12 @@ serializeBitstring(xmlrpc_env * const envP, if (!envP->fault_occurred) { formatOut(envP, outP, "\""); - + XMLRPC_MEMBLOCK_APPEND( char, envP, outP, XMLRPC_MEMBLOCK_CONTENTS(char, base64P), XMLRPC_MEMBLOCK_SIZE(char, base64P)); - + if (!envP->fault_occurred) formatOut(envP, outP, "\""); @@ -1322,7 +1322,7 @@ serializeArray(xmlrpc_env * const envP, for (i = 0; i < size && !envP->fault_occurred; ++i) { xmlrpc_value * const itemP = xmlrpc_array_get_item(envP, valP, i); - + if (!envP->fault_occurred) { if (!envP->fault_occurred) { serializeValue(envP, itemP, level + 1, outP); @@ -1340,7 +1340,7 @@ serializeArray(xmlrpc_env * const envP, } } } -} +} @@ -1352,17 +1352,17 @@ serializeStructMember(xmlrpc_env * const envP, xmlrpc_mem_block * const outP) { serializeValue(envP, memberKeyP, level, outP); - + if (!envP->fault_occurred) { formatOut(envP, outP, ":"); - + if (!envP->fault_occurred) serializeValue(envP, memberValueP, level, outP); } } - + static void serializeStruct(xmlrpc_env * const envP, xmlrpc_value * const valP, @@ -1373,7 +1373,7 @@ serializeStruct(xmlrpc_env * const envP, formatOut(envP, outP, "{\n"); if (!envP->fault_occurred) { unsigned int const size = xmlrpc_struct_size(envP, valP); - + if (!envP->fault_occurred) { unsigned int i; for (i = 0; i < size && !envP->fault_occurred; ++i) { @@ -1386,7 +1386,7 @@ serializeStruct(xmlrpc_env * const envP, if (!envP->fault_occurred) { serializeStructMember(envP, memberKeyP, memberValueP, level + 1, outP); - + if (!envP->fault_occurred && i < size - 1) XMLRPC_MEMBLOCK_APPEND(char, envP, outP, ",\n", 2); } @@ -1416,7 +1416,7 @@ serializeValue(xmlrpc_env * const envP, XMLRPC_ASSERT_ENV_OK(envP); indent(envP, level, outP); - + switch (xmlrpc_value_type(valP)) { case XMLRPC_TYPE_INT: serializeInt(envP, valP, outP); @@ -1444,7 +1444,7 @@ serializeValue(xmlrpc_env * const envP, case XMLRPC_TYPE_BASE64: serializeBitstring(envP, valP, outP); - break; + break; case XMLRPC_TYPE_ARRAY: serializeArray(envP, valP, level, outP); diff --git a/advanced/version.mk b/advanced/version.mk index 7ed5663b3..311603ad2 100644 --- a/advanced/version.mk +++ b/advanced/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 53 +XMLRPC_MINOR_RELEASE = 54 XMLRPC_POINT_RELEASE = 0 From 7a427182e6c67bb725923109b5ffb6a52657ee5e Mon Sep 17 00:00:00 2001 From: giraffedata Date: Wed, 13 Mar 2019 03:21:21 +0000 Subject: [PATCH 044/154] Set up to work on 1.55 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3029 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/version.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/version.mk b/trunk/version.mk index 311603ad2..2272923ff 100644 --- a/trunk/version.mk +++ b/trunk/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 54 -XMLRPC_POINT_RELEASE = 0 +XMLRPC_POINT_RELEASE = 99 From 0194f88e1e93208d0cbf43aa8d3fa5ca61d65c3f Mon Sep 17 00:00:00 2001 From: giraffedata Date: Wed, 13 Mar 2019 03:21:41 +0000 Subject: [PATCH 045/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3030 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/examples/compound_value_client.c | 14 +-- trunk/examples/compound_value_server.c | 10 +-- trunk/lib/abyss/src/conn.c | 26 +++--- trunk/lib/abyss/src/server.c | 108 +++++++++++------------ trunk/lib/abyss/src/thread_pthread.c | 6 +- trunk/src/registry.c | 36 ++++---- trunk/src/xmlrpc_server_abyss.c | 116 ++++++++++++------------- 7 files changed, 158 insertions(+), 158 deletions(-) diff --git a/trunk/examples/compound_value_client.c b/trunk/examples/compound_value_client.c index 057517d5d..e46eef4d1 100644 --- a/trunk/examples/compound_value_client.c +++ b/trunk/examples/compound_value_client.c @@ -50,7 +50,7 @@ #define NAME "Xmlrpc-c Test Client" #define VERSION "1.0" -static void +static void dieIfFaultOccurred (xmlrpc_env * const envP) { if (envP->fault_occurred) { fprintf(stderr, "ERROR: %s (%d)\n", @@ -68,8 +68,8 @@ struct ratio { -int -main(int const argc, +int +main(int const argc, const char ** const argv) { const char * const serverUrl = "http://localhost:8080/RPC2"; @@ -114,21 +114,21 @@ main(int const argc, dieIfFaultOccurred(&env); xmlrpc_struct_set_value(&env, ratioP, "DIVISOR", divisorP); dieIfFaultOccurred(&env); - + xmlrpc_array_append_item(&env, ratioArrayP, ratioP); dieIfFaultOccurred(&env); xmlrpc_DECREF(ratioP); xmlrpc_DECREF(divisorP); xmlrpc_DECREF(dividendP); - } + } /* Make the call */ resultP = xmlrpc_client_call(&env, serverUrl, methodName, "(iA)", (xmlrpc_int32) argVersion, ratioArrayP); dieIfFaultOccurred(&env); - + /* Print out the quotients returned */ quotientCt = xmlrpc_array_size(&env, resultP); @@ -152,7 +152,7 @@ main(int const argc, xmlrpc_DECREF(resultP); xmlrpc_env_clean(&env); - + xmlrpc_client_cleanup(); return 0; diff --git a/trunk/examples/compound_value_server.c b/trunk/examples/compound_value_server.c index f10941802..15a9808c3 100644 --- a/trunk/examples/compound_value_server.c +++ b/trunk/examples/compound_value_server.c @@ -108,7 +108,7 @@ computeQuotients(xmlrpc_env * const envP, if (!envP->fault_occurred) { xmlrpc_array_append_item(envP, quotientArrayP, quotientP); - + xmlrpc_DECREF(quotientP); } } @@ -156,8 +156,8 @@ example_divide(xmlrpc_env * const envP, -int -main(int const argc, +int +main(int const argc, const char ** const argv) { struct xmlrpc_method_info3 const methodInfo = { @@ -175,7 +175,7 @@ main(int const argc, "You specified %d arguments.\n", argc-1); exit(1); } - + xmlrpc_env_init(&env); registryP = xmlrpc_registry_new(&env); @@ -184,7 +184,7 @@ main(int const argc, /* In the modern form of the Abyss API, we supply parameters in memory like a normal API. We select the modern form by setting - config_file_name to NULL: + config_file_name to NULL: */ serverparm.config_file_name = NULL; serverparm.registryP = registryP; diff --git a/trunk/lib/abyss/src/conn.c b/trunk/lib/abyss/src/conn.c index f9f36d06c..1c281654b 100644 --- a/trunk/lib/abyss/src/conn.c +++ b/trunk/lib/abyss/src/conn.c @@ -82,7 +82,7 @@ static void threadDone(void * const userHandle) { TConn * const connectionP = userHandle; - + connDone(connectionP); } @@ -94,7 +94,7 @@ makeThread(TConn * const connectionP, bool const useSigchld, size_t const jobStackSize, const char ** const errorP) { - + switch (foregroundBackground) { case ABYSS_FOREGROUND: connectionP->hasOwnThread = false; @@ -117,7 +117,7 @@ makeThread(TConn * const connectionP, } /* switch */ } - + void ConnCreate(TConn ** const connectionPP, @@ -297,7 +297,7 @@ nextLineSize(const char * const string, string 'string', which is 'stringSize' characters long. 'string' in not NUL-terminated. - + A line begins at beginning of string or after a newline character and runs through the next newline character or end of string. The line includes the newline character at the end, if any. @@ -331,7 +331,7 @@ traceBuffer(const char * const label, size_t const lineSize = nextLineSize(buffer_t, cursor, size); const char * const printableLine = xmlrpc_makePrintable_lp(&buffer_t[cursor], lineSize); - + fprintf(stderr, "%s\n", printableLine); cursor += lineSize; @@ -369,7 +369,7 @@ traceChannelWrite(TConn * const connectionP, const char * const buffer, unsigned int const size, bool const failed) { - + if (connectionP->trace) { const char * const label = failed ? "FAILED TO WRITE TO CHANNEL" : "WROTE TO CHANNEL"; @@ -501,10 +501,10 @@ ConnRead(TConn * const connectionP, bool readyForRead; bool failed; - + ChannelWait(connectionP->channelP, waitForRead, waitForWrite, timeoutMs, &readyForRead, NULL, &failed); - + if (failed) xmlrpc_asprintf(errorP, "Wait for stuff to arrive from client failed."); @@ -529,7 +529,7 @@ ConnRead(TConn * const connectionP, } - + bool ConnWrite(TConn * const connectionP, const void * const buffer, @@ -591,19 +591,19 @@ ConnWriteFromFile(TConn * const connectionP, uint64_t const bytesLeft = totalBytesToRead - bytesread; uint64_t const bytesToRead64 = MIN(readChunkSize, bytesLeft); uint32_t const bytesToRead = (uint32_t)bytesToRead64; - + uint32_t bytesReadThisTime; assert(bytesToRead == bytesToRead64); /* readChunkSize is uint32 */ bytesReadThisTime = FileRead(fileP, buffer, bytesToRead); bytesread += bytesReadThisTime; - + if (bytesReadThisTime > 0) ConnWrite(connectionP, buffer, bytesReadThisTime); else break; - + if (waittime > 0) xmlrpc_millisecond_sleep(waittime); } @@ -649,7 +649,7 @@ ConnFormatClientAddr(TConn * const connectionP, ** 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 diff --git a/trunk/lib/abyss/src/server.c b/trunk/lib/abyss/src/server.c index 13dbdf0ec..5c7f83839 100644 --- a/trunk/lib/abyss/src/server.c +++ b/trunk/lib/abyss/src/server.c @@ -106,7 +106,7 @@ logOpen(struct _TServer * const srvP, *errorP = NULL; srvP->logfileisopen = true; - + if (*errorP) FileClose(srvP->logfileP); } else @@ -174,7 +174,7 @@ initChanSwitchStuff(struct _TServer * const srvP, bool const userChanSwitch, unsigned short const port, const char ** const errorP) { - + if (chanSwitchP) { *errorP = NULL; @@ -203,7 +203,7 @@ createServer(struct _TServer ** const srvPP, bool const noAccept, TChanSwitch * const chanSwitchP, bool const userChanSwitch, - unsigned short const portNumber, + unsigned short const portNumber, const char ** const errorP) { /*---------------------------------------------------------------------------- Create a server object and return it as *srvPP. @@ -249,13 +249,13 @@ createServer(struct _TServer ** const srvPP, ListInitAutoFree(&srvP->handlers); srvP->logfileisopen = false; - + *errorP = NULL; if (*errorP) HandlerDestroy(srvP->builtinHandlerP); } - } + } if (*errorP) free(srvP); } @@ -315,7 +315,7 @@ ServerCreate(TServer * const serverP, success = false; } else { success = true; - + setNamePathLog(serverP, name, filesPath, logFileName); } @@ -395,7 +395,7 @@ ServerCreateSocket(TServer * const serverP, xmlrpc_strfree(error); } else { success = true; - + setNamePathLog(serverP, name, filesPath, logFileName); } if (!success) @@ -435,7 +435,7 @@ ServerCreateNoAccept(TServer * const serverP, xmlrpc_strfree(error); } else { success = true; - + setNamePathLog(serverP, name, filesPath, logFileName); } return success; @@ -472,7 +472,7 @@ void ServerCreateSocket2(TServer * const serverP, TSocket * const socketP, const char ** const errorP) { - + TChanSwitch * const chanSwitchP = SocketGetChanSwitch(socketP); assert(socketP); @@ -521,7 +521,7 @@ ServerFree(TServer * const serverP) { ListFree(&srvP->handlers); HandlerDestroy(srvP->builtinHandlerP); - + logClose(srvP); if (srvP->logfilename) @@ -537,7 +537,7 @@ ServerSetName(TServer * const serverP, const char * const name) { xmlrpc_strfree(serverP->srvP->name); - + serverP->srvP->name = strdup(name); } @@ -555,12 +555,12 @@ ServerSetFilesPath(TServer * const serverP, void ServerSetLogFileName(TServer * const serverP, const char * const logFileName) { - + struct _TServer * const srvP = serverP->srvP; if (srvP->logfilename) xmlrpc_strfree(srvP->logfilename); - + srvP->logfilename = strdup(logFileName); } @@ -605,7 +605,7 @@ ServerSetAdvertise(TServer * const serverP, void ServerSetMimeType(TServer * const serverP, MIMEType * const mimeTypeP) { - + HandlerSetMimeType(serverP->srvP->builtinHandlerP, mimeTypeP); } @@ -665,12 +665,12 @@ runUserHandler(TSession * const sessionP, abyss_bool handled; int i; - + for (i = srvP->handlers.size-1, handled = false; i >= 0 && !handled; --i) { const struct uriHandler * const handlerP = srvP->handlers.item[i]; - + if (handlerP->handleReq3) handlerP->handleReq3(handlerP->userdata, sessionP, &handled); if (handlerP->handleReq2) { @@ -681,7 +681,7 @@ runUserHandler(TSession * const sessionP, } assert(srvP->defaultHandler); - + if (!handled) srvP->defaultHandler(sessionP); } @@ -698,9 +698,9 @@ handleReqTooNewHttpVersion(TSession * const sessionP) { xmlrpc_asprintf(&msg, "Request is in HTTP Version %u" "We understand only HTTP 1", sessionP->version.major); - + ResponseError2(sessionP, msg); - + xmlrpc_strfree(msg); } @@ -766,7 +766,7 @@ processRequestFromClient(TConn * const connectionP, SessionInit(&session, connectionP); session.serverDeniesKeepalive = lastReqOnConn; - + SessionReadRequest(&session, timeout, &error, &httpErrorCode); if (error) { @@ -825,7 +825,7 @@ serverFunc(void * const userHandle) { while (!connectionDone) { bool timedOut, eof; const char * readError; - + /* Wait for and get beginning (at least ) of next request. We do this separately from getting the rest of the request because we treat dead time between requests differently from dead time in @@ -853,19 +853,19 @@ serverFunc(void * const userHandle) { trace(&srvP->tracer, "HTTP request %u at least partially received. " "Receiving the rest and processing", requestCount); - + processRequestFromClient(connectionP, lastReqOnConn, srvP->timeout, &srvP->tracer, &keepalive); trace(&srvP->tracer, "Done processing the HTTP request. Keepalive = %s", keepalive ? "YES" : "NO"); - + ++requestCount; if (!keepalive) connectionDone = true; - + /**************** Must adjust the read buffer *****************/ ConnReadInit(connectionP); } @@ -893,7 +893,7 @@ createSwitchFromPortNum(unsigned short const portNumber, #else ChanSwitchUnixCreate(portNumber, chanSwitchPP, errorP); #endif -} +} @@ -903,7 +903,7 @@ createChanSwitch(struct _TServer * const srvP, TChanSwitch * chanSwitchP; const char * error; - + /* Not valid to call this when channel switch already exists: */ assert(srvP->chanSwitchP == NULL); @@ -915,7 +915,7 @@ createChanSwitch(struct _TServer * const srvP, xmlrpc_strfree(error); } else { *errorP = NULL; - + srvP->weCreatedChanSwitch = true; srvP->chanSwitchP = chanSwitchP; } @@ -935,7 +935,7 @@ ServerInit2(TServer * const serverP, user supplies the channels (TCP connections)). -----------------------------------------------------------------------------*/ struct _TServer * const srvP = serverP->srvP; - + if (!srvP->serverAcceptsConnections) xmlrpc_asprintf(errorP, "ServerInit() is not valid on a server that doesn't " @@ -991,7 +991,7 @@ ServerInit(TServer * const serverP) { -/* We don't do any locking on the outstanding connections list, so +/* We don't do any locking on the outstanding connections list, so we must make sure that only the master thread (the one that listens for connections) ever accesses it. @@ -1062,12 +1062,12 @@ freeFinishedConns(outstandingConnList * const listP) { TConn * const connectionP = (*pp); ThreadUpdateStatus(connectionP->threadP); - + if (connectionP->finished) { /* Take it out of the list */ *pp = connectionP->nextOutstandingP; --listP->count; - + ConnWaitAndRelease(connectionP); } else { /* Move to next connection in list */ @@ -1103,7 +1103,7 @@ waitForNoConnections(outstandingConnList * const outstandingConnListP) { while (outstandingConnListP->firstP) { freeFinishedConns(outstandingConnListP); - + if (outstandingConnListP->firstP) waitForConnectionFreed(outstandingConnListP); } @@ -1141,7 +1141,7 @@ interruptChannels(outstandingConnList * const outstandingConnListP) { /* The connection couldn't be waiting on the channel, and the channel probably doesn't even exit anymore. */ - } else + } else ChannelInterrupt(connP->channelP); } } @@ -1162,7 +1162,7 @@ void ServerUseSigchld(TServer * const serverP) { struct _TServer * const srvP = serverP->srvP; - + srvP->useSigchld = true; } @@ -1199,18 +1199,18 @@ processNewChannel(TServer * const serverP, const char ** const errorP) { struct _TServer * const srvP = serverP->srvP; - + TConn * connectionP; const char * error; freeFinishedConns(outstandingConnListP); - + trace(&srvP->tracer, "Waiting for there to be fewer than the maximum " "%u sessions in progress", srvP->maxConn); waitForConnectionCapacity(outstandingConnListP, srvP->maxConn); - + ConnCreate(&connectionP, serverP, channelP, channelInfoP, &serverFunc, SERVER_FUNC_STACK + srvP->uriHandlerStackSize, @@ -1249,9 +1249,9 @@ acceptAndProcessNextConnection( assert(srvP->readyToAccept); assert(srvP->chanSwitchP); - + ChanSwitchAccept(srvP->chanSwitchP, &channelP, &channelInfoP, &error); - + if (error) { xmlrpc_asprintf(errorP, "Failed to accept the next connection from a client " @@ -1289,7 +1289,7 @@ acceptAndProcessNextConnection( -static void +static void serverRun2(TServer * const serverP, const char ** const errorP) { @@ -1301,7 +1301,7 @@ serverRun2(TServer * const serverP, *errorP = NULL; /* initial value */ trace(&srvP->tracer, "Starting main connection accepting loop"); - + while (!srvP->terminationRequested && !*errorP) acceptAndProcessNextConnection(serverP, outstandingConnListP, errorP); @@ -1316,7 +1316,7 @@ serverRun2(TServer * const serverP, interruptChannels(outstandingConnListP); waitForNoConnections(outstandingConnListP); - + trace(&srvP->tracer, "No connections left"); destroyOutstandingConnList(outstandingConnListP); @@ -1325,7 +1325,7 @@ serverRun2(TServer * const serverP, -void +void ServerRun(TServer * const serverP) { struct _TServer * const srvP = serverP->srvP; @@ -1376,7 +1376,7 @@ serverRunChannel(TServer * const serverP, srvP->keepalivemaxconn = 1; - ConnCreate(&connectionP, + ConnCreate(&connectionP, serverP, channelP, channelInfoP, &serverFunc, SERVER_FUNC_STACK + srvP->uriHandlerStackSize, NULL, ABYSS_FOREGROUND, srvP->useSigchld, @@ -1503,7 +1503,7 @@ ServerRunOnce(TServer * const serverP) { const char * error; TChannel * channelP; void * channelInfoP; - + srvP->keepalivemaxconn = 1; assert(srvP->chanSwitchP); @@ -1558,7 +1558,7 @@ ServerRunOnce2(TServer * const serverP, static void setGroups(const char ** const errorP) { -#if HAVE_SETGROUPS +#if HAVE_SETGROUPS if (setgroups(0, NULL) == -1) xmlrpc_asprintf(errorP, "setgroups() errno = %d (%s)", errno, strerror(errno)); @@ -1595,7 +1595,7 @@ ServerDaemonize(TServer * const serverP) { /* We are the parent */ exit(0); } - + setsid(); /* Change the current user if we are root */ @@ -1616,14 +1616,14 @@ ServerDaemonize(TServer * const serverP) { if (srvP->gid != (gid_t)-1) if (setgid(srvP->gid)==(-1)) TraceExit("Failed to change the group."); - + if (setuid(srvP->uid) == -1) TraceExit("Failed to change the user."); } - + if (srvP->pidfileP) { char z[16]; - + sprintf(z, "%d", XMLRPC_GETPID()); FileWrite(srvP->pidfileP, z, strlen(z)); FileClose(srvP->pidfileP); @@ -1663,7 +1663,7 @@ serverAddHandler(TServer * const serverP, srvP->uriHandlerStackSize = MAX(srvP->uriHandlerStackSize, handleReqStackSize); - + if (handlerP->init == NULL) *successP = true; else { @@ -1706,7 +1706,7 @@ ServerAddHandler2(TServer * const serverP, one which is our argument, but it isn't the same one. User can discard *handlerArgP as soon as we return. */ - + serverAddHandler(serverP, handlerArgP->init, handlerArgP->term, @@ -1789,7 +1789,7 @@ LogWrite(TServer * const serverP, srvP->logLockP->acquire(srvP->logLockP); FileWrite(srvP->logfileP, msg, strlen(msg)); FileWrite(srvP->logfileP, lbr, strlen(lbr)); - + srvP->logLockP->release(srvP->logLockP); } } @@ -1812,7 +1812,7 @@ LogWrite(TServer * const serverP, ** 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 diff --git a/trunk/lib/abyss/src/thread_pthread.c b/trunk/lib/abyss/src/thread_pthread.c index d400f3084..dd0df72cb 100644 --- a/trunk/lib/abyss/src/thread_pthread.c +++ b/trunk/lib/abyss/src/thread_pthread.c @@ -92,7 +92,7 @@ ThreadCreate(TThread ** const threadPP, pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, MAX(MIN_STACK_SIZE, stackSize)); - + threadP->userHandle = userHandle; threadP->func = func; threadP->threadDone = threadDone; @@ -106,7 +106,7 @@ ThreadCreate(TThread ** const threadPP, xmlrpc_asprintf( errorP, "pthread_create() failed, errno = %d (%s)", errno, strerror(errno)); - + pthread_attr_destroy(&attr); if (*errorP) @@ -119,7 +119,7 @@ ThreadCreate(TThread ** const threadPP, bool ThreadRun(TThread * const threadP ATTR_UNUSED) { - return true; + return true; } diff --git a/trunk/src/registry.c b/trunk/src/registry.c index b67944a31..4dae56515 100644 --- a/trunk/src/registry.c +++ b/trunk/src/registry.c @@ -55,7 +55,7 @@ xmlrpc_registry_new(xmlrpc_env * const envP) { xmlrpc_registry * registryP; XMLRPC_ASSERT_ENV_OK(envP); - + MALLOCVAR(registryP); if (registryP == NULL) @@ -79,7 +79,7 @@ xmlrpc_registry_new(xmlrpc_env * const envP) { -void +void xmlrpc_registry_free(xmlrpc_registry * const registryP) { XMLRPC_ASSERT_PTR_OK(registryP); @@ -91,7 +91,7 @@ xmlrpc_registry_free(xmlrpc_registry * const registryP) { -static void +static void registryAddMethod(xmlrpc_env * const envP, xmlrpc_registry * const registryP, const char * const methodName, @@ -126,7 +126,7 @@ registryAddMethod(xmlrpc_env * const envP, -void +void xmlrpc_registry_add_method_w_doc( xmlrpc_env * const envP, xmlrpc_registry * const registryP, @@ -145,7 +145,7 @@ xmlrpc_registry_add_method_w_doc( -void +void xmlrpc_registry_add_method(xmlrpc_env * const envP, xmlrpc_registry * const registryP, const char * const host, @@ -189,7 +189,7 @@ xmlrpc_registry_add_method3( -void +void xmlrpc_registry_set_default_method( xmlrpc_env * const envP ATTR_UNUSED, xmlrpc_registry * const registryP ATTR_UNUSED, @@ -240,7 +240,7 @@ xmlrpc_registry_max_stackSize(xmlrpc_registry * const registryP) { for (p = registryP->methodListP->firstMethodP, stackSize = 0; p; p = p->nextP) { - + stackSize = MAX(stackSize, methodStackSize(p->methodP)); } return stackSize; @@ -248,7 +248,7 @@ xmlrpc_registry_max_stackSize(xmlrpc_registry * const registryP) { -void +void xmlrpc_registry_set_preinvoke_method( xmlrpc_env * const envP ATTR_UNUSED, xmlrpc_registry * const registryP ATTR_UNUSED, @@ -316,9 +316,9 @@ callNamedMethod(xmlrpc_env * const envP, void -xmlrpc_dispatchCall(xmlrpc_env * const envP, +xmlrpc_dispatchCall(xmlrpc_env * const envP, xmlrpc_registry * const registryP, - const char * const methodName, + const char * const methodName, xmlrpc_value * const paramArrayP, void * const callInfoP, xmlrpc_value ** const resultPP) { @@ -345,7 +345,7 @@ xmlrpc_dispatchCall(xmlrpc_env * const envP, xmlrpc_env_set_fault_formatted( envP, XMLRPC_NO_SUCH_METHOD_ERROR, "Method '%s' not defined", methodName); - } + } } } /* For backward compatibility, for sloppy users: */ @@ -397,7 +397,7 @@ xmlrpc_registry_process_call2(xmlrpc_env * const envP, XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT_PTR_OK(callXml); - + xmlrpc_traceXml("XML-RPC CALL", callXml, callXmlLen); /* Allocate our output buffer. @@ -412,7 +412,7 @@ xmlrpc_registry_process_call2(xmlrpc_env * const envP, xmlrpc_env_init(&fault); xmlrpc_env_init(&parseEnv); - xmlrpc_parse_call(&parseEnv, callXml, callXmlLen, + xmlrpc_parse_call(&parseEnv, callXml, callXmlLen, &methodName, ¶mArrayP); if (parseEnv.fault_occurred) @@ -422,7 +422,7 @@ xmlrpc_registry_process_call2(xmlrpc_env * const envP, parseEnv.fault_string); else { xmlrpc_value * resultP; - + xmlrpc_dispatchCall(&fault, registryP, methodName, paramArrayP, callInfo, &resultP); @@ -431,7 +431,7 @@ xmlrpc_registry_process_call2(xmlrpc_env * const envP, resultP, registryP->dialect); xmlrpc_DECREF(resultP); - } + } xmlrpc_strfree(methodName); xmlrpc_DECREF(paramArrayP); } @@ -445,7 +445,7 @@ xmlrpc_registry_process_call2(xmlrpc_env * const envP, XMLRPC_MEMBLOCK_FREE(char, responseXmlP); else { *responseXmlPP = responseXmlP; - xmlrpc_traceXml("XML-RPC RESPONSE", + xmlrpc_traceXml("XML-RPC RESPONSE", XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlP), XMLRPC_MEMBLOCK_SIZE(char, responseXmlP)); } @@ -484,8 +484,8 @@ xmlrpc_registry_process_call(xmlrpc_env * const envP, ** 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. -** +** 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 diff --git a/trunk/src/xmlrpc_server_abyss.c b/trunk/src/xmlrpc_server_abyss.c index f22aee7d8..47c7042aa 100644 --- a/trunk/src/xmlrpc_server_abyss.c +++ b/trunk/src/xmlrpc_server_abyss.c @@ -86,13 +86,13 @@ static unsigned int globallyInitialized = 0; void xmlrpc_server_abyss_global_init(xmlrpc_env * const envP) { - + /* Note that this is specified as not thread safe; user calls it at the beginning of his program, when it is only one thread. */ XMLRPC_ASSERT_ENV_OK(envP); - + if (globallyInitialized == 0) initAbyss(envP); @@ -133,7 +133,7 @@ processXmlrpcCall(xmlrpc_env * const envP, void * const arg, const char * const callXml, size_t const callXmlLen, - TSession * const abyssSessionP, + TSession * const abyssSessionP, xmlrpc_mem_block ** const responseXmlPP) { xmlrpc_registry * const registryP = arg; @@ -151,14 +151,14 @@ setHandler(xmlrpc_env * const envP, TServer * const srvP, struct uriHandlerXmlrpc * const uriHandlerXmlrpcP, size_t const xmlProcessorMaxStackSize) { - + abyss_bool success; xmlrpc_abyss_handler_trace( getenv("XMLRPC_TRACE_ABYSS")); - + { - size_t const stackSize = + size_t const stackSize = xmlrpc_abyss_handler_stacksize() + xmlProcessorMaxStackSize; struct ServerReqHandler3 const handlerDesc = { /* .term = */ &xmlrpc_termUriHandler, @@ -252,7 +252,7 @@ xmlrpc_server_abyss_set_handler3( uriHandlerXmlrpcP->chunkResponse = parmsP->chunk_response; else uriHandlerXmlrpcP->chunkResponse = false; - + interpretHttpAccessControl(parmsP, parmSize, &uriHandlerXmlrpcP->accessControl); @@ -290,7 +290,7 @@ xmlrpc_server_abyss_set_handler2( xmlrpc_server_abyss_set_handler3(&env, srvP, &parms, XMLRPC_AHPSIZE(chunk_response)); - + if (env.fault_occurred) abort(); @@ -316,14 +316,14 @@ xmlrpc_server_abyss_set_handler(xmlrpc_env * const envP, &parms, XMLRPC_AHPSIZE(uri_path)); } - + void xmlrpc_server_abyss_set_default_handler(TServer * const srvP) { ServerDefaultHandler(srvP, xmlrpc_serverAbyssDefaultUriHandler); } - + static void @@ -351,7 +351,7 @@ setHandlersRegistry(TServer * const srvP, xmlrpc_server_abyss_set_handler3( &env, srvP, &parms, XMLRPC_AHPSIZE(access_ctl_max_age)); - + if (env.fault_occurred) abort(); @@ -465,7 +465,7 @@ extractSockAddrParms(xmlrpc_env * const envP, portNumber = parmsP->port_number; else portNumber = 8080; - + if (portNumber > 0xffff) xmlrpc_faultf(envP, "TCP port number %u exceeds the maximum possible " @@ -473,7 +473,7 @@ extractSockAddrParms(xmlrpc_env * const envP, portNumber); *portNumberP = portNumber; - } + } } @@ -489,7 +489,7 @@ extractServerCreateParms( unsigned int * const portNumberP, TOsSocket * const socketFdP, const char ** const logFileNameP) { - + if (parmSize >= XMLRPC_APSIZE(socket_bound)) *socketBoundP = parmsP->socket_bound; @@ -559,10 +559,10 @@ chanSwitchCreateSockAddr(int const protocolFamily, const char ** const errorP) { #if MSVCRT - ChanSwitchWinCreate2(protocolFamily, sockAddrP, sockAddrLen, + ChanSwitchWinCreate2(protocolFamily, sockAddrP, sockAddrLen, chanSwitchPP, errorP); #else - ChanSwitchUnixCreate2(protocolFamily, sockAddrP, sockAddrLen, + ChanSwitchUnixCreate2(protocolFamily, sockAddrP, sockAddrLen, chanSwitchPP, errorP); #endif @@ -624,7 +624,7 @@ createChanSwitchIpv4Port(xmlrpc_env * const envP, chanSwitchCreateSockAddr(PF_INET, (const struct sockaddr *)&sockAddr, sizeof(sockAddr), chanSwitchPP, &error); - + if (error) { xmlrpc_faultf(envP, "Unable to create Abyss channel switch " "to listen on Port %u at any IPv4 address. %s", @@ -680,9 +680,9 @@ createServerBare(xmlrpc_env * const envP, xmlrpc_strfree(error); } else { *chanSwitchPP = chanSwitchP; - + ServerSetName(serverP, "XmlRpcServer"); - + if (logFileName) ServerSetLogFileName(serverP, logFileName); } @@ -699,7 +699,7 @@ createServerBare(xmlrpc_env * const envP, static const char * uriPathParm(const xmlrpc_server_abyss_parms * const parmsP, unsigned int const parmSize) { - + const char * uriPath; if (parmSize >= XMLRPC_APSIZE(uri_path) && parmsP->uri_path) @@ -719,7 +719,7 @@ chunkResponseParm(const xmlrpc_server_abyss_parms * const parmsP, return parmSize >= XMLRPC_APSIZE(chunk_response) && parmsP->chunk_response; -} +} @@ -730,7 +730,7 @@ allowOriginParm(const xmlrpc_server_abyss_parms * const parmsP, return parmSize >= XMLRPC_APSIZE(allow_origin) ? parmsP->allow_origin : NULL; -} +} @@ -741,7 +741,7 @@ expiresParm(const xmlrpc_server_abyss_parms * const parmsP, return parmSize >= XMLRPC_APSIZE(access_ctl_expires) ? parmsP->access_ctl_expires : false; -} +} @@ -752,7 +752,7 @@ maxAgeParm(const xmlrpc_server_abyss_parms * const parmsP, return parmSize >= XMLRPC_APSIZE(access_ctl_max_age) ? parmsP->access_ctl_max_age : 0; -} +} @@ -769,14 +769,14 @@ createServer(xmlrpc_env * const envP, const char * error; setAdditionalServerParms(parmsP, parmSize, abyssServerP); - + setHandlersRegistry(abyssServerP, uriPathParm(parmsP, parmSize), parmsP->registryP, chunkResponseParm(parmsP, parmSize), allowOriginParm(parmsP, parmSize), expiresParm(parmsP, parmSize), maxAgeParm(parmsP, parmSize)); - + ServerInit2(abyssServerP, &error); if (error) { @@ -822,7 +822,7 @@ shutdownAbyss(xmlrpc_env * const faultP, xmlrpc_server_abyss_t * const serverP = context; xmlrpc_env_init(faultP); - + if (!serverP->shutdownEnabled) xmlrpc_env_set_fault_formatted( faultP, XMLRPC_REQUEST_REFUSED_ERROR, @@ -866,14 +866,14 @@ xmlrpc_server_abyss_create(xmlrpc_env * const envP, else { createServer(envP, parmsP, parmSize, &serverP->abyssServer, &serverP->chanSwitchP); - + if (!envP->fault_occurred) { serverP->shutdownEnabled = enableShutdownParm(parmsP, parmSize); xmlrpc_registry_set_shutdown( parmsP->registryP, &shutdownAbyss, serverP); - + if (envP->fault_occurred) free(serverP); else @@ -938,7 +938,7 @@ xmlrpc_server_abyss_reset_terminate( -static void +static void sigchld(int const signalClass ATTR_UNUSED) { /*---------------------------------------------------------------------------- This is a signal handler for a SIGCHLD signal (which informs us that @@ -959,19 +959,19 @@ sigchld(int const signalClass ATTR_UNUSED) { error = false; childrenLeft = true; /* initial assumption */ - + /* Reap defunct children until there aren't any more. */ while (childrenLeft && !error) { int status; pid_t pid; pid = waitpid((pid_t) -1, &status, WNOHANG); - + if (pid == 0) childrenLeft = false; else if (pid < 0) { /* because of ptrace */ - if (errno != EINTR) + if (errno != EINTR) error = true; } else ServerHandleSigchld(pid); @@ -1000,19 +1000,19 @@ static void setupSignalHandlers(xmlrpc_server_abyss_sig * const oldHandlersP) { #if !MSVCRT struct sigaction mysigaction; - + sigemptyset(&mysigaction.sa_mask); mysigaction.sa_flags = 0; /* This signal indicates connection closed in the middle */ mysigaction.sa_handler = SIG_IGN; sigaction(SIGPIPE, &mysigaction, &oldHandlersP->pipe); - + /* This signal indicates a child process (request handler) has died */ mysigaction.sa_handler = sigchld; sigaction(SIGCHLD, &mysigaction, &oldHandlersP->chld); #endif -} +} @@ -1065,7 +1065,7 @@ xmlrpc_server_abyss_restore_sig( restoreSignalHandlers(oldHandlersP); } - + static void @@ -1080,7 +1080,7 @@ runServerDaemon(TServer * const serverP, ServerUseSigchld(serverP); ServerDaemonize(serverP); - + /* We run the user supplied runfirst after forking, but before accepting connections (helpful when running with threads) */ @@ -1099,7 +1099,7 @@ oldHighLevelAbyssRun(xmlrpc_env * const envP, const xmlrpc_server_abyss_parms * const parmsP, unsigned int const parmSize) { /*---------------------------------------------------------------------------- - This is the old deprecated interface, where the caller of the + This is the old deprecated interface, where the caller of the xmlrpc_server_abyss API supplies an Abyss configuration file and we use it to daemonize (fork into the background, chdir, set uid, etc.) and run the Abyss server. @@ -1121,16 +1121,16 @@ oldHighLevelAbyssRun(xmlrpc_env * const envP, void * runfirstArg; assert(parmSize >= XMLRPC_APSIZE(config_file_name)); - + ConfReadServerFile(parmsP->config_file_name, &server); - + assert(parmSize >= XMLRPC_APSIZE(registryP)); - + setHandlersRegistry(&server, "/RPC2", parmsP->registryP, false, NULL, false, 0); - + ServerInit(&server); - + if (parmSize >= XMLRPC_APSIZE(runfirst_arg)) { runfirst = parmsP->runfirst; runfirstArg = parmsP->runfirst_arg; @@ -1150,7 +1150,7 @@ static void normalLevelAbyssRun(xmlrpc_env * const envP, const xmlrpc_server_abyss_parms * const parmsP, unsigned int const parmSize) { - + xmlrpc_server_abyss_t * serverP; xmlrpc_server_abyss_create(envP, parmsP, parmSize, &serverP); @@ -1231,7 +1231,7 @@ static xmlrpc_registry * builtin_registryP; -void +void xmlrpc_server_abyss_init_registry(void) { /* This used to just create the registry and Caller would be @@ -1241,7 +1241,7 @@ xmlrpc_server_abyss_init_registry(void) { together; there's no sense in using the built-in registry and not the built-in handlers because if you're custom building something, you can just make your own regular registry. So now - we tie them together, and we don't export our handlers. + we tie them together, and we don't export our handlers. */ xmlrpc_env env; @@ -1269,7 +1269,7 @@ xmlrpc_server_abyss_registry(void) { /* A quick & easy shorthand for adding a method. */ -void +void xmlrpc_server_abyss_add_method(char * const method_name, xmlrpc_method const method, void * const user_data) { @@ -1297,13 +1297,13 @@ xmlrpc_server_abyss_add_method_w_doc(char * const method_name, &env, builtin_registryP, NULL, method_name, method, user_data, signature, help); dieIfFaultOccurred(&env); - xmlrpc_env_clean(&env); + xmlrpc_env_clean(&env); } -void -xmlrpc_server_abyss_init(int const flags ATTR_UNUSED, +void +xmlrpc_server_abyss_init(int const flags ATTR_UNUSED, const char * const config_file) { abyss_bool success; @@ -1327,16 +1327,16 @@ xmlrpc_server_abyss_init(int const flags ATTR_UNUSED, -void +void xmlrpc_server_abyss_run_first(runfirstFn const runfirst, void * const runfirstArg) { - + runServerDaemon(&globalSrv, runfirst, runfirstArg); } -void +void xmlrpc_server_abyss_run(void) { runServerDaemon(&globalSrv, NULL, NULL); } @@ -1355,8 +1355,8 @@ xmlrpc_server_abyss_run(void) { ** 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. -** +** 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 @@ -1369,6 +1369,6 @@ xmlrpc_server_abyss_run(void) { ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** -** There is more copyright information in the bottom half of this file. -** Please see it for more details. +** There is more copyright information in the bottom half of this file. +** Please see it for more details. */ From 7c2d3ba6db295352493d7cbc260b3e9c4393becf Mon Sep 17 00:00:00 2001 From: giraffedata Date: Thu, 21 Mar 2019 15:16:28 +0000 Subject: [PATCH 046/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3031 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/src/cpp/pstream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/src/cpp/pstream.cpp b/trunk/src/cpp/pstream.cpp index d267315df..e15ac4c44 100644 --- a/trunk/src/cpp/pstream.cpp +++ b/trunk/src/cpp/pstream.cpp @@ -4,7 +4,7 @@ Client XML transport for Xmlrpc-c based on a very simple byte stream. - + The protocol we use is the "packet socket" protocol, which is an Xmlrpc-c invention. It is an almost trivial representation of a sequence of packets on a byte stream. From b4c280b8a9d10a60ce9555ec7d57cb60923ff480 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 29 Mar 2019 03:30:34 +0000 Subject: [PATCH 047/154] Last 1.43 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3032 98333e67-4a24-44d7-a75c-e53540dd3050 From ff958f87c582d963107aade3337f9839cbd77b96 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 29 Mar 2019 03:33:33 +0000 Subject: [PATCH 048/154] Promote stable to super stable git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3033 98333e67-4a24-44d7-a75c-e53540dd3050 From 4afe6a22426ea7b62b60d64dbe9f4788d455ab65 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 29 Mar 2019 03:43:43 +0000 Subject: [PATCH 049/154] try to clean up from prior interrupted commit git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3034 98333e67-4a24-44d7-a75c-e53540dd3050 From 21c3d18d6c5cc8fa52c9286d4a37de44a93b7556 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 29 Mar 2019 03:51:11 +0000 Subject: [PATCH 050/154] Promote Advanced to Stable git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3035 98333e67-4a24-44d7-a75c-e53540dd3050 --- stable/GNUmakefile | 1 + stable/config.mk.in | 1 + stable/configure | 2 + stable/configure.in | 2 + stable/examples/cpp/pstream_serial_server.cpp | 10 +- stable/include/xmlrpc-c/client_transport.hpp | 20 +- stable/lib/abyss/src/http.c | 84 +- stable/lib/abyss/src/sessionReadRequest.c | 50 +- stable/lib/curl_transport/Makefile | 4 +- .../curl_transport/xmlrpc_curl_transport.c | 120 +- stable/lib/expat/Makefile | 2 +- stable/lib/expat/xmltok/xmltok_impl.c | 1039 +++++++++-------- stable/lib/libutil/error.c | 22 +- .../xmlrpc_wininet_transport.c | 108 +- stable/src/Makefile | 2 +- stable/src/cpp/client.cpp | 44 +- stable/src/cpp/client_simple.cpp | 16 +- stable/src/cpp/packetsocket.cpp | 23 +- stable/src/cpp/value.cpp | 8 - stable/src/json.c | 86 +- stable/src/xmlrpc_string.c | 5 - stable/test/cpp/value.cpp | 41 +- stable/tools/lib/Makefile | 2 +- stable/version.mk | 4 +- 24 files changed, 881 insertions(+), 815 deletions(-) diff --git a/stable/GNUmakefile b/stable/GNUmakefile index 7d3aff019..ea6ef12c9 100644 --- a/stable/GNUmakefile +++ b/stable/GNUmakefile @@ -148,6 +148,7 @@ distclean-local: clean-local rm -f config.log config.status config.mk srcdir.mk rm -f xmlrpc_config.h xmlrpc_amconfig.h stamp-h rm -f shell_config xmlrpc-c-config xmlrpc-c-config.test + rm -rf autom4te.cache # gets created by 'autoconf' rm -f TAGS check: $(SUBDIRS:%=%/check) diff --git a/stable/config.mk.in b/stable/config.mk.in index f19ead43e..725c0632f 100644 --- a/stable/config.mk.in +++ b/stable/config.mk.in @@ -32,6 +32,7 @@ BUILD_TOOLS = @BUILD_TOOLS@ BUILD_XMLRPC_PSTREAM = @BUILD_XMLRPC_PSTREAM@ WININET_LDADD = @WININET_LDADD@ WININET_LIBDIR = @WININET_LIBDIR@ +CURL_CONFIG = @CURL_CONFIG@ CURL_LDADD = @CURL_LDADD@ CURL_LIBDIR = @CURL_LIBDIR@ LIBWWW_LDADD = @LIBWWW_LDADD@ diff --git a/stable/configure b/stable/configure index c1b3138d9..472723a4d 100755 --- a/stable/configure +++ b/stable/configure @@ -5956,6 +5956,8 @@ test -n "$CURL_CONFIG" || CURL_CONFIG="no" fi + + CURL_LDADD=$($CURL_CONFIG --libs) diff --git a/stable/configure.in b/stable/configure.in index bb0e6432e..3b71efe5c 100644 --- a/stable/configure.in +++ b/stable/configure.in @@ -676,6 +676,8 @@ if test $MUST_BUILD_CURL_CLIENT = yes; then dnl So we don't do any check now. If we find out there's a problem with dnl older Curls, we will revisit that. + AC_SUBST(CURL_CONFIG) + CURL_LDADD=$($CURL_CONFIG --libs) AC_SUBST(CURL_LDADD) diff --git a/stable/examples/cpp/pstream_serial_server.cpp b/stable/examples/cpp/pstream_serial_server.cpp index 73d96c282..ae73a819b 100644 --- a/stable/examples/cpp/pstream_serial_server.cpp +++ b/stable/examples/cpp/pstream_serial_server.cpp @@ -42,20 +42,20 @@ class sampleAddMethod : public xmlrpc_c::method { void execute(xmlrpc_c::paramList const& paramList, xmlrpc_c::value * const retvalP) { - + int const addend(paramList.getInt(0)); int const adder(paramList.getInt(1)); - + paramList.verifyEnd(2); - + *retvalP = xmlrpc_c::value_int(addend + adder); } }; -int -main(int const, +int +main(int const, const char ** const) { #ifndef _WIN32 diff --git a/stable/include/xmlrpc-c/client_transport.hpp b/stable/include/xmlrpc-c/client_transport.hpp index 4c6c87e1f..9b1bdd9e4 100644 --- a/stable/include/xmlrpc-c/client_transport.hpp +++ b/stable/include/xmlrpc-c/client_transport.hpp @@ -86,7 +86,7 @@ class XMLRPC_CLIENTPP_EXPORTED xmlTransactionPtr : public girmem::autoObjectPtr xmlTransactionPtr(); xmlTransactionPtr(xmlTransaction * xmlTransP); - + xmlrpc_c::xmlTransaction * operator->() const; }; @@ -133,7 +133,7 @@ class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport : public girmem::autoObject { }; class XMLRPC_CLIENTPP_EXPORTED clientXmlTransportPtr : public girmem::autoObjectPtr { - + public: clientXmlTransportPtr(); @@ -166,25 +166,25 @@ class XMLRPC_CLIENTPP_EXPORTED carriageParm_http0 : public xmlrpc_c::carriagePar void disallowAuthBasic(); - + void allowAuthDigest(); void disallowAuthDigest(); - + void allowAuthNegotiate(); void disallowAuthNegotiate(); - + void allowAuthNtlm(); void disallowAuthNtlm(); - + void setBasicAuth(std::string const userid, std::string const password); @@ -219,17 +219,17 @@ class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_http : public xmlrpc_c::client -----------------------------------------------------------------------------*/ 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); @@ -350,7 +350,7 @@ class XMLRPC_CLIENTPP_EXPORTED carriageParm_libwww0Ptr : public xmlrpc_c::carria }; class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_libwww : public xmlrpc_c::clientXmlTransport_http { - + public: clientXmlTransport_libwww(std::string const appname = "", std::string const appversion = ""); diff --git a/stable/lib/abyss/src/http.c b/stable/lib/abyss/src/http.c index 815906e45..f61c9928c 100644 --- a/stable/lib/abyss/src/http.c +++ b/stable/lib/abyss/src/http.c @@ -63,7 +63,7 @@ HTTPRequestHasValidUri(TSession * const sessionP) { if (!sessionP->requestInfo.uri) return false; - + if (xmlrpc_streq(sessionP->requestInfo.uri, "*")) return (sessionP->requestInfo.method != m_options); @@ -154,13 +154,13 @@ RequestAuth(TSession * const sessionP, if (xmlrpc_strcaseeq(authType, "basic")) { const char * userPass; char userPassEncoded[80]; - + NextToken((const char **)&authHdrPtr); - + xmlrpc_asprintf(&userPass, "%s:%s", user, pass); xmlrpc_base64Encode(userPass, userPassEncoded); xmlrpc_strfree(userPass); - + if (xmlrpc_streq(authHdrPtr, userPassEncoded)) { sessionP->requestInfo.user = xmlrpc_strdupsol(user); authorized = true; @@ -245,42 +245,42 @@ HTTPReasonByStatus(uint16_t const code) { }; static struct _HTTPReasons const reasons[] = { - { 100,"Continue" }, - { 101,"Switching Protocols" }, - { 200,"OK" }, - { 201,"Created" }, - { 202,"Accepted" }, - { 203,"Non-Authoritative Information" }, - { 204,"No Content" }, - { 205,"Reset Content" }, - { 206,"Partial Content" }, - { 300,"Multiple Choices" }, - { 301,"Moved Permanently" }, - { 302,"Moved Temporarily" }, - { 303,"See Other" }, - { 304,"Not Modified" }, - { 305,"Use Proxy" }, - { 400,"Bad Request" }, - { 401,"Unauthorized" }, - { 402,"Payment Required" }, - { 403,"Forbidden" }, - { 404,"Not Found" }, - { 405,"Method Not Allowed" }, - { 406,"Not Acceptable" }, - { 407,"Proxy Authentication Required" }, - { 408,"Request Timeout" }, - { 409,"Conflict" }, - { 410,"Gone" }, - { 411,"Length Required" }, - { 412,"Precondition Failed" }, - { 413,"Request Entity Too Large" }, - { 414,"Request-URI Too Long" }, - { 415,"Unsupported Media Type" }, - { 500,"Internal Server Error" }, - { 501,"Not Implemented" }, - { 502,"Bad Gateway" }, - { 503,"Service Unavailable" }, - { 504,"Gateway Timeout" }, + { 100,"Continue" }, + { 101,"Switching Protocols" }, + { 200,"OK" }, + { 201,"Created" }, + { 202,"Accepted" }, + { 203,"Non-Authoritative Information" }, + { 204,"No Content" }, + { 205,"Reset Content" }, + { 206,"Partial Content" }, + { 300,"Multiple Choices" }, + { 301,"Moved Permanently" }, + { 302,"Moved Temporarily" }, + { 303,"See Other" }, + { 304,"Not Modified" }, + { 305,"Use Proxy" }, + { 400,"Bad Request" }, + { 401,"Unauthorized" }, + { 402,"Payment Required" }, + { 403,"Forbidden" }, + { 404,"Not Found" }, + { 405,"Method Not Allowed" }, + { 406,"Not Acceptable" }, + { 407,"Proxy Authentication Required" }, + { 408,"Request Timeout" }, + { 409,"Conflict" }, + { 410,"Gone" }, + { 411,"Length Required" }, + { 412,"Precondition Failed" }, + { 413,"Request Entity Too Large" }, + { 414,"Request-URI Too Long" }, + { 415,"Unsupported Media Type" }, + { 500,"Internal Server Error" }, + { 501,"Not Implemented" }, + { 502,"Bad Gateway" }, + { 503,"Service Unavailable" }, + { 504,"Gateway Timeout" }, { 505,"HTTP Version Not Supported" }, { 000, NULL } }; @@ -360,7 +360,7 @@ bool HTTPWriteContinue(TSession * const sessionP) { char const continueStatus[] = "HTTP/1.1 100 continue\r\n\r\n"; - /* This is a status line plus an end-of-headers empty line */ + /* This is a status line plus an end-of-header empty line */ return ConnWrite(sessionP->connP, continueStatus, strlen(continueStatus)); } @@ -384,7 +384,7 @@ HTTPWriteContinue(TSession * const sessionP) { ** 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 diff --git a/stable/lib/abyss/src/sessionReadRequest.c b/stable/lib/abyss/src/sessionReadRequest.c index 0b77d3ff7..bad3f06f8 100644 --- a/stable/lib/abyss/src/sessionReadRequest.c +++ b/stable/lib/abyss/src/sessionReadRequest.c @@ -133,7 +133,7 @@ getLineInBuffer(TConn * const connectionP, } } } - } + } *lineEndP = lfPos + 1; *timedOutP = timedOut; } @@ -206,7 +206,7 @@ getRestOfField(TConn * const connectionP, bool timedOut; fieldEnd = lineEnd; /* initial value - end of 1st line */ - + for (gotWholeField = false, timedOut = false, *errorP = NULL; !gotWholeField && !timedOut && !*errorP;) { @@ -214,7 +214,7 @@ getRestOfField(TConn * const connectionP, /* Note that we are guaranteed, assuming the HTTP stream is valid, that there is at least one more line in it. Worst - case, it's the empty line that marks the end of the headers. + case, it's the empty line that marks the end of the header. */ getLineInBuffer(connectionP, fieldEnd, deadline, &nextLineEnd, &timedOut, errorP); @@ -258,7 +258,7 @@ readField(TConn * const connectionP, call that empty line the EOH mark. We assume the connection is positioned to a header or EOH mark. - + In the course of reading, we read at least one character past the line delimiter at the end of the field or EOH mark; we may read much more. But we leave everything after the field or EOH (and @@ -340,7 +340,7 @@ skipToNonemptyLine(TConn * const connectionP, bool gotNonEmptyLine; char * lineStart; - + for (lineStart = bufferStart, gotNonEmptyLine = false, *timedOutP = false, *errorP = NULL; !gotNonEmptyLine && !*timedOutP && !*errorP; ) { @@ -380,7 +380,7 @@ readRequestField(TSession * const sessionP, We assume the connection is presently positioned to the beginning of the HTTP document. We leave it positioned after the request field. - + We ignore any empty lines at the beginning of the stream, per RFC2616 Section 4.1. @@ -418,7 +418,7 @@ readRequestField(TSession * const sessionP, encountered EOH: */ assert(!endOfHeader); - + *requestLineP = line; } } @@ -475,15 +475,15 @@ parsePerCentEscape(const char ** const srcP, *errorP = NULL; /* initial assumption */ hexDigitValue(*src++, &digit0, errorP); - + if (!*errorP) { unsigned int digit1; - + if (!*src) xmlrpc_asprintf(errorP, "URI ends after the first digit"); else { hexDigitValue(*src++, &digit1, errorP); - + if (!*errorP) *unescapedP = ((digit0 << 4) | digit1); } @@ -516,7 +516,7 @@ unescapeUri(const char * const uriComponent, char * dst; src = dst = buffer; - + *errorP = NULL; /* initial value */ while (*src && !*errorP) { @@ -588,7 +588,7 @@ parseHostPort(const char * const hostport, for (p = colonPos + 1, port = 0; isdigit(*p) && port < 65535; (port = port * 10 + (*p - '0')), ++p); - + if (*p || port == 0) { xmlrpc_asprintf(errorP, "There is nothing, or something " "non-numeric for the port number after the " @@ -626,7 +626,7 @@ splitUriQuery(const char * const requestUri, xmlrpc_asprintf(errorP, "Couldn't get memory for URI buffer"); else { char * const qmark = strchr(buffer, '?'); - + if (qmark) { *qmark = '\0'; *queryP = xmlrpc_strdupsol(qmark + 1); @@ -660,7 +660,7 @@ parseHttpHostPortPath(const char * const hostportpath, char * const slashPos = strchr(buffer, '/'); char * hostport; - + if (slashPos) { path = xmlrpc_strdupsol(slashPos); /* Includes the initial slash */ @@ -897,9 +897,9 @@ parseRequestLine(char * const requestLine, const char * httpVersion; NextToken((const char **)&p); - + /* HTTP Version Decoding */ - + httpVersion = GetToken(&p); if (httpVersion) { const char * error; @@ -972,7 +972,7 @@ getFieldNameToken(char ** const pP, char * fieldName; NextToken((const char **)pP); - + fieldName = GetToken(pP); if (!fieldName) { xmlrpc_asprintf(errorP, "The header has no field name token"); @@ -987,7 +987,7 @@ getFieldNameToken(char ** const pP, fieldName[strlen(fieldName)-1] = '\0'; /* remove trailing colon */ strtolower(fieldName); - + *errorP = NULL; } } @@ -1112,14 +1112,14 @@ readAndProcessHeaderFields(TSession * const sessionP, getFieldNameToken(&p, &fieldName, errorP, httpErrorCodeP); if (!*errorP) { char * fieldValue; - + NextToken((const char **)&p); - + fieldValue = p; TableAdd(&sessionP->requestHeaderFields, fieldName, fieldValue); - + processField(fieldName, fieldValue, sessionP, errorP, httpErrorCodeP); } @@ -1136,19 +1136,19 @@ SessionReadRequest(TSession * const sessionP, const char ** const errorP, uint16_t * const httpErrorCodeP) { /*---------------------------------------------------------------------------- - Read the headers of a new HTTP request (assuming nothing has yet been + Read the header of a new HTTP request (assuming nothing has yet been read on the session). - Update *sessionP with the information from the headers. + Update *sessionP with the information from the header. Leave the connection positioned to the body of the request, ready to be read by an HTTP request handler (via SessionRefillBuffer() and SessionGetReadData()). - If we are unable to read the headers, we return a text description as + If we are unable to read the header, we return a text description as *errorP and a suitable HTTP status code as *httpErrorCodeP. - If we successfully read the headers, we return *errorP == NULL and + If we successfully read the header, we return *errorP == NULL and nothing as *httpErrorCodeP. -----------------------------------------------------------------------------*/ time_t const deadline = time(NULL) + timeout; diff --git a/stable/lib/curl_transport/Makefile b/stable/lib/curl_transport/Makefile index 499ab7893..03a1973c0 100644 --- a/stable/lib/curl_transport/Makefile +++ b/stable/lib/curl_transport/Makefile @@ -29,7 +29,7 @@ include $(SRCDIR)/common.mk $(SRCDIR)/common.mk: srcdir blddir -CURL_VERSION := $(shell curl-config --vernum) +CURL_VERSION := $(shell $(CURL_CONFIG) --vernum) # Some time at or before Curl 7.12, became an empty file # (no-op). Some time after Curl 7.18, ceased to exist. @@ -43,7 +43,7 @@ ifeq ($(NEED_CURL_TYPES_H),Y) CFLAGS_LOCAL += -DNEED_CURL_TYPES_H endif -CURL_INCLUDES := $(shell curl-config --cflags) +CURL_INCLUDES := $(shell $(CURL_CONFIG) --cflags) # We expect that curl-config --cflags just gives us -I options, because # we need just the -I options for 'make dep'. Plus, it's scary to think # of what any other compiler flag would do to our compile. diff --git a/stable/lib/curl_transport/xmlrpc_curl_transport.c b/stable/lib/curl_transport/xmlrpc_curl_transport.c index 245300c3f..70ebc6765 100644 --- a/stable/lib/curl_transport/xmlrpc_curl_transport.c +++ b/stable/lib/curl_transport/xmlrpc_curl_transport.c @@ -169,7 +169,7 @@ static void addMilliseconds(xmlrpc_timespec const addend, unsigned int const adder, xmlrpc_timespec * const sumP) { - + unsigned int const million = 1000000; unsigned int const billion = 1000000000; @@ -211,7 +211,7 @@ struct xmlrpc_client_transport { the transaction with proper interruptibility. The only Curl transaction ever attached to this multi manager is 'syncCurlSessionP'. - + This is constant (the handle, not the object). */ curlMulti * asyncCurlMultiP; @@ -220,7 +220,7 @@ struct xmlrpc_client_transport { interface. Note that there may be multiple such Curl transactions simultaneously and one can't wait for a particular one to finish; the collection of asynchronous RPCs are an indivisible mass. - + This is constant (the handle, not the object). */ bool dontAdvertise; @@ -234,7 +234,7 @@ struct xmlrpc_client_transport { */ const char * userAgent; /* Information to include in a User-Agent HTTP header, reflecting - facilities outside of Xmlrpc-c. + facilities outside of Xmlrpc-c. Null means none. @@ -307,7 +307,7 @@ initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { #if MSVCRT /* This is CRITICAL so that cURL-Win32 works properly! */ - + /* So this commenter says, but I wonder why. libcurl should do the required WSAStartup() itself, and it looks to me like it does. -Bryan 06.01.01 @@ -316,7 +316,7 @@ initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); - + err = WSAStartup(wVersionRequested, &wsaData); if (err) xmlrpc_env_set_fault_formatted( @@ -324,8 +324,8 @@ initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { "Winsock startup failed. WSAStartup returned rc %d", err); else { if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { - /* Tell the user that we couldn't find a useable */ - /* winsock.dll. */ + /* Tell the user that we couldn't find a useable */ + /* winsock.dll. */ xmlrpc_env_set_fault_formatted( envP, XMLRPC_INTERNAL_ERROR, "Winsock reported that " "it does not implement the requested version 1.1."); @@ -402,14 +402,14 @@ pselectTimeout(xmlrpc_timeoutType const timeoutType, retval.tv_nsec = (uint32_t)((selectTimeoutMillisec % 1000) * million); return retval; -} +} static void processCurlMessages(xmlrpc_env * const envP, curlMulti * const curlMultiP) { - + bool endOfMessages; endOfMessages = false; /* initial assumption */ @@ -457,7 +457,7 @@ waitForWork(xmlrpc_env * const envP, checked, we will return immediately and if it arrives while we're waiting, we will return then. Note that we can provide this service only because pselect() has the same atomic unblock/wait feature. - + If sigmaskP is NULL, wait under whatever the current signal mask is. -----------------------------------------------------------------------------*/ fd_set readFdSet; @@ -487,7 +487,7 @@ waitForWork(xmlrpc_env * const envP, rc = xmlrpc_pselect(maxFd+1, &readFdSet, &writeFdSet, &exceptFdSet, &pselectTimeoutArg, sigmaskP); - + if (rc < 0 && errno != EINTR) xmlrpc_faultf(envP, "Impossible failure of pselect() " "with errno %d (%s)", @@ -532,7 +532,7 @@ waitForWorkInt(xmlrpc_env * const envP, sigfillset(&allSignals); sigprocmask(SIG_BLOCK, &allSignals, &callerBlockSet); - + if (*interruptP == 0) waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); else @@ -637,13 +637,13 @@ finishCurlMulti(xmlrpc_env * const envP, rpcStillRunning = true; /* initial assumption */ timedOut = false; curlCalledSinceInterrupt = false; - + while (rpcStillRunning && !timedOut && !envP->fault_occurred) { if (interruptP && !curlCalledSinceInterrupt) { waitForWorkInt(envP, curlMultiP, timeoutType, deadline, interruptP); - } else + } else waitForWork(envP, curlMultiP, timeoutType, deadline, NULL); if (!envP->fault_occurred) { @@ -660,7 +660,7 @@ finishCurlMulti(xmlrpc_env * const envP, doCurlWork(envP, curlMultiP, &rpcStillRunning); xmlrpc_gettimeofday(&nowTime); - + timedOut = (timeoutType == timeout_yes && timeIsAfter(nowTime, deadline)); } @@ -674,7 +674,7 @@ getTimeoutParm(xmlrpc_env * const envP, const struct xmlrpc_curl_xportparms * const curlXportParmsP, size_t const parmSize, unsigned int * const timeoutP) { - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(timeout)) *timeoutP = 0; else { @@ -702,7 +702,7 @@ getConnectTimeoutParm( const struct xmlrpc_curl_xportparms * const curlXportParmsP, size_t const parmSize, unsigned int * const timeoutP) { - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(connect_timeout)) *timeoutP = 0; else { @@ -777,12 +777,12 @@ getXportParms(xmlrpc_env * const envP, transportP->userAgent = NULL; else transportP->userAgent = strdup(curlXportParmsP->user_agent); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(dont_advertise)) transportP->dontAdvertise = false; else transportP->dontAdvertise = curlXportParmsP->dont_advertise; - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(network_interface)) curlSetupP->networkInterface = NULL; else if (curlXportParmsP->network_interface == NULL) @@ -795,8 +795,8 @@ getXportParms(xmlrpc_env * const envP, curlSetupP->sslVerifyPeer = true; else curlSetupP->sslVerifyPeer = !curlXportParmsP->no_ssl_verifypeer; - - if (!curlXportParmsP || + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(no_ssl_verifyhost)) curlSetupP->sslVerifyHost = true; else @@ -808,87 +808,87 @@ getXportParms(xmlrpc_env * const envP, curlSetupP->sslCert = NULL; else curlSetupP->sslCert = strdup(curlXportParmsP->ssl_cert); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcerttype)) curlSetupP->sslCertType = NULL; else if (curlXportParmsP->sslcerttype == NULL) curlSetupP->sslCertType = NULL; else curlSetupP->sslCertType = strdup(curlXportParmsP->sslcerttype); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcertpasswd)) curlSetupP->sslCertPasswd = NULL; else if (curlXportParmsP->sslcertpasswd == NULL) curlSetupP->sslCertPasswd = NULL; else curlSetupP->sslCertPasswd = strdup(curlXportParmsP->sslcertpasswd); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkey)) curlSetupP->sslKey = NULL; else if (curlXportParmsP->sslkey == NULL) curlSetupP->sslKey = NULL; else curlSetupP->sslKey = strdup(curlXportParmsP->sslkey); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeytype)) curlSetupP->sslKeyType = NULL; else if (curlXportParmsP->sslkeytype == NULL) curlSetupP->sslKeyType = NULL; else curlSetupP->sslKeyType = strdup(curlXportParmsP->sslkeytype); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeypasswd)) curlSetupP->sslKeyPasswd = NULL; else if (curlXportParmsP->sslkeypasswd == NULL) curlSetupP->sslKeyPasswd = NULL; else curlSetupP->sslKeyPasswd = strdup(curlXportParmsP->sslkeypasswd); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine)) curlSetupP->sslEngine = NULL; else if (curlXportParmsP->sslengine == NULL) curlSetupP->sslEngine = NULL; else curlSetupP->sslEngine = strdup(curlXportParmsP->sslengine); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine_default)) curlSetupP->sslEngineDefault = false; else curlSetupP->sslEngineDefault = !!curlXportParmsP->sslengine_default; - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslversion)) curlSetupP->sslVersion = XMLRPC_SSLVERSION_DEFAULT; else curlSetupP->sslVersion = curlXportParmsP->sslversion; - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(cainfo)) curlSetupP->caInfo = NULL; else if (curlXportParmsP->cainfo == NULL) curlSetupP->caInfo = NULL; else curlSetupP->caInfo = strdup(curlXportParmsP->cainfo); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(capath)) curlSetupP->caPath = NULL; else if (curlXportParmsP->capath == NULL) curlSetupP->caPath = NULL; else curlSetupP->caPath = strdup(curlXportParmsP->capath); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(randomfile)) curlSetupP->randomFile = NULL; else if (curlXportParmsP->randomfile == NULL) curlSetupP->randomFile = NULL; else curlSetupP->randomFile = strdup(curlXportParmsP->randomfile); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(egdsocket)) curlSetupP->egdSocket = NULL; else if (curlXportParmsP->egdsocket == NULL) curlSetupP->egdSocket = NULL; else curlSetupP->egdSocket = strdup(curlXportParmsP->egdsocket); - + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(ssl_cipher_list)) curlSetupP->sslCipherList = NULL; else if (curlXportParmsP->ssl_cipher_list == NULL) @@ -1054,7 +1054,7 @@ makeSyncCurlSession(xmlrpc_env * const envP, if (!envP->fault_occurred) { /* We'll need a multi manager to actually execute this session: */ transportP->syncCurlMultiP = curlMulti_create(); - + if (transportP->syncCurlMultiP == NULL) xmlrpc_faultf(envP, "Unable to create Curl multi manager for " "synchronous RPCs"); @@ -1064,7 +1064,7 @@ makeSyncCurlSession(xmlrpc_env * const envP, } if (envP->fault_occurred) transportP->syncCurlSessionLockP->destroy( - transportP->syncCurlSessionLockP); + transportP->syncCurlSessionLockP); } } @@ -1078,12 +1078,12 @@ unmakeSyncCurlSession(struct xmlrpc_client_transport * const transportP) { destroySyncCurlSession(transportP->syncCurlSessionP); transportP->syncCurlSessionLockP->destroy( - transportP->syncCurlSessionLockP); + transportP->syncCurlSessionLockP); } -static void +static void create(xmlrpc_env * const envP, int const flags ATTR_UNUSED, const char * const appname ATTR_UNUSED, @@ -1094,7 +1094,7 @@ create(xmlrpc_env * const envP, /*---------------------------------------------------------------------------- This does the 'create' operation for a Curl client transport. -----------------------------------------------------------------------------*/ - const struct xmlrpc_curl_xportparms * const curlXportParmsP = + const struct xmlrpc_curl_xportparms * const curlXportParmsP = transportparmsP; struct xmlrpc_client_transport * transportP; @@ -1108,16 +1108,16 @@ create(xmlrpc_env * const envP, transportP->interruptP = NULL; transportP->asyncCurlMultiP = curlMulti_create(); - + if (transportP->asyncCurlMultiP == NULL) xmlrpc_faultf(envP, "Unable to create Curl multi manager for " "asynchronous RPCs"); else { getXportParms(envP, curlXportParmsP, parm_size, transportP); - + if (!envP->fault_occurred) { makeSyncCurlSession(envP, transportP); - + if (envP->fault_occurred) freeXportParms(transportP); } @@ -1147,11 +1147,11 @@ assertNoOutstandingCurlWork(curlMulti * const curlMultiP) { xmlrpc_env env; bool immediateWorkToDo; int runningHandles; - + xmlrpc_env_init(&env); - + curlMulti_perform(&env, curlMultiP, &immediateWorkToDo, &runningHandles); - + /* We know the above was a no-op, since we're asserting that there is no outstanding work. */ @@ -1163,7 +1163,7 @@ assertNoOutstandingCurlWork(curlMulti * const curlMultiP) { -static void +static void destroy(struct xmlrpc_client_transport * const clientTransportP) { /*---------------------------------------------------------------------------- This does the 'destroy' operation for a Curl client transport. @@ -1265,7 +1265,7 @@ createRpc(xmlrpc_env * const envP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, xmlrpc_mem_block * const responseXmlP, - xmlrpc_transport_asynch_complete complete, + xmlrpc_transport_asynch_complete complete, xmlrpc_transport_progress progress, struct xmlrpc_call_info * const callInfoP, rpc ** const rpcPP) { @@ -1296,7 +1296,7 @@ createRpc(xmlrpc_env * const envP, curlTransaction_create(envP, curlSessionP, serverP, - callXmlP, responseXmlP, + callXmlP, responseXmlP, clientTransportP->dontAdvertise, clientTransportP->userAgent, &clientTransportP->curlSetupStuff, @@ -1316,7 +1316,7 @@ createRpc(xmlrpc_env * const envP, -static void +static void destroyRpc(rpc * const rpcP) { XMLRPC_ASSERT_PTR_OK(rpcP); @@ -1397,7 +1397,7 @@ curlTransactionProgress(void * const context, The curlTransaction calls this once a second telling us how much data has transferred. If the transport user has set up a progress - function, we call that with this progress information. That + function, we call that with this progress information. That function might e.g. display a progress bar. Additionally, the curlTransaction gives us the opportunity to tell it @@ -1436,8 +1436,8 @@ curlTransactionProgress(void * const context, -static void -sendRequest(xmlrpc_env * const envP, +static void +sendRequest(xmlrpc_env * const envP, struct xmlrpc_client_transport * const clientTransportP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, @@ -1459,7 +1459,7 @@ sendRequest(xmlrpc_env * const envP, responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); if (!envP->fault_occurred) { CURL * const curlSessionP = curl_easy_init(); - + if (curlSessionP == NULL) xmlrpc_faultf(envP, "Could not create Curl session. " "curl_easy_init() failed."); @@ -1467,10 +1467,10 @@ sendRequest(xmlrpc_env * const envP, createRpc(envP, clientTransportP, curlSessionP, serverP, callXmlP, responseXmlP, complete, progress, callInfoP, &rpcP); - + if (!envP->fault_occurred) { startRpc(envP, rpcP); - + if (envP->fault_occurred) destroyRpc(rpcP); } @@ -1489,7 +1489,7 @@ sendRequest(xmlrpc_env * const envP, -static void +static void finishAsynch( struct xmlrpc_client_transport * const clientTransportP, xmlrpc_timeoutType const timeoutType, @@ -1524,7 +1524,7 @@ finishAsynch( /* The datetime after which we should quit waiting */ xmlrpc_env_init(&env); - + if (timeoutType == timeout_yes) { xmlrpc_timespec waitStartTime; xmlrpc_gettimeofday(&waitStartTime); @@ -1545,7 +1545,7 @@ finishAsynch( Note that a failure of finish_curlMulti() does not mean that a session completed with an error or an RPC completed with an - error. Those things are reported up through the user's + error. Those things are reported up through the user's xmlrpc_transport_asynch_complete routine. A failure here is something that stopped us from calling that. @@ -1619,7 +1619,7 @@ setupGlobalConstants(xmlrpc_env * const envP) { CURLcode rc; rc = curl_global_init(CURL_GLOBAL_ALL); - + if (rc != CURLE_OK) xmlrpc_faultf(envP, "curl_global_init() failed with code %d", rc); } diff --git a/stable/lib/expat/Makefile b/stable/lib/expat/Makefile index cf2355302..d8828ff2a 100644 --- a/stable/lib/expat/Makefile +++ b/stable/lib/expat/Makefile @@ -46,7 +46,7 @@ xmlrpc_expat.pc: clean: $(SUBDIRS:%=%/clean) clean-common .PHONY: distclean -distclean: $(SUBDIRS:%=%/distclean) distclean-common +distclean: $(SUBDIRS:%=%/distclean) clean-common distclean-common .PHONY: tags tags: $(SUBDIRS:%=%/tags) TAGS diff --git a/stable/lib/expat/xmltok/xmltok_impl.c b/stable/lib/expat/xmltok/xmltok_impl.c index d0355275f..cf0091d1d 100644 --- a/stable/lib/expat/xmltok/xmltok_impl.c +++ b/stable/lib/expat/xmltok/xmltok_impl.c @@ -21,7 +21,7 @@ See the file copying.txt for copying permission. #define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ case BT_LEAD ## n: \ if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ + return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n)) { \ *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; \ @@ -100,7 +100,7 @@ See the file copying.txt for copying permission. static int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr != end) { if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { @@ -110,24 +110,24 @@ int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); case BT_MINUS: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_COMMENT; - } - break; + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_COMMENT; + } + break; default: - ptr += MINBPC(enc); - break; + ptr += MINBPC(enc); + break; } } } @@ -138,7 +138,7 @@ int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; @@ -160,14 +160,16 @@ int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, switch (BYTE_TYPE(enc, ptr)) { case BT_PERCNT: if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; /* don't allow */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } - /* fall through */ + *nextTokPtr = ptr; + return XML_TOK_DECL_OPEN; + break; case BT_S: case BT_CR: case BT_LF: *nextTokPtr = ptr; return XML_TOK_DECL_OPEN; @@ -184,9 +186,9 @@ int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, } static -int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, - const char * end, +int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, + const char * end, int * tokPtr) { int upper = 0; @@ -232,58 +234,60 @@ int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, static int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int tok; const char *target = ptr; if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } ptr += MINBPC(enc); while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); - case BT_QUEST: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr + MINBPC(enc); - return tok; - } - break; - default: - ptr += MINBPC(enc); - break; - } + INVALID_CASES(ptr, nextTokPtr); + case BT_QUEST: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + *nextTokPtr = ptr + MINBPC(enc); + return tok; + } + break; + default: + ptr += MINBPC(enc); + break; + } } return XML_TOK_PARTIAL; case BT_QUEST: if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr + MINBPC(enc); - return tok; + *nextTokPtr = ptr + MINBPC(enc); + return tok; } - /* fall through */ + *nextTokPtr = ptr; + return XML_TOK_INVALID; + break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; @@ -294,8 +298,8 @@ int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end, static -int PREFIX(scanCdataSection)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, +int PREFIX(scanCdataSection)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, const char * end, const char ** nextTokPtr) { @@ -316,7 +320,7 @@ int PREFIX(scanCdataSection)(const ENCODING * enc ATTR_UNUSED, static int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_NONE; @@ -325,7 +329,7 @@ int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *en if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; end = ptr + n; } } @@ -356,22 +360,22 @@ int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *en case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); default: ptr += MINBPC(enc); break; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NONXML: case BT_MALFORM: @@ -394,35 +398,35 @@ int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *en static int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_CR: case BT_LF: - break; - case BT_GT: - *nextTokPtr = ptr + MINBPC(enc); + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: case BT_CR: case BT_LF: + break; + case BT_GT: + *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_END_TAG; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } } return XML_TOK_PARTIAL; case BT_COLON: - /* no need to check qname syntax here, since end-tag must match exactly */ + /* no need to check qname syntax here, since end-tag must match exactly*/ ptr += MINBPC(enc); break; case BT_GT: @@ -440,7 +444,7 @@ int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { @@ -455,13 +459,13 @@ int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: - break; + break; case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CHAR_REF; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CHAR_REF; default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } } } @@ -472,7 +476,7 @@ int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end static int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr != end) { if (CHAR_MATCHES(enc, ptr, ASCII_x)) @@ -487,13 +491,13 @@ int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: - break; + break; case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CHAR_REF; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CHAR_REF; default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } } } @@ -504,12 +508,12 @@ int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_NUM: return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); default: @@ -518,7 +522,7 @@ int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_ENTITY_REF; @@ -534,148 +538,148 @@ int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int hadColon = 0; while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_COLON: if (hadColon) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } hadColon = 1; ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } break; case BT_S: case BT_CR: case BT_LF: for (;;) { - int t; - - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - t = BYTE_TYPE(enc, ptr); - if (t == BT_EQUALS) - break; - switch (t) { - case BT_S: - case BT_LF: - case BT_CR: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } + int t; + + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + t = BYTE_TYPE(enc, ptr); + if (t == BT_EQUALS) + break; + switch (t) { + case BT_S: + case BT_LF: + case BT_CR: + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } } - /* fall through */ + /* fall through */ case BT_EQUALS: - { - int open; - hadColon = 0; - for (;;) { - - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - open = BYTE_TYPE(enc, ptr); - if (open == BT_QUOT || open == BT_APOS) - break; - switch (open) { - case BT_S: - case BT_LF: - case BT_CR: - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - ptr += MINBPC(enc); - /* in attribute value */ - for (;;) { - int t; - if (ptr == end) - return XML_TOK_PARTIAL; - t = BYTE_TYPE(enc, ptr); - if (t == open) - break; - switch (t) { - INVALID_CASES(ptr, nextTokPtr); - case BT_AMP: - { - int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr); - if (tok <= 0) { - if (tok == XML_TOK_INVALID) - *nextTokPtr = ptr; - return tok; - } - break; - } - case BT_LT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - default: - ptr += MINBPC(enc); - break; - } - } - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: - case BT_CR: - case BT_LF: - break; - case BT_SOL: - goto sol; - case BT_GT: - goto gt; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - /* ptr points to closing quote */ - for (;;) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_CR: case BT_LF: - continue; - case BT_GT: - gt: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_START_TAG_WITH_ATTS; - case BT_SOL: - sol: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - break; - } - break; + { + int open; + hadColon = 0; + for (;;) { + + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + open = BYTE_TYPE(enc, ptr); + if (open == BT_QUOT || open == BT_APOS) + break; + switch (open) { + case BT_S: + case BT_LF: + case BT_CR: + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + ptr += MINBPC(enc); + /* in attribute value */ + for (;;) { + int t; + if (ptr == end) + return XML_TOK_PARTIAL; + t = BYTE_TYPE(enc, ptr); + if (t == open) + break; + switch (t) { + INVALID_CASES(ptr, nextTokPtr); + case BT_AMP: + { + int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr); + if (tok <= 0) { + if (tok == XML_TOK_INVALID) + *nextTokPtr = ptr; + return tok; + } + break; + } + case BT_LT: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + default: + ptr += MINBPC(enc); + break; + } } + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: + case BT_CR: + case BT_LF: + break; + case BT_SOL: + goto sol; + case BT_GT: + goto gt; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + /* ptr points to closing quote */ + for (;;) { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_S: case BT_CR: case BT_LF: + continue; + case BT_GT: + gt: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_START_TAG_WITH_ATTS; + case BT_SOL: + sol: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + break; + } + break; + } default: *nextTokPtr = ptr; return XML_TOK_INVALID; @@ -688,13 +692,13 @@ int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int hadColon; if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_EXCL: if ((ptr += MINBPC(enc)) == end) return XML_TOK_PARTIAL; @@ -718,44 +722,44 @@ int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, /* we have a start-tag */ while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_COLON: if (hadColon) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } hadColon = 1; ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } break; case BT_S: case BT_CR: case BT_LF: - { - ptr += MINBPC(enc); - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: - goto gt; - case BT_SOL: - goto sol; - case BT_S: case BT_CR: case BT_LF: - ptr += MINBPC(enc); - continue; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); - } - return XML_TOK_PARTIAL; + { + ptr += MINBPC(enc); + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: + goto gt; + case BT_SOL: + goto sol; + case BT_S: case BT_CR: case BT_LF: + ptr += MINBPC(enc); + continue; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); } + return XML_TOK_PARTIAL; + } case BT_GT: gt: *nextTokPtr = ptr + MINBPC(enc); @@ -764,10 +768,10 @@ int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, sol: ptr += MINBPC(enc); if (ptr == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; + *nextTokPtr = ptr; + return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_EMPTY_ELEMENT_NO_ATTS; @@ -927,8 +931,9 @@ PREFIX(contentTok)(const ENCODING * const enc, *nextTokPtr = ptr; return XML_TOK_INVALID; } - } - /* fall through */ + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + } break; case BT_AMP: case BT_LT: case BT_NONXML: @@ -956,12 +961,12 @@ PREFIX(contentTok)(const ENCODING * const enc, static int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_PERCENT; @@ -971,7 +976,7 @@ int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_PARAM_ENTITY_REF; @@ -985,19 +990,19 @@ int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_CR: case BT_LF: case BT_S: case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: *nextTokPtr = ptr; @@ -1012,27 +1017,27 @@ int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, static int PREFIX(scanLit)(int open, const ENCODING *enc, - const char *ptr, const char *end, - const char **nextTokPtr) + const char *ptr, const char *end, + const char **nextTokPtr) { while (ptr != end) { int t = BYTE_TYPE(enc, ptr); switch (t) { - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); case BT_QUOT: case BT_APOS: ptr += MINBPC(enc); if (t != open) - break; + break; if (ptr == end) - return -XML_TOK_LITERAL; + return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: case BT_GT: case BT_PERCNT: case BT_LSQB: - return XML_TOK_LITERAL; + return XML_TOK_LITERAL; default: - return XML_TOK_INVALID; + return XML_TOK_INVALID; } default: ptr += MINBPC(enc); @@ -1044,7 +1049,7 @@ int PREFIX(scanLit)(int open, const ENCODING *enc, static int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int tok; if (ptr == end) @@ -1054,7 +1059,7 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; end = ptr + n; } } @@ -1064,27 +1069,27 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_APOS: return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_LT: - { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_EXCL: - return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_QUEST: - return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_NMSTRT: - case BT_HEX: - case BT_NONASCII: - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - *nextTokPtr = ptr - MINBPC(enc); - return XML_TOK_INSTANCE_START; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; + { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_EXCL: + return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_QUEST: + return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_NMSTRT: + case BT_HEX: + case BT_NONASCII: + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + *nextTokPtr = ptr - MINBPC(enc); + return XML_TOK_INSTANCE_START; } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } case BT_CR: if (ptr + MINBPC(enc) == end) return -XML_TOK_PROLOG_S; @@ -1093,18 +1098,20 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, for (;;) { ptr += MINBPC(enc); if (ptr == end) - break; + break; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_LF: - break; + break; case BT_CR: - /* don't split CR/LF pair */ - if (ptr + MINBPC(enc) != end) - break; - /* fall through */ + /* don't split CR/LF pair */ + if (ptr + MINBPC(enc) == end) { + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + } + break; default: - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; } } *nextTokPtr = ptr; @@ -1123,10 +1130,10 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { - *nextTokPtr = ptr + 2*MINBPC(enc); - return XML_TOK_COND_SECT_CLOSE; + *nextTokPtr = ptr + 2*MINBPC(enc); + return XML_TOK_COND_SECT_CLOSE; } } *nextTokPtr = ptr; @@ -1164,22 +1171,22 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_DECL_CLOSE; case BT_NUM: return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NAME; \ - break; \ - } \ - if (IS_NAME_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NMTOKEN; \ - break; \ - } \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ + break; \ + } \ + if (IS_NAME_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NMTOKEN; \ + break; \ + } \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NMSTRT: @@ -1203,72 +1210,74 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, if (IS_NAME_CHAR_MINBPC(enc, ptr)) { ptr += MINBPC(enc); tok = XML_TOK_NMTOKEN; - break; + } else { + *nextTokPtr = ptr; + return XML_TOK_INVALID; } - /* fall through */ + break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } - while (ptr != end) { + while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: case BT_RPAR: case BT_COMMA: - case BT_VERBAR: case BT_LSQB: case BT_PERCNT: - case BT_S: case BT_CR: case BT_LF: - *nextTokPtr = ptr; - return tok; - case BT_COLON: - ptr += MINBPC(enc); - switch (tok) { - case XML_TOK_NAME: - if (ptr == end) - return XML_TOK_PARTIAL; - tok = XML_TOK_PREFIXED_NAME; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - default: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case XML_TOK_PREFIXED_NAME: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case BT_PLUS: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_PLUS; - case BT_AST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_ASTERISK; - case BT_QUEST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_QUESTION; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } + case BT_GT: case BT_RPAR: case BT_COMMA: + case BT_VERBAR: case BT_LSQB: case BT_PERCNT: + case BT_S: case BT_CR: case BT_LF: + *nextTokPtr = ptr; + return tok; + case BT_COLON: + ptr += MINBPC(enc); + switch (tok) { + case XML_TOK_NAME: + if (ptr == end) + return XML_TOK_PARTIAL; + tok = XML_TOK_PREFIXED_NAME; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + default: + tok = XML_TOK_NMTOKEN; + break; } - return -tok; + break; + case XML_TOK_PREFIXED_NAME: + tok = XML_TOK_NMTOKEN; + break; + } + break; + case BT_PLUS: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_PLUS; + case BT_AST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_ASTERISK; + case BT_QUEST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_QUESTION; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -tok; } static int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { const char *start; if (ptr == end) @@ -1282,7 +1291,7 @@ int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char * #undef LEAD_CASE case BT_AMP: if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LT: @@ -1291,27 +1300,27 @@ int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char * return XML_TOK_INVALID; case BT_LF: if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_S: if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_ATTRIBUTE_VALUE_S; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_ATTRIBUTE_VALUE_S; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; @@ -1326,7 +1335,7 @@ int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char * static int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { const char *start; if (ptr == end) @@ -1340,30 +1349,30 @@ int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end #undef LEAD_CASE case BT_AMP: if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_PERCNT: if (ptr == start) - return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LF: if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; @@ -1380,7 +1389,7 @@ int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end static int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) + const char **nextTokPtr) { int level = 0; if (MINBPC(enc) > 1) { @@ -1392,33 +1401,33 @@ int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *e } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); + INVALID_CASES(ptr, nextTokPtr); case BT_LT: if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { - ++level; - ptr += MINBPC(enc); - } + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { + ++level; + ptr += MINBPC(enc); + } } break; case BT_RSQB: if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr += MINBPC(enc); - if (level == 0) { - *nextTokPtr = ptr; - return XML_TOK_IGNORE_SECT; - } - --level; - } + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr += MINBPC(enc); + if (level == 0) { + *nextTokPtr = ptr; + return XML_TOK_IGNORE_SECT; + } + --level; + } } break; default: @@ -1431,9 +1440,23 @@ int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *e +static bool +PREFIX(isSpecialChar)(char const c) { + + switch (c) { + case 0x24: /* $ */ + case 0x40: /* @ */ + return true; + default: + return false; + } +} + + + static int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, - const char **badPtr) + const char **badPtr) { ptr += MINBPC(enc); end -= MINBPC(enc); @@ -1461,51 +1484,51 @@ int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, break; case BT_S: if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { - *badPtr = ptr; - return 0; + *badPtr = ptr; + return 0; } break; case BT_NAME: case BT_NMSTRT: - if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) - break; - default: - switch (BYTE_TO_ASCII(enc, ptr)) { - case 0x24: /* $ */ - case 0x40: /* @ */ - break; - default: - *badPtr = ptr; - return 0; + if (BYTE_TO_ASCII(enc, ptr) & ~0x7f) { + if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { + *badPtr = ptr; + return 0; + } } break; + default: + if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { + *badPtr = ptr; + return 0; + } } } return 1; } /* This must only be called for a well-formed start-tag or empty element tag. -Returns the number of attributes. Pointers to the first attsMax attributes +Returns the number of attributes. Pointers to the first attsMax attributes are stored in atts. */ static int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, - int attsMax, ATTRIBUTE *atts) + int attsMax, ATTRIBUTE *atts) { enum { other, inName, inValue } state = inName; int nAtts = 0; int open = 0; /* defined when state == inValue; - initialization just to shut up compilers */ + initialization just to shut up compilers */ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { #define START_NAME \ if (state == other) { \ - if (nAtts < attsMax) { \ - atts[nAtts].name = ptr; \ - atts[nAtts].normalized = 1; \ - } \ - state = inName; \ + if (nAtts < attsMax) { \ + atts[nAtts].name = ptr; \ + atts[nAtts].normalized = 1; \ + } \ + state = inName; \ } #define LEAD_CASE(n) \ case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; @@ -1519,47 +1542,47 @@ int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, #undef START_NAME case BT_QUOT: if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_QUOT; } else if (open == BT_QUOT) { state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; } break; case BT_APOS: if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_APOS; } else if (open == BT_APOS) { state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; } break; case BT_AMP: if (nAtts < attsMax) - atts[nAtts].normalized = 0; + atts[nAtts].normalized = 0; break; case BT_S: if (state == inName) state = other; else if (state == inValue - && nAtts < attsMax - && atts[nAtts].normalized - && (ptr == atts[nAtts].valuePtr - || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE - || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE - || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) - atts[nAtts].normalized = 0; + && nAtts < attsMax + && atts[nAtts].normalized + && (ptr == atts[nAtts].valuePtr + || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE + || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE + || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) + atts[nAtts].normalized = 0; break; case BT_CR: case BT_LF: /* This case ensures that the first attribute name is counted @@ -1567,12 +1590,12 @@ int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, if (state == inName) state = other; else if (state == inValue && nAtts < attsMax) - atts[nAtts].normalized = 0; + atts[nAtts].normalized = 0; break; case BT_GT: case BT_SOL: if (state != inValue) - return nAtts; + return nAtts; break; default: break; @@ -1593,20 +1616,20 @@ int PREFIX(charRefNumber)(const ENCODING *enc ATTR_UNUSED, const char *ptr) switch (c) { case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: - result <<= 4; - result |= (c - ASCII_0); - break; + result <<= 4; + result |= (c - ASCII_0); + break; case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F: - result <<= 4; - result += 10 + (c - ASCII_A); - break; + result <<= 4; + result += 10 + (c - ASCII_A); + break; case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f: - result <<= 4; - result += 10 + (c - ASCII_a); - break; + result <<= 4; + result += 10 + (c - ASCII_a); + break; } if (result >= 0x110000) - return -1; + return -1; } } else { @@ -1615,15 +1638,15 @@ int PREFIX(charRefNumber)(const ENCODING *enc ATTR_UNUSED, const char *ptr) result *= 10; result += (c - ASCII_0); if (result >= 0x110000) - return -1; + return -1; } } return checkCharRefNumber(result); } static -int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, +int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, const char * end) { switch ((end - ptr)/MINBPC(enc)) { @@ -1631,9 +1654,9 @@ int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { switch (BYTE_TO_ASCII(enc, ptr)) { case ASCII_l: - return ASCII_LT; + return ASCII_LT; case ASCII_g: - return ASCII_GT; + return ASCII_GT; } } break; @@ -1641,9 +1664,9 @@ int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, if (CHAR_MATCHES(enc, ptr, ASCII_a)) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_m)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_p)) - return ASCII_AMP; + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) + return ASCII_AMP; } } break; @@ -1652,23 +1675,23 @@ int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, case ASCII_q: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_u)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_t)) - return ASCII_QUOT; - } + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_t)) + return ASCII_QUOT; + } } break; case ASCII_a: ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, ASCII_p)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_s)) - return ASCII_APOS; - } + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_s)) + return ASCII_APOS; + } } break; } @@ -1681,15 +1704,29 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) { for (;;) { switch (BYTE_TYPE(enc, ptr1)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (*ptr1++ != *ptr2++) \ - return 0; - LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) -#undef LEAD_CASE - /* fall through */ + case BT_LEAD4: if (*ptr1++ != *ptr2++) - return 0; + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_LEAD3: + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_LEAD2: + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; break; case BT_NONASCII: case BT_NMSTRT: @@ -1699,23 +1736,23 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) case BT_NAME: case BT_MINUS: if (*ptr2++ != *ptr1++) - return 0; + return 0; if (MINBPC(enc) > 1) { - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 2) { - if (*ptr2++ != *ptr1++) - return 0; + if (*ptr2++ != *ptr1++) + return 0; + if (MINBPC(enc) > 2) { + if (*ptr2++ != *ptr1++) + return 0; if (MINBPC(enc) > 3) { - if (*ptr2++ != *ptr1++) - return 0; - } - } + if (*ptr2++ != *ptr1++) + return 0; + } + } } break; default: if (MINBPC(enc) == 1 && *ptr1 == *ptr2) - return 1; + return 1; switch (BYTE_TYPE(enc, ptr2)) { case BT_LEAD2: case BT_LEAD3: @@ -1727,9 +1764,9 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) case BT_DIGIT: case BT_NAME: case BT_MINUS: - return 0; + return 0; default: - return 1; + return 1; } } } @@ -1737,9 +1774,9 @@ int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) } static -int PREFIX(nameMatchesAscii)(const ENCODING * enc ATTR_UNUSED, +int PREFIX(nameMatchesAscii)(const ENCODING * enc ATTR_UNUSED, const char * ptr1, - const char * end1, + const char * end1, const char * ptr2) { for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { diff --git a/stable/lib/libutil/error.c b/stable/lib/libutil/error.c index ff3bbe16d..473755773 100644 --- a/stable/lib/libutil/error.c +++ b/stable/lib/libutil/error.c @@ -28,8 +28,8 @@ xmlrpc_assertion_failed(const char * const fileName, static const char * const default_fault_string = "Not enough memory for error message"; -void xmlrpc_env_init (xmlrpc_env* env) -{ +void +xmlrpc_env_init (xmlrpc_env* env) { XMLRPC_ASSERT(env != NULL); env->fault_occurred = 0; @@ -37,6 +37,8 @@ void xmlrpc_env_init (xmlrpc_env* env) env->fault_string = NULL; } + + void xmlrpc_env_clean(xmlrpc_env * const envP) { @@ -55,14 +57,14 @@ xmlrpc_env_clean(xmlrpc_env * const envP) { -void +void xmlrpc_env_set_fault(xmlrpc_env * const envP, - int const faultCode, + int const faultCode, const char * const faultDescription) { char * buffer; - XMLRPC_ASSERT(envP != NULL); + XMLRPC_ASSERT(envP != NULL); XMLRPC_ASSERT(faultDescription != NULL); /* Clean up any leftover pointers. */ @@ -101,10 +103,10 @@ xmlrpc_set_fault_formatted_v(xmlrpc_env * const envP, -void -xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP, +void +xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP, int const code, - const char * const format, + const char * const format, ...) { va_list args; @@ -149,8 +151,8 @@ xmlrpc_faultf(xmlrpc_env * const envP, ** 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. -** +** 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 diff --git a/stable/lib/wininet_transport/xmlrpc_wininet_transport.c b/stable/lib/wininet_transport/xmlrpc_wininet_transport.c index f990afb7b..858a7b461 100644 --- a/stable/lib/wininet_transport/xmlrpc_wininet_transport.c +++ b/stable/lib/wininet_transport/xmlrpc_wininet_transport.c @@ -3,7 +3,7 @@ =============================================================================== WinInet-based client transport for Xmlrpc-c. Copyright information at the bottom of this file. - + =============================================================================*/ #include "xmlrpc_config.h" @@ -55,14 +55,14 @@ struct xmlrpc_client_transport { struct lock * listLockP; struct list_head rpcList; /* List of all RPCs that exist for this transport. An RPC exists - from the time the user requests it until the time the user + from the time the user requests it until the time the user acknowledges it is done. */ int allowInvalidSSLCerts; /* Flag to specify if we ignore invalid SSL Certificates. If this is set to zero, calling a XMLRPC server with an invalid SSL certificate will fail. This is the default behavior of the other - transports, but invalid certificates were allowed in pre 1.2 + transports, but invalid certificates were allowed in pre 1.2 wininet xmlrpc-c transports. */ }; @@ -72,7 +72,7 @@ typedef struct { HINTERNET hHttpRequest; HINTERNET hURL; INTERNET_PORT nPort; - char szHostName[255]; + char szHostName[255]; char szUrlPath[255]; BOOL bUseSSL; char * headerList; @@ -115,7 +115,7 @@ createWinInetHeaderList(xmlrpc_env * const envP, /* NOTE: A newline is required between each added header */ szHeaderList = malloc(strlen(szContentType) + 17 + strlen(serverP->basicAuthHdrValue) + 1); - + if (szHeaderList == NULL) xmlrpc_faultf(envP, "Couldn't allocate memory for authorization header"); @@ -130,11 +130,11 @@ createWinInetHeaderList(xmlrpc_env * const envP, } else { /* Just the content type header is needed */ szHeaderList = malloc(strlen(szContentType) + 1); - + if (szHeaderList == NULL) xmlrpc_faultf(envP, "Couldn't allocate memory for standard header"); - else + else memcpy(szHeaderList, szContentType, strlen(szContentType) + 1); } *headerListP = szHeaderList; @@ -201,7 +201,7 @@ createWinInetTransaction(xmlrpc_env * const envP, XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP); } } - + if (envP->fault_occurred) free(winInetTransactionP); } @@ -236,7 +236,7 @@ get_wininet_response(xmlrpc_env * const envP, unsigned long dwLen; INTERNET_BUFFERS inetBuffer; unsigned long dwFlags; - unsigned long dwErr; + unsigned long dwErr; unsigned long nExpected; void * body; BOOL bOK; @@ -260,14 +260,14 @@ get_wininet_response(xmlrpc_env * const envP, required by XML-RPC. Following fails if server didn't send it. */ - bOK = HttpQueryInfo(winInetTransactionP->hHttpRequest, - HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, + bOK = HttpQueryInfo(winInetTransactionP->hHttpRequest, + HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, &inetBuffer.dwBufferTotal, &dwLen, NULL); if (!bOK) { LPTSTR pMsg; dwErr = GetLastError (); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -288,7 +288,7 @@ get_wininet_response(xmlrpc_env * const envP, inetBuffer.dwBufferLength = nExpected; InternetQueryDataAvailable(winInetTransactionP->hHttpRequest, &inetBuffer.dwBufferLength, 0, 0); - + /* Read Response from InternetFile */ do { if (inetBuffer.dwBufferLength != 0) @@ -306,8 +306,8 @@ get_wininet_response(xmlrpc_env * const envP, dwErr = 0; } else { LPTSTR pMsg; - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -318,7 +318,7 @@ get_wininet_response(xmlrpc_env * const envP, XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); } } - + if (inetBuffer.dwBufferLength) { TCHAR * const oldBufptr = inetBuffer.lpvBuffer; @@ -327,14 +327,14 @@ get_wininet_response(xmlrpc_env * const envP, /* Adjust inetBuffer.dwBufferLength when it is greater than the */ /* expected end of file */ if (inetBuffer.dwBufferLength > nExpected) - inetBuffer.dwBufferLength = nExpected; + inetBuffer.dwBufferLength = nExpected; } else inetBuffer.dwBufferLength = nExpected; dwErr = 0; } while (nExpected != 0); - /* Add to the response buffer. */ + /* Add to the response buffer. */ xmlrpc_mem_block_append(envP, winInetTransactionP->pResponseData, body, inetBuffer.dwBufferTotal); XMLRPC_FAIL_IF_FAULT(envP); @@ -369,11 +369,11 @@ performWinInetTransaction( pMsgMem = NULL; /* initial value */ reqFlags = INTERNET_FLAG_NO_UI; /* initial value */ - + winInetTransactionP->hURL = - InternetConnect(hSyncInternetSession, + InternetConnect(hSyncInternetSession, winInetTransactionP->szHostName, - winInetTransactionP->nPort, + winInetTransactionP->nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); /* Start our request running. */ @@ -386,14 +386,14 @@ performWinInetTransaction( winInetTransactionP->szUrlPath, "HTTP/1.1", NULL, (const char **)&acceptTypes, reqFlags, 1); - + XMLRPC_FAIL_IF_NULL(winInetTransactionP->hHttpRequest, envP, XMLRPC_INTERNAL_ERROR, "Unable to open the requested URL."); succeeded = HttpAddRequestHeaders(winInetTransactionP->hHttpRequest, - winInetTransactionP->headerList, + winInetTransactionP->headerList, strlen (winInetTransactionP->headerList), HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); @@ -411,9 +411,9 @@ performWinInetTransaction( &dwTimeOut, sizeof(dwTimeOut)); } Again: - /* Send the requested XML remote procedure command */ - succeeded = HttpSendRequest(winInetTransactionP->hHttpRequest, NULL, 0, - winInetTransactionP->pSendData, + /* Send the requested XML remote procedure command */ + succeeded = HttpSendRequest(winInetTransactionP->hHttpRequest, NULL, 0, + winInetTransactionP->pSendData, strlen(winInetTransactionP->pSendData)); if (!succeeded) { LPTSTR pMsg; @@ -422,7 +422,7 @@ performWinInetTransaction( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS, + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -473,13 +473,13 @@ performWinInetTransaction( "for example, if you entered www.server.com " "and the common name " "on the certificate says www.different.com. "); - + reqFlags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID; InternetSetOption(winInetTransactionP->hHttpRequest, INTERNET_OPTION_SECURITY_FLAGS, &reqFlags, sizeof(reqFlags)); - + goto Again; } else pMsg = "The SSL certificate common name " @@ -533,14 +533,14 @@ performWinInetTransaction( } } else - pMsg = (LPTSTR)pMsgMem; + pMsg = (LPTSTR)pMsgMem; XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); } queryLen = sizeof(unsigned long); /* initial value */ - succeeded = HttpQueryInfo(winInetTransactionP->hHttpRequest, + succeeded = HttpQueryInfo(winInetTransactionP->hHttpRequest, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, &winInetTransactionP->http_status, &queryLen, NULL); @@ -548,8 +548,8 @@ performWinInetTransaction( LPTSTR pMsg; lastErr = GetLastError(); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, lastErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), @@ -576,7 +576,7 @@ performWinInetTransaction( winInetTransactionP->http_status, errMsg); goto cleanup; } - /* Read the response. */ + /* Read the response. */ get_wininet_response(envP, winInetTransactionP); XMLRPC_FAIL_IF_FAULT(envP); @@ -618,7 +618,7 @@ createRpcThread(xmlrpc_env * const envP, rc = pthread_create(threadP, NULL, doAsyncRpc, rpcP); switch (rc) { - case 0: + case 0: break; case EAGAIN: xmlrpc_faultf(envP, "pthread_create() failed: " @@ -647,7 +647,7 @@ rpcCreate(xmlrpc_env * const envP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, xmlrpc_mem_block * const responseXmlP, - xmlrpc_transport_asynch_complete complete, + xmlrpc_transport_asynch_complete complete, struct xmlrpc_call_info * const callInfoP, rpc ** const rpcPP) { @@ -662,7 +662,7 @@ rpcCreate(xmlrpc_env * const envP, rpcP->responseXmlP = responseXmlP; rpcP->threadExists = FALSE; - createWinInetTransaction(envP, serverP, callXmlP, responseXmlP, + createWinInetTransaction(envP, serverP, callXmlP, responseXmlP, &rpcP->winInetTransactionP); if (!envP->fault_occurred) { if (complete) { @@ -689,7 +689,7 @@ rpcCreate(xmlrpc_env * const envP, -static void +static void rpcDestroy(rpc * const rpcP) { XMLRPC_ASSERT_PTR_OK(rpcP); @@ -704,10 +704,10 @@ rpcDestroy(rpc * const rpcP) { -static void * -finishRpc(struct list_head * const headerP, +static void * +finishRpc(struct list_head * const headerP, void * const context ATTR_UNUSED) { - + rpc * const rpcP = headerP->itemP; if (rpcP->threadExists) { @@ -715,7 +715,7 @@ finishRpc(struct list_head * const headerP, int result; result = pthread_join(rpcP->thread, &status); - + rpcP->threadExists = FALSE; } @@ -807,7 +807,7 @@ statusCallback (HINTERNET const hInternet, -static void +static void create(xmlrpc_env * const envP, int const flags ATTR_UNUSED, const char * const appname ATTR_UNUSED, @@ -818,7 +818,7 @@ create(xmlrpc_env * const envP, /*---------------------------------------------------------------------------- This does the 'create' operation for a WinInet client transport. -----------------------------------------------------------------------------*/ - const struct xmlrpc_wininet_xportparms * const wininetXportParmsP = + const struct xmlrpc_wininet_xportparms * const wininetXportParmsP = transportparmsP; struct xmlrpc_client_transport * transportP; @@ -828,7 +828,7 @@ create(xmlrpc_env * const envP, xmlrpc_faultf(envP, "Unable to allocate transport descriptor."); else { transportP->listLockP = xmlrpc_lock_create(); - + list_make_empty(&transportP->rpcList); if (hSyncInternetSession == NULL) @@ -849,7 +849,7 @@ create(xmlrpc_env * const envP, -static void +static void destroy(struct xmlrpc_client_transport * const clientTransportP) { /*---------------------------------------------------------------------------- This does the 'destroy' operation for a WinInet client transport. @@ -869,8 +869,8 @@ destroy(struct xmlrpc_client_transport * const clientTransportP) { -static void -sendRequest(xmlrpc_env * const envP, +static void +sendRequest(xmlrpc_env * const envP, struct xmlrpc_client_transport * const clientTransportP, const xmlrpc_server_info * const serverP, xmlrpc_mem_block * const callXmlP, @@ -905,7 +905,7 @@ sendRequest(xmlrpc_env * const envP, -static void +static void finishAsynch(struct xmlrpc_client_transport * const clientTransportP, xmlrpc_timeoutType const timeoutType ATTR_UNUSED, xmlrpc_timeout const timeout ATTR_UNUSED) { @@ -950,9 +950,9 @@ call(xmlrpc_env * const envP, if (!envP->fault_occurred) { performWinInetTransaction(envP, rpcP->winInetTransactionP, clientTransportP); - + *responsePP = responseXmlP; - + rpcDestroy(rpcP); } if (envP->fault_occurred) @@ -986,8 +986,8 @@ struct xmlrpc_client_transport_ops xmlrpc_wininet_transport_ops = { ** 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. -** +** 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 diff --git a/stable/src/Makefile b/stable/src/Makefile index 315097c64..1cdf8b021 100644 --- a/stable/src/Makefile +++ b/stable/src/Makefile @@ -57,7 +57,7 @@ ifeq ($(MUST_BUILD_CURL_CLIENT),yes) TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curltransaction TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curlmulti - TRANSPORT_LIBDEP += $(shell curl-config --libs) + TRANSPORT_LIBDEP += $(shell $CURL_CONFIG --libs) TRANSPORT_INCLUDES += -Isrcdir/lib/curl_transport endif ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) diff --git a/stable/src/cpp/client.cpp b/stable/src/cpp/client.cpp index 6b7d27a50..0e8184c14 100644 --- a/stable/src/cpp/client.cpp +++ b/stable/src/cpp/client.cpp @@ -48,7 +48,7 @@ throwIfError(env_wrap const& env) { class memblockStringWrapper { -public: +public: memblockStringWrapper(string const value) { env_wrap env; @@ -60,7 +60,7 @@ class memblockStringWrapper { value.c_str(), value.size()); throwIfError(env); } - + memblockStringWrapper(xmlrpc_mem_block * const memblockP) : memblockP(memblockP) {}; @@ -96,7 +96,7 @@ struct client_xml_impl { transportPtr(transportPtr), dialect(dialect) {} }; - + carriageParm::carriageParm() {} @@ -160,7 +160,7 @@ carriageParm_http0::instantiate(string const serverUrl) { if (c_serverInfoP) throw(error("object already instantiated")); - + env_wrap env; this->c_serverInfoP = @@ -323,7 +323,7 @@ carriageParm_http0::setBasicAuth(string const username, if (!this->c_serverInfoP) throw(error("object not instantiated")); - + env_wrap env; xmlrpc_server_info_set_basic_auth( @@ -388,7 +388,7 @@ xmlTransactionPtr::xmlTransactionPtr() {} xmlTransactionPtr::xmlTransactionPtr(xmlTransaction * xmlTransP) : autoObjectPtr(xmlTransP) {} - + xmlTransaction * @@ -428,7 +428,7 @@ struct xmlTranCtl { callXml.c_str(), callXml.size()); throwIfError(env); } - + ~xmlTranCtl() { XMLRPC_MEMBLOCK_FREE(char, this->callXmlP); } @@ -455,7 +455,7 @@ clientXmlTransport::start(carriageParm * const carriageParmP, // Note: derived class clientXmlTransport_http overrides this, // so it doesn't normally get used. - + string responseXml; this->call(carriageParmP, callXml, &responseXml); @@ -593,7 +593,7 @@ clientXmlTransport_http::call( memblockStringWrapper responseHolder(responseXmlMP); // Makes responseXmlMP get freed at end of scope - + *responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlMP), XMLRPC_MEMBLOCK_SIZE(char, responseXmlMP)); } @@ -869,7 +869,7 @@ client_xml::call(carriageParm * const carriageParmP, string responseXml; xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); - + xml::trace("XML-RPC CALL", callXml); try { @@ -879,7 +879,7 @@ client_xml::call(carriageParm * const carriageParmP, "get XML response back. %s", e.what()); } xml::trace("XML-RPC RESPONSE", responseXml); - + try { xml::parseResponse(responseXml, outcomeP); } catch (exception const& e) { @@ -887,7 +887,7 @@ client_xml::call(carriageParm * const carriageParmP, e.what()); } } - + void @@ -899,14 +899,14 @@ client_xml::start(carriageParm * const carriageParmP, string callXml; xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); - + xml::trace("XML-RPC CALL", callXml); xmlTransaction_clientPtr const xmlTranP(tranP); this->implP->transportP->start(carriageParmP, callXml, xmlTranP); } - + void @@ -1008,14 +1008,14 @@ struct rpc_impl { rpc::rpc(string const methodName, paramList const& paramList) { - + this->implP = new rpc_impl(methodName, paramList); } rpc::~rpc() { - + if (this->implP->state == rpc_impl::STATE_ERROR) delete(this->implP->errorP); @@ -1051,11 +1051,11 @@ rpc::call(connection const& connection) { } - + void rpc::start(client * const clientP, carriageParm * const carriageParmP) { - + if (this->implP->state != rpc_impl::STATE_UNFINISHED) throw(error("Attempt to execute an RPC that has already been " "executed")); @@ -1067,10 +1067,10 @@ rpc::start(client * const clientP, } - + void rpc::start(xmlrpc_c::connection const& connection) { - + this->start(connection.clientP, connection.carriageParmP); } @@ -1129,7 +1129,7 @@ rpc::progress(struct xmlrpc_progress_data const&) const { -----------------------------------------------------------------------------*/ } - + value @@ -1230,7 +1230,7 @@ xmlTransaction_client::finish(string const& responseXml) const { try { rpcOutcome outcome; - + xml::parseResponse(responseXml, &outcome); this->tranP->finish(outcome); diff --git a/stable/src/cpp/client_simple.cpp b/stable/src/cpp/client_simple.cpp index 2bb2ec6ed..abd198452 100644 --- a/stable/src/cpp/client_simple.cpp +++ b/stable/src/cpp/client_simple.cpp @@ -36,7 +36,7 @@ class cValueWrapper { clientSimple::clientSimple() { - + clientXmlTransportPtr const transportP(clientXmlTransport_http::create()); this->clientP = clientPtr(new client_xml(transportP)); @@ -54,7 +54,7 @@ clientSimple::call(string const serverUrl, rpcPtr rpcPtr(methodName, paramList()); rpcPtr->call(this->clientP.get(), &carriageParm); - + *resultP = rpcPtr->getResult(); } @@ -65,7 +65,7 @@ void makeParamArray(string const format, xmlrpc_value ** const paramArrayPP, va_list args) { - + env_wrap env; /* The format is a sequence of parameter specifications, such as @@ -120,10 +120,10 @@ clientSimple::call(string const serverUrl, cValueWrapper paramArrayWrapper(paramArrayP); // ensure destruction unsigned int const paramCount( xmlrpc_array_size(&env.env_c, paramArrayP)); - + if (env.env_c.fault_occurred) throw(error(env.env_c.fault_string)); - + paramList paramList; for (unsigned int i = 0; i < paramCount; ++i) { xmlrpc_value * paramP; @@ -148,13 +148,13 @@ clientSimple::call(string const serverUrl, string const methodName, paramList const& paramList, value * const resultP) { - + carriageParm_http0 carriageParm(serverUrl); - + rpcPtr rpcPtr(methodName, paramList); rpcPtr->call(this->clientP.get(), &carriageParm); - + *resultP = rpcPtr->getResult(); } diff --git a/stable/src/cpp/packetsocket.cpp b/stable/src/cpp/packetsocket.cpp index 328e2c477..3719357a2 100644 --- a/stable/src/cpp/packetsocket.cpp +++ b/stable/src/cpp/packetsocket.cpp @@ -33,7 +33,7 @@ A stream is all the data transmitted during a single socket connection. - End of stream in the middle of a packet is a protocol error. + End of stream in the middle of a packet is a protocol error. All bytes not part of a control word are literal bytes of a packet. @@ -119,7 +119,7 @@ class XMLRPC_DLLEXPORT socketx { */ socketx::socketx(int const sockFd) { -#if MSVCRT +#if MSVCRT // We don't have any way to duplicate; we'll just have to borrow. this->fdIsBorrowed = true; this->fd = sockFd; @@ -196,10 +196,10 @@ socketx::waitForWritable() const { select(this->fd + 1, 0, &wr_set, 0, 0); #else struct pollfd pollfds[1]; - + pollfds[0].fd = this->fd; pollfds[0].events = POLLOUT; - + poll(pollfds, ARRAY_SIZE(pollfds), -1); #endif } @@ -302,7 +302,7 @@ socketx::read(unsigned char * const buffer, arrive later. Return as *bytesReadP the number of bytes put into 'buffer'. - + Throw a BrokenConnectionEx exception if the connection has been broken. -----------------------------------------------------------------------------*/ int rc; @@ -410,7 +410,7 @@ namespace xmlrpc_c { packet::packet() : bytes(NULL), length(0), allocSize(0) {} - + void @@ -673,7 +673,7 @@ packetSocket_impl::writeWait(packetPtr const& packetP) const { if (this->mustTrace) traceWrite(packetP->getBytes(), packetP->getLength()); - + this->sock.writeWait(packetStart, 4); const unsigned char * const end( @@ -769,7 +769,7 @@ packetSocket_impl::takeSomeEscapeSeq(const unsigned char * const buffer, this->escAccum.bytes[0], this->escAccum.bytes[1], this->escAccum.bytes[2]); - + this->inEscapeSeq = false; this->escAccum.len = 0; } @@ -822,7 +822,7 @@ packetSocket_impl::verifyNothingAccumulated() { if (this->inEscapeSeq) throwf("Streams socket closed in the middle of an " "escape sequence"); - + if (this->inPacket) throwf("Stream socket closed in the middle of a packet " "(%u bytes of packet received; no END marker to mark " @@ -855,7 +855,7 @@ packetSocket_impl::processBytesRead(const unsigned char * const buffer, throwf("Byte 0x%02x is not in a packet or escape sequence. " "Sender is probably not using packet socket protocol", buffer[cursor]); - + cursor += bytesTaken; } } @@ -909,10 +909,11 @@ packetSocket_impl::readFromFile() { fprintf(stderr, "EOF on read\n"); this->eof = true; this->verifyNothingAccumulated(); - } else + } else { if (this->mustTrace) traceBytesRead(buffer, bytesRead); this->processBytesRead(buffer, bytesRead); + } } } } diff --git a/stable/src/cpp/value.cpp b/stable/src/cpp/value.cpp index e2c123729..b319430ea 100644 --- a/stable/src/cpp/value.cpp +++ b/stable/src/cpp/value.cpp @@ -1,4 +1,3 @@ -#include /***************************************************************************** value.cpp ****************************************************************************** @@ -622,13 +621,9 @@ class cNewStringWrapper { switch (nlCode) { case value_string::nlCode_all: - cerr << "Going to call xmlrpc_string_new_lp" << endl; - cerr << "length = " << cppvalue.length() << ", value = " - << cppvalue.c_str() << endl; this->valueP = xmlrpc_string_new_lp(&env.env_c, cppvalue.length(), cppvalue.c_str()); - cerr << "Back from xmlrpc_string_new_lp" << endl; break; case value_string::nlCode_lf: this->valueP = xmlrpc_string_new_lp_cr(&env.env_c, @@ -661,12 +656,9 @@ value_string::value_string(std::string const& cppvalue, value_string::value_string(std::string const& cppvalue) { - cerr << "value_string constructor entered" << endl; cNewStringWrapper wrapper(cppvalue, nlCode_all); - cerr << "wrapper constructed" << endl; this->instantiate(wrapper.valueP); - cerr << "value_string constructor exiting" << endl; } diff --git a/stable/src/json.c b/stable/src/json.c index 394202b8e..be0257722 100644 --- a/stable/src/json.c +++ b/stable/src/json.c @@ -203,7 +203,7 @@ finishStringToken(xmlrpc_env * const envP, while (isxdigit(*cur) && cur - tokP->end < 4) ++cur; - + if (cur - tokP->end < 4) setParseErr(envP, tokP, "hex unicode must contain 4 digits. " @@ -268,7 +268,7 @@ isFloat(const char * const token, point number. N.B. This is true of any integer. - + We don't accept plus signs. Examples of valid floating point: 0, 32, 32.5, , 32.500, @@ -385,7 +385,7 @@ advanceToNextToken(Tokenizer * const tokP) { while (*tokP->begin != '\0' && (isspace(*tokP->begin) || atComment(tokP))) { - + advancePastWhiteSpace(tokP); advancePastComments(tokP); @@ -410,7 +410,7 @@ getToken(xmlrpc_env * const envP, tokP->size = tokP->end - tokP->begin; } else { tokP->end = tokP->begin; /* initial value */ - + if (*tokP->begin == '{') { finishDelimiterToken(tokP); tokP->type = typeOpenBrace; @@ -550,7 +550,7 @@ getBackslashSequence(xmlrpc_env * const envP, buffer[0] = '\t'; tsize = 1; *nBytesConsumedP = 1; - break; + break; case 'u': { long digit; strncpy(buffer, cur + 1, 4); @@ -587,7 +587,7 @@ unescapeString(xmlrpc_env * const envP, cur = begin; last = cur; - + while (cur != end && !envP->fault_occurred) { if (*cur == '\\') { if (cur != last) { @@ -634,7 +634,7 @@ static xmlrpc_value * makeUtf8String(xmlrpc_env * const envP, const char * const begin, const char * const end) { -/*---------------------------------------------------------------------------- +/*---------------------------------------------------------------------------- Copy a json string directly into a string value, and convert any json escaping (\uXXXX) to something acceptable to the internal string handling. @@ -671,7 +671,7 @@ stringTokenValue(xmlrpc_env * const envP, assert(tokP->end >= tokP->begin + 2); assert(*tokP->begin == '"'); assert(*(tokP->end-1) == '"'); - + valP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); if (env.fault_occurred) { @@ -706,7 +706,7 @@ integerTokenValue(xmlrpc_env * const envP, tokP->begin, env.fault_string); else valP = xmlrpc_i8_new(envP, value); - + xmlrpc_env_clean(&env); return valP; @@ -772,7 +772,7 @@ parseList(xmlrpc_env * const envP, XMLRPC_ASSERT_ENV_OK(envP); retval = xmlrpc_array_new(envP); - + if (!envP->fault_occurred) { bool endOfList; for (endOfList = false; !endOfList && !envP->fault_occurred; ) { @@ -833,9 +833,9 @@ parseObjectMember(xmlrpc_env * const envP, assert(tokP->end >= tokP->begin + 2); assert(*tokP->begin == '"'); assert(*(tokP->end-1) == '"'); - + keyP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); - + if (env.fault_occurred) setParseErr(envP, tokP, "Error in what is supposed to be " "the key of a member of an object: %s", @@ -858,7 +858,7 @@ parseObjectMember(xmlrpc_env * const envP, } - + static xmlrpc_value * parseObject(xmlrpc_env * const envP, Tokenizer * const tokP) { @@ -884,7 +884,7 @@ parseObject(xmlrpc_env * const envP, if (!envP->fault_occurred) { getToken(envP, tokP); - + if (!envP->fault_occurred) { if (tokP->type == typeComma) { /* member separator; keep going */ @@ -924,9 +924,9 @@ parseValue(xmlrpc_env * const envP, Tokenizer * const tokP) { xmlrpc_value * retval; - + XMLRPC_ASSERT_ENV_OK(envP); - + switch (tokP->type) { case typeOpenBracket: @@ -936,7 +936,7 @@ parseValue(xmlrpc_env * const envP, case typeOpenBrace: retval = parseObject(envP, tokP); break; - + case typeNull: retval = xmlrpc_nil_new(envP); break; @@ -956,7 +956,7 @@ parseValue(xmlrpc_env * const envP, case typeInteger: retval = integerTokenValue(envP, tokP); break; - + case typeFloat: retval = xmlrpc_double_new(envP, strtod(tokP->begin, NULL)); break; @@ -964,7 +964,7 @@ parseValue(xmlrpc_env * const envP, case typeString: retval = stringTokenValue(envP, tokP); break; - + default: retval = NULL; setParseErr(envP, tokP, "Invalid token " @@ -984,9 +984,9 @@ xmlrpc_parse_json(xmlrpc_env * const envP, xmlrpc_value * retval = retval; Tokenizer tok; - + XMLRPC_ASSERT_ENV_OK(envP); - + initializeTokenizer(&tok, str); getToken(envP, &tok); @@ -1093,7 +1093,7 @@ appendEscapeSeq(xmlrpc_env * const envP, char buffer[6+1]; char slashChar; /* Character that goes after the backslash, including 'u' for \uHHHH */ - + switch (c) { case '"' : slashChar = '"'; break; /* U+0022 */ case '\\': slashChar = '\\'; break; /* U+005C */ @@ -1108,7 +1108,7 @@ appendEscapeSeq(xmlrpc_env * const envP, buffer[0] = '\\'; buffer[1] = slashChar; - + if (slashChar == 'u') { sprintf(&buffer[2], "%04x", c); size = 6; /* \u1234 */ @@ -1135,7 +1135,7 @@ makeJsonString(xmlrpc_env * const envP, const char * last; last = cur = begin; - + while (cur != end && !envP->fault_occurred) { unsigned char const c = *cur; @@ -1145,7 +1145,7 @@ makeJsonString(xmlrpc_env * const envP, the characters before it to the output. */ XMLRPC_MEMBLOCK_APPEND(char, envP, outP, last, cur - last); - + if (!envP->fault_occurred) { appendEscapeSeq(envP, outP, c); @@ -1205,7 +1205,7 @@ serializeI8(xmlrpc_env * const envP, xmlrpc_int64 value; xmlrpc_read_i8(envP, valP, &value); - + formatOut(envP, outP, "%" XMLRPC_PRId64, value); } @@ -1215,7 +1215,7 @@ static void serializeBool(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - + xmlrpc_bool value; xmlrpc_read_bool(envP, valP, &value); @@ -1228,7 +1228,7 @@ static void serializeDouble(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - + xmlrpc_double value; xmlrpc_read_double(envP, valP, &value); @@ -1254,16 +1254,16 @@ serializeDatetime(xmlrpc_env * const envP, } - + static void serializeString(xmlrpc_env * const envP, xmlrpc_value * const valP, xmlrpc_mem_block * const outP) { - + formatOut(envP, outP, "\""); - + makeJsonStringFromXmlRpc(envP, valP, outP); - + formatOut(envP, outP, "\""); } @@ -1289,12 +1289,12 @@ serializeBitstring(xmlrpc_env * const envP, if (!envP->fault_occurred) { formatOut(envP, outP, "\""); - + XMLRPC_MEMBLOCK_APPEND( char, envP, outP, XMLRPC_MEMBLOCK_CONTENTS(char, base64P), XMLRPC_MEMBLOCK_SIZE(char, base64P)); - + if (!envP->fault_occurred) formatOut(envP, outP, "\""); @@ -1322,7 +1322,7 @@ serializeArray(xmlrpc_env * const envP, for (i = 0; i < size && !envP->fault_occurred; ++i) { xmlrpc_value * const itemP = xmlrpc_array_get_item(envP, valP, i); - + if (!envP->fault_occurred) { if (!envP->fault_occurred) { serializeValue(envP, itemP, level + 1, outP); @@ -1340,7 +1340,7 @@ serializeArray(xmlrpc_env * const envP, } } } -} +} @@ -1352,17 +1352,17 @@ serializeStructMember(xmlrpc_env * const envP, xmlrpc_mem_block * const outP) { serializeValue(envP, memberKeyP, level, outP); - + if (!envP->fault_occurred) { formatOut(envP, outP, ":"); - + if (!envP->fault_occurred) serializeValue(envP, memberValueP, level, outP); } } - + static void serializeStruct(xmlrpc_env * const envP, xmlrpc_value * const valP, @@ -1373,7 +1373,7 @@ serializeStruct(xmlrpc_env * const envP, formatOut(envP, outP, "{\n"); if (!envP->fault_occurred) { unsigned int const size = xmlrpc_struct_size(envP, valP); - + if (!envP->fault_occurred) { unsigned int i; for (i = 0; i < size && !envP->fault_occurred; ++i) { @@ -1386,7 +1386,7 @@ serializeStruct(xmlrpc_env * const envP, if (!envP->fault_occurred) { serializeStructMember(envP, memberKeyP, memberValueP, level + 1, outP); - + if (!envP->fault_occurred && i < size - 1) XMLRPC_MEMBLOCK_APPEND(char, envP, outP, ",\n", 2); } @@ -1416,7 +1416,7 @@ serializeValue(xmlrpc_env * const envP, XMLRPC_ASSERT_ENV_OK(envP); indent(envP, level, outP); - + switch (xmlrpc_value_type(valP)) { case XMLRPC_TYPE_INT: serializeInt(envP, valP, outP); @@ -1444,7 +1444,7 @@ serializeValue(xmlrpc_env * const envP, case XMLRPC_TYPE_BASE64: serializeBitstring(envP, valP, outP); - break; + break; case XMLRPC_TYPE_ARRAY: serializeArray(envP, valP, level, outP); diff --git a/stable/src/xmlrpc_string.c b/stable/src/xmlrpc_string.c index 2da61e4ee..e6e007166 100644 --- a/stable/src/xmlrpc_string.c +++ b/stable/src/xmlrpc_string.c @@ -1,4 +1,3 @@ -#include /*============================================================================= xmlrpc_string =============================================================================== @@ -746,15 +745,12 @@ stringNew(xmlrpc_env * const envP, enum crTreatment const crTreatment, xmlrpc_value ** const valPP) { - fprintf(stderr, "stringNew entered\n"); xmlrpc_value * valP; xmlrpc_validate_utf8(envP, value, length); if (!envP->fault_occurred) { - fprintf(stderr, "Going to xmlrpc_createXmlrpcValue\n"); xmlrpc_createXmlrpcValue(envP, &valP); - fprintf(stderr, "Back from createXmlrpcValue\n"); if (!envP->fault_occurred) { valP->_type = XMLRPC_TYPE_STRING; @@ -774,7 +770,6 @@ stringNew(xmlrpc_env * const envP, *valPP = valP; } } - fprintf(stderr, "stringNew exiting\n"); } diff --git a/stable/test/cpp/value.cpp b/stable/test/cpp/value.cpp index 30e758c78..3e403c9c1 100644 --- a/stable/test/cpp/value.cpp +++ b/stable/test/cpp/value.cpp @@ -91,7 +91,7 @@ class booleanTestSuite : public testSuite { return "booleanTestSuite"; } virtual void runtests(unsigned int const) { - value_boolean boolean1(true); + value_boolean boolean1(true); TEST(static_cast(boolean1) == true); value_boolean boolean2(false); TEST(static_cast(boolean2) == false); @@ -291,7 +291,7 @@ class stringTestSuite : public testSuite { badString.validate(); TEST_FAILED("'validate' of string containging a control " "character succeeded"); - } catch (error const&) {} + } catch (error const&) {} } }; @@ -397,7 +397,7 @@ class structTestSuite : public testSuite { cstruct structData; pair member("the_integer", value_int(9)); structData.insert(member); - + value_struct struct1(structData); map dataReadBack(struct1); @@ -450,7 +450,7 @@ class arrayTestSuite : public testSuite { TEST(dataReadBack1[1].type() == value::TYPE_DOUBLE); TEST(static_cast(value_double(dataReadBack1[1])) == 2.78); TEST(dataReadBack1[2].type() == value::TYPE_STRING); - TEST(static_cast(value_string(dataReadBack1[2])) == + TEST(static_cast(value_string(dataReadBack1[2])) == "hello world"); value val1(array1); @@ -485,6 +485,38 @@ class arrayTestSuite : public testSuite { }; +class arrayArrayTestSuite : public testSuite { +public: + virtual string suiteName() { + return "arrayArrayTestSuite"; + } + virtual void runtests(unsigned int const) { + + /* Empty array of arrays */ + vector > arrayArrayDataVec; + + value const arrayArray1(toValue(arrayArrayDataVec)); + TEST(arrayArray1.type() == value::TYPE_ARRAY); + TEST(value_array(arrayArray1).size() == 0); + + /* Array of 1 empty array */ + vector innerArray; + arrayArrayDataVec.push_back(innerArray); + value const arrayArray2(toValue(arrayArrayDataVec)); + + TEST(arrayArray2.type() == value::TYPE_ARRAY); + TEST(value_array(arrayArray2).size() == 1); + vector dataReadBackx( + value_array(arrayArray2).vectorValueValue()); + TEST(dataReadBackx.size() == 1); + TEST(dataReadBackx[0].type() == value::TYPE_ARRAY); + vector dataReadBackx2( + value_array(dataReadBackx[0]).vectorValueValue()); + TEST(dataReadBackx2.size() == 0); + } +}; + + } // unnamed namespace @@ -508,4 +540,5 @@ valueTestSuite::runtests(unsigned int const indentation) { i8TestSuite().run(indentation+1); structTestSuite().run(indentation+1); arrayTestSuite().run(indentation+1); + arrayArrayTestSuite().run(indentation+1); } diff --git a/stable/tools/lib/Makefile b/stable/tools/lib/Makefile index 836d9c97c..39d34b844 100644 --- a/stable/tools/lib/Makefile +++ b/stable/tools/lib/Makefile @@ -26,7 +26,7 @@ LIBOBJS = \ .PHONY: all all: $(LIBOBJS) -%.o:%.c +%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h $(CC) -c $(CFLAGS_ALL) $< # This common.mk dependency makes sure the symlinks get built before diff --git a/stable/version.mk b/stable/version.mk index 7b0a4c426..311603ad2 100644 --- a/stable/version.mk +++ b/stable/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 51 -XMLRPC_POINT_RELEASE = 3 +XMLRPC_MINOR_RELEASE = 54 +XMLRPC_POINT_RELEASE = 0 From fb939689be6b0d87b91a544aec8fbc3d4661caac Mon Sep 17 00:00:00 2001 From: giraffedata Date: Mon, 1 Apr 2019 15:22:31 +0000 Subject: [PATCH 051/154] add -xmlsizelimit git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3036 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/tools/xmlrpc/xmlrpc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/trunk/tools/xmlrpc/xmlrpc.c b/trunk/tools/xmlrpc/xmlrpc.c index 3141398c0..938fef812 100644 --- a/trunk/tools/xmlrpc/xmlrpc.c +++ b/trunk/tools/xmlrpc/xmlrpc.c @@ -59,6 +59,8 @@ struct cmdlineInfo { xmlrpc_bool curlnoverifypeer; xmlrpc_bool curlnoverifyhost; const char * curluseragent; + bool xmlsizelimitSpec; + unsigned int xmlsizelimit; }; @@ -152,6 +154,7 @@ parseCommandLine(xmlrpc_env * const envP, cmd_defineOption(cp, "curlnoverifypeer", OPTTYPE_STRING); cmd_defineOption(cp, "curlnoverifyhost", OPTTYPE_STRING); cmd_defineOption(cp, "curluseragent", OPTTYPE_STRING); + cmd_defineOption(cp, "xmlsizelimit", OPTTYPE_UINT); cmd_processOptions(cp, argc, argv, &error); @@ -159,6 +162,13 @@ parseCommandLine(xmlrpc_env * const envP, setError(envP, "Command syntax error. %s", error); strfree(error); } else { + if (cmd_optionIsPresent(cp, "xmlsizelimit")) { + cmdlineP->xmlsizelimitSpec = true; + cmdlineP->xmlsizelimit = + cmd_getOptionValueUint(cp, "xmlsizelimit"); + } else + cmdlineP->xmlsizelimitSpec = false; + cmdlineP->username = cmd_getOptionValueString(cp, "username"); cmdlineP->password = cmd_getOptionValueString(cp, "password"); @@ -901,6 +911,9 @@ main(int const argc, parseCommandLine(&env, argc, argv, &cmdline); die_if_fault_occurred(&env); + if (cmdline.xmlsizelimitSpec) + xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, cmdline.xmlsizelimit); + computeUrl(cmdline.url, &url); computeParamArray(&env, cmdline.paramCount, cmdline.params, ¶mArrayP); From 659490d535cfdfadf0fc56400c4ca95b18050fb6 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Mon, 1 Apr 2019 15:23:27 +0000 Subject: [PATCH 052/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3037 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/tools/xmlrpc/xmlrpc.c | 82 ++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/trunk/tools/xmlrpc/xmlrpc.c b/trunk/tools/xmlrpc/xmlrpc.c index 938fef812..37fb49dd6 100644 --- a/trunk/tools/xmlrpc/xmlrpc.c +++ b/trunk/tools/xmlrpc/xmlrpc.c @@ -49,7 +49,7 @@ struct cmdlineInfo { const char ** params; /* Array of parameters, in order. Has 'paramCount' entries. */ const char * transport; - /* Name of XML transport he wants to use. NULL if he has no + /* Name of XML transport he wants to use. NULL if he has no preference. */ const char * curlinterface; @@ -65,7 +65,7 @@ struct cmdlineInfo { -static void +static void die_if_fault_occurred (xmlrpc_env * const envP) { if (envP->fault_occurred) { fprintf(stderr, "Failed. %s\n", envP->fault_string); @@ -89,7 +89,7 @@ setError(xmlrpc_env * const envP, const char format[], ...) { strfree(faultString); } - + static void @@ -102,7 +102,7 @@ processArguments(xmlrpc_env * const envP, "method name."); else { unsigned int i; - + cmdlineP->url = cmd_getArgument(cp, 0); cmdlineP->methodName = cmd_getArgument(cp, 1); cmdlineP->paramCount = cmd_argumentCount(cp) - 2; @@ -118,13 +118,13 @@ static void chooseTransport(xmlrpc_env * const envP ATTR_UNUSED, cmdlineParser const cp, const char ** const transportPP) { - + const char * transportOpt = cmd_getOptionValueString(cp, "transport"); if (transportOpt) { *transportPP = transportOpt; } else { - if (cmd_optionIsPresent(cp, "curlinterface") || + if (cmd_optionIsPresent(cp, "curlinterface") || cmd_optionIsPresent(cp, "curlnoverifypeer") || cmd_optionIsPresent(cp, "curlnoverifyhost") || cmd_optionIsPresent(cp, "curluseragent")) @@ -178,7 +178,7 @@ parseCommandLine(xmlrpc_env * const envP, else { chooseTransport(envP, cp, &cmdlineP->transport); - cmdlineP->curlinterface = + cmdlineP->curlinterface = cmd_getOptionValueString(cp, "curlinterface"); cmdlineP->curlnoverifypeer = cmd_optionIsPresent(cp, "curlnoverifypeer"); @@ -187,7 +187,7 @@ parseCommandLine(xmlrpc_env * const envP, cmdlineP->curluseragent = cmd_getOptionValueString(cp, "curluseragent"); - if ((!cmdlineP->transport || + if ((!cmdlineP->transport || !streq(cmdlineP->transport, "curl")) && (cmdlineP->curlinterface || @@ -209,7 +209,7 @@ static void freeCmdline(struct cmdlineInfo const cmdline) { unsigned int i; - + strfree(cmdline.url); strfree(cmdline.methodName); if (cmdline.transport) @@ -246,13 +246,13 @@ static const char * tokenTypeName(enum TokenType const type) { switch (type) { - case COMMA: return "comma"; - case COLON: return "colon"; - case LEFTPAREN: return "left parenthesis"; - case RIGHTPAREN: return "right parenthesis"; - case LEFTBRACE: return "left brace"; - case RIGHTBRACE: return "right brace"; - case END: return "end of string"; + case COMMA: return "comma"; + case COLON: return "colon"; + case LEFTPAREN: return "left parenthesis"; + case RIGHTPAREN: return "right parenthesis"; + case LEFTBRACE: return "left brace"; + case RIGHTBRACE: return "right brace"; + case END: return "end of string"; } return NULL; /* defeat bogus compiler warning */ } @@ -313,12 +313,12 @@ getCdata(xmlrpc_env * const envP, for (textCursor = 0, end = false; !end; ) { switch (*cursor) { - case ',': - case ':': - case '(': - case ')': - case '{': - case '}': + case ',': + case ':': + case '(': + case ')': + case '{': + case '}': case '\0': end = true; break; @@ -337,7 +337,7 @@ getCdata(xmlrpc_env * const envP, text[textCursor++] = '\0'; assert(textCursor <= cdataSizeBound); - + *cdataP = text; *cursorP = cursor; } @@ -401,7 +401,7 @@ buildBytestring(xmlrpc_env * const envP, (unsigned)strlen(valueString)); else { size_t const byteStringSize = strlen(valueString)/2; - + unsigned char * byteString; MALLOCARRAY(byteString, byteStringSize); @@ -459,7 +459,7 @@ buildBool(xmlrpc_env * const envP, setError(envP, "Boolean argument has unrecognized value '%s'. " "recognized values are 't', 'f', 'true', and 'false'.", valueString); -} +} @@ -477,7 +477,7 @@ buildDouble(xmlrpc_env * const envP, value = strtod(valueString, &tailptr); if (*tailptr != '\0') - setError(envP, + setError(envP, "\"Double\" argument has non-decimal crap in it: '%s'", tailptr); else @@ -709,11 +709,11 @@ buildValue(xmlrpc_env * const envP, buildString(envP, &cdata[2], valuePP); else if (xmlrpc_strneq(cdata, "h/", 2)) buildBytestring(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "i/", 2)) + else if (xmlrpc_strneq(cdata, "i/", 2)) buildInt(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "I/", 2)) + else if (xmlrpc_strneq(cdata, "I/", 2)) buildI8(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "d/", 2)) + else if (xmlrpc_strneq(cdata, "d/", 2)) buildDouble(envP, &cdata[2], valuePP); else if (xmlrpc_strneq(cdata, "b/", 2)) buildBool(envP, &cdata[2], valuePP); @@ -733,7 +733,7 @@ buildValue(xmlrpc_env * const envP, buildStruct(envP, cursorP, valuePP); } else { /* It's not in normal type/value format, so we take it to be - the shortcut string notation + the shortcut string notation */ buildString(envP, cdata, valuePP); } @@ -767,7 +767,7 @@ computeParamArray(xmlrpc_env * const envP, unsigned int const paramCount, const char ** const params, xmlrpc_value ** const paramArrayPP) { - + unsigned int i; xmlrpc_value * paramArrayP; @@ -814,12 +814,12 @@ callWithClient(xmlrpc_env * const envP, const char * const methodName, xmlrpc_value * const paramArrayP, xmlrpc_value ** const resultPP) { - + xmlrpc_env env; xmlrpc_env_init(&env); *resultPP = xmlrpc_client_call_server_params( &env, serverInfoP, methodName, paramArrayP); - + if (env.fault_occurred) xmlrpc_faultf(envP, "Call failed. %s. (XML-RPC fault code %d)", env.fault_string, env.fault_code); @@ -839,7 +839,7 @@ doCall(xmlrpc_env * const envP, const char * const methodName, xmlrpc_value * const paramArrayP, xmlrpc_value ** const resultPP) { - + struct xmlrpc_clientparms clientparms; XMLRPC_ASSERT(xmlrpc_value_type(paramArrayP) == XMLRPC_TYPE_ARRAY); @@ -854,14 +854,14 @@ doCall(xmlrpc_env * const envP, curlXportParmsP->no_ssl_verifypeer = curlnoverifypeer; curlXportParmsP->no_ssl_verifyhost = curlnoverifyhost; curlXportParmsP->user_agent = curluseragent; - + clientparms.transportparmsP = curlXportParmsP; clientparms.transportparm_size = XMLRPC_CXPSIZE(user_agent); } else { clientparms.transportparmsP = NULL; clientparms.transportparm_size = 0; } - xmlrpc_client_init2(envP, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, + xmlrpc_client_init2(envP, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, &clientparms, XMLRPC_CPSIZE(transportparm_size)); if (!envP->fault_occurred) { callWithClient(envP, serverInfoP, methodName, paramArrayP, resultPP); @@ -895,8 +895,8 @@ createServerInfo(xmlrpc_env * const envP, -int -main(int const argc, +int +main(int const argc, const char ** const argv) { struct cmdlineInfo cmdline; @@ -927,12 +927,12 @@ main(int const argc, cmdline.curlnoverifypeer, cmdline.curlnoverifyhost, cmdline.curluseragent, serverInfoP, - cmdline.methodName, paramArrayP, + cmdline.methodName, paramArrayP, &resultP); die_if_fault_occurred(&env); dumpResult(resultP); - + strfree(url); xmlrpc_DECREF(resultP); @@ -940,6 +940,6 @@ main(int const argc, freeCmdline(cmdline); xmlrpc_env_clean(&env); - + return 0; } From 952647abc5baee240ac0b3868ad6ebede1d529c1 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Mon, 1 Apr 2019 15:36:50 +0000 Subject: [PATCH 053/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3038 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/util/cmdline_parser.c | 72 ++++++++++++++++----------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/trunk/lib/util/cmdline_parser.c b/trunk/lib/util/cmdline_parser.c index cc33d8dd9..d8f127cde 100644 --- a/trunk/lib/util/cmdline_parser.c +++ b/trunk/lib/util/cmdline_parser.c @@ -47,7 +47,7 @@ static struct optionx * createLongOptsArray(struct optionDesc * const optionDescArray, unsigned int const numOptions) { - struct optionx * longopts; + struct optionx * longopts; MALLOCARRAY(longopts, numOptions+1); if (longopts != NULL) { @@ -62,8 +62,8 @@ createLongOptsArray(struct optionDesc * const optionDescArray, We prefer to generate a meaningful error message when the user omits a required option value. */ - longopts[i].has_arg = - optionDescArray[i].type == OPTTYPE_FLAG ? + longopts[i].has_arg = + optionDescArray[i].type == OPTTYPE_FLAG ? no_argument : optional_argument; longopts[i].flag = NULL; longopts[i].val = i; @@ -98,7 +98,7 @@ parseInt(enum optiontype const type, "for numeric option value: '%s'", optarg); else if (errno == ERANGE || longvalue > INT_MAX) casprintf(errorP, "Numeric value out of range: %s", optarg); - else { + else { if (type == OPTTYPE_UINT) { if (longvalue < 0) casprintf(errorP, "Unsigned numeric value is " @@ -158,7 +158,7 @@ parseFloat(const char * const optarg, "for numeric option value: '%s'", optarg); else if (errno == ERANGE) casprintf(errorP, "Numeric value out of range: %s", optarg); - else { + else { *errorP = NULL; *valueP = doublevalue; } @@ -168,16 +168,16 @@ parseFloat(const char * const optarg, static void -parseOptionValue(const char * const optarg, +parseOptionValue(const char * const optarg, struct optionDesc * const optionP, const char ** const errorP) { - + switch (optionP->type) { case OPTTYPE_FLAG: *errorP = NULL; break; case OPTTYPE_INT: - case OPTTYPE_UINT: + case OPTTYPE_UINT: parseInt(optionP->type, optarg, &optionP->value.u, &optionP->value.i, errorP); break; @@ -206,7 +206,7 @@ processOption(struct optionDesc * const optionP, const char ** const errorP) { const char * error; - + parseOptionValue(optarg, optionP, &error); if (error) casprintf(errorP, "Error in '%s' option: %s", optionP->name, error); @@ -220,7 +220,7 @@ static void extractArguments(struct cmdlineParserCtl * const cpP, unsigned int const argc, const char ** const argv) { - + cpP->numArguments = argc - getopt_argstart(); MALLOCARRAY(cpP->argumentArray, cpP->numArguments); @@ -247,14 +247,14 @@ extractArguments(struct cmdlineParserCtl * const cpP, void cmd_processOptions(cmdlineParser const cpP, int const argc, - const char ** const argv, + const char ** const argv, const char ** const errorP) { struct optionx * longopts; longopts = createLongOptsArray(cpP->optionDescArray, cpP->numOptions); - if (longopts == NULL) + if (longopts == NULL) casprintf(errorP, "Unable to get memory for longopts array"); else { int endOfOptions; @@ -268,20 +268,20 @@ cmd_processOptions(cmdlineParser const cpP, cpP->optionDescArray[i].present = false; endOfOptions = false; /* initial value */ - + while (!endOfOptions && !*errorP) { int const opterr0 = 0; /* Don't let getopt_long_only() print an error message */ unsigned int longoptsIndex; const char * unrecognizedOption; const char * optarg; - - getopt_long_onlyx(argc, (char**) argv, "", longopts, + + getopt_long_onlyx(argc, (char**) argv, "", longopts, &longoptsIndex, opterr0, &endOfOptions, &optarg, &unrecognizedOption); - + if (unrecognizedOption) - casprintf(errorP, "Unrecognized option: '%s'", + casprintf(errorP, "Unrecognized option: '%s'", unrecognizedOption); else { if (!endOfOptions) @@ -313,7 +313,7 @@ cmd_createOptionParser(void) { if (optionDescArray == NULL) { free(cpP); cpP = NULL; - } else + } else cpP->optionDescArray = optionDescArray; } return cpP; @@ -323,7 +323,7 @@ cmd_createOptionParser(void) { void cmd_destroyOptionParser(cmdlineParser const cpP) { - + unsigned int i; for (i = 0; i < cpP->numOptions; ++i) { @@ -344,13 +344,13 @@ cmd_destroyOptionParser(cmdlineParser const cpP) { void cmd_defineOption(cmdlineParser const cpP, - const char * const name, + const char * const name, enum optiontype const type) { - + if (cpP->numOptions < MAXOPTS) { cpP->optionDescArray[cpP->numOptions].name = strdup(name); cpP->optionDescArray[cpP->numOptions].type = type; - + ++cpP->numOptions; } } @@ -388,7 +388,7 @@ cmd_optionIsPresent(cmdlineParser const cpP, "optionIsPresent() called for undefined option '%s'\n", name); abort(); - } else + } else present = optionDescP->present; return present; @@ -416,7 +416,7 @@ cmd_getOptionValueUint(cmdlineParser const cpP, "option '%s'\n", optionDescP->name); abort(); } else { - if (optionDescP->present) + if (optionDescP->present) retval = optionDescP->value.u; else retval = 0; @@ -447,7 +447,7 @@ cmd_getOptionValueInt(cmdlineParser const cpP, "option '%s'\n", optionDescP->name); abort(); } else { - if (optionDescP->present) + if (optionDescP->present) retval = optionDescP->value.i; else retval = 0; @@ -469,7 +469,7 @@ cmd_getOptionValueString(cmdlineParser const cpP, if (!optionDescP) { fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueString() called for " + "cmd_getOptionValueString() called for " "undefined option '%s'\n", name); abort(); @@ -483,7 +483,7 @@ cmd_getOptionValueString(cmdlineParser const cpP, if (optionDescP->present) { retval = strdup(optionDescP->value.s); if (retval == NULL) { - fprintf(stderr, + fprintf(stderr, "out of memory in cmd_getOptionValueString()\n"); abort(); } @@ -517,7 +517,7 @@ cmd_getOptionValueBinUint(cmdlineParser const cpP, "option '%s'\n", optionDescP->name); abort(); } else { - if (optionDescP->present) + if (optionDescP->present) retval = optionDescP->value.llu; else retval = 0; @@ -548,7 +548,7 @@ cmd_getOptionValueFloat(cmdlineParser const cpP, "option '%s'\n", optionDescP->name); abort(); } else { - if (optionDescP->present) + if (optionDescP->present) retval = optionDescP->value.d; else retval = 0.0; @@ -559,28 +559,28 @@ cmd_getOptionValueFloat(cmdlineParser const cpP, -unsigned int +unsigned int cmd_argumentCount(cmdlineParser const cpP) { return cpP->numArguments; } - -const char * -cmd_getArgument(cmdlineParser const cpP, - unsigned int const argNumber) { + +const char * +cmd_getArgument(cmdlineParser const cpP, + unsigned int const argNumber) { const char * retval; - + if (argNumber >= cpP->numArguments) retval = NULL; else { retval = strdup(cpP->argumentArray[argNumber]); if (retval == NULL) { - fprintf(stderr, + fprintf(stderr, "out of memory in cmd_getArgument()\n"); abort(); } From 566f714f59a4a13cc833e913946bf5595e2639ed Mon Sep 17 00:00:00 2001 From: giraffedata Date: Mon, 1 Apr 2019 15:38:03 +0000 Subject: [PATCH 054/154] Change -xmlsizelimit to binuint git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3039 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/tools/xmlrpc/xmlrpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/tools/xmlrpc/xmlrpc.c b/trunk/tools/xmlrpc/xmlrpc.c index 37fb49dd6..8d45bdb98 100644 --- a/trunk/tools/xmlrpc/xmlrpc.c +++ b/trunk/tools/xmlrpc/xmlrpc.c @@ -154,7 +154,7 @@ parseCommandLine(xmlrpc_env * const envP, cmd_defineOption(cp, "curlnoverifypeer", OPTTYPE_STRING); cmd_defineOption(cp, "curlnoverifyhost", OPTTYPE_STRING); cmd_defineOption(cp, "curluseragent", OPTTYPE_STRING); - cmd_defineOption(cp, "xmlsizelimit", OPTTYPE_UINT); + cmd_defineOption(cp, "xmlsizelimit", OPTTYPE_BINUINT); cmd_processOptions(cp, argc, argv, &error); From 5b97dec8b3f7fdd924018f05b29c22d7ed251bb2 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Mon, 1 Apr 2019 15:39:22 +0000 Subject: [PATCH 055/154] miscellaneous update git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3040 98333e67-4a24-44d7-a75c-e53540dd3050 From 8d5b979ea846f8d499685423ad8c0848d7b6b5b8 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 28 Jun 2019 20:49:56 +0000 Subject: [PATCH 056/154] Change release number to 1.55.00 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3041 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/version.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trunk/version.mk b/trunk/version.mk index 2272923ff..31e61d2e3 100644 --- a/trunk/version.mk +++ b/trunk/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 54 -XMLRPC_POINT_RELEASE = 99 +XMLRPC_MINOR_RELEASE = 55 +XMLRPC_POINT_RELEASE = 0 From e1a488251d73535fc75545f5501d8881e70e8fb5 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 28 Jun 2019 20:52:36 +0000 Subject: [PATCH 057/154] First 1.55 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3042 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/GNUmakefile | 193 - trunk/Makefile | 17 - trunk/README | 60 - trunk/Windows/CleanAll.bat | 48 - trunk/Windows/CleanWin32.bat | 43 - trunk/Windows/ConfigureWin32.bat | 35 - trunk/Windows/ReadMeWin32.txt | 66 - trunk/Windows/UsingCURLinWin32.txt | 86 - trunk/Windows/UsingProxyDSP.txt | 51 - trunk/Windows/delsln.bat | 56 - trunk/Windows/diffcfg.bat | 6 - trunk/Windows/mkvers.bat | 53 - trunk/Windows/mkvers1.bat | 32 - trunk/Windows/project/vs2008/cpptest.vcproj | 851 -- trunk/Windows/project/vs2008/gennmtab.vcproj | 851 -- trunk/Windows/project/vs2008/rpctest.vcproj | 979 -- .../vs2008/sample_add_asynch_client.vcproj | 839 -- .../project/vs2008/sample_add_server.vcproj | 823 -- .../sample_add_server_w32httpsys.vcproj | 823 -- .../vs2008/sample_add_sync_client.vcproj | 827 -- .../project/vs2008/sample_auth_client.vcproj | 827 -- .../vs2008/tool_xmlrpc-transport.vcproj | 790 -- .../Windows/project/vs2008/tool_xmlrpc.vcproj | 790 -- trunk/Windows/project/vs2008/xmlrpc.sln | 499 - trunk/Windows/project/vs2008/xmlrpc.vcproj | 770 -- trunk/Windows/project/vs2008/xmlrpc__.vcproj | 2430 ---- .../project/vs2008/xmlrpc_abyss.vcproj | 2276 ---- .../project/vs2008/xmlrpc_client.vcproj | 724 -- .../project/vs2008/xmlrpc_server.vcproj | 708 -- .../project/vs2008/xmlrpc_server_abyss.vcproj | 704 -- .../project/vs2008/xmlrpc_server_cgi.vcproj | 696 -- .../vs2008/xmlrpc_server_w32httpsys.vcproj | 700 -- .../Windows/project/vs2008/xmlrpc_util.vcproj | 764 -- .../project/vs2008/xmlrpc_xmlparse.vcproj | 747 -- .../project/vs2008/xmlrpc_xmltok.vcproj | 849 -- .../project/vs2010express/cpptest.vcproj | 851 -- .../project/vs2010express/cpptest.vcxproj | 533 - .../vs2010express/cpptest.vcxproj.filters | 78 - .../vs2010express/cpptest.vcxproj.user | 4 - .../project/vs2010express/gennmtab.vcproj | 851 -- .../project/vs2010express/gennmtab.vcxproj | 515 - .../vs2010express/gennmtab.vcxproj.filters | 22 - .../vs2010express/gennmtab.vcxproj.user | 3 - .../project/vs2010express/rpctest.vcproj | 979 -- .../project/vs2010express/rpctest.vcxproj | 587 - .../vs2010express/rpctest.vcxproj.filters | 127 - .../vs2010express/rpctest.vcxproj.user | 3 - .../sample_add_asynch_client.vcproj | 839 -- .../sample_add_asynch_client.vcxproj | 501 - .../sample_add_asynch_client.vcxproj.filters | 22 - .../sample_add_asynch_client.vcxproj.user | 3 - .../vs2010express/sample_add_server.vcproj | 823 -- .../vs2010express/sample_add_server.vcxproj | 481 - .../sample_add_server.vcxproj.filters | 22 - .../sample_add_server.vcxproj.user | 3 - .../sample_add_server_w32httpsys.vcproj | 823 -- .../sample_add_server_w32httpsys.vcxproj | 481 - ...mple_add_server_w32httpsys.vcxproj.filters | 22 - .../sample_add_server_w32httpsys.vcxproj.user | 3 - .../sample_add_sync_client.vcproj | 827 -- .../sample_add_sync_client.vcxproj | 481 - .../sample_add_sync_client.vcxproj.filters | 22 - .../sample_add_sync_client.vcxproj.user | 3 - .../vs2010express/sample_auth_client.vcproj | 827 -- .../vs2010express/sample_auth_client.vcxproj | 481 - .../sample_auth_client.vcxproj.filters | 22 - .../sample_auth_client.vcxproj.user | 3 - .../tool_xmlrpc-transport.vcproj | 790 -- .../tool_xmlrpc-transport.vcxproj | 519 - .../tool_xmlrpc-transport.vcxproj.filters | 40 - .../tool_xmlrpc-transport.vcxproj.user | 3 - .../project/vs2010express/tool_xmlrpc.vcproj | 790 -- .../project/vs2010express/tool_xmlrpc.vcxproj | 515 - .../vs2010express/tool_xmlrpc.vcxproj.filters | 40 - .../vs2010express/tool_xmlrpc.vcxproj.user | 3 - .../project/vs2010express/vs2010express.sln | 399 - .../project/vs2010express/vs2010express.suo | Bin 34304 -> 0 bytes .../vs2010express/vs2010express.vcxproj | 90 - .../vs2010express.vcxproj.filters | 36 - .../vs2010express/vs2010express.vcxproj.user | 3 - .../project/vs2010express/xmlrpc.vcproj | 770 -- .../project/vs2010express/xmlrpc.vcxproj | 438 - .../vs2010express/xmlrpc.vcxproj.filters | 98 - .../project/vs2010express/xmlrpc.vcxproj.user | 3 - .../project/vs2010express/xmlrpc__.vcproj | 2430 ---- .../project/vs2010express/xmlrpc__.vcxproj | 482 - .../vs2010express/xmlrpc__.vcxproj.filters | 140 - .../vs2010express/xmlrpc__.vcxproj.user | 3 - .../project/vs2010express/xmlrpc_abyss.vcproj | 2276 ---- .../vs2010express/xmlrpc_abyss.vcxproj | 472 - .../xmlrpc_abyss.vcxproj.filters | 140 - .../vs2010express/xmlrpc_abyss.vcxproj.user | 4 - .../vs2010express/xmlrpc_client.vcproj | 724 -- .../vs2010express/xmlrpc_client.vcxproj | 428 - .../xmlrpc_client.vcxproj.filters | 62 - .../vs2010express/xmlrpc_client.vcxproj.user | 3 - .../vs2010express/xmlrpc_server.vcproj | 708 -- .../vs2010express/xmlrpc_server.vcxproj | 421 - .../xmlrpc_server.vcxproj.filters | 53 - .../vs2010express/xmlrpc_server.vcxproj.user | 3 - .../vs2010express/xmlrpc_server_abyss.vcproj | 704 -- .../vs2010express/xmlrpc_server_abyss.vcxproj | 428 - .../xmlrpc_server_abyss.vcxproj.filters | 50 - .../xmlrpc_server_abyss.vcxproj.user | 3 - .../vs2010express/xmlrpc_server_cgi.vcproj | 696 -- .../vs2010express/xmlrpc_server_cgi.vcxproj | 422 - .../xmlrpc_server_cgi.vcxproj.filters | 44 - .../xmlrpc_server_cgi.vcxproj.user | 3 - .../xmlrpc_server_w32httpsys.vcproj | 700 -- .../xmlrpc_server_w32httpsys.vcxproj | 423 - .../xmlrpc_server_w32httpsys.vcxproj.filters | 47 - .../xmlrpc_server_w32httpsys.vcxproj.user | 3 - .../project/vs2010express/xmlrpc_util.vcproj | 764 -- .../project/vs2010express/xmlrpc_util.vcxproj | 438 - .../vs2010express/xmlrpc_util.vcxproj.filters | 86 - .../vs2010express/xmlrpc_util.vcxproj.user | 6 - .../vs2010express/xmlrpc_xmlparse.vcproj | 747 -- .../vs2010express/xmlrpc_xmlparse.vcxproj | 413 - .../xmlrpc_xmlparse.vcxproj.filters | 27 - .../xmlrpc_xmlparse.vcxproj.user | 6 - .../vs2010express/xmlrpc_xmltok.vcproj | 849 -- .../vs2010express/xmlrpc_xmltok.vcxproj | 415 - .../xmlrpc_xmltok.vcxproj.filters | 51 - .../vs2010express/xmlrpc_xmltok.vcxproj.user | 3 - trunk/Windows/project/vs2017/cpptest.vcxproj | 562 - trunk/Windows/project/vs2017/gennmtab.vcxproj | 539 - trunk/Windows/project/vs2017/rpctest.vcxproj | 614 - .../vs2017/sample_add_asynch_client.vcxproj | 525 - .../project/vs2017/sample_add_server.vcxproj | 505 - .../sample_add_server_w32httpsys.vcxproj | 505 - .../vs2017/sample_add_sync_client.vcxproj | 505 - .../project/vs2017/sample_auth_client.vcxproj | 505 - .../vs2017/tool_xmlrpc-transport.vcxproj | 543 - .../project/vs2017/tool_xmlrpc.vcxproj | 539 - trunk/Windows/project/vs2017/xmlrpc.sln | 442 - trunk/Windows/project/vs2017/xmlrpc.vcxproj | 462 - trunk/Windows/project/vs2017/xmlrpc__.vcxproj | 505 - .../project/vs2017/xmlrpc_abyss.vcxproj | 494 - .../project/vs2017/xmlrpc_abyss__.vcxproj | 479 - .../project/vs2017/xmlrpc_client.vcxproj | 452 - .../project/vs2017/xmlrpc_server.vcxproj | 445 - .../vs2017/xmlrpc_server_abyss.vcxproj | 452 - .../project/vs2017/xmlrpc_server_cgi.vcxproj | 446 - .../vs2017/xmlrpc_server_w32httpsys.vcxproj | 447 - .../project/vs2017/xmlrpc_util.vcxproj | 462 - .../project/vs2017/xmlrpc_util__.vcxproj | 475 - .../project/vs2017/xmlrpc_xmlparse.vcxproj | 437 - .../project/vs2017/xmlrpc_xmltok.vcxproj | 439 - trunk/Windows/socketpair.cpp | 71 - trunk/Windows/transport_config_win32.h | 13 - trunk/Windows/updcfg.bat | 9 - trunk/Windows/win32_config.h | 42 - trunk/Windows/xmlrpc_win32_config.h | 275 - trunk/aclocal.m4 | 545 - trunk/common.mk | 814 -- trunk/config.guess | 1502 --- trunk/config.mk.in | 457 - trunk/config.sub | 1714 --- trunk/configure | 7505 ------------- trunk/configure.in | 837 -- trunk/dll-common.mk | 22 - trunk/doc/COPYING | 143 - trunk/doc/CREDITS | 19 - trunk/doc/DEVELOPING | 82 - trunk/doc/HISTORY | 61 - trunk/doc/INSTALL | 246 - trunk/doc/SECURITY | 50 - trunk/doc/TESTING | 96 - trunk/doc/TODO | 60 - trunk/doc/configure_doc | 189 - trunk/dylib-common.mk | 37 - trunk/examples/Makefile | 158 - trunk/examples/README | 35 - trunk/examples/auth_client.c | 84 - trunk/examples/compound_value_client.c | 160 - trunk/examples/compound_value_server.c | 201 - trunk/examples/cpp/Makefile | 124 - trunk/examples/cpp/asynch_client.cpp | 76 - trunk/examples/cpp/callinfo_abyss_server.cpp | 149 - trunk/examples/cpp/pstream_client.cpp | 88 - trunk/examples/cpp/pstream_inetd_server.cpp | 87 - trunk/examples/cpp/pstream_serial_server.cpp | 86 - .../cpp/sample_add_client_complex.cpp | 72 - trunk/examples/cpp/xmlrpc_inetd_server.cpp | 81 - trunk/examples/cpp/xmlrpc_loop_server.cpp | 74 - .../examples/cpp/xmlrpc_sample_add_client.cpp | 40 - .../examples/cpp/xmlrpc_sample_add_server.cpp | 78 - .../cpp/xmlrpc_sample_add_server_cgi.cpp | 62 - trunk/examples/curl_client.c | 151 - trunk/examples/gen_sample_add_xml.c | 73 - trunk/examples/interrupted_client.c | 165 - trunk/examples/interrupted_server.c | 168 - trunk/examples/json.c | 116 - trunk/examples/ssl_secure_server.c | 242 - trunk/examples/ssl_server.c | 230 - trunk/examples/synch_client.c | 66 - trunk/examples/xmlrpc_asynch_client.c | 123 - trunk/examples/xmlrpc_inetd_server.c | 128 - trunk/examples/xmlrpc_loop_server.c | 185 - trunk/examples/xmlrpc_sample_add_client.c | 84 - trunk/examples/xmlrpc_sample_add_server.c | 128 - trunk/examples/xmlrpc_sample_add_server_cgi.c | 75 - .../xmlrpc_sample_add_server_w32httpsys.c | 190 - trunk/examples/xmlrpc_server_validatee.c | 412 - trunk/examples/xmlrpc_socket_server.c | 113 - trunk/include/Makefile | 178 - trunk/include/xmlrpc-c/AbyssChanSwitch.hpp | 47 - .../xmlrpc-c/AbyssChanSwitchOpenSsl.hpp | 35 - .../include/xmlrpc-c/AbyssChanSwitchUnix.hpp | 23 - trunk/include/xmlrpc-c/AbyssChanSwitchWin.hpp | 30 - trunk/include/xmlrpc-c/AbyssEnvironment.hpp | 32 - trunk/include/xmlrpc-c/AbyssServer.hpp | 252 - trunk/include/xmlrpc-c/Lock.hpp | 32 - trunk/include/xmlrpc-c/abyss.h | 696 -- trunk/include/xmlrpc-c/abyss_openssl.h | 82 - .../xmlrpc-c/abyss_reqhandler_xmlrpc.hpp | 50 - trunk/include/xmlrpc-c/abyss_unixsock.h | 61 - trunk/include/xmlrpc-c/abyss_winsock.h | 48 - trunk/include/xmlrpc-c/base.h | 955 -- trunk/include/xmlrpc-c/base.hpp | 588 - trunk/include/xmlrpc-c/base64.hpp | 41 - trunk/include/xmlrpc-c/base64_int.h | 24 - trunk/include/xmlrpc-c/base_int.h | 238 - trunk/include/xmlrpc-c/c_util.h | 32 - trunk/include/xmlrpc-c/client.h | 439 - trunk/include/xmlrpc-c/client.hpp | 312 - trunk/include/xmlrpc-c/client_global.h | 145 - trunk/include/xmlrpc-c/client_int.h | 152 - trunk/include/xmlrpc-c/client_simple.hpp | 57 - trunk/include/xmlrpc-c/client_transport.hpp | 449 - trunk/include/xmlrpc-c/env_wrap.hpp | 33 - trunk/include/xmlrpc-c/girerr.hpp | 49 - trunk/include/xmlrpc-c/girmem.hpp | 81 - trunk/include/xmlrpc-c/inttypes.h | 22 - trunk/include/xmlrpc-c/json.h | 39 - trunk/include/xmlrpc-c/lock.h | 26 - trunk/include/xmlrpc-c/lock_none.h | 9 - trunk/include/xmlrpc-c/lock_platform.h | 32 - trunk/include/xmlrpc-c/lock_pthread.h | 24 - trunk/include/xmlrpc-c/lock_windows.h | 24 - trunk/include/xmlrpc-c/oldcppwrapper.hpp | 418 - trunk/include/xmlrpc-c/oldxmlrpc.h | 2 - trunk/include/xmlrpc-c/openssl_thread.h | 10 - trunk/include/xmlrpc-c/packetsocket.hpp | 140 - trunk/include/xmlrpc-c/registry.hpp | 242 - trunk/include/xmlrpc-c/select_int.h | 51 - trunk/include/xmlrpc-c/server.h | 210 - trunk/include/xmlrpc-c/server_abyss.h | 382 - trunk/include/xmlrpc-c/server_abyss.hpp | 196 - trunk/include/xmlrpc-c/server_cgi.h | 70 - trunk/include/xmlrpc-c/server_cgi.hpp | 59 - trunk/include/xmlrpc-c/server_pstream.hpp | 193 - trunk/include/xmlrpc-c/server_w32httpsys.h | 111 - trunk/include/xmlrpc-c/sleep_int.h | 31 - trunk/include/xmlrpc-c/string_int.h | 149 - trunk/include/xmlrpc-c/string_number.h | 35 - trunk/include/xmlrpc-c/time_int.h | 54 - trunk/include/xmlrpc-c/timeout.hpp | 36 - trunk/include/xmlrpc-c/transport.h | 95 - trunk/include/xmlrpc-c/util.h | 381 - trunk/include/xmlrpc-c/util_int.h | 83 - trunk/include/xmlrpc-c/xml.hpp | 71 - trunk/install-sh | 251 - trunk/irix-common.mk | 31 - trunk/lib/Makefile | 72 - trunk/lib/abyss++/AbyssChanSwitch.cpp | 38 - trunk/lib/abyss++/AbyssChanSwitchOpenSsl.cpp | 59 - trunk/lib/abyss++/AbyssChanSwitchUnix.cpp | 33 - trunk/lib/abyss++/AbyssChanSwitchWin.cpp | 33 - trunk/lib/abyss++/AbyssEnvironment.cpp | 42 - trunk/lib/abyss++/AbyssServer.cpp | 1035 -- trunk/lib/abyss++/Makefile | 153 - trunk/lib/abyss/HISTORY | 122 - trunk/lib/abyss/Makefile | 44 - trunk/lib/abyss/README | 23 - trunk/lib/abyss/conf/abyss.conf | 56 - trunk/lib/abyss/conf/mime.types | 276 - trunk/lib/abyss/example/conf/abyss.conf | 56 - trunk/lib/abyss/example/conf/mime.types | 276 - trunk/lib/abyss/example/htdocs/index.htm | 21 - trunk/lib/abyss/example/htdocs/pwrabyss.gif | Bin 2198 -> 0 bytes trunk/lib/abyss/license.txt | 27 - trunk/lib/abyss/src/Makefile | 167 - trunk/lib/abyss/src/abyss_info.h | 20 - trunk/lib/abyss/src/channel.c | 198 - trunk/lib/abyss/src/channel.h | 112 - trunk/lib/abyss/src/chanswitch.c | 252 - trunk/lib/abyss/src/chanswitch.h | 82 - trunk/lib/abyss/src/conf.c | 398 - trunk/lib/abyss/src/conn.c | 665 -- trunk/lib/abyss/src/conn.h | 126 - trunk/lib/abyss/src/data.c | 696 -- trunk/lib/abyss/src/data.h | 174 - trunk/lib/abyss/src/date.c | 206 - trunk/lib/abyss/src/date.h | 21 - trunk/lib/abyss/src/file.c | 384 - trunk/lib/abyss/src/file.h | 112 - trunk/lib/abyss/src/handler.c | 838 -- trunk/lib/abyss/src/handler.h | 33 - trunk/lib/abyss/src/http.c | 400 - trunk/lib/abyss/src/http.h | 33 - trunk/lib/abyss/src/init.c | 101 - trunk/lib/abyss/src/main.c | 254 - trunk/lib/abyss/src/response.c | 826 -- trunk/lib/abyss/src/server.c | 1828 --- trunk/lib/abyss/src/server.h | 123 - trunk/lib/abyss/src/session.c | 726 -- trunk/lib/abyss/src/session.h | 146 - trunk/lib/abyss/src/sessionReadRequest.c | 1210 -- trunk/lib/abyss/src/sessionReadRequest.h | 12 - trunk/lib/abyss/src/socket.c | 127 - trunk/lib/abyss/src/socket.h | 60 - trunk/lib/abyss/src/socket_openssl.c | 973 -- trunk/lib/abyss/src/socket_openssl.h | 14 - trunk/lib/abyss/src/socket_unix.c | 873 -- trunk/lib/abyss/src/socket_unix.h | 14 - trunk/lib/abyss/src/socket_win.c | 1083 -- trunk/lib/abyss/src/socket_win.h | 10 - trunk/lib/abyss/src/sockutil.c | 490 - trunk/lib/abyss/src/sockutil.h | 72 - trunk/lib/abyss/src/thread.h | 57 - trunk/lib/abyss/src/thread_fork.c | 293 - trunk/lib/abyss/src/thread_pthread.c | 202 - trunk/lib/abyss/src/thread_windows.c | 171 - trunk/lib/abyss/src/token.c | 65 - trunk/lib/abyss/src/token.h | 14 - trunk/lib/abyss/src/trace.c | 78 - trunk/lib/abyss/src/trace.h | 11 - trunk/lib/curl_transport/Makefile | 83 - trunk/lib/curl_transport/curlmulti.c | 320 - trunk/lib/curl_transport/curlmulti.h | 51 - trunk/lib/curl_transport/curltransaction.c | 1031 -- trunk/lib/curl_transport/curltransaction.h | 127 - trunk/lib/curl_transport/curlversion.h | 26 - .../curl_transport/xmlrpc_curl_transport.c | 1652 --- trunk/lib/expat/Makefile | 70 - trunk/lib/expat/expat.html | 93 - trunk/lib/expat/gennmtab/Makefile | 49 - trunk/lib/expat/gennmtab/gennmtab.c | 433 - trunk/lib/expat/xmlparse/Makefile | 96 - trunk/lib/expat/xmlparse/xmlparse.c | 5029 --------- trunk/lib/expat/xmlparse/xmlparse.h | 584 - trunk/lib/expat/xmltok/Makefile | 112 - trunk/lib/expat/xmltok/ascii.h | 86 - trunk/lib/expat/xmltok/asciitab.h | 37 - trunk/lib/expat/xmltok/dllmain.c | 15 - trunk/lib/expat/xmltok/iasciitab.h | 38 - trunk/lib/expat/xmltok/latin1tab.h | 37 - trunk/lib/expat/xmltok/utf8tab.h | 38 - trunk/lib/expat/xmltok/xmldef.h | 49 - trunk/lib/expat/xmltok/xmlrole.c | 1262 --- trunk/lib/expat/xmltok/xmlrole.h | 99 - trunk/lib/expat/xmltok/xmltok.c | 1570 --- trunk/lib/expat/xmltok/xmltok.h | 356 - trunk/lib/expat/xmltok/xmltok_impl.c | 1889 ---- trunk/lib/expat/xmltok/xmltok_impl.h | 46 - trunk/lib/expat/xmltok/xmltok_ns.c | 148 - trunk/lib/expat/xmlwf/Makefile.in | 209 - trunk/lib/expat/xmlwf/codepage.c | 66 - trunk/lib/expat/xmlwf/codepage.h | 7 - trunk/lib/expat/xmlwf/filemap.h | 17 - trunk/lib/expat/xmlwf/readfilemap.c | 74 - trunk/lib/expat/xmlwf/unixfilemap.c | 57 - trunk/lib/expat/xmlwf/win32filemap.c | 96 - trunk/lib/expat/xmlwf/xmlfile.c | 223 - trunk/lib/expat/xmlwf/xmlfile.h | 11 - trunk/lib/expat/xmlwf/xmltchar.h | 36 - trunk/lib/expat/xmlwf/xmlwf.c | 767 -- trunk/lib/expat/xmlwf/xmlwf.dsp | 136 - trunk/lib/libutil++/Lock.cpp | 65 - trunk/lib/libutil++/Makefile | 133 - trunk/lib/libutil++/base64.cpp | 254 - trunk/lib/libutil++/env_wrap.cpp | 18 - trunk/lib/libutil++/girerr.cpp | 28 - trunk/lib/libutil++/girmem.cpp | 209 - trunk/lib/libutil/Makefile | 137 - trunk/lib/libutil/asprintf.c | 199 - trunk/lib/libutil/base64.c | 333 - trunk/lib/libutil/error.c | 167 - trunk/lib/libutil/lock_none.c | 61 - trunk/lib/libutil/lock_platform.c | 48 - trunk/lib/libutil/lock_pthread.c | 78 - trunk/lib/libutil/lock_windows.c | 85 - trunk/lib/libutil/make_printable.c | 101 - trunk/lib/libutil/memblock.c | 272 - trunk/lib/libutil/mempool.c | 98 - trunk/lib/libutil/select.c | 62 - trunk/lib/libutil/sleep.c | 23 - trunk/lib/libutil/string_number.c | 46 - trunk/lib/libutil/time.c | 174 - trunk/lib/libutil/utf8.c | 608 - trunk/lib/libwww_transport/Makefile | 64 - .../xmlrpc_libwww_transport.c | 956 -- trunk/lib/openssl/Makefile | 121 - trunk/lib/openssl/xmlrpc_openssl_thread.c | 124 - trunk/lib/util/Makefile | 84 - trunk/lib/util/casprintf.c | 143 - trunk/lib/util/cmdline_parser.c | 589 - trunk/lib/util/cmdline_parser_cpp.cpp | 157 - trunk/lib/util/getoptx.c | 466 - trunk/lib/util/getoptx.h | 51 - trunk/lib/util/include/assertx.hpp | 27 - trunk/lib/util/include/bool.h | 18 - trunk/lib/util/include/c_util.h | 19 - trunk/lib/util/include/casprintf.h | 29 - trunk/lib/util/include/cmdline_parser.h | 86 - trunk/lib/util/include/cmdline_parser.hpp | 59 - trunk/lib/util/include/girmath.h | 39 - trunk/lib/util/include/girstring.h | 51 - trunk/lib/util/include/inline.h | 19 - trunk/lib/util/include/int.h | 63 - trunk/lib/util/include/linklist.h | 193 - trunk/lib/util/include/mallocvar.h | 111 - trunk/lib/util/include/stdargx.h | 67 - trunk/lib/util/include/string_parser.h | 31 - trunk/lib/util/include/unistdx.h | 14 - trunk/lib/util/string_parser.c | 226 - trunk/lib/util/stripcaseeq.c | 68 - trunk/lib/wininet_transport/Makefile | 61 - trunk/lib/wininet_transport/pthreadx.h | 73 - trunk/lib/wininet_transport/pthreadx_win32.c | 121 - .../xmlrpc_wininet_transport.c | 1001 -- trunk/missing | 190 - trunk/mkinstalldirs | 40 - trunk/src/Makefile | 421 - trunk/src/abyss_handler.c | 642 -- trunk/src/abyss_handler.h | 49 - trunk/src/base_global.c | 52 - trunk/src/cpp/Makefile | 432 - trunk/src/cpp/XmlRpcCpp.cpp | 397 - trunk/src/cpp/abyss_reqhandler_xmlrpc.cpp | 109 - trunk/src/cpp/client.cpp | 1279 --- trunk/src/cpp/client_simple.cpp | 161 - trunk/src/cpp/curl.cpp | 412 - trunk/src/cpp/fault.cpp | 35 - trunk/src/cpp/global.cpp | 30 - trunk/src/cpp/libwww.cpp | 159 - trunk/src/cpp/outcome.cpp | 57 - trunk/src/cpp/packetsocket.cpp | 1106 -- trunk/src/cpp/param_list.cpp | 303 - trunk/src/cpp/pstream.cpp | 264 - trunk/src/cpp/registry.cpp | 593 - trunk/src/cpp/server_abyss.cpp | 1064 -- trunk/src/cpp/server_cgi.cpp | 359 - trunk/src/cpp/server_pstream.cpp | 278 - trunk/src/cpp/server_pstream_conn.cpp | 364 - trunk/src/cpp/value.cpp | 1140 -- trunk/src/cpp/wininet.cpp | 166 - trunk/src/cpp/xml.cpp | 312 - trunk/src/double.c | 285 - trunk/src/double.h | 11 - trunk/src/json.c | 1485 --- trunk/src/method.c | 455 - trunk/src/method.h | 125 - trunk/src/parse_datetime.c | 467 - trunk/src/parse_datetime.h | 12 - trunk/src/parse_value.c | 744 -- trunk/src/parse_value.h | 13 - trunk/src/parse_xml.c | 103 - trunk/src/registry.c | 499 - trunk/src/registry.h | 15 - trunk/src/resource.c | 31 - trunk/src/system_method.c | 886 -- trunk/src/system_method.h | 14 - trunk/src/trace.c | 63 - trunk/src/version.c | 18 - trunk/src/xmlparser.h | 131 - trunk/src/xmlrpc_array.c | 278 - trunk/src/xmlrpc_authcookie.c | 86 - trunk/src/xmlrpc_build.c | 430 - trunk/src/xmlrpc_client.c | 1201 -- trunk/src/xmlrpc_client_global.c | 370 - trunk/src/xmlrpc_data.c | 721 -- trunk/src/xmlrpc_datetime.c | 672 -- trunk/src/xmlrpc_decompose.c | 1153 -- trunk/src/xmlrpc_expat.c | 546 - trunk/src/xmlrpc_libxml2.c | 533 - trunk/src/xmlrpc_parse.c | 754 -- trunk/src/xmlrpc_parse.h | 42 - trunk/src/xmlrpc_serialize.c | 780 -- trunk/src/xmlrpc_server_abyss.c | 1374 --- trunk/src/xmlrpc_server_cgi.c | 331 - trunk/src/xmlrpc_server_info.c | 350 - trunk/src/xmlrpc_server_w32httpsys.c | 1016 -- trunk/src/xmlrpc_string.c | 993 -- trunk/src/xmlrpc_struct.c | 711 -- trunk/srcdir.mk.in | 1 - trunk/stamp-h.in | 1 - trunk/test/Makefile | 122 - trunk/test/abyss.c | 416 - trunk/test/abyss.h | 2 - trunk/test/abyss_dummy.c | 14 - trunk/test/cgi.c | 60 - trunk/test/cgi.h | 2 - trunk/test/cgitest1.c | 79 - trunk/test/client.c | 508 - trunk/test/client.h | 2 - trunk/test/client_dummy.c | 14 - trunk/test/cpp/Makefile | 134 - trunk/test/cpp/abyss.cpp | 115 - trunk/test/cpp/abyss.hpp | 8 - trunk/test/cpp/abyss_dummy.cpp | 29 - trunk/test/cpp/base64.cpp | 54 - trunk/test/cpp/base64.hpp | 9 - trunk/test/cpp/registry.cpp | 550 - trunk/test/cpp/registry.hpp | 9 - trunk/test/cpp/server_abyss.cpp | 410 - trunk/test/cpp/server_abyss.hpp | 8 - trunk/test/cpp/server_abyss_dummy.cpp | 29 - trunk/test/cpp/server_pstream.cpp | 821 -- trunk/test/cpp/server_pstream.hpp | 8 - trunk/test/cpp/test.cpp | 390 - trunk/test/cpp/testclient.cpp | 953 -- trunk/test/cpp/testclient.hpp | 9 - trunk/test/cpp/testclient_dummy.cpp | 29 - trunk/test/cpp/tools.cpp | 87 - trunk/test/cpp/tools.hpp | 85 - trunk/test/cpp/value.cpp | 544 - trunk/test/cpp/value.hpp | 9 - trunk/test/cpp/xml.cpp | 100 - trunk/test/cpp/xml.hpp | 9 - trunk/test/data/req_no_params.xml | 9 - trunk/test/data/req_out_of_order.xml | 12 - trunk/test/data/req_value_name.xml | 14 - trunk/test/data/sample_add_call.xml | 8 - trunk/test/eftest_wrapper.sh | 17 - trunk/test/http-req-simple.txt | 11 - trunk/test/memblock.c | 237 - trunk/test/memblock.h | 7 - trunk/test/method_registry.c | 1126 -- trunk/test/method_registry.h | 7 - trunk/test/parse_xml.c | 529 - trunk/test/parse_xml.h | 2 - trunk/test/req_no_params.xml | 9 - trunk/test/serialize.c | 316 - trunk/test/serialize.h | 2 - trunk/test/serialize_value.c | 241 - trunk/test/serialize_value.h | 7 - trunk/test/server_abyss.c | 277 - trunk/test/server_abyss.h | 2 - trunk/test/server_abyss_dummy.c | 14 - trunk/test/test.c | 740 -- trunk/test/testtool.c | 88 - trunk/test/testtool.h | 93 - trunk/test/value.c | 2043 ---- trunk/test/value.h | 2 - trunk/test/value_datetime.c | 448 - trunk/test/value_datetime.h | 7 - trunk/test/xml_data.c | 200 - trunk/test/xml_data.h | 28 - trunk/tools/Makefile | 48 - trunk/tools/binmode-rpc-kit/COPYING | 24 - trunk/tools/binmode-rpc-kit/Makefile | 6 - trunk/tools/binmode-rpc-kit/README | 31 - .../tools/binmode-rpc-kit/binmode-rpc-rfc.txt | 338 - .../tools/binmode-rpc-kit/binmode-rpc2xml-rpc | 552 - .../binmode-rpc-kit/examples/good-1.binmode | Bin 80 -> 0 bytes .../tools/binmode-rpc-kit/examples/good-1.xml | 32 - .../binmode-rpc-kit/examples/good-2.binmode | Bin 36 -> 0 bytes .../tools/binmode-rpc-kit/examples/good-2.xml | 12 - .../binmode-rpc-kit/examples/good-3.binmode | Bin 18 -> 0 bytes .../tools/binmode-rpc-kit/examples/good-3.xml | 8 - .../binmode-rpc-kit/examples/good-4.binmode | Bin 76 -> 0 bytes .../tools/binmode-rpc-kit/examples/good-4.xml | 17 - .../binmode-rpc-kit/examples/good-5.binmode | Bin 51 -> 0 bytes .../tools/binmode-rpc-kit/examples/good-5.xml | 19 - .../binmode-rpc-kit/examples/good-6.binmode | Bin 52 -> 0 bytes .../tools/binmode-rpc-kit/examples/good-6.xml | 8 - .../examples/invalid-1.binmode | Bin 19 -> 0 bytes .../examples/invalid-2.binmode | Bin 33 -> 0 bytes .../examples/invalid-3.binmode | 1 - .../examples/invalid-4.binmode | Bin 51 -> 0 bytes .../examples/invalid-5.binmode | Bin 51 -> 0 bytes trunk/tools/binmode-rpc-kit/oct2bin | 12 - trunk/tools/common.mk | 49 - trunk/tools/interop-server/interop-cgi.c | 215 - trunk/tools/lib/Makefile | 46 - trunk/tools/lib/dumpvalue.c | 497 - trunk/tools/lib/include/dumpvalue.h | 10 - trunk/tools/perl_packetsocket/PacketSocket.pm | 186 - trunk/tools/turbocharger/Makefile | 6 - trunk/tools/turbocharger/README | 37 - trunk/tools/turbocharger/mod_gzip.c | 9843 ----------------- trunk/tools/turbocharger/mod_gzip.c.diff | 365 - trunk/tools/xml-rpc-api2cpp/DataType.cpp | 268 - trunk/tools/xml-rpc-api2cpp/DataType.hpp | 43 - trunk/tools/xml-rpc-api2cpp/Makefile | 73 - trunk/tools/xml-rpc-api2cpp/SystemProxy.cpp | 39 - trunk/tools/xml-rpc-api2cpp/SystemProxy.hpp | 48 - trunk/tools/xml-rpc-api2cpp/XmlRpcClass.cpp | 84 - trunk/tools/xml-rpc-api2cpp/XmlRpcClass.hpp | 22 - .../tools/xml-rpc-api2cpp/XmlRpcFunction.cpp | 216 - .../tools/xml-rpc-api2cpp/XmlRpcFunction.hpp | 39 - trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1 | 62 - .../tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp | 212 - trunk/tools/xml-rpc-api2txt/Makefile | 42 - trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt | 147 - trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt.1 | 47 - trunk/tools/xml/Makefile | 68 - trunk/tools/xml/xmlrpc_parsecall.c | 95 - trunk/tools/xmlrpc/Makefile | 68 - trunk/tools/xmlrpc/xmlrpc.c | 945 -- trunk/tools/xmlrpc_cpp_proxy/Makefile | 70 - trunk/tools/xmlrpc_cpp_proxy/proxyClass.cpp | 85 - trunk/tools/xmlrpc_cpp_proxy/proxyClass.hpp | 32 - trunk/tools/xmlrpc_cpp_proxy/systemProxy.cpp | 57 - trunk/tools/xmlrpc_cpp_proxy/systemProxy.hpp | 25 - trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp | 240 - trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp | 59 - trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp | 270 - trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp | 43 - .../xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp | 208 - trunk/tools/xmlrpc_dumpserver/Makefile | 72 - .../xmlrpc_dumpserver/xmlrpc_dumpserver.c | 269 - trunk/tools/xmlrpc_pstream/Makefile | 79 - trunk/tools/xmlrpc_pstream/test | 28 - trunk/tools/xmlrpc_pstream/xmlrpc_pstream.cpp | 507 - trunk/tools/xmlrpc_transport/Makefile | 63 - .../tools/xmlrpc_transport/xmlrpc_transport.c | 290 - .../xmlrpc_transport/xmlrpc_transport.html | 93 - trunk/transport_config.mk | 39 - trunk/unix-common.mk | 104 - trunk/version.mk | 11 - trunk/xmlrpc-c-config.main | 207 - trunk/xmlrpc-c-config.test.main | 175 - trunk/xmlrpc_config.h.in | 242 - 626 files changed, 192926 deletions(-) delete mode 100644 trunk/GNUmakefile delete mode 100644 trunk/Makefile delete mode 100644 trunk/README delete mode 100644 trunk/Windows/CleanAll.bat delete mode 100644 trunk/Windows/CleanWin32.bat delete mode 100644 trunk/Windows/ConfigureWin32.bat delete mode 100644 trunk/Windows/ReadMeWin32.txt delete mode 100644 trunk/Windows/UsingCURLinWin32.txt delete mode 100644 trunk/Windows/UsingProxyDSP.txt delete mode 100644 trunk/Windows/delsln.bat delete mode 100644 trunk/Windows/diffcfg.bat delete mode 100644 trunk/Windows/mkvers.bat delete mode 100644 trunk/Windows/mkvers1.bat delete mode 100644 trunk/Windows/project/vs2008/cpptest.vcproj delete mode 100644 trunk/Windows/project/vs2008/gennmtab.vcproj delete mode 100644 trunk/Windows/project/vs2008/rpctest.vcproj delete mode 100644 trunk/Windows/project/vs2008/sample_add_asynch_client.vcproj delete mode 100644 trunk/Windows/project/vs2008/sample_add_server.vcproj delete mode 100644 trunk/Windows/project/vs2008/sample_add_server_w32httpsys.vcproj delete mode 100644 trunk/Windows/project/vs2008/sample_add_sync_client.vcproj delete mode 100644 trunk/Windows/project/vs2008/sample_auth_client.vcproj delete mode 100644 trunk/Windows/project/vs2008/tool_xmlrpc-transport.vcproj delete mode 100644 trunk/Windows/project/vs2008/tool_xmlrpc.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc.sln delete mode 100644 trunk/Windows/project/vs2008/xmlrpc.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc__.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc_abyss.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc_client.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc_server.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc_server_abyss.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc_server_cgi.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc_server_w32httpsys.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc_util.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc_xmlparse.vcproj delete mode 100644 trunk/Windows/project/vs2008/xmlrpc_xmltok.vcproj delete mode 100644 trunk/Windows/project/vs2010express/cpptest.vcproj delete mode 100644 trunk/Windows/project/vs2010express/cpptest.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/cpptest.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/cpptest.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/gennmtab.vcproj delete mode 100644 trunk/Windows/project/vs2010express/gennmtab.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/gennmtab.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/gennmtab.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/rpctest.vcproj delete mode 100644 trunk/Windows/project/vs2010express/rpctest.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/rpctest.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/rpctest.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/sample_add_asynch_client.vcproj delete mode 100644 trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/sample_add_server.vcproj delete mode 100644 trunk/Windows/project/vs2010express/sample_add_server.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/sample_add_server.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/sample_add_server.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcproj delete mode 100644 trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/sample_add_sync_client.vcproj delete mode 100644 trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/sample_auth_client.vcproj delete mode 100644 trunk/Windows/project/vs2010express/sample_auth_client.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/sample_auth_client.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/sample_auth_client.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcproj delete mode 100644 trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/tool_xmlrpc.vcproj delete mode 100644 trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/vs2010express.sln delete mode 100644 trunk/Windows/project/vs2010express/vs2010express.suo delete mode 100644 trunk/Windows/project/vs2010express/vs2010express.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/vs2010express.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/vs2010express.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc__.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc__.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc__.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc__.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_abyss.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_client.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_util.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.user delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.filters delete mode 100644 trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.user delete mode 100644 trunk/Windows/project/vs2017/cpptest.vcxproj delete mode 100644 trunk/Windows/project/vs2017/gennmtab.vcxproj delete mode 100644 trunk/Windows/project/vs2017/rpctest.vcxproj delete mode 100644 trunk/Windows/project/vs2017/sample_add_asynch_client.vcxproj delete mode 100644 trunk/Windows/project/vs2017/sample_add_server.vcxproj delete mode 100644 trunk/Windows/project/vs2017/sample_add_server_w32httpsys.vcxproj delete mode 100644 trunk/Windows/project/vs2017/sample_add_sync_client.vcxproj delete mode 100644 trunk/Windows/project/vs2017/sample_auth_client.vcxproj delete mode 100644 trunk/Windows/project/vs2017/tool_xmlrpc-transport.vcxproj delete mode 100644 trunk/Windows/project/vs2017/tool_xmlrpc.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc.sln delete mode 100644 trunk/Windows/project/vs2017/xmlrpc.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc__.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_abyss.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_abyss__.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_client.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_server.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_server_abyss.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_server_cgi.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_server_w32httpsys.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_util.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_util__.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_xmlparse.vcxproj delete mode 100644 trunk/Windows/project/vs2017/xmlrpc_xmltok.vcxproj delete mode 100644 trunk/Windows/socketpair.cpp delete mode 100644 trunk/Windows/transport_config_win32.h delete mode 100644 trunk/Windows/updcfg.bat delete mode 100644 trunk/Windows/win32_config.h delete mode 100644 trunk/Windows/xmlrpc_win32_config.h delete mode 100644 trunk/aclocal.m4 delete mode 100644 trunk/common.mk delete mode 100755 trunk/config.guess delete mode 100644 trunk/config.mk.in delete mode 100755 trunk/config.sub delete mode 100755 trunk/configure delete mode 100644 trunk/configure.in delete mode 100644 trunk/dll-common.mk delete mode 100644 trunk/doc/COPYING delete mode 100644 trunk/doc/CREDITS delete mode 100644 trunk/doc/DEVELOPING delete mode 100644 trunk/doc/HISTORY delete mode 100644 trunk/doc/INSTALL delete mode 100644 trunk/doc/SECURITY delete mode 100644 trunk/doc/TESTING delete mode 100644 trunk/doc/TODO delete mode 100644 trunk/doc/configure_doc delete mode 100644 trunk/dylib-common.mk delete mode 100644 trunk/examples/Makefile delete mode 100644 trunk/examples/README delete mode 100644 trunk/examples/auth_client.c delete mode 100644 trunk/examples/compound_value_client.c delete mode 100644 trunk/examples/compound_value_server.c delete mode 100644 trunk/examples/cpp/Makefile delete mode 100644 trunk/examples/cpp/asynch_client.cpp delete mode 100644 trunk/examples/cpp/callinfo_abyss_server.cpp delete mode 100644 trunk/examples/cpp/pstream_client.cpp delete mode 100644 trunk/examples/cpp/pstream_inetd_server.cpp delete mode 100644 trunk/examples/cpp/pstream_serial_server.cpp delete mode 100644 trunk/examples/cpp/sample_add_client_complex.cpp delete mode 100644 trunk/examples/cpp/xmlrpc_inetd_server.cpp delete mode 100644 trunk/examples/cpp/xmlrpc_loop_server.cpp delete mode 100644 trunk/examples/cpp/xmlrpc_sample_add_client.cpp delete mode 100644 trunk/examples/cpp/xmlrpc_sample_add_server.cpp delete mode 100644 trunk/examples/cpp/xmlrpc_sample_add_server_cgi.cpp delete mode 100644 trunk/examples/curl_client.c delete mode 100644 trunk/examples/gen_sample_add_xml.c delete mode 100644 trunk/examples/interrupted_client.c delete mode 100644 trunk/examples/interrupted_server.c delete mode 100644 trunk/examples/json.c delete mode 100644 trunk/examples/ssl_secure_server.c delete mode 100644 trunk/examples/ssl_server.c delete mode 100644 trunk/examples/synch_client.c delete mode 100644 trunk/examples/xmlrpc_asynch_client.c delete mode 100644 trunk/examples/xmlrpc_inetd_server.c delete mode 100644 trunk/examples/xmlrpc_loop_server.c delete mode 100644 trunk/examples/xmlrpc_sample_add_client.c delete mode 100644 trunk/examples/xmlrpc_sample_add_server.c delete mode 100644 trunk/examples/xmlrpc_sample_add_server_cgi.c delete mode 100644 trunk/examples/xmlrpc_sample_add_server_w32httpsys.c delete mode 100644 trunk/examples/xmlrpc_server_validatee.c delete mode 100644 trunk/examples/xmlrpc_socket_server.c delete mode 100644 trunk/include/Makefile delete mode 100644 trunk/include/xmlrpc-c/AbyssChanSwitch.hpp delete mode 100644 trunk/include/xmlrpc-c/AbyssChanSwitchOpenSsl.hpp delete mode 100644 trunk/include/xmlrpc-c/AbyssChanSwitchUnix.hpp delete mode 100644 trunk/include/xmlrpc-c/AbyssChanSwitchWin.hpp delete mode 100644 trunk/include/xmlrpc-c/AbyssEnvironment.hpp delete mode 100644 trunk/include/xmlrpc-c/AbyssServer.hpp delete mode 100644 trunk/include/xmlrpc-c/Lock.hpp delete mode 100644 trunk/include/xmlrpc-c/abyss.h delete mode 100644 trunk/include/xmlrpc-c/abyss_openssl.h delete mode 100644 trunk/include/xmlrpc-c/abyss_reqhandler_xmlrpc.hpp delete mode 100644 trunk/include/xmlrpc-c/abyss_unixsock.h delete mode 100644 trunk/include/xmlrpc-c/abyss_winsock.h delete mode 100644 trunk/include/xmlrpc-c/base.h delete mode 100644 trunk/include/xmlrpc-c/base.hpp delete mode 100644 trunk/include/xmlrpc-c/base64.hpp delete mode 100644 trunk/include/xmlrpc-c/base64_int.h delete mode 100644 trunk/include/xmlrpc-c/base_int.h delete mode 100644 trunk/include/xmlrpc-c/c_util.h delete mode 100644 trunk/include/xmlrpc-c/client.h delete mode 100644 trunk/include/xmlrpc-c/client.hpp delete mode 100644 trunk/include/xmlrpc-c/client_global.h delete mode 100644 trunk/include/xmlrpc-c/client_int.h delete mode 100644 trunk/include/xmlrpc-c/client_simple.hpp delete mode 100644 trunk/include/xmlrpc-c/client_transport.hpp delete mode 100644 trunk/include/xmlrpc-c/env_wrap.hpp delete mode 100644 trunk/include/xmlrpc-c/girerr.hpp delete mode 100644 trunk/include/xmlrpc-c/girmem.hpp delete mode 100644 trunk/include/xmlrpc-c/inttypes.h delete mode 100644 trunk/include/xmlrpc-c/json.h delete mode 100644 trunk/include/xmlrpc-c/lock.h delete mode 100644 trunk/include/xmlrpc-c/lock_none.h delete mode 100644 trunk/include/xmlrpc-c/lock_platform.h delete mode 100644 trunk/include/xmlrpc-c/lock_pthread.h delete mode 100644 trunk/include/xmlrpc-c/lock_windows.h delete mode 100644 trunk/include/xmlrpc-c/oldcppwrapper.hpp delete mode 100644 trunk/include/xmlrpc-c/oldxmlrpc.h delete mode 100644 trunk/include/xmlrpc-c/openssl_thread.h delete mode 100644 trunk/include/xmlrpc-c/packetsocket.hpp delete mode 100644 trunk/include/xmlrpc-c/registry.hpp delete mode 100644 trunk/include/xmlrpc-c/select_int.h delete mode 100644 trunk/include/xmlrpc-c/server.h delete mode 100644 trunk/include/xmlrpc-c/server_abyss.h delete mode 100644 trunk/include/xmlrpc-c/server_abyss.hpp delete mode 100644 trunk/include/xmlrpc-c/server_cgi.h delete mode 100644 trunk/include/xmlrpc-c/server_cgi.hpp delete mode 100644 trunk/include/xmlrpc-c/server_pstream.hpp delete mode 100644 trunk/include/xmlrpc-c/server_w32httpsys.h delete mode 100644 trunk/include/xmlrpc-c/sleep_int.h delete mode 100644 trunk/include/xmlrpc-c/string_int.h delete mode 100644 trunk/include/xmlrpc-c/string_number.h delete mode 100644 trunk/include/xmlrpc-c/time_int.h delete mode 100644 trunk/include/xmlrpc-c/timeout.hpp delete mode 100644 trunk/include/xmlrpc-c/transport.h delete mode 100644 trunk/include/xmlrpc-c/util.h delete mode 100644 trunk/include/xmlrpc-c/util_int.h delete mode 100644 trunk/include/xmlrpc-c/xml.hpp delete mode 100755 trunk/install-sh delete mode 100644 trunk/irix-common.mk delete mode 100644 trunk/lib/Makefile delete mode 100644 trunk/lib/abyss++/AbyssChanSwitch.cpp delete mode 100644 trunk/lib/abyss++/AbyssChanSwitchOpenSsl.cpp delete mode 100644 trunk/lib/abyss++/AbyssChanSwitchUnix.cpp delete mode 100644 trunk/lib/abyss++/AbyssChanSwitchWin.cpp delete mode 100644 trunk/lib/abyss++/AbyssEnvironment.cpp delete mode 100644 trunk/lib/abyss++/AbyssServer.cpp delete mode 100644 trunk/lib/abyss++/Makefile delete mode 100644 trunk/lib/abyss/HISTORY delete mode 100644 trunk/lib/abyss/Makefile delete mode 100644 trunk/lib/abyss/README delete mode 100644 trunk/lib/abyss/conf/abyss.conf delete mode 100644 trunk/lib/abyss/conf/mime.types delete mode 100644 trunk/lib/abyss/example/conf/abyss.conf delete mode 100644 trunk/lib/abyss/example/conf/mime.types delete mode 100644 trunk/lib/abyss/example/htdocs/index.htm delete mode 100644 trunk/lib/abyss/example/htdocs/pwrabyss.gif delete mode 100644 trunk/lib/abyss/license.txt delete mode 100644 trunk/lib/abyss/src/Makefile delete mode 100644 trunk/lib/abyss/src/abyss_info.h delete mode 100644 trunk/lib/abyss/src/channel.c delete mode 100644 trunk/lib/abyss/src/channel.h delete mode 100644 trunk/lib/abyss/src/chanswitch.c delete mode 100644 trunk/lib/abyss/src/chanswitch.h delete mode 100644 trunk/lib/abyss/src/conf.c delete mode 100644 trunk/lib/abyss/src/conn.c delete mode 100644 trunk/lib/abyss/src/conn.h delete mode 100644 trunk/lib/abyss/src/data.c delete mode 100644 trunk/lib/abyss/src/data.h delete mode 100644 trunk/lib/abyss/src/date.c delete mode 100644 trunk/lib/abyss/src/date.h delete mode 100644 trunk/lib/abyss/src/file.c delete mode 100644 trunk/lib/abyss/src/file.h delete mode 100644 trunk/lib/abyss/src/handler.c delete mode 100644 trunk/lib/abyss/src/handler.h delete mode 100644 trunk/lib/abyss/src/http.c delete mode 100644 trunk/lib/abyss/src/http.h delete mode 100644 trunk/lib/abyss/src/init.c delete mode 100644 trunk/lib/abyss/src/main.c delete mode 100644 trunk/lib/abyss/src/response.c delete mode 100644 trunk/lib/abyss/src/server.c delete mode 100644 trunk/lib/abyss/src/server.h delete mode 100644 trunk/lib/abyss/src/session.c delete mode 100644 trunk/lib/abyss/src/session.h delete mode 100644 trunk/lib/abyss/src/sessionReadRequest.c delete mode 100644 trunk/lib/abyss/src/sessionReadRequest.h delete mode 100644 trunk/lib/abyss/src/socket.c delete mode 100644 trunk/lib/abyss/src/socket.h delete mode 100644 trunk/lib/abyss/src/socket_openssl.c delete mode 100644 trunk/lib/abyss/src/socket_openssl.h delete mode 100644 trunk/lib/abyss/src/socket_unix.c delete mode 100644 trunk/lib/abyss/src/socket_unix.h delete mode 100644 trunk/lib/abyss/src/socket_win.c delete mode 100644 trunk/lib/abyss/src/socket_win.h delete mode 100644 trunk/lib/abyss/src/sockutil.c delete mode 100644 trunk/lib/abyss/src/sockutil.h delete mode 100644 trunk/lib/abyss/src/thread.h delete mode 100644 trunk/lib/abyss/src/thread_fork.c delete mode 100644 trunk/lib/abyss/src/thread_pthread.c delete mode 100644 trunk/lib/abyss/src/thread_windows.c delete mode 100644 trunk/lib/abyss/src/token.c delete mode 100644 trunk/lib/abyss/src/token.h delete mode 100644 trunk/lib/abyss/src/trace.c delete mode 100644 trunk/lib/abyss/src/trace.h delete mode 100644 trunk/lib/curl_transport/Makefile delete mode 100644 trunk/lib/curl_transport/curlmulti.c delete mode 100644 trunk/lib/curl_transport/curlmulti.h delete mode 100644 trunk/lib/curl_transport/curltransaction.c delete mode 100644 trunk/lib/curl_transport/curltransaction.h delete mode 100644 trunk/lib/curl_transport/curlversion.h delete mode 100644 trunk/lib/curl_transport/xmlrpc_curl_transport.c delete mode 100644 trunk/lib/expat/Makefile delete mode 100644 trunk/lib/expat/expat.html delete mode 100644 trunk/lib/expat/gennmtab/Makefile delete mode 100644 trunk/lib/expat/gennmtab/gennmtab.c delete mode 100644 trunk/lib/expat/xmlparse/Makefile delete mode 100644 trunk/lib/expat/xmlparse/xmlparse.c delete mode 100644 trunk/lib/expat/xmlparse/xmlparse.h delete mode 100644 trunk/lib/expat/xmltok/Makefile delete mode 100644 trunk/lib/expat/xmltok/ascii.h delete mode 100644 trunk/lib/expat/xmltok/asciitab.h delete mode 100644 trunk/lib/expat/xmltok/dllmain.c delete mode 100644 trunk/lib/expat/xmltok/iasciitab.h delete mode 100644 trunk/lib/expat/xmltok/latin1tab.h delete mode 100644 trunk/lib/expat/xmltok/utf8tab.h delete mode 100644 trunk/lib/expat/xmltok/xmldef.h delete mode 100644 trunk/lib/expat/xmltok/xmlrole.c delete mode 100644 trunk/lib/expat/xmltok/xmlrole.h delete mode 100644 trunk/lib/expat/xmltok/xmltok.c delete mode 100644 trunk/lib/expat/xmltok/xmltok.h delete mode 100644 trunk/lib/expat/xmltok/xmltok_impl.c delete mode 100644 trunk/lib/expat/xmltok/xmltok_impl.h delete mode 100644 trunk/lib/expat/xmltok/xmltok_ns.c delete mode 100644 trunk/lib/expat/xmlwf/Makefile.in delete mode 100644 trunk/lib/expat/xmlwf/codepage.c delete mode 100644 trunk/lib/expat/xmlwf/codepage.h delete mode 100644 trunk/lib/expat/xmlwf/filemap.h delete mode 100644 trunk/lib/expat/xmlwf/readfilemap.c delete mode 100644 trunk/lib/expat/xmlwf/unixfilemap.c delete mode 100644 trunk/lib/expat/xmlwf/win32filemap.c delete mode 100644 trunk/lib/expat/xmlwf/xmlfile.c delete mode 100644 trunk/lib/expat/xmlwf/xmlfile.h delete mode 100644 trunk/lib/expat/xmlwf/xmltchar.h delete mode 100644 trunk/lib/expat/xmlwf/xmlwf.c delete mode 100644 trunk/lib/expat/xmlwf/xmlwf.dsp delete mode 100644 trunk/lib/libutil++/Lock.cpp delete mode 100644 trunk/lib/libutil++/Makefile delete mode 100644 trunk/lib/libutil++/base64.cpp delete mode 100644 trunk/lib/libutil++/env_wrap.cpp delete mode 100644 trunk/lib/libutil++/girerr.cpp delete mode 100644 trunk/lib/libutil++/girmem.cpp delete mode 100644 trunk/lib/libutil/Makefile delete mode 100644 trunk/lib/libutil/asprintf.c delete mode 100644 trunk/lib/libutil/base64.c delete mode 100644 trunk/lib/libutil/error.c delete mode 100644 trunk/lib/libutil/lock_none.c delete mode 100644 trunk/lib/libutil/lock_platform.c delete mode 100644 trunk/lib/libutil/lock_pthread.c delete mode 100644 trunk/lib/libutil/lock_windows.c delete mode 100644 trunk/lib/libutil/make_printable.c delete mode 100644 trunk/lib/libutil/memblock.c delete mode 100644 trunk/lib/libutil/mempool.c delete mode 100644 trunk/lib/libutil/select.c delete mode 100644 trunk/lib/libutil/sleep.c delete mode 100644 trunk/lib/libutil/string_number.c delete mode 100644 trunk/lib/libutil/time.c delete mode 100644 trunk/lib/libutil/utf8.c delete mode 100644 trunk/lib/libwww_transport/Makefile delete mode 100644 trunk/lib/libwww_transport/xmlrpc_libwww_transport.c delete mode 100644 trunk/lib/openssl/Makefile delete mode 100644 trunk/lib/openssl/xmlrpc_openssl_thread.c delete mode 100644 trunk/lib/util/Makefile delete mode 100644 trunk/lib/util/casprintf.c delete mode 100644 trunk/lib/util/cmdline_parser.c delete mode 100644 trunk/lib/util/cmdline_parser_cpp.cpp delete mode 100644 trunk/lib/util/getoptx.c delete mode 100644 trunk/lib/util/getoptx.h delete mode 100644 trunk/lib/util/include/assertx.hpp delete mode 100644 trunk/lib/util/include/bool.h delete mode 100644 trunk/lib/util/include/c_util.h delete mode 100644 trunk/lib/util/include/casprintf.h delete mode 100644 trunk/lib/util/include/cmdline_parser.h delete mode 100644 trunk/lib/util/include/cmdline_parser.hpp delete mode 100644 trunk/lib/util/include/girmath.h delete mode 100644 trunk/lib/util/include/girstring.h delete mode 100644 trunk/lib/util/include/inline.h delete mode 100644 trunk/lib/util/include/int.h delete mode 100644 trunk/lib/util/include/linklist.h delete mode 100644 trunk/lib/util/include/mallocvar.h delete mode 100644 trunk/lib/util/include/stdargx.h delete mode 100644 trunk/lib/util/include/string_parser.h delete mode 100644 trunk/lib/util/include/unistdx.h delete mode 100644 trunk/lib/util/string_parser.c delete mode 100644 trunk/lib/util/stripcaseeq.c delete mode 100644 trunk/lib/wininet_transport/Makefile delete mode 100644 trunk/lib/wininet_transport/pthreadx.h delete mode 100644 trunk/lib/wininet_transport/pthreadx_win32.c delete mode 100644 trunk/lib/wininet_transport/xmlrpc_wininet_transport.c delete mode 100755 trunk/missing delete mode 100755 trunk/mkinstalldirs delete mode 100644 trunk/src/Makefile delete mode 100644 trunk/src/abyss_handler.c delete mode 100644 trunk/src/abyss_handler.h delete mode 100644 trunk/src/base_global.c delete mode 100644 trunk/src/cpp/Makefile delete mode 100644 trunk/src/cpp/XmlRpcCpp.cpp delete mode 100644 trunk/src/cpp/abyss_reqhandler_xmlrpc.cpp delete mode 100644 trunk/src/cpp/client.cpp delete mode 100644 trunk/src/cpp/client_simple.cpp delete mode 100644 trunk/src/cpp/curl.cpp delete mode 100644 trunk/src/cpp/fault.cpp delete mode 100644 trunk/src/cpp/global.cpp delete mode 100644 trunk/src/cpp/libwww.cpp delete mode 100644 trunk/src/cpp/outcome.cpp delete mode 100644 trunk/src/cpp/packetsocket.cpp delete mode 100644 trunk/src/cpp/param_list.cpp delete mode 100644 trunk/src/cpp/pstream.cpp delete mode 100644 trunk/src/cpp/registry.cpp delete mode 100644 trunk/src/cpp/server_abyss.cpp delete mode 100644 trunk/src/cpp/server_cgi.cpp delete mode 100644 trunk/src/cpp/server_pstream.cpp delete mode 100644 trunk/src/cpp/server_pstream_conn.cpp delete mode 100644 trunk/src/cpp/value.cpp delete mode 100644 trunk/src/cpp/wininet.cpp delete mode 100644 trunk/src/cpp/xml.cpp delete mode 100644 trunk/src/double.c delete mode 100644 trunk/src/double.h delete mode 100644 trunk/src/json.c delete mode 100644 trunk/src/method.c delete mode 100644 trunk/src/method.h delete mode 100644 trunk/src/parse_datetime.c delete mode 100644 trunk/src/parse_datetime.h delete mode 100644 trunk/src/parse_value.c delete mode 100644 trunk/src/parse_value.h delete mode 100644 trunk/src/parse_xml.c delete mode 100644 trunk/src/registry.c delete mode 100644 trunk/src/registry.h delete mode 100644 trunk/src/resource.c delete mode 100644 trunk/src/system_method.c delete mode 100644 trunk/src/system_method.h delete mode 100644 trunk/src/trace.c delete mode 100644 trunk/src/version.c delete mode 100644 trunk/src/xmlparser.h delete mode 100644 trunk/src/xmlrpc_array.c delete mode 100644 trunk/src/xmlrpc_authcookie.c delete mode 100644 trunk/src/xmlrpc_build.c delete mode 100644 trunk/src/xmlrpc_client.c delete mode 100644 trunk/src/xmlrpc_client_global.c delete mode 100644 trunk/src/xmlrpc_data.c delete mode 100644 trunk/src/xmlrpc_datetime.c delete mode 100644 trunk/src/xmlrpc_decompose.c delete mode 100644 trunk/src/xmlrpc_expat.c delete mode 100644 trunk/src/xmlrpc_libxml2.c delete mode 100644 trunk/src/xmlrpc_parse.c delete mode 100644 trunk/src/xmlrpc_parse.h delete mode 100644 trunk/src/xmlrpc_serialize.c delete mode 100644 trunk/src/xmlrpc_server_abyss.c delete mode 100644 trunk/src/xmlrpc_server_cgi.c delete mode 100644 trunk/src/xmlrpc_server_info.c delete mode 100644 trunk/src/xmlrpc_server_w32httpsys.c delete mode 100644 trunk/src/xmlrpc_string.c delete mode 100644 trunk/src/xmlrpc_struct.c delete mode 100644 trunk/srcdir.mk.in delete mode 100644 trunk/stamp-h.in delete mode 100644 trunk/test/Makefile delete mode 100644 trunk/test/abyss.c delete mode 100644 trunk/test/abyss.h delete mode 100644 trunk/test/abyss_dummy.c delete mode 100644 trunk/test/cgi.c delete mode 100644 trunk/test/cgi.h delete mode 100644 trunk/test/cgitest1.c delete mode 100644 trunk/test/client.c delete mode 100644 trunk/test/client.h delete mode 100644 trunk/test/client_dummy.c delete mode 100644 trunk/test/cpp/Makefile delete mode 100644 trunk/test/cpp/abyss.cpp delete mode 100644 trunk/test/cpp/abyss.hpp delete mode 100644 trunk/test/cpp/abyss_dummy.cpp delete mode 100644 trunk/test/cpp/base64.cpp delete mode 100644 trunk/test/cpp/base64.hpp delete mode 100644 trunk/test/cpp/registry.cpp delete mode 100644 trunk/test/cpp/registry.hpp delete mode 100644 trunk/test/cpp/server_abyss.cpp delete mode 100644 trunk/test/cpp/server_abyss.hpp delete mode 100644 trunk/test/cpp/server_abyss_dummy.cpp delete mode 100644 trunk/test/cpp/server_pstream.cpp delete mode 100644 trunk/test/cpp/server_pstream.hpp delete mode 100644 trunk/test/cpp/test.cpp delete mode 100644 trunk/test/cpp/testclient.cpp delete mode 100644 trunk/test/cpp/testclient.hpp delete mode 100644 trunk/test/cpp/testclient_dummy.cpp delete mode 100644 trunk/test/cpp/tools.cpp delete mode 100644 trunk/test/cpp/tools.hpp delete mode 100644 trunk/test/cpp/value.cpp delete mode 100644 trunk/test/cpp/value.hpp delete mode 100644 trunk/test/cpp/xml.cpp delete mode 100644 trunk/test/cpp/xml.hpp delete mode 100644 trunk/test/data/req_no_params.xml delete mode 100644 trunk/test/data/req_out_of_order.xml delete mode 100644 trunk/test/data/req_value_name.xml delete mode 100644 trunk/test/data/sample_add_call.xml delete mode 100644 trunk/test/eftest_wrapper.sh delete mode 100644 trunk/test/http-req-simple.txt delete mode 100644 trunk/test/memblock.c delete mode 100644 trunk/test/memblock.h delete mode 100644 trunk/test/method_registry.c delete mode 100644 trunk/test/method_registry.h delete mode 100644 trunk/test/parse_xml.c delete mode 100644 trunk/test/parse_xml.h delete mode 100644 trunk/test/req_no_params.xml delete mode 100644 trunk/test/serialize.c delete mode 100644 trunk/test/serialize.h delete mode 100644 trunk/test/serialize_value.c delete mode 100644 trunk/test/serialize_value.h delete mode 100644 trunk/test/server_abyss.c delete mode 100644 trunk/test/server_abyss.h delete mode 100644 trunk/test/server_abyss_dummy.c delete mode 100644 trunk/test/test.c delete mode 100644 trunk/test/testtool.c delete mode 100644 trunk/test/testtool.h delete mode 100644 trunk/test/value.c delete mode 100644 trunk/test/value.h delete mode 100644 trunk/test/value_datetime.c delete mode 100644 trunk/test/value_datetime.h delete mode 100644 trunk/test/xml_data.c delete mode 100644 trunk/test/xml_data.h delete mode 100644 trunk/tools/Makefile delete mode 100644 trunk/tools/binmode-rpc-kit/COPYING delete mode 100644 trunk/tools/binmode-rpc-kit/Makefile delete mode 100644 trunk/tools/binmode-rpc-kit/README delete mode 100644 trunk/tools/binmode-rpc-kit/binmode-rpc-rfc.txt delete mode 100755 trunk/tools/binmode-rpc-kit/binmode-rpc2xml-rpc delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-1.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-1.xml delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-2.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-2.xml delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-3.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-3.xml delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-4.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-4.xml delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-5.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-5.xml delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-6.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/good-6.xml delete mode 100644 trunk/tools/binmode-rpc-kit/examples/invalid-1.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/invalid-2.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/invalid-3.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/invalid-4.binmode delete mode 100644 trunk/tools/binmode-rpc-kit/examples/invalid-5.binmode delete mode 100755 trunk/tools/binmode-rpc-kit/oct2bin delete mode 100644 trunk/tools/common.mk delete mode 100644 trunk/tools/interop-server/interop-cgi.c delete mode 100644 trunk/tools/lib/Makefile delete mode 100644 trunk/tools/lib/dumpvalue.c delete mode 100644 trunk/tools/lib/include/dumpvalue.h delete mode 100644 trunk/tools/perl_packetsocket/PacketSocket.pm delete mode 100644 trunk/tools/turbocharger/Makefile delete mode 100644 trunk/tools/turbocharger/README delete mode 100644 trunk/tools/turbocharger/mod_gzip.c delete mode 100644 trunk/tools/turbocharger/mod_gzip.c.diff delete mode 100644 trunk/tools/xml-rpc-api2cpp/DataType.cpp delete mode 100644 trunk/tools/xml-rpc-api2cpp/DataType.hpp delete mode 100644 trunk/tools/xml-rpc-api2cpp/Makefile delete mode 100644 trunk/tools/xml-rpc-api2cpp/SystemProxy.cpp delete mode 100644 trunk/tools/xml-rpc-api2cpp/SystemProxy.hpp delete mode 100644 trunk/tools/xml-rpc-api2cpp/XmlRpcClass.cpp delete mode 100644 trunk/tools/xml-rpc-api2cpp/XmlRpcClass.hpp delete mode 100644 trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.cpp delete mode 100644 trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.hpp delete mode 100644 trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1 delete mode 100644 trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp delete mode 100644 trunk/tools/xml-rpc-api2txt/Makefile delete mode 100644 trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt delete mode 100644 trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt.1 delete mode 100644 trunk/tools/xml/Makefile delete mode 100644 trunk/tools/xml/xmlrpc_parsecall.c delete mode 100644 trunk/tools/xmlrpc/Makefile delete mode 100644 trunk/tools/xmlrpc/xmlrpc.c delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/Makefile delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/proxyClass.cpp delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/proxyClass.hpp delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/systemProxy.cpp delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/systemProxy.hpp delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp delete mode 100644 trunk/tools/xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp delete mode 100644 trunk/tools/xmlrpc_dumpserver/Makefile delete mode 100644 trunk/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c delete mode 100644 trunk/tools/xmlrpc_pstream/Makefile delete mode 100755 trunk/tools/xmlrpc_pstream/test delete mode 100644 trunk/tools/xmlrpc_pstream/xmlrpc_pstream.cpp delete mode 100644 trunk/tools/xmlrpc_transport/Makefile delete mode 100644 trunk/tools/xmlrpc_transport/xmlrpc_transport.c delete mode 100644 trunk/tools/xmlrpc_transport/xmlrpc_transport.html delete mode 100644 trunk/transport_config.mk delete mode 100644 trunk/unix-common.mk delete mode 100644 trunk/version.mk delete mode 100644 trunk/xmlrpc-c-config.main delete mode 100644 trunk/xmlrpc-c-config.test.main delete mode 100644 trunk/xmlrpc_config.h.in diff --git a/trunk/GNUmakefile b/trunk/GNUmakefile deleted file mode 100644 index ea6ef12c9..000000000 --- a/trunk/GNUmakefile +++ /dev/null @@ -1,193 +0,0 @@ -include srcdir.mk - -BLDDIR = $(CURDIR) -SUBDIR = - -export SRCDIR -export BLDDIR - -include $(BLDDIR)/config.mk - -SUBDIRS = include lib src test examples - -ifeq ($(BUILD_TOOLS),yes) - SUBDIRS += tools -endif - -# The reason we don't build tools and examples by default is that they -# contain executables, which require significantly more from the -# environment to build than libraries. Ergo, they are signficantly -# more likely to fail to build. Indeed, when 'tools' was built by -# default, the majority of the reported build problems were with that. -# Since they are ancillary to the package, building them by default is -# not worth causing the whole build to fail. - -# As with any subdirectory, to build 'tools' or 'examples', cd to the -# subdirectory and make there. - -DEFAULT_SUBDIRS = include lib src - -PROGRAMS_TO_INSTALL = xmlrpc-c-config - -default: xmlrpc-c-config xmlrpc-c-config.test $(DEFAULT_SUBDIRS:%=%/all) - -# We don't want common.mk's rule for version.h -OMIT_VERSION_H = Y - -# We don't want common.mk's rule for transport_config.h -OMIT_TRANSPORT_CONFIG_H = Y - -# We don't want common.mk's rule for xmlrpc-c-config.test: -OMIT_XMLRPC_C_CONFIG_TEST = Y - -include $(SRCDIR)/common.mk - -.PHONY: all -all: xmlrpc-c-config xmlrpc-c-config.test $(SUBDIRS:%=%/all) - -# The examples subdirectory is special, because even the make file in there -# is designed to be an example. So it has to be simple and as close as -# possible to something a person could use outside of the Xmlrpc-c source -# tree. One ramification of that is that it does not specify dependencies -# on other parts of the Xmlrpc-c build. That means we must separately -# ensure that the Xmlrpc-c libraries are built before making the example -# programs. -# -# It also means that you have to manually clean the examples directory -# in order to get the examples rebuilt after you modify the Xmlrpc-c -# libraries. - -examples/all: xmlrpc-c-config.test lib/all src/all include/all - -# Parallel make (make --jobs) is not smart enough to coordinate builds -# between submakes, so a naive parallel make would cause certain -# targets to get built multiple times simultaneously. That is usually -# unacceptable. So we introduce extra dependencies here just to make -# sure such targets are already up to date before the submake starts, -# for the benefit of parallel make. Note that we ensure that parallel -# make works for 'make all' in the top directory, but it may still fail -# for the aforementioned reason for other invocations. - -tools/all test/all: include/all lib/all src/all -src/all lib/all: include/all -src/all: lib/all - -MAJOR := $(XMLRPC_MAJOR_RELEASE) -MINOR := $(XMLRPC_MINOR_RELEASE) -POINT := $(XMLRPC_POINT_RELEASE) -version.h: $(SRCDIR)/version.mk - rm -f $@ - echo "/* Generated by make file rule */" >>$@ - echo "#define XMLRPC_C_VERSION" \"$(MAJOR).$(MINOR).$(POINT)"\"" >>$@ - echo "#define XMLRPC_VERSION_MAJOR $(MAJOR)" >>$@ - echo "#define XMLRPC_VERSION_MINOR $(MINOR)" >>$@ - echo "#define XMLRPC_VERSION_POINT $(POINT)" >>$@ - -include transport_config.mk - -# shell_config is a fragment to place inside a Bourne shell program that -# sets variables that tell how the build is configured. - -shell_config: $(BLDDIR)/config.mk - rm -f $@ - @echo "Lots of echoes to '$@' suppressed here ..." - @echo '#' >>$@ - @echo '#######################################################' >>$@ - @echo "# From '$@'" >>$@ - @echo '#######################################################' >>$@ - @echo 'ENABLE_ABYSS_THREADS="$(ENABLE_ABYSS_THREADS)"' >>$@ - @echo 'THREAD_LIBS="$(THREAD_LIBS)"' >>$@ - @echo 'ENABLE_LIBXML2_BACKEND="$(ENABLE_LIBXML2_BACKEND)"' >>$@ - @echo 'MUST_BUILD_WININET_CLIENT="$(MUST_BUILD_WININET_CLIENT)"'>>$@ - @echo 'MUST_BUILD_CURL_CLIENT="$(MUST_BUILD_CURL_CLIENT)"' >>$@ - @echo 'MUST_BUILD_LIBWWW_CLIENT="$(MUST_BUILD_LIBWWW_CLIENT)"' >>$@ - @echo 'NEED_RPATH="$(NEED_RPATH)"' >>$@ - @echo 'NEED_WL_RPATH="$(NEED_WL_RPATH)"' >>$@ - @echo 'LIBXMLRPCPP_NAME="$(LIBXMLRPCPP_NAME)"' >>$@ - @echo 'SOCKETLIBOPT="$(SOCKETLIBOPT)"' >>$@ - @echo 'WININET_LDADD="$(WININET_LDADD)"' >>$@ - @echo 'WININET_LIBDIR="$(WININET_LIBDIR)"' >>$@ - @echo 'CURL_LDADD="$(CURL_LDADD)"' >>$@ - @echo 'CURL_LIBDIR="$(CURL_LIBDIR)"' >>$@ - @echo 'LIBWWW_LDADD="$(LIBWWW_LDADD)"' >>$@ - @echo 'LIBWWW_LIBDIR="$(LIBWWW_LIBDIR)"' >>$@ - @echo 'XMLRPC_MAJOR_RELEASE="$(XMLRPC_MAJOR_RELEASE)"' >>$@ - @echo 'XMLRPC_MINOR_RELEASE="$(XMLRPC_MINOR_RELEASE)"' >>$@ - @echo 'XMLRPC_POINT_RELEASE="$(XMLRPC_POINT_RELEASE)"' >>$@ - @echo 'FEATURE_LIST="$(FEATURE_LIST)"' >>$@ - @echo 'PREFIX="$(PREFIX)"' >>$@ - @echo 'HEADERINST_DIR="$(HEADERINST_DIR)"' >>$@ - @echo 'LIBINST_DIR="$(LIBINST_DIR)"' >>$@ - @echo 'BLDDIR="$(BLDDIR)"' >>$@ - @echo 'ABS_SRCDIR="$(ABS_SRCDIR)"' >>$@ - @echo 'ABYSS_DOES_OPENSSL="$(MUST_BUILD_ABYSS_OPENSSL)"' >>$@ - @echo 'OPENSSL_LDADD="$(OPENSSL_LDADD)"' >>$@ - @echo '#######################################################' >>$@ - -xmlrpc-c-config xmlrpc-c-config.test:%: %.main shell_config - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo '#! /bin/sh' >>$@ - @echo '#' >>$@ - @echo '# This file was generated by a make rule' >>$@ - @echo '#' >>$@ - cat shell_config >>$@ - cat $< >>$@ - chmod a+rx $@ - -.PHONY: clean clean-local -clean: $(SUBDIRS:%=%/clean) clean-common clean-local - -clean-local: - rm -f transport_config.h version.h - -.PHONY: distclean distclean-local -distclean: $(SUBDIRS:%=%/distclean) distclean-common distclean-local - -distclean-local: clean-local - rm -f config.log config.status config.mk srcdir.mk - rm -f xmlrpc_config.h xmlrpc_amconfig.h stamp-h - rm -f shell_config xmlrpc-c-config xmlrpc-c-config.test - rm -rf autom4te.cache # gets created by 'autoconf' - rm -f TAGS - -check: $(SUBDIRS:%=%/check) - $(MAKE) -C test runtests - -DISTFILES = - -.PHONY: distdir -distdir: distdir-common - -.PHONY: install -install: $(DEFAULT_SUBDIRS:%=%/install) install-common - -HEADERDESTDIR = $(DESTDIR)$(HEADERINST_DIR) - -.PHONY: uninstall -uninstall: $(DEFAULT_SUBDIRS:%=%/uninstall) uninstall-common - -rmdir $(HEADERDESTDIR)/xmlrpc-c - -.PHONY: dep -dep: version.h $(BLDDIR)/include/xmlrpc-c/config.h $(SUBDIRS:%=%/dep) - -xmlrpc_config.h \ - :%:%.in $(SRCDIR)/configure - $(SRCDIR)/configure - -# A trick to catch a common user error. When you don't run 'configure', -# you don't have a srcdir.mk, which means $(SRCDIR) is null. - -/common.mk: - @echo ======================================= - @echo = You must run Configure before Make. = - @echo ======================================= - false - -# 'tags' generates/updates an Emacs tags file, anmed TAGS, in the current -# directory. Use with Emacs command 'find-tag'. - -.PHONY: tags -tags: - find . -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" | \ - etags - diff --git a/trunk/Makefile b/trunk/Makefile deleted file mode 100644 index 871bf9dcb..000000000 --- a/trunk/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# The make files for this package exploit features of GNU Make that -# other Makes do not have. Because it is a common mistake for users -# to try to build with a different Make, we have this make file that -# does nothing but tell the user to use GNU Make. - -# If the user were using GNU Make now, this file would not get used because -# GNU Make uses a make file named "GNUmakefile" in preference to "Makefile" -# if it exists. This package contains a "GNUmakefile". - -default: all - -all install clean dep depend: - @echo "You must use GNU Make to build this. You are running some " - @echo "other Make. GNU Make may be installed on your system with " - @echo "the name 'gmake'. If not, see http://www.gnu.org/software ." - @echo - false diff --git a/trunk/README b/trunk/README deleted file mode 100644 index eb06fddb0..000000000 --- a/trunk/README +++ /dev/null @@ -1,60 +0,0 @@ -This is the source code for XML-RPC for C/C++, called Xmlrpc-c for short. - -XML-RPC for C/C++ is programming libraries and related tools to help you -write an XML-RPC server or client in C or C++. - -Documentation for the package is at - - http://xmlrpc-c.sourceforge.net/doc - -See the Xmlrpc-c website at: - - http://xmlrpc-c.sourceforge.net/ - - -PREREQUISITES -------------- - -To build a useful Xmlrpc-c client library, you'll need to have at -least one HTTP library. Xmlrpc-c knows how to use W3C Libwww (Version -5.3.2 or newer), Curl, and Wininet. The configurator gives you the -option of building libraries that use any or all of these, and -defaults to every one you appear to have installed. If you don't -appear to have any installed, the configurator causes the build to -omit client facilities altogether. - -Information about W3C Libwww, including how to get it are at -. - -For Curl, see . - -Wininet comes with Windows, and isn't available for any other platform. - -You also need an XML parser/builder library. An old version of Expat -is included in the package and used by default, so there's no actual -prerequisite here. But if you separately obtain Libxml2, you can -configure the build to use that instead. There's no really pressing -reason to do that, though. - - -BUILDING, INSTALLING --------------------- - -See the file doc/INSTALL. - -In the simplest case, it's just a conventional - - $ ./configure - $ make - $ make install - -And then, if Linux: - - $ ldconfig - - -ADDITIONAL INFORMATION ----------------------- - -See the doc/ directory of the source tree for information about the -source code. User documentation is on the web, as described above. diff --git a/trunk/Windows/CleanAll.bat b/trunk/Windows/CleanAll.bat deleted file mode 100644 index b6d8ecb79..000000000 --- a/trunk/Windows/CleanAll.bat +++ /dev/null @@ -1,48 +0,0 @@ -@echo This batch file requires a powerful XDELETE program. One -@echo that will REMOVE whole directories recursively ... -@echo If you do NOT have such a program, then abort now, and -@echo adjust the line below ... -@set TEMPX=xdelete -dfrm -@echo set TEMPX=%TEMPX% -@pause -@echo ##################################################### -@echo ARE YOU SURE YOU WANT TO DO THIS? Ctrl+C to abort ... -@echo ##################################################### -@pause -@echo CleanAll: Last chance ... ctrl+c to abort ... -@pause -@echo CleanAll: Cleaning the headers ... -call CleanWin32 -@echo CleanAll: and removing the SOLUTION files ... -call delsln -@echo CleanAll: Cleaning the gennmtab generated header ... -@if EXIST ..\lib\expat\xmltok\nametab.h del ..\lib\expat\xmltok\nametab.h > nul -@echo CleanAll: Cleaning all built binaries ... -@if EXIST ..\bin\*.exe del ..\bin\*.exe > nul -@if EXIST ..\bin\*.exp del ..\bin\*.exp > nul -@if EXIST ..\bin\*.ilk del ..\bin\*.ilk > nul -@if EXIST ..\bin\*.lib del ..\bin\*.lib > nul -@if EXIST ..\lib\*.lib del ..\lib\*.lib > nul -@if EXIST ..\lib\*.dll del ..\lib\*.dll > nul -@echo CleanAll: Cleaning test data files ... -@if EXIST ..\bin\data\*.xml del ..\bin\data\*.xml > nul -@if EXIST ..\bin\data\. rd ..\bin\data > nul -@if EXIST ..\bin\. rd ..\bin > nul -@echo CleanAll: Cleaning old residual built binaries ... but none should exist ... -@if EXIST ..\lib\expat\gennmtab\Debug\. %TEMPX% ..\lib\expat\gennmtab\Debug -@if EXIST ..\lib\expat\gennmtab\Release\. %TEMPX% ..\lib\expat\gennmtab\Release -@if EXIST ..\lib\expat\xmlparse\Debug\. %TEMPX% ..\lib\expat\xmlparse\Debug -@if EXIST ..\lib\expat\xmlparse\DebugDLL\. %TEMPX% ..\lib\expat\xmlparse\DebugDLL -@if EXIST ..\lib\expat\xmlparse\Release\. %TEMPX% ..\lib\expat\xmlparse\Release -@if EXIST ..\lib\expat\xmlparse\ReleaseDLL\. %TEMPX% ..\lib\expat\xmlparse\ReleaseDLL -@if EXIST ..\lib\expat\xmlparse\ReleaseMinSizeDLL\. %TEMPX% ..\lib\expat\xmlparse\ReleaseMinSizeDLL -@if EXIST ..\lib\expat\xmltok\Debug\. %TEMPX% ..\lib\expat\xmltok\Debug -@if EXIST ..\lib\expat\xmltok\DebugDLL\. %TEMPX% ..\lib\expat\xmltok\DebugDLL -@if EXIST ..\lib\expat\xmltok\Release\. %TEMPX% ..\lib\expat\xmltok\Release -@if EXIST ..\lib\expat\xmltok\ReleaseDLL\. %TEMPX% ..\lib\expat\xmltok\ReleaseDLL -@echo CleanAll: Finally, cleaning the main intermediate directories ... -@if EXIST Debug\. %TEMPX% Debug -@if EXIST Release\. %TEMPX% Release -@echo . -@echo CleanAll: Phew ... all done ... -@echo . diff --git a/trunk/Windows/CleanWin32.bat b/trunk/Windows/CleanWin32.bat deleted file mode 100644 index 907b32bd9..000000000 --- a/trunk/Windows/CleanWin32.bat +++ /dev/null @@ -1,43 +0,0 @@ -@echo Windows build -@echo This batch file deletes the copied header files, -@echo Deleting Win32 header files... -@echo ##################################################### -@echo IF YOU HAVE MADE CHANGES IN ..\xmlrpc_config.h, ..\include\xmlrpc-c\config.h etc ... -@echo THESE CHANGES WILL BE LOST! -@echo You should run diffcfg.bat first to check for changes, -@echo and updcfg.bat if you have made changes ... -@echo ##################################################### -@echo ARE YOU SURE YOU WANT TO DO THIS? Ctrl+C to abort ... -@echo ##################################################### -@pause -@set TEMP1= -@if NOT EXIST ..\include\xmlrpc-c\config.h goto DN1 -del ..\include\xmlrpc-c\config.h > nul -@set TEMP1=%TEMP1% ..\include\xmlrpc-c\config.h -:DN1 -@if NOT EXIST ..\xmlrpc_config.h goto DN2 -del ..\xmlrpc_config.h > nul -@set TEMP1=%TEMP1% ..\xmlrpc_config.h -:DN2 -@if NOT EXIST ..\transport_config.h goto DN3 -del ..\transport_config.h > nul -@set TEMP1=%TEMP1% ..\transport_config.h -:DN3 -@if NOT EXIST ..\version.h goto DN4 -del ..\version.h > nul -@set TEMP1=%TEMP1% ..\version.h -:DN4 -@if NOT EXIST ..\examples\config.h goto DN5 -del ..\examples\config.h > nul -@set TEMP1=%TEMP1% ..\examples\config.h -:DN5 -@if "%TEMP1%." == "." goto ALLDN -@echo DELETED win32 header files. -@echo %TEMP1% -@goto END - -:ALLDN -@echo NOne to DELETE ... -@goto END - -:END diff --git a/trunk/Windows/ConfigureWin32.bat b/trunk/Windows/ConfigureWin32.bat deleted file mode 100644 index f38c4f59f..000000000 --- a/trunk/Windows/ConfigureWin32.bat +++ /dev/null @@ -1,35 +0,0 @@ -@REM Windows build -@REM This must be RUN once to establish some header files, -@REM that are generated by the automake process -@echo creating Win32 header files...once only -@set TEMPV= -@if EXIST ..\include\xmlrpc-c\config.h goto DN1 -copy .\win32_config.h ..\include\xmlrpc-c\config.h > nul -@set TEMPV=%TEMPV% ..\include\xmlrpc-c\config.h -:DN1 -@if EXIST ..\xmlrpc_config.h goto DN2 -copy .\xmlrpc_win32_config.h ..\xmlrpc_config.h > nul -@set TEMPV=%TEMPV% ..\xmlrpc_config.h -:DN2 -@if EXIST ..\transport_config.h goto DN3 -copy .\transport_config_win32.h ..\transport_config.h > nul -@set TEMPV=%TEMPV% ..\transport_config.h -:DN3 -@if EXIST ..\version.h goto DN4 -call mkvers -@set TEMPV=%TEMPV% ..\version.h -:DN4 -@if EXIST ..\examples\config.h goto DN5 -copy .\xmlrpc_win32_config.h ..\examples\config.h > nul -@set TEMPV=%TEMPV% ..\examples\config.h -:DN5 -@if "%TEMPV%." == "." goto ALLDN -@echo Generated the following win32 header files ... -@echo %TEMPV% -@goto END - -:ALLDN -@echo Using previous copies ... Use CleanWin32.bat to remove, and do again ... -@goto END - -:END diff --git a/trunk/Windows/ReadMeWin32.txt b/trunk/Windows/ReadMeWin32.txt deleted file mode 100644 index 117815928..000000000 --- a/trunk/Windows/ReadMeWin32.txt +++ /dev/null @@ -1,66 +0,0 @@ -Build Instructions For XML-RPC For C/C++ On Windows ---------------------------------------------------- - -------------------------------------------------------------------------- -These instructions are for static link libraries, using Microsoft Visual -Studio 7 and later. There are project files to create DLLs, using -Visual Studio 2008 or later, in the 'dll' subdirectory. People maintain -those project files separately from the rest of the build system, so it's -not uncommon for something to work with one but not the other. -------------------------------------------------------------------------- - - -1. Run the batch file ConfigureWin32.bat, found in the Windows -directory. This will copy four(4) headers to the appropriate folders. - -2. Load xmlrpc.dsw in MSVC[7,8] or later, and build the Release or Debug -configurations. DLL configurations are not included, and may not compile. - -This build requires that you have a Microsoft SDK, or Plaform SDK -installed, since among other things, it uses , and -HTTPAPI.LIB, from the SDK. - -Once built, the rpctest.exe, in the bin folder, should run with no errors, -and the xmlrpc_sample_add_server.exe, using port 8080, and -xmlrpc_sample_add_sync_client.exe should communicate ... proving 7+5 = 12 ;=)) - -Have fun. - -PS: Several other batch files are included in the Windows folder ... - -delsln.bat - to delete all the MSVC7 and 8 solution file. - -diffcfg.bat - compare the headers in windows with the version used in -the compile. Requires diff.exe to be in the path. - -updcfg.bat - copy the 3 manually maintained configuration files back -to the Windows folder (for distribution). - -cleawin32.bat - deletes the headers used in the compile. That is does the -opposite of ConfigureWin32.bat. - -cleanall.bat - to remove ALL the binary files created. Requires an xdelete -program which will recursively delete an entire folder. - - -There is some historical information in ReadMeOld.txt, which used to be -the contents of this file. Some of it is still valid. - - -Developing XML-RPC For C/C++ for Windows ----------------------------------------- - -If you fix or enhance something in the Windows build system, please send -your updates to the Xmlrpc-c maintainer to be included in future releases -so others don't have to repeat your work. - -Output of a Subversion 'diff' is usually the best way to send updates, -but you can also send complete files or just a description of the -change if that is easier. - -For the project files, we distribute only MSVC6-compatible DSP and DSW -files (which are, of course, usable as input to later versions of MSVC -as well). That means if you need to modify something in the project -files and you are not using MSVC6, you must edit the project files -manually as text files. Modifying them via the IDE would simply -generate new files in a format that cannot be used with older MSVC. diff --git a/trunk/Windows/UsingCURLinWin32.txt b/trunk/Windows/UsingCURLinWin32.txt deleted file mode 100644 index 1ee2635c7..000000000 --- a/trunk/Windows/UsingCURLinWin32.txt +++ /dev/null @@ -1,86 +0,0 @@ -These are instructions for using the Curl HTTP client library for the XML-RPC -communication in an XML-RPC client, on Windows. Normally, an XML-RPC client -running on Windows uses the HTTP client facilities built into Windows -(Wininet) instead. - -These instructions worked at one time, but they do not appear to work with -current Xmlrpc-c code. If you are able to update them to work with current -Xmlrpc-c code, please send the updates to the Xmlrpc-c maintainer to help the -next person. - - -Motivation: - -Let’s say you need to have a Xmlrpc-c client running as a service. In this -situation you cannot use WinInet. You can find details of the restriction on -the Curl website or various Microsoft KB articles. Your alternative is to use -the Curl HTTP client library. This document tells how to use use the Curl -library instead of the default Wininet as your client XML transport mechanism. - -Overview: - -The default projects in Xmlrpc-c create standalone executables that do not -require other DLL’s. Therefore, we need to create static link libraries for -libcurl. Once we create the link libraries, we add them (plus the requisite -curl headers) into the Xmlrpc-c project. Finally, we configure the build to -build the curl transport and build client libraries that use it. Finally, we -build and test the project. - - -BUILD THE CURL LIBRARY ----------------------- - -Download the Curl source code. Run the buildconf.bat to generate some -additional files. This builds a 'dummy' hugehelp.c, but it can also be built -using the src\mkhelp.pl Perl script. You may have to build your own VCPROJ -file for CURL, if you want to use MSVC. - -To build all the CURL library variations, use - - > nmake /nologo vc-all - -but note this will use the /MD[d] DLL runtime. Only by adding -RTCFGLIB=static to each of the makefile commands will /MT[d] be -used. - -Essentially, for building the static Debug or Release CURL libraries, it is -all the sources in the curl\lib folder. Make sure you choose /MT and /MTd for -the runtime, and build both using the name 'libcurl.lib'. - - -BUILD XMLRPC-C, LINK WITH CURL ------------------------------- - -From the step above, you have Debug\libcurl.lib and Release\libcurl.lib. - -After running xmlrpc-c\Windows\configurewin32.bat, start Visual Studio. - -In the File View, in the 'xmlrpc' project, in the properties of -xmlrpc_curl_transport.c, change "Exclude file from build" from "yes" to "no", -for Debug and Release. ==>BUT NOTE: in current Xmlrpc-c, this is broken - -there is no 'xmlrpc' project and no xmlrpc_curl_transport.c in any projects. -You need to add it. What you need to do is apparently to get -xmlrpc_curl_transport.c, curltransaction.c, curlmulti.c into the -libxmlrpc_client library built by the libxmlrpc_client project. - -In the 'Header Files' section, open the "transport_config.h" file, -and change MUST_BUILD_CURL_CLIENT to 1, and the XMLRPC_DEFAULT_TRANSPORT -to "curl", if you want. - -As usual, for each of the "client" projects, and 'rpctest', in the properties, -Linker section, you can add the library libcurl.lib on the Input tab, and the -relative path to the library in the General tab to something like - -..\..\curl\Debug and ..\..\curl\Release (or wherever you placed the static -Curl libraries you built if you didn't follow recommendations above). - -Or you can adjust the Windows/curlink.h, to directly point to your respective -Debug and Release static Curl libraries. - -Now, Xmlrpc-c should build using the Curl transport. - -Note, for the final linking, all libraries must be linked the same. A mixture -of /MD and /MT will give big linkage problems. Any one project built with the -alternate library will show many items defined more than once. And of course, -you also cannot mix Debug with Release. That is /MDd with /MD, nor /MTd with -/MT. Otherwise, there will be unresolved debug items. - diff --git a/trunk/Windows/UsingProxyDSP.txt b/trunk/Windows/UsingProxyDSP.txt deleted file mode 100644 index 515f73d1d..000000000 --- a/trunk/Windows/UsingProxyDSP.txt +++ /dev/null @@ -1,51 +0,0 @@ - -Using xmlrpc_cpp_proxy.dsp - -While not included in the main xmlrpc.dsw file, this -xmlrpc_cpp_proxy.dsp, if added as a project to the xmlrpc solution, -will build bin\xmlrpc_cpp_proxy.exe and xmlrpc_cpp_proxyD.exe, for -testing using the default WinINET transport. - -After you have loaded the xmlrpc_cpp_proxy.dsp, which adds an -xmlrpc_cpp_proxy project, it is necessary to ADD a dependance on -the xmlrpc library, to complete the link. - -To do this in say MSVC8, select the xmlrpc_cpp_proxy project, and right -mouse click, and in the context menu, select 'Project Dependancies...'. -And in the Project Dependancies dialog, check the xmlrpc proejct, -then [Ok] ... - -To test your xmlrpc_cpp_proxy[D].exe - - - -1. In a console start the server, like - - -bin/xmlrpc_sample_add_serverD 8080 - -Note, since this server opens a socket, you may have to enable it on some -anti-virus software that detects the socket being established, and -'Unblock' it in the Windows Security Alert system dialog that appears. - -You can later remove this program from the Firewall exceptions, through -Control Panel -> Windows Firewall, selecting the 'Exceptions' tab, where -you can also disable this 'blocking' notification, but not recommended. - -The server should start, and report - -Running XML-RPC server... - - -2. In another console run the cpp proxy client, with say - - -bin>xmlrpc_cpp_proxyD http://localhost:8080/RPC2 null null - -The client should connect to the server, and output a 'null' header, -and implementation file. If this functions, for a bigger example, try - - -bin>xmlrpc_cpp_proxyD http://localhost:8080/RPC2 system systemProxy - -and you should see a better example of a class header, and the -implementation code ... - -20 December, 2007 - -EOF diff --git a/trunk/Windows/delsln.bat b/trunk/Windows/delsln.bat deleted file mode 100644 index 80504d054..000000000 --- a/trunk/Windows/delsln.bat +++ /dev/null @@ -1,56 +0,0 @@ -@echo Delete the MSVC7 or MSVC8 soultion files ... -@echo ***************************************************** -@echo ARE YOU SURE YOU WANT TO DO THIS? Ctrl+C to ABORT ... -@echo ***************************************************** -@pause -@echo Deleting SOLUTION files ... -@if EXIST *.sln del *.sln > nul -@if EXIST *.vcproj del *.vcproj > nul -@if EXIST *.old echo Deleting *.old ... -@if EXIST *.old Del *.old > nul -@if EXIST *.bak echo Deleting *.bak ... -@if EXIST *.bak Del *.bak > nul -@if NOT EXIST temp*.* goto dntmp -@echo Delete temp*.* ... -@del temp*.* > nul -:dntmp -@if NOT EXIST *.obj goto dnobj -@echo Delete *.obj ... -@del *.obj > nul -:dnobj -@if NOT EXIST *.err goto dnerr -@echo Delete *.err ... -@del *.err > nul -:dnerr -@if NOT EXIST *.pdb goto dnpdb -@echo Delete *.pdb ... -@del *.pdb > nul -:dnpdb -@if NOT EXIST *.lst goto dnlst -@echo Delete *.lst ... -@del *.lst > nul -:dnlst -@if EXIST *.pch echo Deleting *.pch ... -@if EXIST *.pch Del *.pch > nul -@if EXIST *.ilk echo Deleting *.ilk ... -@if EXIST *.ilk Del *.ilk > nul -@if EXIST *.NCB echo Deleting *.NCB ... -@if EXIST *.NCB Del *.NCB > nul -@if EXIST *.plg echo Deleting *.plg ... -@if EXIST *.plg Del *.plg > nul -@if EXIST *.OPT echo Deleting *.OPT ... -@if EXIST *.OPT Del *.OPT > nul -@if EXIST *.idb echo Deleting *.idb ... -@if EXIST *.idb Del *.idb > nul -@if EXIST *.aps echo Deleting *.aps ... -@if EXIST *.aps Del *.aps > nul -@if EXIST *.sbr echo Deleting *.sbr ... -@if EXIST *.sbr Del *.sbr > nul -@if NOT EXIST *.suo goto DNSUO -@attrib -S -R -H *.suo > nul -@if EXIST *.suo echo Deleting *.suo ... -@if EXIST *.suo Del *.suo > nul -:DNSUO -@if EXIST *.user echo Deleting *.user ... -@if EXIST *.user Del *.user > nul -@echo All done ... diff --git a/trunk/Windows/diffcfg.bat b/trunk/Windows/diffcfg.bat deleted file mode 100644 index ba73fb276..000000000 --- a/trunk/Windows/diffcfg.bat +++ /dev/null @@ -1,6 +0,0 @@ -diff -us win32_config.h ..\include\xmlrpc-c\config.h > tempcfg.diff -diff -us xmlrpc_win32_config.h ..\xmlrpc_config.h >> tempcfg.diff -diff -us transport_config_win32.h ..\transport_config.h >> tempcfg.diff -diff -us xmlrpc_win32_config.h ..\examples\config.h >> tempcfg.diff -np tempcfg.diff - diff --git a/trunk/Windows/mkvers.bat b/trunk/Windows/mkvers.bat deleted file mode 100644 index 3d2fb7f54..000000000 --- a/trunk/Windows/mkvers.bat +++ /dev/null @@ -1,53 +0,0 @@ -@if EXIST ..\version.h goto SHOW -@if NOT EXIST ..\version.mk goto ERR1 -@if NOT EXIST mkvers1.bat goto ERR2 -@echo updating/creating ..\version.h ... -@set TEMP1=1 -@for /F "skip=8 tokens=3" %%i in (..\version.mk) do @call mkvers1 %%i -@if "%TEMPX1%." == "." goto NOX1 -@if "%TEMPX2%." == "." goto NOX1 -@if "%TEMPX3%." == "." goto NOX1 -@set TEMP1=..\version.h -@echo #ifndef XMLRPC_C_VERSION_INCLUDED > %TEMP1% -@echo #define XMLRPC_C_VERSION_INCLUDED >> %TEMP1% -@echo /* generated by Windows/mkvers.bat on %DATE% ... */ >> %TEMP1% -@echo #define XMLRPC_C_VERSION "%TEMPX1%.%TEMPX2%.%TEMPX3%" >> %TEMP1% -@echo #define XMLRPC_VERSION_MAJOR %TEMPX1% >> %TEMP1% -@echo #define XMLRPC_VERSION_MINOR %TEMPX2% >> %TEMP1% -@echo #define XMLRPC_VERSION_POINT %TEMPX3% >> %TEMP1% -@echo #endif >> %TEMP1% -type %TEMP1% -@echo ..\version.h set to the above ... -@set TEMP1= -@set TEMPX1= -@set TEMPX2= -@set TEMPX3= -@goto END - -:NOX1 -@echo Some error occurred in the batch process ... -@goto NOVER - -:NOVER -@echo Failed to create ..\version.h . -@pause -@goto END - - -:ERR1 -@echo Can not locate ..\version.mk ... check name, location ... -@pause -@goto END -:ERR2 -@echo Can not locate mkvers1.bat ... check name, location ... -@pause -@goto END - -:SHOW -@echo ..\version.h already exist, with version ... -@type ..\version.h -@echo Delete this file if you wish to redo it ... -@pause -@goto END - -:END diff --git a/trunk/Windows/mkvers1.bat b/trunk/Windows/mkvers1.bat deleted file mode 100644 index 262a94e9e..000000000 --- a/trunk/Windows/mkvers1.bat +++ /dev/null @@ -1,32 +0,0 @@ -@if "%1." == "." goto ERR2 -@if "%TEMP1%." == "." goto ERR1 -@if "%TEMP1%" == "1" goto SET1 -@if "%TEMP1%" == "2" goto SET2 -@if "%TEMP1%" == "3" goto SET3 -@echo environment variable has an invalid value %TEMP1% ... -@goto ERR2 - -:SET1 -@set TEMPX1=%1 -@set TEMP1=2 -@goto END - -:SET2 -@set TEMPX2=%1 -@set TEMP1=3 -@goto END - -:SET3 -@set TEMPX3=%1 -@set TEMP1=4 -@goto END - - -:ERR1 -@echo Environment variable TEMP1 not set ... -:ERR2 -@echo This batch is only intended to be run from within UPDVERS.BAT ... -@pause -@goto END - -:END diff --git a/trunk/Windows/project/vs2008/cpptest.vcproj b/trunk/Windows/project/vs2008/cpptest.vcproj deleted file mode 100644 index 97458c8bf..000000000 --- a/trunk/Windows/project/vs2008/cpptest.vcproj +++ /dev/null @@ -1,851 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/gennmtab.vcproj b/trunk/Windows/project/vs2008/gennmtab.vcproj deleted file mode 100644 index 02b6420aa..000000000 --- a/trunk/Windows/project/vs2008/gennmtab.vcproj +++ /dev/null @@ -1,851 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/rpctest.vcproj b/trunk/Windows/project/vs2008/rpctest.vcproj deleted file mode 100644 index ac7d0314f..000000000 --- a/trunk/Windows/project/vs2008/rpctest.vcproj +++ /dev/null @@ -1,979 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/sample_add_asynch_client.vcproj b/trunk/Windows/project/vs2008/sample_add_asynch_client.vcproj deleted file mode 100644 index ed1102437..000000000 --- a/trunk/Windows/project/vs2008/sample_add_asynch_client.vcproj +++ /dev/null @@ -1,839 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/sample_add_server.vcproj b/trunk/Windows/project/vs2008/sample_add_server.vcproj deleted file mode 100644 index 2d2cbaf46..000000000 --- a/trunk/Windows/project/vs2008/sample_add_server.vcproj +++ /dev/null @@ -1,823 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/sample_add_server_w32httpsys.vcproj b/trunk/Windows/project/vs2008/sample_add_server_w32httpsys.vcproj deleted file mode 100644 index 25233507e..000000000 --- a/trunk/Windows/project/vs2008/sample_add_server_w32httpsys.vcproj +++ /dev/null @@ -1,823 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/sample_add_sync_client.vcproj b/trunk/Windows/project/vs2008/sample_add_sync_client.vcproj deleted file mode 100644 index 5f23a6a12..000000000 --- a/trunk/Windows/project/vs2008/sample_add_sync_client.vcproj +++ /dev/null @@ -1,827 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/sample_auth_client.vcproj b/trunk/Windows/project/vs2008/sample_auth_client.vcproj deleted file mode 100644 index 31ea15c1c..000000000 --- a/trunk/Windows/project/vs2008/sample_auth_client.vcproj +++ /dev/null @@ -1,827 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/tool_xmlrpc-transport.vcproj b/trunk/Windows/project/vs2008/tool_xmlrpc-transport.vcproj deleted file mode 100644 index 014d2747d..000000000 --- a/trunk/Windows/project/vs2008/tool_xmlrpc-transport.vcproj +++ /dev/null @@ -1,790 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/tool_xmlrpc.vcproj b/trunk/Windows/project/vs2008/tool_xmlrpc.vcproj deleted file mode 100644 index d85bda710..000000000 --- a/trunk/Windows/project/vs2008/tool_xmlrpc.vcproj +++ /dev/null @@ -1,790 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc.sln b/trunk/Windows/project/vs2008/xmlrpc.sln deleted file mode 100644 index c1aa230ec..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc.sln +++ /dev/null @@ -1,499 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmlparse", "xmlrpc_xmlparse.vcproj", "{40B0756D-AFEE-4A38-9F38-A372CE431404}" - ProjectSection(ProjectDependencies) = postProject - {BD9F6041-A272-462D-8C41-87CEF1F11408} = {BD9F6041-A272-462D-8C41-87CEF1F11408} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmltok", "xmlrpc_xmltok.vcproj", "{BD9F6041-A272-462D-8C41-87CEF1F11408}" - ProjectSection(ProjectDependencies) = postProject - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412} = {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennmtab", "gennmtab.vcproj", "{99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_util", "xmlrpc_util.vcproj", "{29FBABB6-E36A-4559-9514-B3DAF6AE1416}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc", "xmlrpc.vcproj", "{226AB06F-60CA-4B21-9040-C6ECC0581522}" - ProjectSection(ProjectDependencies) = postProject - {40B0756D-AFEE-4A38-9F38-A372CE431404} = {40B0756D-AFEE-4A38-9F38-A372CE431404} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_abyss", "xmlrpc_abyss.vcproj", "{20A8F64B-F738-4D32-A798-A65AD8291541}" - ProjectSection(ProjectDependencies) = postProject - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server", "xmlrpc_server.vcproj", "{74B67128-BC84-4BCB-A256-9286B6371552}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_abyss", "xmlrpc_server_abyss.vcproj", "{E98186CB-F1B0-40A6-87A5-77B13A3F1600}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_cgi", "xmlrpc_server_cgi.vcproj", "{A2AAAF37-F382-4A11-8D86-53B589921616}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_w32httpsys", "xmlrpc_server_w32httpsys.vcproj", "{0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_client", "xmlrpc_client.vcproj", "{28BB53D9-D487-41DF-BBB3-FDB5846D1630}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_asynch_client", "sample_add_asynch_client.vcproj", "{2D4A179E-E2BA-4ED9-934E-7E54C08F1652}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server", "sample_add_server.vcproj", "{BEEB1B9C-BAF4-4B54-AB51-891156301702}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server_w32httpsys", "sample_add_server_w32httpsys.vcproj", "{B6887828-9480-4D4D-9CFC-AE4980D41707}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} = {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_sync_client", "sample_add_sync_client.vcproj", "{A7A81BBD-C84D-479A-A9BD-194ADA3B1710}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_auth_client", "sample_auth_client.vcproj", "{29A2BBC4-9ED9-4162-817C-FEEB36FB1714}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpctest", "rpctest.vcproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} - {40B0756D-AFEE-4A38-9F38-A372CE431404} = {40B0756D-AFEE-4A38-9F38-A372CE431404} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc++", "xmlrpc__.vcproj", "{3E7064F3-6200-4C39-85BE-775931D21828}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpptest", "cpptest.vcproj", "{26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - {3E7064F3-6200-4C39-85BE-775931D21828} = {3E7064F3-6200-4C39-85BE-775931D21828} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "tool_xmlrpc.vcproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc_transport", "tool_xmlrpc-transport.vcproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug-DLL|Win32 = Debug-DLL|Win32 - Debug-DLL|x64 = Debug-DLL|x64 - Debug-Static|Win32 = Debug-Static|Win32 - Debug-Static|x64 = Debug-Static|x64 - Release-DLL|Win32 = Release-DLL|Win32 - Release-DLL|x64 = Release-DLL|x64 - Release-Static|Win32 = Release-Static|Win32 - Release-Static|x64 = Release-Static|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|x64.Build.0 = Release-Static|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|x64.Build.0 = Release-Static|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|x64.Build.0 = Release-Static|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|x64.Build.0 = Release-Static|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|x64.Build.0 = Release-Static|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|x64.Build.0 = Release-Static|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|x64.Build.0 = Release-Static|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|x64.Build.0 = Release-Static|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|x64.Build.0 = Release-Static|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|x64.Build.0 = Release-Static|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|x64.Build.0 = Release-Static|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|x64.Build.0 = Release-Static|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|x64.Build.0 = Release-Static|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|x64.Build.0 = Release-Static|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|x64.Build.0 = Release-Static|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|x64.Build.0 = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|x64.Build.0 = Release-Static|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|x64.Build.0 = Release-Static|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|x64.Build.0 = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|x64.Build.0 = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|x64.Build.0 = Release-Static|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/trunk/Windows/project/vs2008/xmlrpc.vcproj b/trunk/Windows/project/vs2008/xmlrpc.vcproj deleted file mode 100644 index b5804cf41..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc.vcproj +++ /dev/null @@ -1,770 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc__.vcproj b/trunk/Windows/project/vs2008/xmlrpc__.vcproj deleted file mode 100644 index 4206b032a..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc__.vcproj +++ /dev/null @@ -1,2430 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc_abyss.vcproj b/trunk/Windows/project/vs2008/xmlrpc_abyss.vcproj deleted file mode 100644 index 6e281ef78..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc_abyss.vcproj +++ /dev/null @@ -1,2276 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc_client.vcproj b/trunk/Windows/project/vs2008/xmlrpc_client.vcproj deleted file mode 100644 index e35fdb5dd..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc_client.vcproj +++ /dev/null @@ -1,724 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc_server.vcproj b/trunk/Windows/project/vs2008/xmlrpc_server.vcproj deleted file mode 100644 index 05e35f0d6..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc_server.vcproj +++ /dev/null @@ -1,708 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc_server_abyss.vcproj b/trunk/Windows/project/vs2008/xmlrpc_server_abyss.vcproj deleted file mode 100644 index ce02c2943..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc_server_abyss.vcproj +++ /dev/null @@ -1,704 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc_server_cgi.vcproj b/trunk/Windows/project/vs2008/xmlrpc_server_cgi.vcproj deleted file mode 100644 index 39e4ff289..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc_server_cgi.vcproj +++ /dev/null @@ -1,696 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc_server_w32httpsys.vcproj b/trunk/Windows/project/vs2008/xmlrpc_server_w32httpsys.vcproj deleted file mode 100644 index 3029a8919..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc_server_w32httpsys.vcproj +++ /dev/null @@ -1,700 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc_util.vcproj b/trunk/Windows/project/vs2008/xmlrpc_util.vcproj deleted file mode 100644 index 259740242..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc_util.vcproj +++ /dev/null @@ -1,764 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc_xmlparse.vcproj b/trunk/Windows/project/vs2008/xmlrpc_xmlparse.vcproj deleted file mode 100644 index a7048291d..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc_xmlparse.vcproj +++ /dev/null @@ -1,747 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2008/xmlrpc_xmltok.vcproj b/trunk/Windows/project/vs2008/xmlrpc_xmltok.vcproj deleted file mode 100644 index b6227a153..000000000 --- a/trunk/Windows/project/vs2008/xmlrpc_xmltok.vcproj +++ /dev/null @@ -1,849 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/cpptest.vcproj b/trunk/Windows/project/vs2010express/cpptest.vcproj deleted file mode 100644 index 97458c8bf..000000000 --- a/trunk/Windows/project/vs2010express/cpptest.vcproj +++ /dev/null @@ -1,851 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/cpptest.vcxproj b/trunk/Windows/project/vs2010express/cpptest.vcxproj deleted file mode 100644 index 274542659..000000000 --- a/trunk/Windows/project/vs2010express/cpptest.vcxproj +++ /dev/null @@ -1,533 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856} - cpptest - - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - - /D INTERNAL_EXPAT %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - /D INTERNAL_EXPAT %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - /D INTERNAL_EXPAT %(AdditionalOptions) - Disabled - ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILDING_LIBPP;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - /D INTERNAL_EXPAT %(AdditionalOptions) - Disabled - ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - /D INTERNAL_EXPAT %(AdditionalOptions) - Disabled - ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - /D INTERNAL_EXPAT %(AdditionalOptions) - Disabled - ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - /D INTERNAL_EXPAT %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - /D INTERNAL_EXPAT %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {3e7064f3-6200-4c39-85be-775931d21828} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/cpptest.vcxproj.filters b/trunk/Windows/project/vs2010express/cpptest.vcxproj.filters deleted file mode 100644 index c16994a4a..000000000 --- a/trunk/Windows/project/vs2010express/cpptest.vcxproj.filters +++ /dev/null @@ -1,78 +0,0 @@ - - - - - {f5252a96-d4c6-445e-8c35-ca0248ffbb90} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {03ef63c2-410d-4c91-b5ad-640704d05a21} - h;hpp;hxx;hm;inl - - - {0619edec-58a6-46c4-bd19-cc5c1d85d0a5} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/cpptest.vcxproj.user b/trunk/Windows/project/vs2010express/cpptest.vcxproj.user deleted file mode 100644 index 7cbb3216a..000000000 --- a/trunk/Windows/project/vs2010express/cpptest.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/gennmtab.vcproj b/trunk/Windows/project/vs2010express/gennmtab.vcproj deleted file mode 100644 index 02b6420aa..000000000 --- a/trunk/Windows/project/vs2010express/gennmtab.vcproj +++ /dev/null @@ -1,851 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/gennmtab.vcxproj b/trunk/Windows/project/vs2010express/gennmtab.vcxproj deleted file mode 100644 index 1b5dc5e45..000000000 --- a/trunk/Windows/project/vs2010express/gennmtab.vcxproj +++ /dev/null @@ -1,515 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412} - gennmtab - - - - Application - v100 - false - - - Application - v100 - false - - - Application - v100 - false - - - Application - v100 - false - - - Application - v100 - false - - - Application - v100 - false - - - Application - v100 - false - - - Application - v100 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - true - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - true - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - true - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - true - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - - - - $(OutDir)$(ProjectName).tlb - - - - Disabled - ../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - (D) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - X64 - $(OutDir)$(ProjectName).tlb - - - - Disabled - ../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - (D) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - $(OutDir)$(ProjectName).tlb - - - - MaxSpeed - OnlyExplicitInline - ../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - (R) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - X64 - $(OutDir)$(ProjectName).tlb - - - - MaxSpeed - OnlyExplicitInline - ../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - (R) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - $(OutDir)$(ProjectName).tlb - - - - Disabled - ../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - (D) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - X64 - $(OutDir)$(ProjectName).tlb - - - - Disabled - ../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - (D) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - $(OutDir)$(ProjectName).tlb - - - - MaxSpeed - OnlyExplicitInline - ../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - (R) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - X64 - $(OutDir)$(ProjectName).tlb - - - - MaxSpeed - OnlyExplicitInline - ../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - (R) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/gennmtab.vcxproj.filters b/trunk/Windows/project/vs2010express/gennmtab.vcxproj.filters deleted file mode 100644 index 316180282..000000000 --- a/trunk/Windows/project/vs2010express/gennmtab.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {5d8a7041-77b6-4734-af85-85cf63011a8b} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90 - - - {0c293b56-e683-47a1-844d-ac211aa2c2c7} - ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe - - - {2716887d-8a6c-4d92-b804-f03db0b67175} - h;hpp;hxx;hm;inl;fi;fd - - - - - Source Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/gennmtab.vcxproj.user b/trunk/Windows/project/vs2010express/gennmtab.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/gennmtab.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/rpctest.vcproj b/trunk/Windows/project/vs2010express/rpctest.vcproj deleted file mode 100644 index ac7d0314f..000000000 --- a/trunk/Windows/project/vs2010express/rpctest.vcproj +++ /dev/null @@ -1,979 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/rpctest.vcxproj b/trunk/Windows/project/vs2010express/rpctest.vcxproj deleted file mode 100644 index bd9f069df..000000000 --- a/trunk/Windows/project/vs2010express/rpctest.vcxproj +++ /dev/null @@ -1,587 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722} - rpctest - - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $OutDir)\data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $OutDir)\data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $(OutDir)data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $(OutDir)data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $OutDir)\data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $OutDir)\data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $(OutDir)data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $(OutDir)data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {e98186cb-f1b0-40a6-87a5-77b13a3f1600} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {40b0756d-afee-4a38-9f38-a372ce431404} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/rpctest.vcxproj.filters b/trunk/Windows/project/vs2010express/rpctest.vcxproj.filters deleted file mode 100644 index 14cbe16ae..000000000 --- a/trunk/Windows/project/vs2010express/rpctest.vcxproj.filters +++ /dev/null @@ -1,127 +0,0 @@ - - - - - {1c8c37ff-1b10-4421-8a91-f19e6247b6f9} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {6b698982-c603-4655-9359-13b6b0059aaf} - h;hpp;hxx;hm;inl - - - {f5cd24c3-8ff7-45eb-9198-80c9a81b9b79} - - - {a0d0e69f-fd5e-407b-8b8c-ade4c1768ee2} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - TestFiles - - - - - TestFiles - - - TestFiles - - - TestFiles - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/rpctest.vcxproj.user b/trunk/Windows/project/vs2010express/rpctest.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/rpctest.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcproj b/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcproj deleted file mode 100644 index ed1102437..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcproj +++ /dev/null @@ -1,839 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj b/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj deleted file mode 100644 index 54fe1d820..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj +++ /dev/null @@ -1,501 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652} - sample_add_asynch_client - - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - odbc32.lib;odbccp32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - odbc32.lib;odbccp32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.filters b/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.filters deleted file mode 100644 index fcb4b4c46..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {9d1d1ca2-e002-4e95-960a-68ce98d812d6} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {cccace1e-db4f-4da4-95c2-ed2230affe3e} - h;hpp;hxx;hm;inl - - - {878cc7dc-a7e7-4255-8a4f-209a757107a7} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.user b/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_asynch_client.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_server.vcproj b/trunk/Windows/project/vs2010express/sample_add_server.vcproj deleted file mode 100644 index 2d2cbaf46..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_server.vcproj +++ /dev/null @@ -1,823 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/sample_add_server.vcxproj b/trunk/Windows/project/vs2010express/sample_add_server.vcxproj deleted file mode 100644 index 9bdfe26e8..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_server.vcxproj +++ /dev/null @@ -1,481 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {BEEB1B9C-BAF4-4B54-AB51-891156301702} - sample_add_server - - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {e98186cb-f1b0-40a6-87a5-77b13a3f1600} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_server.vcxproj.filters b/trunk/Windows/project/vs2010express/sample_add_server.vcxproj.filters deleted file mode 100644 index 1fff72dc5..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_server.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {78f7e7a1-21a8-403e-96c5-4490959577fe} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {d52a357e-0a48-4f06-aad1-5fd5e922b6eb} - h;hpp;hxx;hm;inl - - - {d7b48ffa-20c8-4d45-81f9-56d6e5bdc8c3} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_server.vcxproj.user b/trunk/Windows/project/vs2010express/sample_add_server.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_server.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcproj b/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcproj deleted file mode 100644 index 25233507e..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcproj +++ /dev/null @@ -1,823 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj b/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj deleted file mode 100644 index 48387784e..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj +++ /dev/null @@ -1,481 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {B6887828-9480-4D4D-9CFC-AE4980D41707} - sample_add_server_w32httpsys - - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {0eecb080-fc8f-4c46-9fb7-5db22f9d1622} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.filters b/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.filters deleted file mode 100644 index c973d393d..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {d850a83b-706b-4478-8141-956e906663bd} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {9e5db171-0efd-4c2f-9d85-9dbb14d0f96c} - h;hpp;hxx;hm;inl - - - {6070c286-d300-47f6-b001-efebf8190759} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.user b/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_server_w32httpsys.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_sync_client.vcproj b/trunk/Windows/project/vs2010express/sample_add_sync_client.vcproj deleted file mode 100644 index 5f23a6a12..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_sync_client.vcproj +++ /dev/null @@ -1,827 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj b/trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj deleted file mode 100644 index aac62116d..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj +++ /dev/null @@ -1,481 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710} - sample_add_sync_client - - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj.filters b/trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj.filters deleted file mode 100644 index 9198d1fe5..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {27eac376-bbcc-46ec-bbcb-f9bac54d664e} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {e0b59389-fbfc-4db6-abca-73c84a9326d5} - h;hpp;hxx;hm;inl - - - {f418327e-7416-493b-a34f-66bc7e2ba523} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj.user b/trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/sample_add_sync_client.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_auth_client.vcproj b/trunk/Windows/project/vs2010express/sample_auth_client.vcproj deleted file mode 100644 index 31ea15c1c..000000000 --- a/trunk/Windows/project/vs2010express/sample_auth_client.vcproj +++ /dev/null @@ -1,827 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/sample_auth_client.vcxproj b/trunk/Windows/project/vs2010express/sample_auth_client.vcxproj deleted file mode 100644 index 765a663c5..000000000 --- a/trunk/Windows/project/vs2010express/sample_auth_client.vcxproj +++ /dev/null @@ -1,481 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714} - sample_auth_client - - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_auth_client.vcxproj.filters b/trunk/Windows/project/vs2010express/sample_auth_client.vcxproj.filters deleted file mode 100644 index 675e9e788..000000000 --- a/trunk/Windows/project/vs2010express/sample_auth_client.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {51df2750-29e7-46f9-a1dd-26d18780f433} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {af693b21-170c-437e-8084-2bd3883deadf} - h;hpp;hxx;hm;inl - - - {185dcef2-b402-4b32-b59b-f992f113d086} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/sample_auth_client.vcxproj.user b/trunk/Windows/project/vs2010express/sample_auth_client.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/sample_auth_client.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcproj b/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcproj deleted file mode 100644 index 014d2747d..000000000 --- a/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcproj +++ /dev/null @@ -1,790 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj b/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj deleted file mode 100644 index de11f0cdf..000000000 --- a/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj +++ /dev/null @@ -1,519 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - xmlrpc_transport - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942} - - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.filters b/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.filters deleted file mode 100644 index d7049523a..000000000 --- a/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.filters +++ /dev/null @@ -1,40 +0,0 @@ - - - - - {95618a07-efd6-4963-ad2e-3f963cde6816} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {e5a752dc-fcf4-4e81-81b9-d856d1c6d892} - h;hpp;hxx;hm;inl - - - {b0f90688-1d56-49c9-a6d6-2471a08f07fa} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.user b/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/tool_xmlrpc-transport.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/tool_xmlrpc.vcproj b/trunk/Windows/project/vs2010express/tool_xmlrpc.vcproj deleted file mode 100644 index d85bda710..000000000 --- a/trunk/Windows/project/vs2010express/tool_xmlrpc.vcproj +++ /dev/null @@ -1,790 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj b/trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj deleted file mode 100644 index 9d6280625..000000000 --- a/trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj +++ /dev/null @@ -1,515 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - xmlrpc - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940} - - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - Application - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj.filters b/trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj.filters deleted file mode 100644 index d83dd8fb4..000000000 --- a/trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj.filters +++ /dev/null @@ -1,40 +0,0 @@ - - - - - {13c7b6bf-db0d-4f32-b15d-ed7499cca73c} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {1327ed33-278c-4453-9d06-be01f5c61f76} - h;hpp;hxx;hm;inl - - - {53663fed-de9a-42f2-9022-ee40672d92f6} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj.user b/trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/tool_xmlrpc.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/vs2010express.sln b/trunk/Windows/project/vs2010express/vs2010express.sln deleted file mode 100644 index 412aa432a..000000000 --- a/trunk/Windows/project/vs2010express/vs2010express.sln +++ /dev/null @@ -1,399 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpptest", "cpptest.vcxproj", "{26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - {3E7064F3-6200-4C39-85BE-775931D21828} = {3E7064F3-6200-4C39-85BE-775931D21828} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennmtab", "gennmtab.vcxproj", "{99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpctest", "rpctest.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} - {40B0756D-AFEE-4A38-9F38-A372CE431404} = {40B0756D-AFEE-4A38-9F38-A372CE431404} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_asynch_client", "sample_add_asynch_client.vcxproj", "{2D4A179E-E2BA-4ED9-934E-7E54C08F1652}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server", "sample_add_server.vcxproj", "{BEEB1B9C-BAF4-4B54-AB51-891156301702}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server_w32httpsys", "sample_add_server_w32httpsys.vcxproj", "{B6887828-9480-4D4D-9CFC-AE4980D41707}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} = {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_sync_client", "sample_add_sync_client.vcxproj", "{A7A81BBD-C84D-479A-A9BD-194ADA3B1710}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_auth_client", "sample_auth_client.vcxproj", "{29A2BBC4-9ED9-4162-817C-FEEB36FB1714}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "tool_xmlrpc.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}" - ProjectSection(ProjectDependencies) = postProject - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc_transport", "tool_xmlrpc-transport.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {226AB06F-60CA-4B21-9040-C6ECC0581522} = {226AB06F-60CA-4B21-9040-C6ECC0581522} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc", "xmlrpc.vcxproj", "{226AB06F-60CA-4B21-9040-C6ECC0581522}" - ProjectSection(ProjectDependencies) = postProject - {40B0756D-AFEE-4A38-9F38-A372CE431404} = {40B0756D-AFEE-4A38-9F38-A372CE431404} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc++", "xmlrpc__.vcxproj", "{3E7064F3-6200-4C39-85BE-775931D21828}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {20A8F64B-F738-4D32-A798-A65AD8291541} = {20A8F64B-F738-4D32-A798-A65AD8291541} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - {E98186CB-F1B0-40A6-87A5-77B13A3F1600} = {E98186CB-F1B0-40A6-87A5-77B13A3F1600} - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} = {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_abyss", "xmlrpc_abyss.vcxproj", "{20A8F64B-F738-4D32-A798-A65AD8291541}" - ProjectSection(ProjectDependencies) = postProject - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_client", "xmlrpc_client.vcxproj", "{28BB53D9-D487-41DF-BBB3-FDB5846D1630}" - ProjectSection(ProjectDependencies) = postProject - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_abyss", "xmlrpc_server_abyss.vcxproj", "{E98186CB-F1B0-40A6-87A5-77B13A3F1600}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_cgi", "xmlrpc_server_cgi.vcxproj", "{A2AAAF37-F382-4A11-8D86-53B589921616}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_w32httpsys", "xmlrpc_server_w32httpsys.vcxproj", "{0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}" - ProjectSection(ProjectDependencies) = postProject - {74B67128-BC84-4BCB-A256-9286B6371552} = {74B67128-BC84-4BCB-A256-9286B6371552} - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} = {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_util", "xmlrpc_util.vcxproj", "{29FBABB6-E36A-4559-9514-B3DAF6AE1416}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmlparse", "xmlrpc_xmlparse.vcxproj", "{40B0756D-AFEE-4A38-9F38-A372CE431404}" - ProjectSection(ProjectDependencies) = postProject - {BD9F6041-A272-462D-8C41-87CEF1F11408} = {BD9F6041-A272-462D-8C41-87CEF1F11408} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmltok", "xmlrpc_xmltok.vcxproj", "{BD9F6041-A272-462D-8C41-87CEF1F11408}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server", "xmlrpc_server.vcxproj", "{74B67128-BC84-4BCB-A256-9286B6371552}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug-DLL|Win32 = Debug-DLL|Win32 - Debug-Static|Win32 = Debug-Static|Win32 - Release|Win32 = Release|Win32 - Release-DLL|Win32 = Release-DLL|Win32 - Release-Static|Win32 = Release-Static|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug|Win32.Build.0 = Debug-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release|Win32.ActiveCfg = Release-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release|Win32.Build.0 = Release-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug|Win32.Build.0 = Debug-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release|Win32.ActiveCfg = Release-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release|Win32.Build.0 = Release-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug|Win32.Build.0 = Debug-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release|Win32.ActiveCfg = Release-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release|Win32.Build.0 = Release-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug|Win32.Build.0 = Debug-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release|Win32.ActiveCfg = Release-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release|Win32.Build.0 = Release-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug|Win32.Build.0 = Debug-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release|Win32.ActiveCfg = Release-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release|Win32.Build.0 = Release-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug|Win32.Build.0 = Debug-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release|Win32.ActiveCfg = Release-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release|Win32.Build.0 = Release-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug|Win32.Build.0 = Debug-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release|Win32.ActiveCfg = Release-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release|Win32.Build.0 = Release-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug|Win32.Build.0 = Debug-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release|Win32.ActiveCfg = Release-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release|Win32.Build.0 = Release-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug|Win32.Build.0 = Debug-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release|Win32.ActiveCfg = Release-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release|Win32.Build.0 = Release-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug|Win32.Build.0 = Debug-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release|Win32.ActiveCfg = Release-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release|Win32.Build.0 = Release-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug|Win32.Build.0 = Debug-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release|Win32.ActiveCfg = Release-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release|Win32.Build.0 = Release-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug|Win32.Build.0 = Debug-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release|Win32.ActiveCfg = Release-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release|Win32.Build.0 = Release-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug|Win32.Build.0 = Debug-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release|Win32.ActiveCfg = Release-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release|Win32.Build.0 = Release-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug|Win32.Build.0 = Debug-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release|Win32.ActiveCfg = Release-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release|Win32.Build.0 = Release-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug|Win32.Build.0 = Debug-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release|Win32.ActiveCfg = Release-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release|Win32.Build.0 = Release-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug|Win32.Build.0 = Debug-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release|Win32.ActiveCfg = Release-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release|Win32.Build.0 = Release-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug|Win32.Build.0 = Debug-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release|Win32.ActiveCfg = Release-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release|Win32.Build.0 = Release-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug|Win32.ActiveCfg = Debug-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug|Win32.Build.0 = Debug-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release|Win32.ActiveCfg = Release-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release|Win32.Build.0 = Release-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.Build.0 = Release-Static|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/trunk/Windows/project/vs2010express/vs2010express.suo b/trunk/Windows/project/vs2010express/vs2010express.suo deleted file mode 100644 index 24315f40c508561bf01d63d5cf5d0e6b4e3b4ba8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34304 zcmeHQeUMyLmG6N>AYvpqOu&RV30XI2dg!m|nF%JQzXp=bBttR`1V)CQnVv}}o$j%_ zXOfr@gGN3gZdeo+BP0+NP<9C}YjD9(ShclUx(k-ZD)FCn)v}h=+S=$A{sF@Ne)smB zdGn?}-krWLVCn5T{l4yd=iGaL_uO;Od+)p-zP#Y)kACC*|LL)%HJ)=lZ@zVb=UtZl z4Ol0Mbdkq%4pvBSzV+5ya;L|G)xV@ap&IxjWSxt~YXi*zvAxd&T>v^CbRlRS=-r_A zfaZhH^q%*ER)ekrT?~33s1bAts0p+Xv=nq1=>4EYpv9oeK}$d%05yXafR=%-04)do z73hPYzXq)UT?zUS=)<6uATOu|M9lfH^n(JRASeWC1%*NFAm-`7auw)m&__UPKoQVK zL2E(GL;7<~n>{)FifD_3CyQm?vj?@}JT-adPWE}WbG3BQzhD0Cm;66&I2V~-WFsQ= zfMd?H-LnqdN3fRg?3M={{x?AbS=-LxX#&H{+v`bs3Z5OFE>9ZEqUU=2ry!HsU#M}x z<={^&v)@pT8rj9+2K=*cG4+D)7;1q$3ndv+sEZ-&agvsJ&S_wOW8ZbkpE`Rk|Bw{^ z*(SUOb%D|Wl#zOX{a@vy4p8gV1MI)5|8qb4zdC-rv|g?MFGZeZAl?2?y~F-b9mM{> z1;qY;3yA%n`s^S`$)fr{x2XeE|EDg9f?}XJC;{pOT?4unv<|c$v;ouw>IQ8DZ36Xx zt^;ibeIC>cx*pUAx&d?}Xe;O@(9NKJ(8oY`f(Aghf|8&?&=6=C#8w{xje@p;(xC02 z9iR+oCnyWbfyO`|2jxM;X%RFIngHzru_v)Ne*&}@v=4L}Xg}zapaYw9L%J|Mq+m{l`W(P)0uQ}PfHIaEnv@3>cd@PC6(uSTZ*}S zisgK_u&2&;@#nJSS#yQ96jK$sR3WikCX*Us>yhOgR*_IV7o3aDi}=Sx+hVp!HDW#I zv%kh*CG?}m>_jiiqh}4l(ip;?8_)x@=$Se6r~a!udR& z!anA8lIA$cQ1GhXzYSc9x<5iev8}w8kiY9D{Da z8ATl5CUVzi+>G&u_<|x-UY`%4r4ov+U%}R5|C= z5!$qarA<43+8-Qy$G|rY39?nW(^fsFfn_-lTb^!U4 zFR$m6|9g@5L#2*0f^s%v#G>^xj<(NWYYX;`Lk5<=Ss=Rw=4Yf!7?XBV4_6?1V6;p*`%S2`T?LkWp zqOEClR8GL(WZ!d&KiXjGigy0p=zByM=ONQ|uR3G;awYiFW@Vpp%AftUw{#gh|ML3B zDoN?Y(jtWZM}5LE%qjmSEj`lcu}Z&viaDNU_rMslQK-=i+%+`y_4SJhqrIrP?X z)VaK}wWK}Z$vH_iP3S}Un^7Lx{Z7kI-@t#BfFB2sO8nJaEG{%l5@*d!E#OZJl)RZ{ z=9sz1ia+Yv49c&{DC>Cyr5?pzj-Tqt%M7kbYo?N9)8=f5Vq}5ez<|)s|_&aHP%%=R;0+GW)pJq|!45aB47Kzlb z?(?7WcMO!QpiD&!9xQ`Fm~rzO*S!A03-@2R;mIX0|LUI(T}pR~@FC}(-oEVnw=Ugq z@7jO;?Ta^FvTVa^Pc*mxA<+H!gOAkG^sM)-eh@|&qUukX<6n6YWW$LAV?~&CC7=R4Z?bPYMs+q@IASLZ5X(#Qj zC}9-k8-llm_9s0K^gVQy`a?Cl8y6O7HuFE;vs=uY3`nZ~%l_62DaKLO;^h6HJZ!LP zHaO-Vb@jhK)J(HY3MrYhf82j+AO>kuJMI5L+ZIQM!P-&!+CbZNYfRF@Qcu z&dO?OK#o7MBg5! zK(3sn>X8XI4E4%Rd8HN?FM8=a>rXHD{BGdpA6_-`$ZPBkstVPzs@&?JX+1Bs{+Q^E z9Cs?&gQjLU9T@ezpbp?5jx|5lLfDRjf?}L(!#*EI#1@AmVgNZuaHhJC5XC4ujOv>5 zA;hq?7uRnCwd3m167LwcLPClVj@2Vs9Aj9QWt6ThQ{1>rQ=Y|2wnJ^HBCblMUrQk& zPe8OyK(t#7E#}2`0`1m;wGi4f46W%EE!&3C)hleQ1ab#UUL!wRm)03EHH;aD9CN7i z>2=x!qThZBFT5X5+m47Z!_}E>SG#>AlHHU{zl|i4P0C~r$!fmK%mA?2 zDrN+<{v%?Ivw}{6o2xGo{k6C1qXk?h<`8K4C9-@lOv9 z?NsXI0JJVG4xiAx^x=e|pJVv>pp$7&wjz&|$GJ}C8K$_JMY5Zc>9>)xF3i=IIV78` zDXUcawIq=o1TNbIibJp!f1*7e-~t=G@$Yz9CN$MjjkbiW~I3+IdX22A>ZuSTnx^(vd5Lr>j@ufHAaT1y}G zN;jxy1L~K_+6$Fua=QP$_8d*lp-tA5RVw{jlDeS-{hS^bsSnuuBhU$P^ndCG&ZgzO zI$qKj5ivS(zL5YbWzG6=w%#1tBv(6LX4^h;4(+C7`fVhUY*HpGW@cMc63K2!rC&>? zW*%+8u`ZJ9pLtAiHH&07CDU&sQ!|gL+A@b^lQm_PO23xW%tQKi=%1vX^@8Yclrs=4K432w_=?$4|;~^`Q+R~PbUY2uIIhy`nj4#vYV3Ww~?|g%(amfGxh0YlQm_P zO23vQk~yEC$DQ|9I)G2FKyjzADL98FYH4wBjkD=?e zNN&^A$x-wJQ(R3W**(eh+ejhVoJ=N>?2c6WwIq>j@_x5-zh*72)xAz;v8(5q(vwWT zRU~#z%480^Zb_wIOUg3#!CIh=8-`AeLgRKqBL}gE-ikQZc*mbuqvqurEnz-ILaj~P zf)SWIMq-9K95C(pU>LpEcC8E=+PYi)1$? z({Ce*WRo&kF;kzN?3PsewIq?u=Y@z<&fBP6iR6I5Dv``*3yJP_VP{B-neX55c_F_b ziDcd92~Bb}i)1$?({Ce*WRo(PL$X^^>DQ7(avShUtAg)=(XT>}n|%9^Nai~I8ALaA zHth`N3X5~7o#{{3f6~GvSF=cVQ!@QFl1MfwlQ|^2C6#_H@xA8=-qB`!Fh<{r;jLFj z?d6lmjaWKGNGT8)&Uic0^oXU?V@}AeqKFSr={;n3;%`ltW1!+&&_&d``S@Eh{%fts zWA4NYD&W28op=M5kw+LsiLqh0WON`#1>c4(Cy}SziLO*$I&0*oN;o;{N=wz2X8`XP zJCCw--&vJXwy3lAJakqhW5f-o2y-VQ6}1f`-3%c1##C&g@~EN&Kl#e(jSqVsd-Uj= zjSPV((k)lK-t|=9?>4+JdieB-frZPslks`$jYsr@J8pmV=`)Y5z4NQPzOm|~O&)uE zqMhSUul=7B?dy-Ve>wkBtZ~lKh3mb~{o<94pWnE@_r=3an<)q5DB9()$3e1R_n}3< zdEx(_>)r6=b$2i5^DPvSTjrFxjy---EqPb$zU$0a+F7K&DPdwiJy(8Cr?bK!Ke|GgkhDVuIx&P()<5#|N zbTD%JzBhjpetjVa)mdFI+L%G`7PPGeV1@izA) zwmxrj&(7-eHutpSYf2#| zdpEdLI46!b;V z5fJ0uJp_6f#JtC_e5ADg4_JN~^aSXurG1Z=mS4m2>!2q=e_z_i^PQw`mGVDVS~@xB z&n=Jr9+y7$%=wn}dDrg^w0`eE_xnDz!wkwe`&||1?nNN8zQnk=_W2sG$VsAgp22+f z`KdjgF3)3FR{QmI}^VlwovuyRV*vrR!PTGa}tf^ewXzTHr>odPUQLpz`-AB^VJ^UsVzfQ%7 zh4SkZ{qV^$+HyaR$mp&7pB@EY#bcg}Vy&&B5$snS6yDzy?tX>f2Ul02AE~$ERTxir z5YnXJTVO0veyL3Q)21Se$~`l`TISRPCtK&N_YA)Cq*7S6 z`!+M8efaH9#(Ld`Y;?oLE7s~v#N}}&ziUtswX?^95$ZfX$5OtJOkHULb;@txP=X`LQAIP(MFR)sGKU^%qk4 ziBx_dIk=}#Xu*zs`}W3t34f$D7WPJitsUM_BINgWM8iIBFc@y_2n1q*NFZ=qgGYqq zW+BpRYkU}MjdS_Sb;LOje0O8^g)`r}`M;O=K6~KAcgWLjLULcl6m`zOQbV7)d;FID z55}%NwrWju+x-naE5OXL47K84Ggf)EG@JO_U%>^5Gp1VnLo!>%f5zWljH63HEOf<; zmIIGreYCV)i$7zfS4*=g|D(8Iu5{5_{M)KA$1#?l#VJ+6R6`$S~vgO?AUX#B&$tv~%GZ$epn z2-nrc9W2%NT4qMp(|@8T4t^%%2e!bDQ(xDuHwL_0@#|`hKj9i}!13pD - - - - Debug - Win32 - - - Release - Win32 - - - - {3B52A2DE-8AF9-40F2-8CB3-9A91129FA2E7} - Win32Proj - vs2010express - - - - Application - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - true - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - true - true - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/vs2010express.vcxproj.filters b/trunk/Windows/project/vs2010express/vs2010express.vcxproj.filters deleted file mode 100644 index 37c27d537..000000000 --- a/trunk/Windows/project/vs2010express/vs2010express.vcxproj.filters +++ /dev/null @@ -1,36 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - - - Заголовочные файлы - - - Заголовочные файлы - - - - - Файлы иÑходного кода - - - Файлы иÑходного кода - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/vs2010express.vcxproj.user b/trunk/Windows/project/vs2010express/vs2010express.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/vs2010express.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc.vcproj b/trunk/Windows/project/vs2010express/xmlrpc.vcproj deleted file mode 100644 index b5804cf41..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc.vcproj +++ /dev/null @@ -1,770 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc.vcxproj deleted file mode 100644 index 350056b19..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc.vcxproj +++ /dev/null @@ -1,438 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc - {226AB06F-60CA-4B21-9040-C6ECC0581522} - libxmlrpc - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - NotSet - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - NotSet - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {40b0756d-afee-4a38-9f38-a372ce431404} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc.vcxproj.filters deleted file mode 100644 index 426f4daf9..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc.vcxproj.filters +++ /dev/null @@ -1,98 +0,0 @@ - - - - - {7ba6ba0b-5e14-4a4e-a655-a2117da5f14c} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc - - - {ace2259f-e281-4bac-a92d-05106c0956b7} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc__.vcproj b/trunk/Windows/project/vs2010express/xmlrpc__.vcproj deleted file mode 100644 index 4206b032a..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc__.vcproj +++ /dev/null @@ -1,2430 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc__.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc__.vcxproj deleted file mode 100644 index 70c37263d..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc__.vcxproj +++ /dev/null @@ -1,482 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc++ - {3E7064F3-6200-4C39-85BE-775931D21828} - xmlrpc++ - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {e98186cb-f1b0-40a6-87a5-77b13a3f1600} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc__.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc__.vcxproj.filters deleted file mode 100644 index a2bf2a8fb..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc__.vcxproj.filters +++ /dev/null @@ -1,140 +0,0 @@ - - - - - {e0ec1689-aae9-4f03-9c1a-d6af7b5e4786} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc - - - {1b40cc94-4f18-4dae-a340-9064f2748356} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc__.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc__.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc__.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcproj b/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcproj deleted file mode 100644 index 6e281ef78..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcproj +++ /dev/null @@ -1,2276 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj deleted file mode 100644 index 316cf96e2..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj +++ /dev/null @@ -1,472 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_abyss - {20A8F64B-F738-4D32-A798-A65AD8291541} - xmlrpc_abyss - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib %(AdditionalOptions) - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib %(AdditionalOptions) - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib %(AdditionalOptions) - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib %(AdditionalOptions) - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.filters deleted file mode 100644 index bee0fab2d..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.filters +++ /dev/null @@ -1,140 +0,0 @@ - - - - - {2fe8d434-30aa-44b1-9cab-5a05e3fd9da6} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {c891c99d-77cb-41ea-9015-c88ecce64065} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.user deleted file mode 100644 index 6e2aec7ae..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_abyss.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_client.vcproj b/trunk/Windows/project/vs2010express/xmlrpc_client.vcproj deleted file mode 100644 index e35fdb5dd..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_client.vcproj +++ /dev/null @@ -1,724 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj deleted file mode 100644 index 08844cb0c..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj +++ /dev/null @@ -1,428 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_client - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - libxmlrpc_client - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wininet.lib;%(AdditionalDependencies) - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wininet.lib;%(AdditionalDependencies) - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj.filters deleted file mode 100644 index 4432089b6..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj.filters +++ /dev/null @@ -1,62 +0,0 @@ - - - - - {da1113f6-bb68-4b77-bf28-50f90042f5ba} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc - - - {9379c908-e99b-4868-b75b-caa13139f18e} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_client.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server.vcproj b/trunk/Windows/project/vs2010express/xmlrpc_server.vcproj deleted file mode 100644 index 05e35f0d6..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server.vcproj +++ /dev/null @@ -1,708 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj deleted file mode 100644 index c82deea29..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj +++ /dev/null @@ -1,421 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_server - {74B67128-BC84-4BCB-A256-9286B6371552} - libxmlrpc_server - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj.filters deleted file mode 100644 index 8685df386..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj.filters +++ /dev/null @@ -1,53 +0,0 @@ - - - - - {98f0c562-c723-44d4-8265-509fc4d0793f} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc - - - {e560ea87-f609-4ffe-b12d-9048ef152de6} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcproj b/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcproj deleted file mode 100644 index ce02c2943..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcproj +++ /dev/null @@ -1,704 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj deleted file mode 100644 index 5b1ceb9a2..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj +++ /dev/null @@ -1,428 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_server_abyss - {E98186CB-F1B0-40A6-87A5-77B13A3F1600} - libxmlrpc_server_abyss - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.filters deleted file mode 100644 index 164423cfa..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.filters +++ /dev/null @@ -1,50 +0,0 @@ - - - - - {c6beca11-dace-4a60-9e79-68a2573517f8} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc - - - {a05de9d2-31db-4777-9b4a-22d71cca26b2} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_abyss.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcproj b/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcproj deleted file mode 100644 index 39e4ff289..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcproj +++ /dev/null @@ -1,696 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj deleted file mode 100644 index 2bc73f722..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj +++ /dev/null @@ -1,422 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_server_cgi - {A2AAAF37-F382-4A11-8D86-53B589921616} - libxmlrpc_server_cgi - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.filters deleted file mode 100644 index 6a577d5a3..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.filters +++ /dev/null @@ -1,44 +0,0 @@ - - - - - {eedbc6b9-1776-449c-b523-0272aadada5e} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc - - - {a3db0447-e924-4ba9-88e0-e957f7d46f12} - h;hpp;hxx;hm;inl - - - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_cgi.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcproj b/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcproj deleted file mode 100644 index 3029a8919..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcproj +++ /dev/null @@ -1,700 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj deleted file mode 100644 index 5081386ba..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj +++ /dev/null @@ -1,423 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_server_w32httpsys - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} - libxmlrpc_server_w32httpsys - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.filters deleted file mode 100644 index fb2577652..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.filters +++ /dev/null @@ -1,47 +0,0 @@ - - - - - {c8071e7f-a99b-4320-9b1a-7c6cc15eed44} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc - - - {c61ba18d-d4b1-4a4d-bd76-49583e5fb2d0} - h;hpp;hxx;hm;inl - - - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_server_w32httpsys.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_util.vcproj b/trunk/Windows/project/vs2010express/xmlrpc_util.vcproj deleted file mode 100644 index 259740242..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_util.vcproj +++ /dev/null @@ -1,764 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj deleted file mode 100644 index ab913a907..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj +++ /dev/null @@ -1,438 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_util - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - libxmlrpc_util - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - NotSet - true - $(OutDir)$(ProjectName).pdb - true - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - NotSet - true - $(OutDir)$(ProjectName).pdb - true - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - NotSet - true - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - NotSet - true - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj.filters deleted file mode 100644 index 0d8d717c6..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj.filters +++ /dev/null @@ -1,86 +0,0 @@ - - - - - {891eb28b-6895-4b33-8ddb-51d5c9a8be5f} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc - - - {deb57323-308f-49f5-b527-1760d95ab89f} - h;hpp;hxx;hm;inl - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj.user deleted file mode 100644 index f5e1823bd..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_util.vcxproj.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - false - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcproj b/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcproj deleted file mode 100644 index a7048291d..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcproj +++ /dev/null @@ -1,747 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj deleted file mode 100644 index fe888b734..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj +++ /dev/null @@ -1,413 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_xmlparse - {40B0756D-AFEE-4A38-9F38-A372CE431404} - xmlparse - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - MaxSpeed - OnlyExplicitInline - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - false - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - false - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib/util/include;../../../include;../../../lib/expat/xmltok;../../../lib/expat/xmlwf;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {bd9f6041-a272-462d-8c41-87cef1f11408} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.filters deleted file mode 100644 index 5125369c5..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.filters +++ /dev/null @@ -1,27 +0,0 @@ - - - - - {28aa86ac-4de8-468e-91f0-423092a981ef} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90 - - - {2c49a70c-181b-438a-b095-9edd602e690f} - h;hpp;hxx;hm;inl;fi;fd - - - {2afaacc0-9676-41dc-aba3-fe726ab15dfb} - ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe - - - - - Source Files - - - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.user deleted file mode 100644 index 2c48fb598..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_xmlparse.vcxproj.user +++ /dev/null @@ -1,6 +0,0 @@ - - - - true - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcproj b/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcproj deleted file mode 100644 index b6227a153..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcproj +++ /dev/null @@ -1,849 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj b/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj deleted file mode 100644 index 9986e3a88..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj +++ /dev/null @@ -1,415 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_xmltok - {BD9F6041-A272-462D-8C41-87CEF1F11408} - xmltok - - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - StaticLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - DynamicLibrary - v100 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26730.3 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - - - - Disabled - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - {99bd200e-a4d5-4ed4-9d00-a6a19efe1412} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.filters b/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.filters deleted file mode 100644 index 364e94ba7..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.filters +++ /dev/null @@ -1,51 +0,0 @@ - - - - - {1cad20ff-e903-4647-bb2c-fa93de37be3c} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90 - - - {0de6fd22-54e7-4338-82ac-f4fec07bde99} - h;hpp;hxx;hm;inl;fi;fd - - - {356469e0-2d7e-42fd-b712-57e23c58124c} - ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.user b/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.user deleted file mode 100644 index 695b5c78b..000000000 --- a/trunk/Windows/project/vs2010express/xmlrpc_xmltok.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/cpptest.vcxproj b/trunk/Windows/project/vs2017/cpptest.vcxproj deleted file mode 100644 index 21119857f..000000000 --- a/trunk/Windows/project/vs2017/cpptest.vcxproj +++ /dev/null @@ -1,562 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856} - cpptest - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - - /D INTERNAL_EXPAT %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - /D INTERNAL_EXPAT %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - /D INTERNAL_EXPAT %(AdditionalOptions) - Disabled - ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - /D INTERNAL_EXPAT %(AdditionalOptions) - Disabled - ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - /D INTERNAL_EXPAT %(AdditionalOptions) - Disabled - ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - /D INTERNAL_EXPAT %(AdditionalOptions) - Disabled - ../../../;../..;../../../include;../../../lib/util/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - /D INTERNAL_EXPAT %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - /D INTERNAL_EXPAT %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;CURL_STATICLIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {08cc5327-8e78-4768-9edb-c17649092ae1} - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {08cc5327-8e78-4768-9edb-c07649092ae1} - - - {3e7064f3-6200-4c39-85be-775931d21828} - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/gennmtab.vcxproj b/trunk/Windows/project/vs2017/gennmtab.vcxproj deleted file mode 100644 index 211ef60c5..000000000 --- a/trunk/Windows/project/vs2017/gennmtab.vcxproj +++ /dev/null @@ -1,539 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412} - gennmtab - - - - Application - v141 - false - - - Application - v141 - false - - - Application - v141 - false - - - Application - v141 - false - - - Application - v141 - false - - - Application - v141 - false - - - Application - v141 - false - - - Application - v141 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - true - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - true - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - true - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - true - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - true - MinimumRecommendedRules.ruleset - - - - - - $(OutDir)$(ProjectName).tlb - - - - Disabled - ../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - (D) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - X64 - $(OutDir)$(ProjectName).tlb - - - - Disabled - ../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - (D) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - $(OutDir)$(ProjectName).tlb - - - - MaxSpeed - OnlyExplicitInline - ../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - (R) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - X64 - $(OutDir)$(ProjectName).tlb - - - - MaxSpeed - OnlyExplicitInline - ../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - (R) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - $(OutDir)$(ProjectName).tlb - - - - Disabled - ../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - (D) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - X64 - $(OutDir)$(ProjectName).tlb - - - - Disabled - ../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - (D) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - $(OutDir)$(ProjectName).tlb - - - - MaxSpeed - OnlyExplicitInline - ../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - (R) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - X64 - $(OutDir)$(ProjectName).tlb - - - - MaxSpeed - OnlyExplicitInline - ../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0809 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - (R) Generating nametab.h ... - $(OutDir)$(ProjectName).exe >..\..\..\lib\expat\xmltok\nametab.h - - - - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/rpctest.vcxproj b/trunk/Windows/project/vs2017/rpctest.vcxproj deleted file mode 100644 index 2d49e5544..000000000 --- a/trunk/Windows/project/vs2017/rpctest.vcxproj +++ /dev/null @@ -1,614 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722} - rpctest - 10.0.14393.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $OutDir)\data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $OutDir)\data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $(OutDir)data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $(OutDir)data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $OutDir)\data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $OutDir)\data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $(OutDir)data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - Copy test files - if not exist $(OutDir)data md $(OutDir)data -copy ..\..\..\test\data\*.* $(OutDir)data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {e98186cb-f1b0-40a6-87a5-77b13a3f1600} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {40b0756d-afee-4a38-9f38-a372ce431404} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/sample_add_asynch_client.vcxproj b/trunk/Windows/project/vs2017/sample_add_asynch_client.vcxproj deleted file mode 100644 index fc4edec5a..000000000 --- a/trunk/Windows/project/vs2017/sample_add_asynch_client.vcxproj +++ /dev/null @@ -1,525 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652} - sample_add_asynch_client - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - odbc32.lib;odbccp32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - odbc32.lib;odbccp32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - WinInet.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/sample_add_server.vcxproj b/trunk/Windows/project/vs2017/sample_add_server.vcxproj deleted file mode 100644 index 517d109f5..000000000 --- a/trunk/Windows/project/vs2017/sample_add_server.vcxproj +++ /dev/null @@ -1,505 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {BEEB1B9C-BAF4-4B54-AB51-891156301702} - sample_add_server - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {e98186cb-f1b0-40a6-87a5-77b13a3f1600} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/sample_add_server_w32httpsys.vcxproj b/trunk/Windows/project/vs2017/sample_add_server_w32httpsys.vcxproj deleted file mode 100644 index 61fdc3e31..000000000 --- a/trunk/Windows/project/vs2017/sample_add_server_w32httpsys.vcxproj +++ /dev/null @@ -1,505 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {B6887828-9480-4D4D-9CFC-AE4980D41707} - sample_add_server_w32httpsys - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {0eecb080-fc8f-4c46-9fb7-5db22f9d1622} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/sample_add_sync_client.vcxproj b/trunk/Windows/project/vs2017/sample_add_sync_client.vcxproj deleted file mode 100644 index ca2c0d857..000000000 --- a/trunk/Windows/project/vs2017/sample_add_sync_client.vcxproj +++ /dev/null @@ -1,505 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710} - sample_add_sync_client - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/sample_auth_client.vcxproj b/trunk/Windows/project/vs2017/sample_auth_client.vcxproj deleted file mode 100644 index 9c364159f..000000000 --- a/trunk/Windows/project/vs2017/sample_auth_client.vcxproj +++ /dev/null @@ -1,505 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714} - sample_auth_client - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/tool_xmlrpc-transport.vcxproj b/trunk/Windows/project/vs2017/tool_xmlrpc-transport.vcxproj deleted file mode 100644 index a9270c6a3..000000000 --- a/trunk/Windows/project/vs2017/tool_xmlrpc-transport.vcxproj +++ /dev/null @@ -1,543 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - xmlrpc_transport - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942} - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/tool_xmlrpc.vcxproj b/trunk/Windows/project/vs2017/tool_xmlrpc.vcxproj deleted file mode 100644 index 7eb710d07..000000000 --- a/trunk/Windows/project/vs2017/tool_xmlrpc.vcxproj +++ /dev/null @@ -1,539 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - xmlrpc - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940} - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - Disabled - ../../../;../..;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - true - $(OutDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../..;../../../include;../../../lib/util/include;../../../;../../../lib/expat/xmlparse;../../../tools/lib/include;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;ABYSS_WIN32;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc.sln b/trunk/Windows/project/vs2017/xmlrpc.sln deleted file mode 100644 index 1ddb5c19a..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc.sln +++ /dev/null @@ -1,442 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.10 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmlparse", "xmlrpc_xmlparse.vcxproj", "{40B0756D-AFEE-4A38-9F38-A372CE431404}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_xmltok", "xmlrpc_xmltok.vcxproj", "{BD9F6041-A272-462D-8C41-87CEF1F11408}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennmtab", "gennmtab.vcxproj", "{99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_util", "xmlrpc_util.vcxproj", "{29FBABB6-E36A-4559-9514-B3DAF6AE1416}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc", "xmlrpc.vcxproj", "{226AB06F-60CA-4B21-9040-C6ECC0581522}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_abyss", "xmlrpc_abyss.vcxproj", "{20A8F64B-F738-4D32-A798-A65AD8291541}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server", "xmlrpc_server.vcxproj", "{74B67128-BC84-4BCB-A256-9286B6371552}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_abyss", "xmlrpc_server_abyss.vcxproj", "{E98186CB-F1B0-40A6-87A5-77B13A3F1600}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_cgi", "xmlrpc_server_cgi.vcxproj", "{A2AAAF37-F382-4A11-8D86-53B589921616}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_server_w32httpsys", "xmlrpc_server_w32httpsys.vcxproj", "{0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_client", "xmlrpc_client.vcxproj", "{28BB53D9-D487-41DF-BBB3-FDB5846D1630}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_asynch_client", "sample_add_asynch_client.vcxproj", "{2D4A179E-E2BA-4ED9-934E-7E54C08F1652}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server", "sample_add_server.vcxproj", "{BEEB1B9C-BAF4-4B54-AB51-891156301702}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_server_w32httpsys", "sample_add_server_w32httpsys.vcxproj", "{B6887828-9480-4D4D-9CFC-AE4980D41707}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_add_sync_client", "sample_add_sync_client.vcxproj", "{A7A81BBD-C84D-479A-A9BD-194ADA3B1710}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_auth_client", "sample_auth_client.vcxproj", "{29A2BBC4-9ED9-4162-817C-FEEB36FB1714}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpctest", "rpctest.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc++", "xmlrpc__.vcxproj", "{3E7064F3-6200-4C39-85BE-775931D21828}" - ProjectSection(ProjectDependencies) = postProject - {08CC5327-8E78-4768-9EDB-C07649092AE1} = {08CC5327-8E78-4768-9EDB-C07649092AE1} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpptest", "cpptest.vcxproj", "{26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}" - ProjectSection(ProjectDependencies) = postProject - {08CC5327-8E78-4768-9EDB-C07649092AE1} = {08CC5327-8E78-4768-9EDB-C07649092AE1} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc", "tool_xmlrpc.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmlrpc_transport", "tool_xmlrpc-transport.vcxproj", "{4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_util++", "xmlrpc_util__.vcxproj", "{08CC5327-8E78-4768-9EDB-C07649092AE1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxmlrpc_abyss++", "xmlrpc_abyss__.vcxproj", "{08CC5327-8E78-4768-9EDB-C17649092AE1}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug-DLL|Win32 = Debug-DLL|Win32 - Debug-DLL|x64 = Debug-DLL|x64 - Debug-Static|Win32 = Debug-Static|Win32 - Debug-Static|x64 = Debug-Static|x64 - Release-DLL|Win32 = Release-DLL|Win32 - Release-DLL|x64 = Release-DLL|x64 - Release-Static|Win32 = Release-Static|Win32 - Release-Static|x64 = Release-Static|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {40B0756D-AFEE-4A38-9F38-A372CE431404}.Release-Static|x64.Build.0 = Release-Static|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {BD9F6041-A272-462D-8C41-87CEF1F11408}.Release-Static|x64.Build.0 = Release-Static|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {99BD200E-A4D5-4ED4-9D00-A6A19EFE1412}.Release-Static|x64.Build.0 = Release-Static|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {29FBABB6-E36A-4559-9514-B3DAF6AE1416}.Release-Static|x64.Build.0 = Release-Static|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {226AB06F-60CA-4B21-9040-C6ECC0581522}.Release-Static|x64.Build.0 = Release-Static|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {20A8F64B-F738-4D32-A798-A65AD8291541}.Release-Static|x64.Build.0 = Release-Static|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {74B67128-BC84-4BCB-A256-9286B6371552}.Release-Static|x64.Build.0 = Release-Static|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {E98186CB-F1B0-40A6-87A5-77B13A3F1600}.Release-Static|x64.Build.0 = Release-Static|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {A2AAAF37-F382-4A11-8D86-53B589921616}.Release-Static|x64.Build.0 = Release-Static|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622}.Release-Static|x64.Build.0 = Release-Static|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {28BB53D9-D487-41DF-BBB3-FDB5846D1630}.Release-Static|x64.Build.0 = Release-Static|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {2D4A179E-E2BA-4ED9-934E-7E54C08F1652}.Release-Static|x64.Build.0 = Release-Static|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {BEEB1B9C-BAF4-4B54-AB51-891156301702}.Release-Static|x64.Build.0 = Release-Static|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {B6887828-9480-4D4D-9CFC-AE4980D41707}.Release-Static|x64.Build.0 = Release-Static|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {A7A81BBD-C84D-479A-A9BD-194ADA3B1710}.Release-Static|x64.Build.0 = Release-Static|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {29A2BBC4-9ED9-4162-817C-FEEB36FB1714}.Release-Static|x64.Build.0 = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1722}.Release-Static|x64.Build.0 = Release-Static|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {3E7064F3-6200-4C39-85BE-775931D21828}.Release-Static|x64.Build.0 = Release-Static|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {26FB3E14-7E0C-4B0C-AB1E-CFE4B48A1856}.Release-Static|x64.Build.0 = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1940}.Release-Static|x64.Build.0 = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {4CFB235E-56AE-4BF2-BE67-8FD4AF5F1942}.Release-Static|x64.Build.0 = Release-Static|x64 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {08CC5327-8E78-4768-9EDB-C07649092AE1}.Release-Static|x64.Build.0 = Release-Static|x64 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-Static|Win32.ActiveCfg = Debug-Static|Win32 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-Static|Win32.Build.0 = Debug-Static|Win32 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-Static|x64.ActiveCfg = Debug-Static|x64 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Debug-Static|x64.Build.0 = Debug-Static|x64 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-DLL|x64.Build.0 = Release-DLL|x64 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-Static|Win32.ActiveCfg = Release-Static|Win32 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-Static|Win32.Build.0 = Release-Static|Win32 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-Static|x64.ActiveCfg = Release-Static|x64 - {08CC5327-8E78-4768-9EDB-C17649092AE1}.Release-Static|x64.Build.0 = Release-Static|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/trunk/Windows/project/vs2017/xmlrpc.vcxproj b/trunk/Windows/project/vs2017/xmlrpc.vcxproj deleted file mode 100644 index 441a4d8f8..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc.vcxproj +++ /dev/null @@ -1,462 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc - {226AB06F-60CA-4B21-9040-C6ECC0581522} - libxmlrpc - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - NotSet - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - NotSet - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {40b0756d-afee-4a38-9f38-a372ce431404} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc__.vcxproj b/trunk/Windows/project/vs2017/xmlrpc__.vcxproj deleted file mode 100644 index fcbdbd4ee..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc__.vcxproj +++ /dev/null @@ -1,505 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc++ - {3E7064F3-6200-4C39-85BE-775931D21828} - xmlrpc++ - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {e98186cb-f1b0-40a6-87a5-77b13a3f1600} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {08cc5327-8e78-4768-9edb-c07649092ae1} - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_abyss.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_abyss.vcxproj deleted file mode 100644 index c746bbdf9..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_abyss.vcxproj +++ /dev/null @@ -1,494 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_abyss - {20A8F64B-F738-4D32-A798-A65AD8291541} - xmlrpc_abyss - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib %(AdditionalOptions) - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib %(AdditionalOptions) - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib %(AdditionalOptions) - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib %(AdditionalOptions) - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ..\..\..\;..\..\..\include;..\..\..\lib\util\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;ABYSS_WIN32;_THREAD;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_abyss__.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_abyss__.vcxproj deleted file mode 100644 index 06bf5ed7f..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_abyss__.vcxproj +++ /dev/null @@ -1,479 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_abyss++ - {08CC5327-8E78-4768-9EDB-C17649092AE1} - libxmlrpc_abyss++ - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSSPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSSPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSSPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_ABYSSPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {e98186cb-f1b0-40a6-87a5-77b13a3f1600} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {08cc5327-8e78-4768-9edb-c07649092ae1} - - - {3e7064f3-6200-4c39-85be-775931d21828} - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_client.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_client.vcxproj deleted file mode 100644 index 25d549a5c..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_client.vcxproj +++ /dev/null @@ -1,452 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_client - {28BB53D9-D487-41DF-BBB3-FDB5846D1630} - libxmlrpc_client - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wininet.lib;%(AdditionalDependencies) - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wininet.lib;%(AdditionalDependencies) - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_CLIENT;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_server.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_server.vcxproj deleted file mode 100644 index 1ad6427ad..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_server.vcxproj +++ /dev/null @@ -1,445 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_server - {74B67128-BC84-4BCB-A256-9286B6371552} - libxmlrpc_server - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_server_abyss.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_server_abyss.vcxproj deleted file mode 100644 index 664a313b5..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_server_abyss.vcxproj +++ /dev/null @@ -1,452 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_server_abyss - {E98186CB-F1B0-40A6-87A5-77B13A3F1600} - libxmlrpc_server_abyss - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_ABYSS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_server_cgi.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_server_cgi.vcxproj deleted file mode 100644 index 84599bc52..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_server_cgi.vcxproj +++ /dev/null @@ -1,446 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_server_cgi - {A2AAAF37-F382-4A11-8D86-53B589921616} - libxmlrpc_server_cgi - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_CGI;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_server_w32httpsys.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_server_w32httpsys.vcxproj deleted file mode 100644 index d192c9613..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_server_w32httpsys.vcxproj +++ /dev/null @@ -1,447 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_server_w32httpsys - {0EECB080-FC8F-4C46-9FB7-5DB22F9D1622} - libxmlrpc_server_w32httpsys - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_SERVER_HTTPSYS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - c:\Program Files (x86)\Microsoft SDKs\Windows\v5.0\Include\;../../../;../../../lib;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/wininet_transport;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_util.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_util.vcxproj deleted file mode 100644 index aae0bd3d4..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_util.vcxproj +++ /dev/null @@ -1,462 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_util - {29FBABB6-E36A-4559-9514-B3DAF6AE1416} - libxmlrpc_util - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - false - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - NotSet - true - $(OutDir)$(ProjectName).pdb - true - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - NotSet - true - $(OutDir)$(ProjectName).pdb - true - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - NotSet - true - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_UTIL;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;%(AdditionalDependencies) - NotSet - true - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../include;../../../lib/util/include;../../../lib/expat/xmlparse;../../../lib/wininet_transport;../../../lib/abyss/src;../../../lib/expat/xmlparse;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_util__.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_util__.vcxproj deleted file mode 100644 index a9b497592..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_util__.vcxproj +++ /dev/null @@ -1,475 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_util++ - {08CC5327-8E78-4768-9EDB-C07649092AE1} - xmlrpc++ - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBUTILPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBUTILPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBUTILPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;XMLRPC_BUILD_DLL;XMLRPC_BUILDING_LIBUTILPP;XMLRPC_BUILDING_CLIENTPP;XMLRPC_BUILDING_OLDCPPWRAPPER;XMLRPC_BUILDING_PACKETSOCKET;XMLRPC_BUILDING_SERVERPP;XMLRPC_BUILDING_SERVER_ABYSSPP;XMLRPC_BUILDING_SERVER_CGIPP;XMLRPC_BUILDING_SERVER_PSTREAMPP - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../lib;../../../lib/curl_transport;../../../lib/util/include;../../../include;../..;../../../lib/expat/xmlparse;../../../lib/abyss/src;../../../lib/wininet_transport;../../../;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_LIB;ABYSS_WIN32;CURL_STATICLIB - true - MultiThreadedDLL - true - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - {226ab06f-60ca-4b21-9040-c6ecc0581522} - false - - - {20a8f64b-f738-4d32-a798-a65ad8291541} - false - - - {28bb53d9-d487-41df-bbb3-fdb5846d1630} - false - - - {74b67128-bc84-4bcb-a256-9286b6371552} - false - - - {e98186cb-f1b0-40a6-87a5-77b13a3f1600} - false - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - - - - - - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_xmlparse.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_xmlparse.vcxproj deleted file mode 100644 index 9cb49d836..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_xmlparse.vcxproj +++ /dev/null @@ -1,437 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_xmlparse - {40B0756D-AFEE-4A38-9F38-A372CE431404} - xmlparse - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - MaxSpeed - OnlyExplicitInline - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - false - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - false - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib/util/include;../../../include;../../../lib/expat/xmltok;../../../lib/expat/xmlwf;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\;..\..\..\lib\util\include;..\..\..\include;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ..\..\..\lib\expat\xmltok;..\..\..\lib\expat\xmlwf;..\..\..\lib\util\include;..\..\..\include;..\..\..\;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_WINDOWS;XML_DTD;_LIB - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - {29fbabb6-e36a-4559-9514-b3daf6ae1416} - false - - - {bd9f6041-a272-462d-8c41-87cef1f11408} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/project/vs2017/xmlrpc_xmltok.vcxproj b/trunk/Windows/project/vs2017/xmlrpc_xmltok.vcxproj deleted file mode 100644 index 8399e9b80..000000000 --- a/trunk/Windows/project/vs2017/xmlrpc_xmltok.vcxproj +++ /dev/null @@ -1,439 +0,0 @@ - - - - - Debug-DLL - Win32 - - - Debug-DLL - x64 - - - Debug-Static - Win32 - - - Debug-Static - x64 - - - Release-DLL - Win32 - - - Release-DLL - x64 - - - Release-Static - Win32 - - - Release-Static - x64 - - - - libxmlrpc_xmltok - {BD9F6041-A272-462D-8C41-87CEF1F11408} - xmltok - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - DynamicLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.26228.10 - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - ..\..\..\bin\$(Configuration)-$(Platform)\ - ..\..\..\temp\$(Platform)\$(Configuration)\$(ProjectName)\ - MinimumRecommendedRules.ruleset - - - - - - Disabled - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;XMLRPC_BUILD_DLL;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(OutDir)$(ProjectName).pdb - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;XMLRPC_BUILD_DLL - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)$(ProjectName).lib - MachineX64 - - - true - $(IntDir)$(ProjectName).bsc - - - - - Disabled - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - EditAndContinue - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - Disabled - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - _DEBUG;WIN32;_WINDOWS;XML_DTD;XML_NS;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - ../../../;../../../lib/util/include;../../../include;%(AdditionalIncludeDirectories) - NDEBUG;XML_NS;WIN32;_WINDOWS;XML_DTD;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(ProjectName).pch - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - $(IntDir)$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - {99bd200e-a4d5-4ed4-9d00-a6a19efe1412} - false - - - - - - \ No newline at end of file diff --git a/trunk/Windows/socketpair.cpp b/trunk/Windows/socketpair.cpp deleted file mode 100644 index 77310eb58..000000000 --- a/trunk/Windows/socketpair.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include - - -int -xmlrpc_win32_socketpair(int const domain, - int const type, - int const protocol, - SOCKET socks[2]) { - bool error; - - error = false; // initial value - - SOCKET listener; - listener = socket(AF_INET, SOCK_STREAM, 0); - if (listener == INVALID_SOCKET) - error = true; - else { - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(0x7f000001); - addr.sin_port = 0; - - int rc; - rc = bind(listener, (const struct sockaddr*) &addr, sizeof(addr)); - if (rc == SOCKET_ERROR) - error = true; - else { - int addrlen; - int rc; - addrlen = sizeof(addr); // initial value - rc = getsockname(listener, (struct sockaddr*) &addr, &addrlen); - if (rc == SOCKET_ERROR) - error = true; - else { - int rc; - - rc = listen(listener, 1); - if (rc == SOCKET_ERROR) - error = true; - else { - socks[0] = socket(AF_INET, SOCK_STREAM, 0); - if (socks[0] == INVALID_SOCKET) - error = true; - else { - int rc; - rc = connect(socks[0], - (const struct sockaddr*) &addr, - sizeof(addr)); - if (rc == SOCKET_ERROR) - error = true; - else { - socks[1] = accept(listener, NULL, NULL); - if (socks[1] == INVALID_SOCKET) - error = true; - } - if (error) - closesocket(socks[0]); - } - } - } - } - closesocket(listener); - } - - return error ? -1 : 0; -} - - - - diff --git a/trunk/Windows/transport_config_win32.h b/trunk/Windows/transport_config_win32.h deleted file mode 100644 index 264216805..000000000 --- a/trunk/Windows/transport_config_win32.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Win32 version of transport_config.h. - - For other platforms, this is generated automatically, but for Windows, - someone generates it manually. Nonetheless, we keep it looking as much - as possible like the automatically generated one to make it easier to - maintain (e.g. you can compare the two and see why something builds - differently for Windows that for some other platform). -*/ -#define MUST_BUILD_WININET_CLIENT 1 -#define MUST_BUILD_CURL_CLIENT 0 -#define MUST_BUILD_LIBWWW_CLIENT 0 -static const char * const XMLRPC_DEFAULT_TRANSPORT = -"wininet"; diff --git a/trunk/Windows/updcfg.bat b/trunk/Windows/updcfg.bat deleted file mode 100644 index de699cc3c..000000000 --- a/trunk/Windows/updcfg.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo This will COPY the current config.h, xmlrpc_config.h, transprt_config.h, -@echo version.h, overwriting files in this 'Windows' folder! -@echo ARE YOU SURE YOU WANT TO DO THIS??? Ctrl+C to abort ... -@pause -copy ..\include\xmlrpc-c\config.h win32_config.h -copy ..\xmlrpc_config.h xmlrpc_win32_config.h -copy ..\transport_config.h transport_config_win32.h -@echo all done ... - diff --git a/trunk/Windows/win32_config.h b/trunk/Windows/win32_config.h deleted file mode 100644 index 7101fb994..000000000 --- a/trunk/Windows/win32_config.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef XMLRPC_C_CONFIG_H_INCLUDED -#define XMLRPC_C_CONFIG_H_INCLUDED - -/* This file, part of XML-RPC For C/C++, is meant to - define characteristics of this particular installation - that the other header files need in - order to compile correctly when #included in Xmlrpc-c - user code. - - Those header files #include this one. - - This file was created by a make rule. -*/ -#define XMLRPC_HAVE_WCHAR 1 -#ifdef WIN32 - /* SOCKET is a type defined by . Anyone who - uses XMLRPC_SOCKET on a WIN32 system must #include - - */ - #define XMLRPC_SOCKET SOCKET - #define XMLRPC_HAVE_TIMEVAL 0 - #define XMLRPC_HAVE_TIMESPEC 0 - #define XMLRPC_HAVE_PTHREAD 0 -#else - #define XMLRPC_SOCKET int - #define XMLRPC_HAVE_TIMEVAL 1 - #define XMLRPC_HAVE_TIMESPEC 1 - #define XMLRPC_HAVE_PTHREAD 1 -#endif - -#if defined(_MSC_VER) - /* Newer MSVC has long long, but MSVC 6 does not */ - #define XMLRPC_INT64 __int64 - #define XMLRPC_INT32 __int32 - #define XMLRPC_PRId64 PRId64 -#else - #define XMLRPC_INT64 long long - #define XMLRPC_INT32 int - #define XMLRPC_PRId64 "I64d" -#endif -#endif - diff --git a/trunk/Windows/xmlrpc_win32_config.h b/trunk/Windows/xmlrpc_win32_config.h deleted file mode 100644 index 9a9ecb18d..000000000 --- a/trunk/Windows/xmlrpc_win32_config.h +++ /dev/null @@ -1,275 +0,0 @@ -/* Win32 version of xmlrpc_config.h. - - For other platforms, this is generated automatically, but for Windows, - someone generates it manually. Nonetheless, we keep it looking as much - as possible like the automatically generated one to make it easier to - maintain (e.g. you can compare the two and see why something builds - differently for Windows than for some other platform). - - The purpose of this file is to define stuff particular to the build - environment being used to build Xmlrpc-c. Xmlrpc-c source files can - #include this file and have build-environment-independent source code. - - A major goal of this file is to reduce conditional compilation in - the other source files as much as possible. Even more, we want to avoid - having to generate source code particular to a build environment - except in this file. - - This file is NOT meant to be used by any code outside of the - Xmlrpc-c source tree. There is a similar file that gets installed - as that performs the same function for Xmlrpc-c - interface header files that get compiled as part of a user's program. - - Logical macros are 0 or 1 instead of the more traditional defined and - undefined. That's so we can distinguish when compiling code between - "false" and some problem with the code. -*/ - -#ifndef XMLRPC_CONFIG_H_INCLUDED -#define XMLRPC_CONFIG_H_INCLUDED - -/* From xmlrpc_amconfig.h */ - -#define HAVE__STRICMP 1 -#define HAVE__STRTOUI64 1 - -/* Name of package */ -#define PACKAGE "xmlrpc-c" -/*----------------------------------*/ - -#ifndef HAVE_SETGROUPS -#define HAVE_SETGROUPS 0 -#endif -#ifndef HAVE_ASPRINTF -#define HAVE_ASPRINTF 0 -#endif -#ifndef HAVE_SETENV -#define HAVE_SETENV 0 -#endif -#ifndef HAVE_PSELECT -#define HAVE_PSELECT 0 -#endif -#ifndef HAVE_WCSNCMP -#define HAVE_WCSNCMP 1 -#endif -#ifndef HAVE_GETTIMEOFDAY -#define HAVE_GETTIMEOFDAY 0 -#endif -#ifndef HAVE_LOCALTIME_R -#define HAVE_LOCALTIME_R 0 -#endif -#ifndef HAVE_GMTIME_R -#define HAVE_GMTIME_R 0 -#endif -#ifndef HAVE_STRCASECMP -#define HAVE_STRCASECMP 0 -#endif -#ifndef HAVE_STRICMP -#define HAVE_STRICMP 0 -#endif -#ifndef HAVE__STRICMP -#define HAVE__STRICMP 0 -#endif - -#define HAVE_WCHAR_H 1 -#define HAVE_SYS_FILIO_H 0 -#define HAVE_SYS_IOCTL_H 0 -#define HAVE_SYS_SELECT_H 0 - -#define VA_LIST_IS_ARRAY 0 - -#define HAVE_LIBWWW_SSL 0 - -/* Used to mark an unused function parameter */ -#define ATTR_UNUSED - -#define DIRECTORY_SEPARATOR "\\" - -#define HAVE_UNICODE_WCHAR 1 - -/* Xmlrpc-c code uses __inline__ to declare functions that should - be compiled as inline code. GNU C recognizes the __inline__ keyword. - Others recognize 'inline' or '__inline' or nothing at all to say - a function should be inlined. - - We could make 'configure' simply do a trial compile to figure out - which one, but for now, this approximation is easier: -*/ -#if (!defined(__GNUC__)) - #if (!defined(__inline__)) - #if (defined(__sgi) || defined(_AIX) || defined(_MSC_VER)) - #define __inline__ __inline - #else - #define __inline__ - #endif - #endif -#endif - -/* MSVCRT means we're using the Microsoft Visual C++ runtime library */ - -/* MSVCRT means we're using the Microsoft Visual C++ runtime library, - msvcrt.dll. Note that there are other DLLs in the suite, but only the - basic msvcrt.dll comes with Windows. -*/ - -#if defined(_MSC_VER) - /* The compiler is Microsoft Visual C++ */ - #define MSVCRT _MSC_VER -#elif defined(__MINGW32__) - /* The compiler is Mingw, which is the Windows version of the GNU - compiler. Programs built with this normally use the Microsoft Visual - C++ runtime library, in addition to a small library with some of the - things a program would expect to find on a GNU system: libmingwex.a. - */ - #define MSVCRT 1 -#else - #define MSVCRT 0 -#endif - -#if MSVCRT - /* The MSVC runtime library _does_ have a 'struct timeval', but it is - part of the Winsock interface (along with select(), which is probably - its intended use), so isn't intended for use for general timekeeping. - */ - #define HAVE_TIMEVAL 0 - #define HAVE_TIMESPEC 0 -#else - #define HAVE_TIMEVAL 1 - /* timespec is Posix.1b. If we need to work on a non-Posix.1b non-Windows - system, we'll have to figure out how to make Configure determine this. - */ - #define HAVE_TIMESPEC 1 -#endif - -#if MSVCRT - #define HAVE_WINDOWS_THREAD 1 -#else - #define HAVE_WINDOWS_THREAD 0 -#endif - -/* Some people have and use pthreads on Windows. See - http://sourceware.org/pthreads-win32 . For that case, we can set - HAVE_PTHREAD to 1. The builder prefers to use pthreads if it has - a choice. -*/ -#define HAVE_PTHREAD 0 - -/* Note that the return value of XMLRPC_[V]SNPRINTF is int on Windows, - ssize_t on POSIX. On Windows, it is a return code; on POSIX, the size - of the complete string (regardless of how much of it got returned). -*/ -#if MSVCRT - #define XMLRPC_SNPRINTF _snprintf - #define XMLRPC_VSNPRINTF _vsnprintf -#else - #define XMLRPC_SNPRINTF snprintf - #define XMLRPC_VSNPRINTF vsnprintf -#endif - -#if MSVCRT - #define HAVE_REGEX 0 -#else - #define HAVE_REGEX 1 -#endif - -#if MSVCRT - #define XMLRPC_SOCKETPAIR xmlrpc_win32_socketpair - #define XMLRPC_CLOSESOCKET closesocket -#else - #define XMLRPC_SOCKETPAIR socketpair - #define XMLRPC_CLOSESOCKET close -#endif - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -/* Starting with MSVC 8, the runtime library defines various POSIX functions - such as strdup() whose names violate the ISO C standard (the standard - says the strXXX names are reserved for the standard), but warns you of - the standards violation. That warning is 4996, along with other warnings - that tell you you're using a function that Microsoft thinks you - shouldn't. - - Well, POSIX is more important than that element of ISO C, so we disable - that warning. - - FYI, msvcrt also defines _strdup(), etc, which doesn't violate the - naming standard. But since other environments don't define _strdup(), - we can't use it in portable code. -*/ -#pragma warning(disable:4996) -#endif -/* Warning C4090 is "different 'const' qualifiers". - - We disable this warning because MSVC erroneously issues it when there is - in fact no difference in const qualifiers: - - const char ** p; - void * q; - q = p; - - Note that both p and q are pointers to non-const. - - We have seen this in MSVC 7.1, 8, and 9 (but not 6). -*/ -#pragma warning(disable:4090) - -#if HAVE_STRTOLL - # define XMLRPC_STRTOLL strtoll -#elif HAVE_STRTOQ - # define XMLRPC_STRTOLL strtoq /* Interix */ -#elif HAVE___STRTOLL - # define XMLRPC_STRTOLL __strtoll /* HP-UX <= 11.11 */ -#elif HAVE__STRTOUI64 - #define XMLRPC_STRTOLL _strtoui64 /* Windows MSVC */ -#endif - -#if HAVE_STRTOULL - # define XMLRPC_STRTOULL strtoull -#elif HAVE_STRTOUQ - # define XMLRPC_STRTOULL strtouq /* Interix */ -#elif HAVE___STRTOULL - # define XMLRPC_STRTOULL __strtoull /* HP-UX <= 11.11 */ -#elif HAVE__STRTOUI64 - #define XMLRPC_STRTOULL _strtoui64 /* Windows MSVC */ -#endif - -#if MSVCRT - #define popen _popen -#endif - -/* S_IRUSR is POSIX, defined in Some old BSD systems and Windows - systems have S_IREAD instead. Most Unix today (2011) has both. In 2011, - Android has S_IRUSR and not S_IREAD. - - Some Windows (2011) has _S_IREAD. - - We're ignoring S_IREAD now to see if anyone misses it. If there are still - users that need it, we can handle it here. -*/ -#if MSVCRT - #define XMLRPC_S_IWUSR _S_IWRITE - #define XMLRPC_S_IRUSR _S_IREAD -#else - #define XMLRPC_S_IWUSR S_IWUSR - #define XMLRPC_S_IRUSR S_IRUSR -#endif - - -#if MSVCRT - #define XMLRPC_CHDIR _chdir -#else - #define XMLRPC_CHDIR chdir -#endif - -#if MSVCRT - #define XMLRPC_FINITE _finite -#else - #define XMLRPC_FINITE finite -#endif - -#if MSVCRT - #define XMLRPC_GETPID _getpid -#else - #define XMLRPC_GETPID getpid -#endif - -#endif diff --git a/trunk/aclocal.m4 b/trunk/aclocal.m4 deleted file mode 100644 index 9f6a1252c..000000000 --- a/trunk/aclocal.m4 +++ /dev/null @@ -1,545 +0,0 @@ -dnl aclocal.m4 generated automatically by aclocal 1.4 - -dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl This program is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without -dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A -dnl PARTICULAR PURPOSE. - -# Like AC_CONFIG_HEADER, but automatically create stamp file. - -AC_DEFUN(AM_CONFIG_HEADER, -[AC_PREREQ([2.12]) -AC_CONFIG_HEADER([$1]) -dnl When config.status generates a header, we must update the stamp-h file. -dnl This file resides in the same directory as the config header -dnl that is generated. We must strip everything past the first ":", -dnl and everything past the last "/". -AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl -ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, -<>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, -<>; do - case " <<$>>CONFIG_HEADERS " in - *" <<$>>am_file "*<<)>> - echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx - ;; - esac - am_indx=`expr "<<$>>am_indx" + 1` -done<<>>dnl>>) -changequote([,]))]) - -# Do all the work for Automake. This macro actually does too much -- -# some checks are only needed if your package does certain things. -# But this isn't really a big deal. - -# serial 1 - -dnl Usage: -dnl AM_INIT_AUTOMAKE(package,version, [no-define]) - -AC_DEFUN(AM_INIT_AUTOMAKE, -[AC_REQUIRE([AC_PROG_INSTALL]) -PACKAGE=[$1] -AC_SUBST(PACKAGE) -VERSION=[$2] -AC_SUBST(VERSION) -dnl test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) -fi -ifelse([$3],, -AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) -AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) -AC_REQUIRE([AM_SANITY_CHECK]) -AC_REQUIRE([AC_ARG_PROGRAM]) -dnl FIXME This is truly gross. -missing_dir=`cd $ac_aux_dir && pwd` -AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) -AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) -AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) -AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) -AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) -AC_REQUIRE([AC_PROG_MAKE_SET])]) - -# -# Check to make sure that the build environment is sane. -# - -AC_DEFUN(AM_SANITY_CHECK, -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftestfile -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` - if test "[$]*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftestfile` - fi - if test "[$]*" != "X $srcdir/configure conftestfile" \ - && test "[$]*" != "X conftestfile $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "[$]2" = conftestfile - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -rm -f conftest* -AC_MSG_RESULT(yes)]) - -dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) -dnl The program must properly implement --version. -AC_DEFUN(AM_MISSING_PROG, -[AC_MSG_CHECKING(for working $2) -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if ($2 --version) < /dev/null > /dev/null 2>&1; then - $1=$2 - AC_MSG_RESULT(found) -else - $1="$3/missing $2" - AC_MSG_RESULT(missing) -fi -AC_SUBST($1)]) - - -# serial 40 AC_PROG_LIBTOOL -AC_DEFUN(AC_PROG_LIBTOOL, -[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl - -# Save cache, so that ltconfig can load it -AC_CACHE_SAVE - -# Actually configure libtool. ac_aux_dir is where install-sh is found. -CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ -LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ -LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \ -DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \ -${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ -$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \ -|| AC_MSG_ERROR([libtool configure failed]) - -# Reload cache, that may have been modified by ltconfig -AC_CACHE_LOAD - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -# Redirect the config.log output again, so that the ltconfig log is not -# clobbered by the next message. -exec 5>>./config.log -]) - -AC_DEFUN(AC_LIBTOOL_SETUP, -[AC_PREREQ(2.13)dnl -AC_REQUIRE([AC_ENABLE_SHARED])dnl -AC_REQUIRE([AC_ENABLE_STATIC])dnl -AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([AC_PROG_RANLIB])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_LD])dnl -AC_REQUIRE([AC_PROG_NM])dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -dnl - -case "$target" in -NONE) lt_target="$host" ;; -*) lt_target="$target" ;; -esac - -# Check for any special flags to pass to ltconfig. -# -# the following will cause an existing older ltconfig to fail, so -# we ignore this at the expense of the cache file... Checking this -# will just take longer ... bummer! -#libtool_flags="--cache-file=$cache_file" -# -test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" -test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" -test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" -test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" -test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" -ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], -[libtool_flags="$libtool_flags --enable-dlopen"]) -ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], -[libtool_flags="$libtool_flags --enable-win32-dll"]) -AC_ARG_ENABLE(libtool-lock, - [ --disable-libtool-lock avoid locking (might break parallel builds)]) -test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" -test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case "$lt_target" in -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case "`/usr/bin/file conftest.o`" in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; - -ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], -[*-*-cygwin* | *-*-mingw*) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -]) -esac -]) - -# AC_LIBTOOL_DLOPEN - enable checks for dlopen support -AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) - -# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's -AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) - -# AC_ENABLE_SHARED - implement the --enable-shared flag -# Usage: AC_ENABLE_SHARED[(DEFAULT)] -# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to -# `yes'. -AC_DEFUN(AC_ENABLE_SHARED, [dnl -define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE(shared, -changequote(<<, >>)dnl -<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], -changequote([, ])dnl -[p=${PACKAGE-default} -case "$enableval" in -yes) enable_shared=yes ;; -no) enable_shared=no ;; -*) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac], -enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl -]) - -# AC_DISABLE_SHARED - set the default shared flag to --disable-shared -AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_SHARED(no)]) - -# AC_ENABLE_STATIC - implement the --enable-static flag -# Usage: AC_ENABLE_STATIC[(DEFAULT)] -# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to -# `yes'. -AC_DEFUN(AC_ENABLE_STATIC, [dnl -define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE(static, -changequote(<<, >>)dnl -<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], -changequote([, ])dnl -[p=${PACKAGE-default} -case "$enableval" in -yes) enable_static=yes ;; -no) enable_static=no ;; -*) - enable_static=no - # Look at the argument we got. We use all the common list separators. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac], -enable_static=AC_ENABLE_STATIC_DEFAULT)dnl -]) - -# AC_DISABLE_STATIC - set the default static flag to --disable-static -AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_STATIC(no)]) - - -# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag -# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] -# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to -# `yes'. -AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl -define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE(fast-install, -changequote(<<, >>)dnl -<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], -changequote([, ])dnl -[p=${PACKAGE-default} -case "$enableval" in -yes) enable_fast_install=yes ;; -no) enable_fast_install=no ;; -*) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac], -enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl -]) - -# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install -AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_FAST_INSTALL(no)]) - -# AC_PROG_LD - find the path to the GNU or non-GNU linker -AC_DEFUN(AC_PROG_LD, -[AC_ARG_WITH(gnu-ld, -[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], -test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -ac_prog=ld -if test "$ac_cv_prog_gcc" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by GCC]) - ac_prog=`($CC -print-prog-name=ld) 2>&5` - case "$ac_prog" in - # Accept absolute paths. -changequote(,)dnl - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' -changequote([,])dnl - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(ac_cv_path_LD, -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - ac_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - ac_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$ac_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_PROG_LD_GNU -]) - -AC_DEFUN(AC_PROG_LD_GNU, -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 &5; then - ac_cv_prog_gnu_ld=yes -else - ac_cv_prog_gnu_ld=no -fi]) -]) - -# AC_PROG_NM - find the path to a BSD-compatible name lister -AC_DEFUN(AC_PROG_NM, -[AC_MSG_CHECKING([for BSD-compatible nm]) -AC_CACHE_VAL(ac_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - ac_cv_path_NM="$NM" -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - ac_cv_path_NM="$ac_dir/nm -B" - break - elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - ac_cv_path_NM="$ac_dir/nm -p" - break - else - ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - fi - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm -fi]) -NM="$ac_cv_path_NM" -AC_MSG_RESULT([$NM]) -]) - -# AC_CHECK_LIBM - check for math library -AC_DEFUN(AC_CHECK_LIBM, -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case "$lt_target" in -*-*-beos* | *-*-cygwin*) - # These system don't have libm - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, main, LIBM="-lm") - ;; -esac -]) - -# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for -# the libltdl convenience library and INCLTDL to the include flags for -# the libltdl header and adds --enable-ltdl-convenience to the -# configure arguments. Note that LIBLTDL and INCLTDL are not -# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not -# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed -# with '${top_builddir}/' and INCLTDL will be prefixed with -# '${top_srcdir}/' (note the single quotes!). If your package is not -# flat and you're not using automake, define top_builddir and -# top_srcdir appropriately in the Makefiles. -AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - case "$enable_ltdl_convenience" in - no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; - "") enable_ltdl_convenience=yes - ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; - esac - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la - INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) -]) - -# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for -# the libltdl installable library and INCLTDL to the include flags for -# the libltdl header and adds --enable-ltdl-install to the configure -# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is -# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed -# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will -# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed -# with '${top_srcdir}/' (note the single quotes!). If your package is -# not flat and you're not using automake, define top_builddir and -# top_srcdir appropriately in the Makefiles. -# In the future, this macro may have to be called after AC_PROG_LIBTOOL. -AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - AC_CHECK_LIB(ltdl, main, - [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], - [if test x"$enable_ltdl_install" = xno; then - AC_MSG_WARN([libltdl not installed, but installation disabled]) - else - enable_ltdl_install=yes - fi - ]) - if test x"$enable_ltdl_install" = x"yes"; then - ac_configure_args="$ac_configure_args --enable-ltdl-install" - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la - INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - else - ac_configure_args="$ac_configure_args --enable-ltdl-install=no" - LIBLTDL="-lltdl" - INCLTDL= - fi -]) - -dnl old names -AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl -AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl -AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl -AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl -AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl -AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl -AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl - -dnl This is just to silence aclocal about the macro not being used -ifelse([AC_DISABLE_FAST_INSTALL])dnl - diff --git a/trunk/common.mk b/trunk/common.mk deleted file mode 100644 index 68dcfdf52..000000000 --- a/trunk/common.mk +++ /dev/null @@ -1,814 +0,0 @@ -# This file contains rules and variable settings for the convenience -# of every other make file in the package. - -# No make file is required to use this file, but it usually saves a lot -# of duplication. - -# The following make variables are meaningful as input to this file: -# -# SRCDIR: Name of directory which is the top of the Xmlrpc-c source tree. -# BLDDIR: Name of directory which is the top of the Xmlrpc-c build tree. - -include $(SRCDIR)/version.mk - -XMLRPC_VERSION_STRING=\ -$(XMLRPC_MAJOR_RELEASE).$(XMLRPC_MINOR_RELEASE).$(XMLRPC_POINT_RELEASE) - -# .DELETE_ON_ERROR is a special predefined Make target that says to delete -# the target if a command in the rule for it fails. That's important, -# because we don't want a half-made target sitting around looking like it's -# fully made. -.DELETE_ON_ERROR: - -GCC_WARNINGS = -Wall -W -Wno-uninitialized -Wundef \ - -Wno-unknown-pragmas - # We need -Wwrite-strings after we fix all the missing consts - # - # -Wuninitialized catches some great bugs, but it also flags a whole lot - # of perfectly good code that can't be written any better. Too bad there's - # no way to annotate particular variables as being OK, so we could turn - # on -Wuninitialized for all the others. - -GCC_C_WARNINGS = $(GCC_WARNINGS) \ - -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wimplicit - -GCC_CXX_WARNINGS = $(GCC_WARNINGS) -Wsynth - -# Before 09.05.20, we had -Woverloaded-virtual, but it doesn't seem to do -# anything useful. It causes a warning that a method was hidden, but -# experiments show nothing is actually hidden. The GCC manual's description -# of what it does does not match empirical evidence. The option causes -# warnings when a derived class of xmlrpc_c::method2 overrides one of the -# execute() methods and not the other (as cpp/test/registry.cpp does), but the -# code works fine. - -# The NDEBUG macro says not build the code to assume there are no bugs. -# This makes the code go faster. The main thing it does is tell the C library -# to make assert() a no-op as opposed to generating code to check the -# assertion and crash the program if it isn't really true. You can add -# -UNDEBUG (in any of various ways) to override this. -# -CFLAGS_COMMON = -DNDEBUG $(CFLAGS_PTHREAD) -CXXFLAGS_COMMON = -DNDEBUG $(CFLAGS_PTHREAD) - -ifeq ($(C_COMPILER_GNU),yes) - CFLAGS_COMMON += $(GCC_C_WARNINGS) -fno-common -g -O3 -endif - -ifeq ($(CXX_COMPILER_GNU),yes) - CXXFLAGS_COMMON += $(GCC_CXX_WARNINGS) -g -endif - -# -qrtti tell the IBM compilers to allow dynamic type casting. Without it, -# code that has a dynamic type cast fails at run time. - -ifeq ($(CXX_COMPILER_IBM),yes) - CXXFLAGS_COMMON += -qrtti -endif - -DISTDIR = $(BLDDIR)/$(PACKAGE)-$(VERSION)/$(SUBDIR) - -# MIN is the minor version number for shared libraries. -# MAJ is the major version number, but is set separately by -# individual make files so that the major number of one library can change -# from one release to another while the major number of another does not. -MIN = $(XMLRPC_MINOR_RELEASE) - -# CURDIR was introduced in GNU Make 3.77. -ifeq ($(CURDIR)x,x) - CURDIR := $(shell /bin/pwd) -endif - -# The package XmlRpc++ on Sourceforge includes a library named -# libxmlrpc++ just as Xmlrpc-c does. To use them both, you may need -# to rename one. To rename the Xmlrpc-c one, set the make variable -# LIBXMLRPCPP_NAME, e.g. on the 'make' command line. - -ifeq ($(LIBXMLRPCPP_NAME),) - LIBXMLRPCPP_NAME := xmlrpc++ -endif - -ifneq ($(LADD),) -# We used to use make variable LADD, but now use the conventional LDFLAGS, -# for user-supplied additional link flags - LDFLAGS := $(LADD) -endif - -LDFLAGS_ALL = $(LDFLAGS_PTHREAD) $(LDFLAGS_PERSONAL) $(LDFLAGS) - -LDFLAGS_FOR_BUILD_ALL = \ - $(LDFLAGS_PTHREAD) $(LDFLAGS_PERSONAL) $(LDFLAGS_FOR_BUILD) - -############################################################################## -# STATIC LINK LIBRARY RULES # -############################################################################## - - -# To use this rule, the including make file must set a target-specific -# variable LIBOBJECTS (and declare dependencies that include LIBOBJECTS). -# Example: -# FOO_OBJECTS = foo1.o foo2.o -# libfoo.a: LIBOBJECTS = $(FOO_OBJECTS) -# libfoo.a: $(FOO_OBJECTS) -# TARGET_LIBRARY_NAMES = libfoo - -TARGET_STATIC_LIBRARIES = \ - $(TARGET_LIBRARY_NAMES:%=%.a) $(TARGET_LIB_NAMES_PP:%=%.a) -$(TARGET_STATIC_LIBRARIES): - -rm -f $@ - $(AR) cru $@ $(LIBOBJECTS) - $(RANLIB) $@ - - -############################################################################## -# SHARED LIBRARY RULES, VARIABLES # -############################################################################## - -ifeq ($(SHARED_LIB_TYPE),unix) - include $(SRCDIR)/unix-common.mk - endif - -ifeq ($(SHARED_LIB_TYPE),irix) - include $(SRCDIR)/irix-common.mk - endif - -ifeq ($(SHARED_LIB_TYPE),dll) - include $(SRCDIR)/dll-common.mk - endif - -ifeq ($(SHARED_LIB_TYPE),dylib) - include $(SRCDIR)/dylib-common.mk - endif - -ifeq ($(SHARED_LIB_TYPE),NONE) - install-shared-libraries: - endif - -# To use this rule, the including make file must set a target-specific -# variable LIBOBJECTS (and declare dependencies that include LIBOBJECTS). -# Analogous to static library rule above. - -# Optionally, including make file can set LIBDEP (probably -# target-specific) to the -L and -l options necessary to declare the -# libraries the target uses at run time. (This information gets built -# into the shared library so that the runtime library loader will load -# the specified libraries when asked to load the target library). - -ifeq ($(MUST_BUILD_SHLIB),Y) - TARGET_SHARED_LIBRARIES = $(call shlibfn, $(TARGET_LIBRARY_NAMES)) - TARGET_SHARED_LIBS_PP = $(call shlibfn, $(TARGET_LIB_NAMES_PP)) - ifeq ($(MUST_BUILD_SHLIBLE),Y) - TARGET_SHARED_LE_LIBS = \ - $(call shliblefn, $(TARGET_LIBRARY_NAMES) $(TARGET_LIB_NAMES_PP)) - else - TARGET_SHARED_LE_LIBS = - endif -else - TARGET_SHARED_LIBRARIES = - TARGET_SHARED_LIBS_PP = - TARGET_SHARED_LE_LIBS = -endif - -LDFLAGS_SHLIB_ALL=$(LDFLAGS_ALL) $(LDFLAGS_SHLIB) - -#------ the actual rules ---------------------------------------------------- -$(TARGET_SHARED_LIBRARIES) dummyshlib: - $(CCLD) $(LDFLAGS_SHLIB_ALL) $(LIBOBJECTS) $(LIBDEP) -o $@ - -$(TARGET_SHARED_LIBS_PP) dummyshlibpp: - $(CXXLD) $(LDFLAGS_SHLIB_ALL) $(LIBOBJECTS) $(LIBDEP) -o $@ -#---------------------------------------------------------------------------- - -LIBXMLRPC_UTIL_DIR = $(BLDDIR)/lib/libutil - -ifneq ($(OMIT_LIBXMLRPC_UTIL_RULE),Y) -LIBXMLRPC_UTIL = \ - $(call shliblefn, $(LIBXMLRPC_UTIL_DIR)/libxmlrpc_util) -LIBXMLRPC_UTIL_A = $(LIBXMLRPC_UTIL_DIR)/libxmlrpc_util.a -endif - -LIBXMLRPC_UTILPP_DIR = $(BLDDIR)/lib/libutil++ - -ifneq ($(OMIT_LIBXMLRPC_UTILPP_RULE),Y) -LIBXMLRPC_UTILPP = \ - $(call shliblefn, $(LIBXMLRPC_UTILPP_DIR)/libxmlrpc_util++) -LIBXMLRPC_UTILPP_A = $(LIBXMLRPC_UTILPP_DIR)/libxmlrpc_util++.a -endif - -ifneq ($(OMIT_XMLRPC_LIB_RULE),Y) - -LIBXMLRPC = \ - $(call shliblefn, $(BLDDIR)/src/libxmlrpc) -LIBXMLRPC_CLIENT = \ - $(call shliblefn, $(BLDDIR)/src/libxmlrpc_client) -LIBXMLRPC_SERVER = \ - $(call shliblefn, $(BLDDIR)/src/libxmlrpc_server) -LIBXMLRPC_SERVER_ABYSS = \ - $(call shliblefn, $(BLDDIR)/src/libxmlrpc_server_abyss) -LIBXMLRPC_SERVER_CGI = \ - $(call shliblefn, $(BLDDIR)/src/libxmlrpc_server_cgi) - -LIBXMLRPC_A = $(BLDDIR)/src/libxmlrpc.a -LIBXMLRPC_CLIENT_A = $(BLDDIR)/src/libxmlrpc_client.a -LIBXMLRPC_SERVER_A = $(BLDDIR)/src/libxmlrpc_server.a -LIBXMLRPC_SERVER_ABYSS_A = $(BLDDIR)/src/libxmlrpc_server_abyss.a -LIBXMLRPC_SERVER_CGI_A = $(BLDDIR)/src/libxmlrpc_server_cgi.a - -endif - -LIBXMLRPC_XMLTOK_DIR = $(BLDDIR)/lib/expat/xmltok - -ifneq ($(OMIT_XMLTOK_LIB_RULE),Y) -LIBXMLRPC_XMLTOK = \ - $(call shliblefn, $(LIBXMLRPC_XMLTOK_DIR)/libxmlrpc_xmltok) -LIBXMLRPC_XMLTOK_A = $(LIBXMLRPC_XMLTOK_DIR)/libxmlrpc_xmltok.a -endif - -LIBXMLRPC_XMLPARSE_DIR = $(BLDDIR)/lib/expat/xmlparse - -ifneq ($(OMIT_XMLPARSE_LIB_RULE),Y) -LIBXMLRPC_XMLPARSE = \ - $(call shliblefn, $(LIBXMLRPC_XMLPARSE_DIR)/libxmlrpc_xmlparse) -LIBXMLRPC_XMLPARSE_A = $(LIBXMLRPC_XMLPARSE_DIR)/libxmlrpc_xmlparse.a -endif - -LIBXMLRPC_ABYSS_DIR = $(BLDDIR)/lib/abyss/src - -ifneq ($(OMIT_ABYSS_LIB_RULE),Y) -LIBXMLRPC_ABYSS = \ - $(call shliblefn, $(LIBXMLRPC_ABYSS_DIR)/libxmlrpc_abyss) -LIBXMLRPC_ABYSS_A = $(LIBXMLRPC_ABYSS_DIR)/libxmlrpc_abyss.a -endif - -LIBXMLRPC_ABYSSPP_DIR = $(BLDDIR)/lib/abyss++ - -ifneq ($(OMIT_ABYSSPP_LIB_RULE),Y) -LIBXMLRPC_ABYSSPP = \ - $(call shliblefn, $(LIBXMLRPC_ABYSSPP_DIR)/libxmlrpc_abyss++) -LIBXMLRPC_ABYSSPP_A = $(LIBXMLRPC_ABYSSPP_DIR)/libxmlrpc_abyss++.a -endif - -LIBXMLRPC_CPP = \ - $(call shliblefn, $(BLDDIR)/src/cpp/libxmlrpc_cpp) -LIBXMLRPC_CPP_A = $(BLDDIR)/src/cpp/libxmlrpc_cpp.a -LIBXMLRPCPP = \ - $(call shliblefn, $(BLDDIR)/src/cpp/libxmlrpc++) -LIBXMLRPCPP_A = $(BLDDIR)/src/cpp/libxmlrpc++.a -LIBXMLRPC_PACKETSOCKET = \ - $(call shliblefn, $(BLDDIR)/src/cpp/libxmlrpc_packetsocket) -LIBXMLRPC_PACKETSOCKET_A = $(BLDDIR)/src/cpp/libxmlrpc_packetsocket.a -LIBXMLRPC_CLIENTPP = \ - $(call shliblefn, $(BLDDIR)/src/cpp/libxmlrpc_client++) -LIBXMLRPC_CLIENTPP_A = $(BLDDIR)/src/cpp/libxmlrpc_client++.a -LIBXMLRPC_SERVERPP = \ - $(call shliblefn, $(BLDDIR)/src/cpp/libxmlrpc_server++) -LIBXMLRPC_SERVERPP_A = $(BLDDIR)/src/cpp/libxmlrpc_server++.a -LIBXMLRPC_SERVER_ABYSSPP = \ - $(call shliblefn, $(BLDDIR)/src/cpp/libxmlrpc_server_abyss++) -LIBXMLRPC_SERVER_ABYSSPP_A = $(BLDDIR)/src/cpp/libxmlrpc_server_abyss++.a -LIBXMLRPC_SERVER_PSTREAMPP = \ - $(call shliblefn, $(BLDDIR)/src/cpp/libxmlrpc_server_pstream++) -LIBXMLRPC_SERVER_PSTREAMPP_A = $(BLDDIR)/src/cpp/libxmlrpc_server_pstream++.a - -# LIBXMLRPC_XML is the list of Xmlrpc-c libraries we need to parse -# XML. If we're using an external library to parse XML, this is null. -# LDLIBS_XML is the corresponding -L/-l options - -ifneq ($(ENABLE_LIBXML2_BACKEND),yes) - # We're using the internal Expat XML parser - LIBXMLRPC_XML = $(LIBXMLRPC_XMLPARSE) $(LIBXMLRPC_XMLTOK) - LDLIBS_XML = \ - -L$(BLDDIR)/lib/expat/xmlparse -lxmlrpc_xmlparse \ - -L$(BLDDIR)/lib/expat/xmltok -lxmlrpc_xmltok -else - LDLIBS_XML = $(shell xml2-config --libs) -endif - -# LIBXMLRPC_UTIL_LIBDEP is the string of linker options you need on the link -# of a shared library that refers to symbols in libxmlrpc_util. It tells -# the linker to record a dependency upon libxmlrpc_util in the shared library -# being built, and also dependencies on things on which libxmlrpc_util -# depends. You might think that the linker could get the latter out of -# libxmlrpc_util itself, but we have found (2012.12) that in a Mingw build -# it does not. - -LIBXMLRPC_UTIL_LIBDEP = -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util $(THREAD_LIBS) - -############################################################################## -# RULES TO BUILD OBJECT FILES TO LINK INTO LIBRARIES # -############################################################################## - -# The including make file sets TARGET_MODS to a list of all modules that -# might go into a library. Its a list of the bare module names. The -# including make file also sets INCLUDES, in a target-dependent manner, -# to the string of -I options needed for each target. Example: - -# TARGET_MODS = foo bar -# -# foo.o foo.osh: INCLUDES = -Iinclude -I/usr/include/foostuff -# bar.o bar.osh: INCLUDES = -Iinclude -I/usr/include/barstuff -# -# include common.mk -# -# The above generates rules to build foo.o, bar.o, foo.osh, and bar.osh -# -# For C++ source files, use TARGET_MODS_PP instead. - -# CFLAGS and CXXFLAGS are designed to be picked up as environment -# variables. The user may use them to add inclusion search directories -# (-I) or control 32/64 bitness or the like. Using these is always -# iffy, because the options one might include can interact in unpredictable -# ways with what the make file is trying to do. But at least some users -# get useful results. - -ifneq ($(CADD),) -# We used to use make variable CADD, but now use the conventional CFLAGS, -# for user-supplied additional link flags - CFLAGS := $(CADD) - CXXFLAGS := $(CADD) -endif - -CFLAGS_ALL = $(CFLAGS_COMMON) $(CFLAGS_LOCAL) $(CFLAGS_TARGET) \ - $(INCLUDES) $(CFLAGS_PERSONAL) $(CFLAGS) - -CFLAGS_ALL_FOR_BUILD = $(CFLAGS_COMMON) $(CFLAGS_LOCAL) $(CFLAGS_TARGET) \ - $(INCLUDES) $(CFLAGS_PERSONAL) $(CFLAGS_FOR_BUILD) - -CXXFLAGS_ALL = $(CXXFLAGS_COMMON) $(CFLAGS_LOCAL) $(CFLAGS_TARGET) \ - $(INCLUDES) $(CFLAGS_PERSONAL) $(CXXFLAGS) - - -$(TARGET_MODS:%=%.o):%.o:%.c - $(CC) -c -o $@ $(CFLAGS_ALL) $< - -$(TARGET_MODS:%=%.osh): CFLAGS_COMMON += $(CFLAGS_SHLIB) - -$(TARGET_MODS:%=%.osh):%.osh:%.c - $(CC) -c -o $@ $(INCLUDES) $(CFLAGS_ALL) $(CFLAGS_SHLIB) $< - -$(TARGET_MODS_PP:%=%.o):%.o:%.cpp - $(CXX) -c -o $@ $(INCLUDES) $(CXXFLAGS_ALL) $< - -$(TARGET_MODS_PP:%=%.osh): CXXFLAGS_COMMON += $(CFLAGS_SHLIB) - -$(TARGET_MODS_PP:%=%.osh):%.osh:%.cpp - $(CXX) -c -o $@ $(INCLUDES) $(CXXFLAGS_ALL) $< - - -############################################################################## -# MISC BUILD RULES # -############################################################################## - -# We use the srcdir symbolic link simply to make the make -# rules easier to read in the make output. We could use the $(SRCDIR) -# variable, but that makes the compile and link commands -# a mile long. Note that Make sometime figures that a directory which -# is a dependency is newer than the symbolic link pointing to it and wants -# to rebuild the symbolic link. So we don't make $(SRCDIR) a -# dependency of 'srcdir'. - -srcdir: - $(LN_S) $(SRCDIR) $@ -blddir: - $(LN_S) $(BLDDIR) $@ - -############################################################################## -# RECURSIVE SUBDIRECTORY BUILD RULES # -############################################################################## - -.PHONY: $(SUBDIRS:%=%/all) -$(SUBDIRS:%=%/all): %/all: $(CURDIR)/% - $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ - $(notdir $@) - -.PHONY: $(SUBDIRS:%=%/install) -$(SUBDIRS:%=%/install): %/install: $(CURDIR)/% - $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ - $(notdir $@) - -.PHONY: $(SUBDIRS:%=%/uninstall) -$(SUBDIRS:%=%/uninstall): %/uninstall: $(CURDIR)/% - $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ - $(notdir $@) - -.PHONY: $(SUBDIRS:%=%/clean) -$(SUBDIRS:%=%/clean): %/clean: $(CURDIR)/% - $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ - $(notdir $@) - -.PHONY: $(SUBDIRS:%=%/distclean) -$(SUBDIRS:%=%/distclean): %/distclean: $(CURDIR)/% - $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ - $(notdir $@) - -.PHONY: $(SUBDIRS:%=%/check) -$(SUBDIRS:%=%/check): %/check: $(CURDIR)/% - $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ - $(notdir $@) - -.PHONY: $(SUBDIRS:%=%/distdir) -$(SUBDIRS:%=%/distdir): %/distdir: $(CURDIR)/% - $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ - $(notdir $@) - -.PHONY: $(SUBDIRS:%=%/dep) -$(SUBDIRS:%=%/dep): %/dep: $(CURDIR)/% - $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ - $(notdir $@) - - -############################################################################## -# CROSS-COMPONENT BUILD RULES # -############################################################################## - -ifneq ($(OMIT_WININET_TRANSPORT_RULE),Y) -$(BLDDIR)/lib/wininet_transport/xmlrpc_wininet_transport.o \ -$(BLDDIR)/lib/wininet_transport/xmlrpc_wininet_transport.osh \ -: FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/wininet_transport/Makefile \ - $(notdir $@) -endif - -ifneq ($(OMIT_CURL_TRANSPORT_RULE),Y) -$(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport.o \ -$(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport.osh \ -$(BLDDIR)/lib/curl_transport/curltransaction.o \ -$(BLDDIR)/lib/curl_transport/curltransaction.osh \ -$(BLDDIR)/lib/curl_transport/curlmulti.o \ -$(BLDDIR)/lib/curl_transport/curlmulti.osh \ -$(BLDDIR)/lib/curl_transport/lock_pthread.o \ -$(BLDDIR)/lib/curl_transport/lock_pthread.osh \ -: FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/curl_transport/Makefile \ - $(notdir $@) -endif - -ifneq ($(OMIT_LIBWWW_TRANSPORT_RULE),Y) -$(BLDDIR)/lib/libwww_transport/xmlrpc_libwww_transport.o \ -$(BLDDIR)/lib/libwww_transport/xmlrpc_libwww_transport.osh \ -: FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/libwww_transport/Makefile \ - $(notdir $@) -endif - -$(LIBXMLRPC) \ -$(LIBXMLRPC_CLIENT) \ -$(LIBXMLRPC_SERVER) \ -$(LIBXMLRPC_SERVER_ABYSS) \ -$(LIBXMLRPC_SERVER_CGI) \ -$(LIBXMLRPC_A) \ -$(LIBXMLRPC_CLIENT_A) \ -$(LIBXMLRPC_SERVER_A) \ -$(LIBXMLRPC_SERVER_ABYSS_A) \ -$(LIBXMLRPC_SERVER_CGI_A): FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/src/Makefile \ - $(notdir $@) - -$(LIBXMLRPC_UTIL) $(LIBXMLRPC_UTIL_A) : FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/libutil/Makefile \ - $(notdir $@) - -$(LIBXMLRPC_UTILPP) $(LIBXMLRPC_UTILPP_A) : FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/libutil++/Makefile \ - $(notdir $@) - -$(LIBXMLRPC_XMLPARSE) $(LIBXMLRPC_XMLPARSE_A) : FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/expat/xmlparse/Makefile \ - $(notdir $@) - -$(LIBXMLRPC_XMLTOK) $(LIBXMLRPC_XMLTOK_A) : FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/expat/xmltok/Makefile \ - $(notdir $@) - -$(LIBXMLRPC_ABYSS) $(LIBXMLRPC_ABYSS_A): FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/abyss/src/Makefile \ - $(notdir $@) - -$(LIBXMLRPC_ABYSSPP) $(LIBXMLRPC_ABYSSPP_A): FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/abyss++/Makefile \ - $(notdir $@) - -ifneq ($(OMIT_CPP_LIB_RULES),Y) - -$(LIBXMLRPCPP) $(LIBXMLRPCPP_A) \ -$(LIBXMLRPC_PACKETSOCKET) $(LIBXMLRPC_PACKETSOCKET_A) \ -$(LIBXMLRPC_CLIENTPP) $(LIBXMLRPC_CLIENTPP_A) \ -$(LIBXMLRPC_SERVERPP) $(LIBXMLRPC_SERVERPP_A) \ -$(LIBXMLRPC_SERVER_ABYSSPP) $(LIBXMLRPC_SERVER_ABYSSPP_A) \ -$(LIBXMLRPC_SERVER_PSTREAMPP) $(LIBXMLRPC_SERVER_PSTREAMPP_A) \ -$(LIBXMLRPC_CPP) $(LIBXMLRPC_CPP_A) : FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/src/cpp/Makefile \ - $(notdir $@) -endif - -# For the following utilities, we don't bother with a library -- we -# just explicitly link the object file we need. This is to save -# complexity. If the list gets too big, we may need a library just to -# keep link commands short. - -UTIL_DIR = $(BLDDIR)/lib/util - -UTILS = \ - casprintf.o \ - cmdline_parser.o \ - cmdline_parser_cpp.o \ - getoptx.o \ - stripcaseeq.o \ - string_parser.o \ - -ifneq ($(OMIT_UTILS_RULE),Y) -$(UTILS:%=$(UTIL_DIR)/%): FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/lib/util/Makefile \ - $(notdir $@) -endif - -CASPRINTF = $(UTIL_DIR)/casprintf.o - - -# About version.h: This is a built header file, which means it is a supreme -# pain in the ass. The biggest problem is that when we automatically make -# dependencies (depend.mk), it doesn't exist yet. This means Gcc -# generates a dependency on it being in the local directory. Therefore, -# we generate it in the local directory, as a symbolic link, wherever it -# is needed. But the original is always in the top level directory, -# generated by a rule in that directory's make file. Problem 2 is that -# the top directory's make file includes common.mk, so the rules -# below conflict with it. That's what OMIT_VERSION_H is for. - -ifneq ($(OMIT_VERSION_H),Y) - -$(BLDDIR)/version.h: - $(MAKE) -C $(dir $@) -f $(SRCDIR)/GNUmakefile $(notdir $@) - -version.h: $(BLDDIR)/version.h - $(LN_S) $< $@ - -endif - -ifneq ($(OMIT_CONFIG_H_RULE),Y) -$(BLDDIR)/include/xmlrpc-c/config.h: - $(MAKE) -C $(BLDDIR)/include -f $(SRCDIR)/include/Makefile \ - xmlrpc-c/config.h -endif - -ifneq ($(OMIT_TRANSPORT_CONFIG_H),Y) -$(BLDDIR)/transport_config.h: - $(MAKE) -C $(dir $@) -f $(SRCDIR)/GNUmakefile $(notdir $@) -endif - -ifneq ($(OMIT_XMLRPC_C_CONFIG_TEST),Y) -$(BLDDIR)/xmlrpc-c-config.test: - $(MAKE) -C $(dir $@) -f $(SRCDIR)/GNUmakefile $(notdir $@) -endif - -$(TARGET_MODS:%=%.o) $(TARGET_MODS:%=%.osh) \ - $(TARGET_MODS_PP:%=%.o) $(TARGET_MODS_PP:%=%.osh): \ - $(BLDDIR)/include/xmlrpc-c/config.h - -ifneq ($(OMIT_XMLRPC_LIB_RULE),Y) -$(BLDDIR)/src/libxmlrpc_client.cflags: - $(MAKE) -C $(dir $@) -f $(SRCDIR)/src/Makefile $(notdir $@) -$(BLDDIR)/src/libxmlrpc_client.ldflags: - $(MAKE) -C $(dir $@) -f $(SRCDIR)/src/Makefile $(notdir $@) -endif - -# With a separate build directory, you have to make the directory itself -# before you can make anything in it. Here's the rule to do that. -$(SUBDIRS:%=$(CURDIR)/%): - mkdir $@ - - -LIBDESTDIR = $(DESTDIR)$(LIBINST_DIR) -HEADERDESTDIR = $(DESTDIR)$(HEADERINST_DIR) -PROGRAMDESTDIR = $(DESTDIR)$(PROGRAMINST_DIR) -MANDESTDIR = $(DESTDIR)$(MANINST_DIR) -PKGCONFIGDESTDIR = $(DESTDIR)$(PKGCONFIGINST_DIR) - - -############################################################################## -# INSTALL RULES # -# (except shared libraries) # -############################################################################## - -MKINSTALLDIRS = $(SHELL) $(SRCDIR)/mkinstalldirs - -.PHONY: install-common install-headers install-bin install-man -install-common: \ - install-static-libraries \ - install-shared-libraries \ - install-headers \ - install-bin \ - install-man \ - install-pkgconfig \ - -INSTALL_LIB_CMD = $(INSTALL_DATA) $$p $(LIBDESTDIR)/$$p -RANLIB_CMD = $(RANLIB) $(DESTDIR)$(LIBINST_DIR)/$$p - -install-static-libraries: $(STATIC_LIBRARIES_TO_INSTALL) - $(MKINSTALLDIRS) $(LIBDESTDIR) - @list='$(STATIC_LIBRARIES_TO_INSTALL)'; \ - for p in $$list; do \ - echo " $(INSTALL_LIB_CMD)"; \ - $(INSTALL_LIB_CMD); \ - done - @$(POST_INSTALL) - @list='$(STATIC_LIBRARIES_TO_INSTALL)'; \ - for p in $$list; do \ - echo " $(RANLIB_CMD)"; \ - $(RANLIB_CMD); \ - done - -INSTALL_HDR_CMD = $(INSTALL_DATA) $$p $(HEADERDESTDIR)/$$p - -install-headers: $(HEADERS_TO_INSTALL) - $(MKINSTALLDIRS) $(HEADERDESTDIR) - $(MKINSTALLDIRS) $(HEADERDESTDIR)/xmlrpc-c - @list='$(HEADERS_TO_INSTALL)'; \ - for p in $$list; do \ - echo " $(INSTALL_HDR_CMD)"; \ - $(INSTALL_HDR_CMD); \ - done - -INSTALL_PROGRAM_CMD = $(INSTALL_PROGRAM) $$p $(PROGRAMDESTDIR)/$$p - -install-bin: $(PROGRAMS_TO_INSTALL) $(DESTDIR)$(PROGRAMINST_DIR) - @list='$(PROGRAMS_TO_INSTALL)'; \ - for p in $$list; do \ - echo "$(INSTALL_PROGRAM_CMD)"; \ - $(INSTALL_PROGRAM_CMD); \ - done - -$(DESTDIR)$(PROGRAMINST_DIR): - $(MKINSTALLDIRS) $@ - -INSTALL_MAN_CMD = $(INSTALL_DATA) $$p $(MANDESTDIR)/$$p - -install-man: $(MAN_FILES_TO_INSTALL) - @list='$(MAN_FILES_TO_INSTALL)'; \ - for p in $$list; do \ - $(MKINSTALLDIRS) $(MANDESTDIR) \ - echo "$(INSTALL_MAN_CMD)"; \ - $(INSTALL_MAN_CMD); \ - done - -INSTALL_PKGCONFIG_CMD = $(INSTALL_DATA) $$p $(PKGCONFIGDESTDIR)/$$p - -install-pkgconfig: $(PKGCONFIG_FILES_TO_INSTALL) - $(MKINSTALLDIRS) $(PKGCONFIGDESTDIR) - @list='$(PKGCONFIG_FILES_TO_INSTALL)'; \ - for p in $$list; do \ - echo "$(INSTALL_PKGCONFIG_CMD)"; \ - $(INSTALL_PKGCONFIG_CMD); \ - done - - -############################################################################## -# UNINSTALL RULES # -############################################################################## - -RM = rm -f - -.PHONY: uninstall-common uninstall-headers uninstall-bin uninstall-man -uninstall-common: \ - uninstall-pkgconfig \ - uninstall-man \ - uninstall-bin \ - uninstall-headers \ - uninstall-shared-libraries \ - uninstall-static-libraries \ - -UNINSTALL_LIB_CMD = $(RM) $(LIBDESTDIR)/$$p - -uninstall-static-libraries: - @list='$(STATIC_LIBRARIES_TO_INSTALL)'; \ - for p in $$list; do \ - echo " $(UNINSTALL_LIB_CMD)"; \ - $(UNINSTALL_LIB_CMD); \ - done - -UNINSTALL_HDR_CMD = rm -f $(HEADERDESTDIR)/$$p - -uninstall-headers: - @list='$(HEADERS_TO_INSTALL)'; \ - for p in $$list; do \ - echo " $(UNINSTALL_HDR_CMD)"; \ - $(UNINSTALL_HDR_CMD); \ - done; - -UNINSTALL_PROGRAM_CMD = rm -f $(PROGRAMDESTDIR)/$$p - -uninstall-bin: - @list='$(PROGRAMS_TO_INSTALL)'; \ - for p in $$list; do \ - echo "$(UNINSTALL_PROGRAM_CMD)"; \ - $(UNINSTALL_PROGRAM_CMD); \ - done - -UNINSTALL_MAN_CMD = rm -f $(MANDESTDIR)/$$p - -uninstall-man: - @list='$(MAN_FILES_TO_INSTALL)'; \ - for p in $$list; do \ - echo "$(UNINSTALL_MAN_CMD)"; \ - $(UNINSTALL_MAN_CMD); \ - done - -UNINSTALL_PKGCONFIG_CMD = rm -f $(PKGCONFIGDESTDIR)/$$p - -uninstall-pkgconfig: - @list='$(PKGCONFIG_FILES_TO_INSTALL)'; \ - for p in $$list; do \ - echo "$(UNINSTALL_PKGCONFIG_CMD)"; \ - $(UNINSTALL_PKGCONFIG_CMD); \ - done - - -############################################################################## -# MISCELLANEOUS RULES # -############################################################################## - -.PHONY: clean-common -clean-common: - rm -f *.o *.osh *.a *.s *.i *.la *.lo *.cflags *.ldflags *.pc - rm -f *.$(SHLIB_SUFFIX) *.$(SHLIB_SUFFIX).* - rm -rf .libs -ifneq ($(OMIT_VERSION_H),Y) - rm -f version.h -endif - -.PHONY: distclean-common -distclean-common: -# depend.mk is generated by 'make dep' and contains only dependencies -# that make parts get _rebuilt_ when parts upon which they depend change. -# It does not contain dependencies that are necessary to cause a part to -# get built in the first place. E.g. if foo.c uses bar.h and bar.h gets built -# by a make rule, you must put the dependency of foo.c on bar.h somewhere -# besides depend.mk. -# -# Because of this, a user doesn't need depend.mk, because he -# doesn't modify source files. A developer, on the other hand, must make his -# own depend.mk, because 'make dep' creates depend.mk with -# absolute pathnames, specific to the developer's system. -# -# So we obliterate depend.mk here. The build will automatically -# create an empty depend.mk when it is needed for the user. The -# developer must do 'make dep' if he wants to edit and rebuild. -# -# Other projects have the build automatically build a true -# depend.mk, suitable for a developer. We have found that to be -# an utter disaster -- it's way too complicated and prone to failure, -# especially with built .h files. Better not to burden the user, who -# gains nothing from it, with that. -# - rm -f depend.mk - rm -f Makefile.depend # We used to create a file by this name - rm -f srcdir blddir - -.PHONY: distdir-common -distdir-common: - @for file in $(DISTFILES); do \ - d=$(SRCDIR); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(DISTDIR)/$$file; \ - else \ - test -f $(DISTDIR)/$$file \ - || ln $$d/$$file $(DISTDIR)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(DISTDIR)/$$file || :; \ - fi; \ - done - -DEP_SOURCES = $(wildcard *.c *.cpp) - -# This is a filter to turn "foo.o:" rules into "foo.o foo.lo foo.osh:" -# to make dependencies for all the various forms of object file out of -# a file made by a dependency generator that knows only about .o. - -DEPEND_MASSAGER = perl -walnpe's{^(.*)\.o:}{$$1.o $$1.lo $$1.osh:}' - - - -.PHONY: dep-common -dep-common: FORCE -ifneq ($(DEP_SOURCES)x,x) - -$(CC) -MM -MG -I. $(INCLUDES) $(DEP_SOURCES) | \ - $(DEPEND_MASSAGER) \ - >depend.mk -endif - -depend.mk: - cat /dev/null >$@ - -# The automatic dependency generation is a pain in the butt and -# totally unnecessary for people just installing the distributed code, -# so to avoid needless failures in the field and a complex build, the -# 'distclean' target simply makes depend.mk an empty file. A -# developer may do 'make dep' to create a depend.mk full of real -# dependencies. - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: - - -# Use the FORCE target as a dependency to force a target to get remade -FORCE: diff --git a/trunk/config.guess b/trunk/config.guess deleted file mode 100755 index c2246a4f7..000000000 --- a/trunk/config.guess +++ /dev/null @@ -1,1502 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 -# Free Software Foundation, Inc. - -timestamp='2009-12-30' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free -Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[456]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/trunk/config.mk.in b/trunk/config.mk.in deleted file mode 100644 index 725c0632f..000000000 --- a/trunk/config.mk.in +++ /dev/null @@ -1,457 +0,0 @@ -# config.mk is generated by 'configure' using config.mk.in -# as a template and information that 'configure' gathers from the build -# system and from user options. - -# config.mk should someday replace most of the other files that -# 'configure' generates, thus simplifying development and customization. -# config.mk is intended to contain information specific to the -# particular build environment or user build choices. - -# Furthermore, most of the logic in 'configure', and thus 'configure.in', -# should go into the make files to simplify the build. config.mk -# should just pass raw configure variables through to the make file. - -# Tokens of the form @TOKEN@ in the template file get replaced by -# 'configure' with the values of variables of the same name within -# 'configure', because of a AC_SUBST(TOKEN) statement in the -# 'configure.in' from which 'configure' was built. - -# Here are the options the user chose on 'configure': - -ENABLE_ABYSS_SERVER = @ENABLE_ABYSS_SERVER@ -ENABLE_ABYSS_THREADS = @ENABLE_ABYSS_THREADS@ -ENABLE_CPLUSPLUS = @ENABLE_CPLUSPLUS@ -ENABLE_CGI_SERVER = @ENABLE_CGI_SERVER@ -ENABLE_LIBXML2_BACKEND = @ENABLE_LIBXML2_BACKEND@ - -MUST_BUILD_WININET_CLIENT = @MUST_BUILD_WININET_CLIENT@ -MUST_BUILD_CURL_CLIENT = @MUST_BUILD_CURL_CLIENT@ -MUST_BUILD_LIBWWW_CLIENT = @MUST_BUILD_LIBWWW_CLIENT@ -MUST_BUILD_ABYSS_OPENSSL = @MUST_BUILD_ABYSS_OPENSSL@ -BUILD_TOOLS = @BUILD_TOOLS@ -BUILD_XMLRPC_PSTREAM = @BUILD_XMLRPC_PSTREAM@ -WININET_LDADD = @WININET_LDADD@ -WININET_LIBDIR = @WININET_LIBDIR@ -CURL_CONFIG = @CURL_CONFIG@ -CURL_LDADD = @CURL_LDADD@ -CURL_LIBDIR = @CURL_LIBDIR@ -LIBWWW_LDADD = @LIBWWW_LDADD@ -LIBWWW_LIBDIR = @LIBWWW_LIBDIR@ -FEATURE_LIST = @FEATURE_LIST@ -ABS_SRCDIR = @abs_srcdir@ -PREFIX = @prefix@ - - -HAVE_WCHAR_H_DEFINE = @HAVE_WCHAR_H_DEFINE@ - -# Stuff 'configure' figured out about our build platform: - -SHELL = @SHELL@ -CC = @CC@ -CXX = @CXX@ -CCLD = $(CC) -CXXLD = $(CXX) -AR = @AR@ -RANLIB = @RANLIB@ -LN_S = ln -s -INSTALL = $(SRCDIR)/install-sh - -C_COMPILER_GNU = @C_COMPILER_GNU@ -CXX_COMPILER_GNU = @CXX_COMPILER_GNU@ - -# Stuff 'configure' figured out via AC_CANONICAL_HOST macro in configure.in -# and config.guess program and 'configure' command options: - -# HOST_OS names the operating system on which Xmlrpc-c is to run. -# E.g. "linux-gnu". -HOST_OS = @host_os@ - -############################################################################### - -MUST_BUILD_CLIENT = no -ifeq ($(MUST_BUILD_WININET_CLIENT),yes) - MUST_BUILD_CLIENT = yes -endif -ifeq ($(MUST_BUILD_CURL_CLIENT),yes) - MUST_BUILD_CLIENT = yes -endif -ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) - MUST_BUILD_CLIENT = yes -endif - - -############################################################################## -# SHARED LIBRARY STUFF -############################################################################## - -# Shared libraries are very difficult, because how you build and use -# them varies greatly from one platform to the next. - -# First, we break down shared library schemes into a few major types, -# and indicate the type by SHARED_LIB_TYPE. - -# We also have a bunch of other make variables that reflect the different -# ways we have to build on and for different platforms: - -# CFLAGS_SHLIB is a set of flags needed to compile a module which will -# become part of a shared library. - -# On older systems, you have to make shared libraries out of position -# independent code, so you need -fpic or -fPIC here. (The rule is: if -# -fpic works, use it. If it bombs, go to -fPIC). On newer systems, -# it isn't necessary, but can save real memory at the expense of -# execution speed. Without position independent code, the library -# loader may have to patch addresses into the executable text. On an -# older system, this would cause a program crash because the loader -# would be writing into read-only shared memory. But on newer -# systems, the system silently creates a private mapping of the page -# or segment being modified (the "copy on write" phenomenon). So it -# needs its own private real page frame. - -# We have seen -fPIC required on IA64 and AMD64 machines (GNU -# compiler/linker). Build-time linking fails without it. I don't -# know why -- history seems to be repeating itself. 2005.02.23. - -# SHLIB_CLIB is the link option to include the C library in a shared library, -# normally "-lc". On typical systems, this serves no purpose. On some, -# though, it causes information about which C library to use to be recorded -# in the shared library and thus choose the correct library among several or -# avoid using an incompatible one. But on some systems, the link fails. -# On 2002.09.30, "John H. DuBois III" reports that on -# SCO OpenServer, he gets the following error message with -lc: -# -# -lc; relocations referenced ; from file(s) /usr/ccs/lib/libc.so(random.o); -# fatal error: relocations remain against allocatable but non-writable -# section: ; .text -# -# On Bryan's system, with gcc 2.95.3 and glibc 2.2.2, -lc causes -# throws (from anywhere in a program that links the shared library) -# not to work. I have no idea how. - -# LDFLAGS_SHLIB is the linker (Ld) flags needed to generate a shared -# library from object files. It may use $(SONAME) as the soname for -# the shared library being created (assuming sonames exist). -# -# This make file defines these functions that the including make file -# can use: -# -# $(call shlibfn, LIBNAMELIST): file names of shared libraries -# whose base names are LIBNAMELIST. E.g. if LIBNAMELIST is -# "libfoo libbar", function returns "libfoo.so.3.1 libbar.so.3.1" -# -# $(call shliblefn, LIBNAMELIST): same as shlibfn, but for the file you -# use at link-edit time. E.g. libfoo.so . - -# NEED_RPATH says on this platform, when you link-edit an executable you -# need to have -R linker options to tell where to look, at run time, -# for the shared libraries that the program uses. The linker puts that -# information into the executable. - -# NEED_WL_RPATH is like NEED_RPATH, but it's a compiler option for when -# you have the compiler call the linker. So E.g. "-Wl,-rpath,/my/runtime", -# which tells the compiler to pass the option "-rpath /my/runtime" to -# the linker. - -# Defaults: -NEED_WL_RPATH=no -NEED_RPATH=no - -# We build shared libraries only for platforms for which we've figured -# out how. For the rest, we have this default: -SHARED_LIB_TYPE = NONE -MUST_BUILD_SHLIB = N -MUST_BUILD_SHLIBLE = N -shlibfn = $(1:%=%.shlibdummy) -shliblefn = $(1:%=%.shlibledummy) - -# HOST_OS is usually has a version number suffix, e.g. "aix5.3.0.0", so -# we compare based on prefix. - -ifeq ($(patsubst linux-%,linux-,$(HOST_OS)),linux-) - # Examples we've seen that work here are linux-gnuXXX and linux-uclibcXXX - # Assume linker is GNU Compiler (gcc) - SHARED_LIB_TYPE = unix - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - SHLIB_SUFFIX = so - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) -# SHLIB_CLIB = -lc - LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB) - CFLAGS_SHLIB=-fPIC -endif - -ifeq ($(patsubst solaris%,solaris,$(HOST_OS)),solaris) - SHARED_LIB_TYPE = unix - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - SHLIB_SUFFIX = so - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - # We assume Sun compiler and linker here. It isn't clear what to do - # about a user who uses GNU compiler and Ld instead. For that, the - # options should be the same as "linux-gnu" platform, above, except - # with NEED_WL_RPATH. If the user uses the GNU compiler but the Sun - # linker, it's even more complicated: we need an rpath option of the - # form -Wl,-R . - - # Solaris compiler (Sun C 5.5) can't take multiple ld options as - # -Wl,-a,-b . Ld sees -a,-b in that case. - LDFLAGS_SHLIB = -Wl,-Bdynamic -Wl,-G -Wl,-h -Wl,$(SONAME) - CFLAGS_SHLIB = -Kpic - NEED_RPATH=yes -endif - -ifeq ($(patsubst aix%,aix,$(HOST_OS)),aix) - SHARED_LIB_TYPE = unix - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y -# AIX can use a classic .a archive file as a shared library, and that is -# how e.g. libc works. But as of late, it also can use an XCOFF file with -# the shared flag set, with the conventional suffix .so. We build our library -# that way to avoid confusion with .a static link libraries. - SHLIB_SUFFIX = so - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - # -brtl says "rtl option". rtl option says to allow runtime linking, which - # means that the link editor can use a share object (.so) file instead of an - # archive (.a) file and build the library to link to that shared object at - # runtime. Without -brtl, the link editor ignores .so files. One thing - # that is typically a .so file is the Curl library. - LDFLAGS_SHLIB = -qmkshrobj -brtl - ifeq ($(C_COMPILER_GNU), no) - C_COMPILER_IBM = yes - CXX_COMPILER_IBM = yes - endif -endif - -ifeq ($(patsubst hpux%,hpux,$(HOST_OS)),hpux) - SHARED_LIB_TYPE = unix - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - SHLIB_SUFFIX = sl - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - LDFLAGS_SHLIB: -shared -fPIC -endif - -ifeq ($(patsubst osf%,osf,$(HOST_OS)),osf) - SHARED_LIB_TYPE = unix - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - SHLIB_SUFFIX = so - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - LDFLAGS_SHLIB = -shared -expect_unresolved -endif - -ifeq ($(patsubst netbsd%,netbsd,$(HOST_OS)),netbsd) - SHARED_LIB_TYPE = unix - SHLIB_SUFFIX = so - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - CFLAGS_SHLIB = -fpic - LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB) - NEED_WL_RPATH=yes -endif - -ifeq ($(patsubst freebsd%,freebsd,$(HOST_OS)),freebsd) - SHARED_LIB_TYPE = unix - SHLIB_SUFFIX = so - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - CFLAGS_SHLIB = -fpic - LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB) - NEED_WL_RPATH=yes -endif - -ifeq ($(findstring interix,$(HOST_OS)),interix) - SHARED_LIB_TYPE = unix - SHLIB_SUFFIX = so - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - CFLAGS_SHLIB = - LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB) - NEED_WL_RPATH=yes -endif - -ifeq ($(patsubst dragonfly%,dragonfly,$(HOST_OS)),dragonfly) - SHARED_LIB_TYPE = unix - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - SHLIB_SUFFIX = so - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - CFLAGS_SHLIB = -fpic - LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB) -endif - -ifeq ($(patsubst beos%,beos,$(HOST_OS)),beos) - SHARED_LIB_TYPE = unix - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - SHLIB_SUFFIX = so - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ).$(MIN)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - LDFLAGS_SHLIB = -nostart -endif - -ifeq ($(patsubst darwin%,darwin,$(HOST_OS)),darwin) - SHARED_LIB_TYPE = dylib - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - SHLIB_SUFFIX = dylib - shlibfn = $(1:%=%.$(MAJ).$(MIN).$(SHLIB_SUFFIX)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - LDFLAGS_SHLIB = -dynamiclib -undefined suppress -single_module \ - -flat_namespace -install_name $(LIBINST_DIR)/$(SONAME) $(SHLIB_CLIB) -endif - -ifeq ($(patsubst irix%,irix,$(HOST_OS)),irix) - SHARED_LIB_TYPE = irix - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = Y - SHLIB_SUFFIX = so - shlibfn = $(1:%=%.$(SHLIB_SUFFIX).$(MAJ)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - - VERSIONPERLPROG = \ - print "sgi$(MAJ)." . join(":sgi$(MAJ) . ", (0..$(MIN))) . "\n" - LDFLAGS_SHLIB = -shared -n32 -soname $(SONAME) \ - -set_version $(shell perl -e '$(VERSIONPERLPROG)') -lc -endif - -ifeq ($(patsubst cygwin%,cygwin,$(HOST_OS)),cygwin) - SHARED_LIB_TYPE = dll - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = N - SHLIB_SUFFIX = dll - shlibfn = $(1:%=%.$(SHLIB_SUFFIX)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB) -endif - -ifeq ($(patsubst mingw32%,mingw32,$(HOST_OS)),mingw32) - SHARED_LIB_TYPE = dll - MUST_BUILD_SHLIB = Y - MUST_BUILD_SHLIBLE = N - SHLIB_SUFFIX = dll - shlibfn = $(1:%=%.$(SHLIB_SUFFIX)) - shliblefn = $(1:%=%.$(SHLIB_SUFFIX)) - LDFLAGS_SHLIB = -shared -Wl,-soname,$(SONAME) $(SHLIB_CLIB) - MSVCRT = yes -endif - -ifeq ($(patsubst mingw32%,mingw32,$(HOST_OS)),mingw32) - SOCKETLIBOPT = -lws2_32 -lwsock32 -else - SOCKETLIBOPT = @LSOCKET@ -endif - -############################################################################## -# MISCELLANEOUS -############################################################################## - -# CC_FOR_BUILD is the compiler to use to generate build tools, which we -# will then run to build the product. The typical reason this would be -# different from CC is that you're cross-compiling: the product will run -# in Environment A, but you're building in Environment B, so you must -# build the build tools for Environment B. - -# The build system uses CC_FOR_BUILD for linking as well. - -# The build system use CFLAGS_FOR_BUILD and LDFLAGS_FOR_BUILD when compiling -# and linking, respectively, build tools. - -# The cross compiling user can update config.mk or override -# CC_FOR_BUILD on a make command. - -# LDFLAGS_FOR_BUILD is similar - -# These variable names are conventional. - -CC_FOR_BUILD = $(CC) -CFLAGS_FOR_BUILD = $(CFLAGS) -LDFLAGS_FOR_BUILD = $(LDFLAGS) - - -ifeq ($(C_COMPILER_GNU),yes) - CFLAGS_NO_INLINE_WARNING = -Wno-inline -else - CFLAGS_NO_INLINE_WARNING = -endif - -# Today, we use make files only on systems that have pthreads (libpthread), -# so the following is hardcoded. But it is conceivable that we could later -# use make files on something that doesn't, like some Windows environment. -HAVE_PTHREAD = yes -# Much of our code uses pthreads and some code that doesn't use them directly -# needs them anyway because it uses libraries that are meant to work with othe -# code that does. So we build everything with pthread capability. -# -# On some systems, that just means we have to link a pthread library. But -# on other systems, it is more involved and the compiler and linker have a -# -pthread option to take care of everything, including linking whatever -# libraries are required. -ifeq ($(C_COMPILER_GNU),yes) - # We assume the linker is GCC as well. - CFLAGS_PTHREAD = -pthread - LDFLAGS_PTHREAD = -pthread - THREAD_LIBS = -else - CFLAGS_PTHREAD = - LDFLAGS_PTHREAD = - THREAD_LIBS = -lpthread -endif - -# Here are the commands 'make install' uses to install various kinds of files: - -INSTALL_PROGRAM ?= $(INSTALL) -c -m 755 -INSTALL_SHLIB ?= $(INSTALL) -c -m 755 -INSTALL_DATA ?= $(INSTALL) -c -m 644 -INSTALL_SCRIPT ?= $(INSTALL) -c -m 755 - -# Here are the locations at which 'make install' puts files: - -# PREFIX is designed to be overridden at make time if the user decides -# he doesn't like the default specified at 'configure' time. - -prefix = $(PREFIX) -datarootdir = $(DATAROOT_DIR) - -#datarootdir is the new Autoconf(2.60) name for datadir, which is still -#accepted, but a warning is issued if datarootdir is not also used. - -exec_prefix = @exec_prefix@ -DATAROOT_DIR = @datarootdir@ -DATAINST_DIR = @datadir@ -LIBINST_DIR = @libdir@ -HEADERINST_DIR = @includedir@ -PROGRAMINST_DIR = @bindir@ -MANINST_DIR = @mandir@/man1 -PKGCONFIGINST_DIR = @libdir@/pkgconfig - -# DESTDIR is designed to be overridden at make time in order to relocate -# the entire install into a subdirectory. -DESTDIR = - -# VPATH probably doesn't belong in this file, but it's a convenient -# place to set it once. VPATH is a special Make variable that tells -# Make where to look for dependencies. E.g. if a make file says bar.c -# is a dependency of bar.o and VPATH is ".:/usr/src/mypkg", Make will -# look for bar.c first in the current directory (.) (as it would with -# no VPATH), then in /usr/src/mypkg. The purpose of this is to allow -# you to build in a fresh build directory, while your source stays in -# the read-only directory /usr/src/mypkg . - -VPATH := .:$(SRCDIR)/$(SUBDIR) - -HAVE_OPENSSL = @HAVE_OPENSSL@ -OPENSSL_LDADD = @OPENSSL_LDADD@ -OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ diff --git a/trunk/config.sub b/trunk/config.sub deleted file mode 100755 index c2d125724..000000000 --- a/trunk/config.sub +++ /dev/null @@ -1,1714 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 -# Free Software Foundation, Inc. - -timestamp='2010-01-22' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free -Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ - uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nios | nios2 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e \ - | we32k \ - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | picochip) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile-* | tilegx-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze) - basic_machine=microblaze-xilinx - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - # This must be matched before tile*. - tilegx*) - basic_machine=tilegx-unknown - os=-linux-gnu - ;; - tile*) - basic_machine=tile-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/trunk/configure b/trunk/configure deleted file mode 100755 index 472723a4d..000000000 --- a/trunk/configure +++ /dev/null @@ -1,7505 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= -PACKAGE_URL= - -ac_unique_file="include/xmlrpc-c/base.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='LTLIBOBJS -LIBOBJS -RANLIB -AR -BUILDDIR -CPP_WARN_FLAGS -CC_WARN_FLAGS -CXX_COMPILER_GNU -C_COMPILER_GNU -ENABLE_LIBXML2_BACKEND -have_xml2_config -HAVE_LIBWWW_SSL_DEFINE -HAVE_ABYSS_OPENSSL_DEFINE -MUST_BUILD_ABYSS_OPENSSL -OPENSSL_CFLAGS -OPENSSL_LDADD -CURL_LIBDIR -CURL_LDADD -CURL_CONFIG -LIBWWW_LIBDIR -LIBWWW_LDADD -LIBWWW_CONFIG -WININET_LIBDIR -WININET_LDADD -WININET_CFLAGS -WININET_CONFIG -ENABLE_ABYSS_THREADS -DIRECTORY_SEPARATOR -HAVE__STRICMP_DEFINE -HAVE_STRICMP_DEFINE -HAVE_STRCASECMP_DEFINE -HAVE_GMTIME_R_DEFINE -HAVE_LOCALTIME_R_DEFINE -HAVE_GETTIMEOFDAY_DEFINE -HAVE_PSELECT_DEFINE -HAVE__STRTOUI64_DEFINE -HAVE___STRTOULL_DEFINE -HAVE___STRTOLL_DEFINE -HAVE_STRTOUQ_DEFINE -HAVE_STRTOQ_DEFINE -HAVE_STRTOULL_DEFINE -HAVE_STRTOLL_DEFINE -HAVE_SETENV_DEFINE -HAVE_ASPRINTF_DEFINE -HAVE_SETGROUPS_DEFINE -HAVE_WCSNCMP_DEFINE -ATTR_UNUSED -VA_LIST_IS_ARRAY_DEFINE -HAVE_SYS_SELECT_H_DEFINE -HAVE_SYS_IOCTL_H_DEFINE -HAVE_SYS_FILIO_H_DEFINE -HAVE_WCHAR_H_DEFINE -EGREP -GREP -CPP -LSOCKET -ac_ct_CXX -CXXFLAGS -CXX -FEATURE_LIST -XML_RPC_API2CPP_SUBDIR -XMLRPCCPP_H -CPPTEST -LIBXMLRPC_CPP_A -ENABLE_CPLUSPLUS -ENABLE_CGI_SERVER -SERVER -XMLRPC_ABYSS_H -VALIDATEE -SERVERTEST -ABYSS_SUBDIR -ENABLE_ABYSS_SERVER -QUERY_MEERKAT -AUTH_CLIENT -ASYNCH_CLIENT -SYNCH_CLIENT -XMLRPC_TRANSPORT_H -XMLRPC_CLIENT_H -CLIENTTEST -BUILD_XMLRPC_PSTREAM -BUILD_TOOLS -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -MUST_BUILD_LIBWWW_CLIENT -have_libwww_config -MUST_BUILD_CURL_CLIENT -have_curl_config -MUST_BUILD_WININET_CLIENT -have_wininet_config -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -SET_MAKE -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_wininet_client -enable_curl_client -enable_libwww_client -enable_abyss_server -enable_cgi_server -enable_cplusplus -enable_abyss_threads -enable_abyss_openssl -with_libwww_ssl -enable_libxml2_backend -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CXX -CXXFLAGS -CCC -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-wininet-client Don't build the Wininet client transport - --disable-curl-client Don't build the Curl client transport - --disable-libwww-client Don't build the Libwww client transport - --disable-abyss-server Don't build the Abyss server module - --disable-cgi-server Don't build the CGI server module - --disable-cplusplus Don't build the C++ wrapper classes or tools - --disable-abyss-threads Use fork in Abyss instead of pthreads - --disable-abyss-openssl Don't build Abyss Openssl channel function - --enable-libxml2-backend Use libxml2 instead of built-in expat - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-libwww-ssl Include libwww SSL capability. - - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CXX C++ compiler command - CXXFLAGS C++ compiler flags - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to the package provider. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -configure -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_cxx_try_compile LINENO -# ---------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_compile - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftestfile -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftestfile` - fi - if test "$*" != "X $srcdir/configure conftestfile" \ - && test "$*" != "X conftestfile $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi - - test "$2" = conftestfile - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -rm -f conftest* -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - - -PACKAGE=xmlrpc-c - -VERSION=x.xx - -if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 -fi - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - - - -missing_dir=`cd $ac_aux_dir && pwd` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working aclocal" >&5 -$as_echo_n "checking for working aclocal... " >&6; } -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (aclocal --version) < /dev/null > /dev/null 2>&1; then - ACLOCAL=aclocal - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 -$as_echo "found" >&6; } -else - ACLOCAL="$missing_dir/missing aclocal" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: missing" >&5 -$as_echo "missing" >&6; } -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working autoconf" >&5 -$as_echo_n "checking for working autoconf... " >&6; } -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (autoconf --version) < /dev/null > /dev/null 2>&1; then - AUTOCONF=autoconf - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 -$as_echo "found" >&6; } -else - AUTOCONF="$missing_dir/missing autoconf" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: missing" >&5 -$as_echo "missing" >&6; } -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working automake" >&5 -$as_echo_n "checking for working automake... " >&6; } -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (automake --version) < /dev/null > /dev/null 2>&1; then - AUTOMAKE=automake - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 -$as_echo "found" >&6; } -else - AUTOMAKE="$missing_dir/missing automake" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: missing" >&5 -$as_echo "missing" >&6; } -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working autoheader" >&5 -$as_echo_n "checking for working autoheader... " >&6; } -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (autoheader --version) < /dev/null > /dev/null 2>&1; then - AUTOHEADER=autoheader - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 -$as_echo "found" >&6; } -else - AUTOHEADER="$missing_dir/missing autoheader" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: missing" >&5 -$as_echo "missing" >&6; } -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working makeinfo" >&5 -$as_echo_n "checking for working makeinfo... " >&6; } -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (makeinfo --version) < /dev/null > /dev/null 2>&1; then - MAKEINFO=makeinfo - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 -$as_echo "found" >&6; } -else - MAKEINFO="$missing_dir/missing makeinfo" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: missing" >&5 -$as_echo "missing" >&6; } -fi - - - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - - - -FEATURE_LIST= - -# Check whether --enable-wininet-client was given. -if test "${enable_wininet_client+set}" = set; then : - enableval=$enable_wininet_client; -else - enable_wininet_client=maybe -fi - - -if test $enable_wininet_client = maybe; then - # Extract the first word of "wininet-config", so it can be a program name with args. -set dummy wininet-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_have_wininet_config+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$have_wininet_config"; then - ac_cv_prog_have_wininet_config="$have_wininet_config" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_have_wininet_config="yes" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_have_wininet_config" && ac_cv_prog_have_wininet_config="no" -fi -fi -have_wininet_config=$ac_cv_prog_have_wininet_config -if test -n "$have_wininet_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_wininet_config" >&5 -$as_echo "$have_wininet_config" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test $have_wininet_config = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: You don't appear to have Wininet installed (no working wininet-config in your command search path), so we will not build the Wininet client XML transport" >&5 -$as_echo "$as_me: You don't appear to have Wininet installed (no working wininet-config in your command search path), so we will not build the Wininet client XML transport" >&6;} - MUST_BUILD_WININET_CLIENT=no - else - MUST_BUILD_WININET_CLIENT=yes - fi -else - MUST_BUILD_WININET_CLIENT=$enable_wininet_client -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Wininet client XML transport module" >&5 -$as_echo_n "checking whether to build Wininet client XML transport module... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MUST_BUILD_WININET_CLIENT" >&5 -$as_echo "$MUST_BUILD_WININET_CLIENT" >&6; } - - - -# Check whether --enable-curl-client was given. -if test "${enable_curl_client+set}" = set; then : - enableval=$enable_curl_client; -else - enable_curl_client=maybe -fi - - -if test $enable_curl_client = maybe; then - # Extract the first word of "curl-config", so it can be a program name with args. -set dummy curl-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_have_curl_config+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$have_curl_config"; then - ac_cv_prog_have_curl_config="$have_curl_config" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_have_curl_config="yes" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_have_curl_config" && ac_cv_prog_have_curl_config="no" -fi -fi -have_curl_config=$ac_cv_prog_have_curl_config -if test -n "$have_curl_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_curl_config" >&5 -$as_echo "$have_curl_config" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test $have_curl_config = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: You don't appear to have Curl installed (no working curl-config in your command search path), so we will not build the Curl client XML transport" >&5 -$as_echo "$as_me: You don't appear to have Curl installed (no working curl-config in your command search path), so we will not build the Curl client XML transport" >&6;} - MUST_BUILD_CURL_CLIENT=no - else - MUST_BUILD_CURL_CLIENT=yes - fi -else - MUST_BUILD_CURL_CLIENT=$enable_curl_client -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Curl client XML transport module" >&5 -$as_echo_n "checking whether to build Curl client XML transport module... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MUST_BUILD_CURL_CLIENT" >&5 -$as_echo "$MUST_BUILD_CURL_CLIENT" >&6; } - - - -# Check whether --enable-libwww-client was given. -if test "${enable_libwww_client+set}" = set; then : - enableval=$enable_libwww_client; -else - enable_libwww_client=maybe -fi - - -if test $enable_libwww_client = maybe; then - # Extract the first word of "libwww-config", so it can be a program name with args. -set dummy libwww-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_have_libwww_config+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$have_libwww_config"; then - ac_cv_prog_have_libwww_config="$have_libwww_config" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_have_libwww_config="yes" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_have_libwww_config" && ac_cv_prog_have_libwww_config="no" -fi -fi -have_libwww_config=$ac_cv_prog_have_libwww_config -if test -n "$have_libwww_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_libwww_config" >&5 -$as_echo "$have_libwww_config" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test $have_libwww_config = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: You don't appear to have Libwww installed (no working libwww-config in your command search path), so we will not build the Libwww client XML transport" >&5 -$as_echo "$as_me: You don't appear to have Libwww installed (no working libwww-config in your command search path), so we will not build the Libwww client XML transport" >&6;} - MUST_BUILD_LIBWWW_CLIENT=no - else - MUST_BUILD_LIBWWW_CLIENT=yes - fi -else - MUST_BUILD_LIBWWW_CLIENT=$enable_libwww_client -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Libwww client XML transport module" >&5 -$as_echo_n "checking whether to build Libwww client XML transport module... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MUST_BUILD_LIBWWW_CLIENT" >&5 -$as_echo "$MUST_BUILD_LIBWWW_CLIENT" >&6; } - - - -# The first AC_CHECK_LIB has to be in unconditional code because as a -# side effect, it determines what the object file suffix is on this system, -# and if it is statically present even though not actually executed, Autoconf -# later thinks it has already computed the object file suffix and uses it -# without computing it. This was with Autoconf 2.59 -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lncurses" >&5 -$as_echo_n "checking for main in -lncurses... " >&6; } -if ${ac_cv_lib_ncurses_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lncurses $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ncurses_main=yes -else - ac_cv_lib_ncurses_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_main" >&5 -$as_echo "$ac_cv_lib_ncurses_main" >&6; } -if test "x$ac_cv_lib_ncurses_main" = xyes; then : - have_libncurses=yes -else - have_libncurses=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lreadline" >&5 -$as_echo_n "checking for main in -lreadline... " >&6; } -if ${ac_cv_lib_readline_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_main=yes -else - ac_cv_lib_readline_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_main" >&5 -$as_echo "$ac_cv_lib_readline_main" >&6; } -if test "x$ac_cv_lib_readline_main" = xyes; then : - have_libreadline=yes -else - have_libreadline=no -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build tools" >&5 -$as_echo_n "checking whether to build tools... " >&6; } - -BUILD_XMLRPC_PSTREAM=no - -if ! test "$MUST_BUILD_WININET_CLIENT $MUST_BUILD_CURL_CLIENT $MUST_BUILD_LIBWWW_CLIENT" = "no no no"; then - if test $have_libreadline = yes && test $have_libncurses = yes; then - BUILD_XMLRPC_PSTREAM=yes - fi - BUILD_TOOLS=yes -else - BUILD_TOOLS=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_TOOLS" >&5 -$as_echo "$BUILD_TOOLS" >&6; } - - -if test $BUILD_TOOLS = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build the xmlrpc_pstream tool" >&5 -$as_echo_n "checking whether to build the xmlrpc_pstream tool... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_XMLRPC_PSTREAM" >&5 -$as_echo "$BUILD_XMLRPC_PSTREAM" >&6; } - -fi - - - -CLIENTTEST=clienttest - -XMLRPC_CLIENT_H=xmlrpc_client.h - -XMLRPC_TRANSPORT_H=xmlrpc_transport.h - -SYNCH_CLIENT=synch_client - -ASYNCH_CLIENT=asynch_client - -AUTH_CLIENT=auth_client - -QUERY_MEERKAT=query-meerkat - - -if test $MUST_BUILD_WININET_CLIENT = yes; then - FEATURE_LIST="wininet-client $FEATURE_LIST" -fi -if test $MUST_BUILD_CURL_CLIENT = yes; then - FEATURE_LIST="curl-client $FEATURE_LIST" -fi -if test $MUST_BUILD_LIBWWW_CLIENT = yes; then - FEATURE_LIST="libwww-client $FEATURE_LIST" -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Abyss server module" >&5 -$as_echo_n "checking whether to build Abyss server module... " >&6; } -# Check whether --enable-abyss-server was given. -if test "${enable_abyss_server+set}" = set; then : - enableval=$enable_abyss_server; -else - enable_abyss_server=yes -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_abyss_server" >&5 -$as_echo "$enable_abyss_server" >&6; } -ENABLE_ABYSS_SERVER=$enable_abyss_server - - -ABYSS_SUBDIR= -SERVERTEST= -VALIDATEE= -XMLRPC_ABYSS_H= -SERVER= -if test x"$enable_abyss_server" != xno; then - FEATURE_LIST="abyss-server $FEATURE_LIST" - ABYSS_SUBDIR=abyss - SERVERTEST=servertest - VALIDATEE=validatee - XMLRPC_ABYSS_H=xmlrpc_abyss.h - SERVER=server -fi - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build CGI server module" >&5 -$as_echo_n "checking whether to build CGI server module... " >&6; } -# Check whether --enable-cgi-server was given. -if test "${enable_cgi_server+set}" = set; then : - enableval=$enable_cgi_server; -else - enable_cgi_server=yes -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_cgi_server" >&5 -$as_echo "$enable_cgi_server" >&6; } -ENABLE_CGI_SERVER=$enable_cgi_server - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build C++ wrappers and tools" >&5 -$as_echo_n "checking whether to build C++ wrappers and tools... " >&6; } -# Check whether --enable-cplusplus was given. -if test "${enable_cplusplus+set}" = set; then : - enableval=$enable_cplusplus; -else - enable_cplusplus=yes -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_cplusplus" >&5 -$as_echo "$enable_cplusplus" >&6; } -ENABLE_CPLUSPLUS=$enable_cplusplus - - -LIBXMLRPC_CPP_A= -CPPTEST= -XMLRPCCPP_H= -XML_RPC_API2CPP_SUBDIR= -MEERKAT_APP_LIST= -INTEROP_CLIENT_SUBDIR= -if test x"$enable_cplusplus" != xno; then - FEATURE_LIST="c++ $FEATURE_LIST" - LIBXMLRPC_CPP_A=libxmlrpc_cpp.a - CPPTEST=cpptest - XMLRPCCPP_H=XmlRpcCpp.h - - if test $MUST_BUILD_LIBWWW_CLIENT = yes; then - XML_RPC_API2CPP_SUBDIR=xml-rpc-api2cpp - elif test $MUST_BUILD_CURL_CLIENT = yes; then - XML_RPC_API2CPP_SUBDIR=xml-rpc-api2cpp - fi -fi - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test x"$enable_cplusplus" != xno; then - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -z "$CXX"; then - if test -n "$CCC"; then - CXX=$CCC - else - if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 -$as_echo "$ac_ct_CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CXX" && break -done - - if test "x$ac_ct_CXX" = x; then - CXX="g++" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CXX=$ac_ct_CXX - fi -fi - - fi -fi -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 -$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 -$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GXX=yes -else - GXX= -fi -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 -$as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_cxx_werror_flag=$ac_cxx_werror_flag - ac_cxx_werror_flag=yes - ac_cv_prog_cxx_g=no - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -else - CXXFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - -else - ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 -$as_echo "$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi - - - -# Code by albert chin to check for various -# oddball networking libraries. Solaris and some other operating systems -# hide their networking code in various places. (Yes, this links too many -# of our libraries against -lsocket, but a finer-grained mechanism would -# require too much testing.) -ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" -if test "x$ac_cv_func_socket" = xyes; then : - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 -$as_echo_n "checking for socket in -lsocket... " >&6; } -if ${ac_cv_lib_socket_socket+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char socket (); -int -main () -{ -return socket (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_socket=yes -else - ac_cv_lib_socket_socket=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 -$as_echo "$ac_cv_lib_socket_socket" >&6; } -if test "x$ac_cv_lib_socket_socket" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSOCKET 1 -_ACEOF - - LIBS="-lsocket $LIBS" - -fi - -fi - - -# Above sets LIBS, which is not all that useful because we don't want -# to include every library in every link. It also sets -# ac_cv_lib_socket_socket, which we use to pass more specific information -# to the configuration files. - -if test x"$ac_cv_lib_socket_socket" = xyes; then - LSOCKET=-lsocket -else - LSOCKET= -fi - - -# For some reason, we don't seem to need this on Solaris. If you do -# need it, go ahead and try it. -# AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - - - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in wchar.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" -if test "x$ac_cv_header_wchar_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_WCHAR_H 1 -_ACEOF - -fi - -done - - -if test x"$ac_cv_header_wchar_h" = xyes; then - HAVE_WCHAR_H_DEFINE=1 -else - HAVE_WCHAR_H_DEFINE=0 -fi - - -# Needed by Abyss on Solaris: - -for ac_header in sys/filio.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/filio.h" "ac_cv_header_sys_filio_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_filio_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_FILIO_H 1 -_ACEOF - -fi - -done - -if test x"$ac_cv_header_sys_filio_h" = xyes; then - HAVE_SYS_FILIO_H_DEFINE=1 -else - HAVE_SYS_FILIO_H_DEFINE=0 -fi - - -# Needed by Abyss on Solaris: - -for ac_header in sys/ioctl.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_ioctl_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_IOCTL_H 1 -_ACEOF - -fi - -done - -if test x"$ac_cv_header_sys_ioctl_h" = xyes; then - HAVE_SYS_IOCTL_H_DEFINE=1 -else - HAVE_SYS_IOCTL_H_DEFINE=0 -fi - - -for ac_header in sys/select.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_select_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_SELECT_H 1 -_ACEOF - -fi - -done - -if test x"$ac_cv_header_sys_select_h" = xyes; then - HAVE_SYS_SELECT_H_DEFINE=1 -else - HAVE_SYS_SELECT_H_DEFINE=0 -fi - - - -for ac_header in stdarg.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" -if test "x$ac_cv_header_stdarg_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STDARG_H 1 -_ACEOF - -else - -as_fn_error $? "stdarg.h is required to build this library" "$LINENO" 5 - -fi - -done - - - - -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - - -va_list_is_array=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether va_list is an array" >&5 -$as_echo_n "checking whether va_list is an array... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include - -int -main () -{ -va_list list1, list2; list1 = list2; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - va_list_is_array=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $va_list_is_array" >&5 -$as_echo "$va_list_is_array" >&6; } -if test x"$va_list_is_array" = xyes; then - VA_LIST_IS_ARRAY_DEFINE=1 -else - VA_LIST_IS_ARRAY_DEFINE=0 -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler has __attribute__" >&5 -$as_echo_n "checking whether compiler has __attribute__... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -int x __attribute__((__unused__)); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - compiler_has_attribute=yes -else - compiler_has_attribute=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $compiler_has_attribute" >&5 -$as_echo "$compiler_has_attribute" >&6; } -if test x"$compiler_has_attribute" = xyes; then - ATTR_UNUSED="__attribute__((__unused__))" -else - ATTR_UNUSED= -fi - - - - -ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" -if test "x$ac_cv_func_vsnprintf" = xyes; then : - -else - -as_fn_error $? "your C library does not provide vsnprintf" "$LINENO" 5 - -fi - - -for ac_func in wcsncmp -do : - ac_fn_c_check_func "$LINENO" "wcsncmp" "ac_cv_func_wcsncmp" -if test "x$ac_cv_func_wcsncmp" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_WCSNCMP 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_wcsncmp" = x""yes; then - HAVE_WCSNCMP_DEFINE=1 -else - HAVE_WCSNCMP_DEFINE=0 -fi - - -for ac_func in setgroups -do : - ac_fn_c_check_func "$LINENO" "setgroups" "ac_cv_func_setgroups" -if test "x$ac_cv_func_setgroups" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SETGROUPS 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_setgroups" = x""yes; then - HAVE_SETGROUPS_DEFINE=1 -else - HAVE_SETGROUPS_DEFINE=0 -fi - - -for ac_func in asprintf -do : - ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf" -if test "x$ac_cv_func_asprintf" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ASPRINTF 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_asprintf" = x""yes; then - HAVE_ASPRINTF_DEFINE=1 -else - HAVE_ASPRINTF_DEFINE=0 -fi - - -for ac_func in setenv -do : - ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv" -if test "x$ac_cv_func_setenv" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SETENV 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_setenv" = x""yes; then - HAVE_SETENV_DEFINE=1 -else - HAVE_SETENV_DEFINE=0 -fi - - -for ac_func in strtoll -do : - ac_fn_c_check_func "$LINENO" "strtoll" "ac_cv_func_strtoll" -if test "x$ac_cv_func_strtoll" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STRTOLL 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_strtoll" = x""yes; then - HAVE_STRTOLL_DEFINE=1 -else - HAVE_STRTOLL_DEFINE=0 -fi - - -for ac_func in strtoull -do : - ac_fn_c_check_func "$LINENO" "strtoull" "ac_cv_func_strtoull" -if test "x$ac_cv_func_strtoull" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STRTOULL 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_strtoull" = x""yes; then - HAVE_STRTOULL_DEFINE=1 -else - HAVE_STRTOULL_DEFINE=0 -fi - - -for ac_func in strtoq -do : - ac_fn_c_check_func "$LINENO" "strtoq" "ac_cv_func_strtoq" -if test "x$ac_cv_func_strtoq" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STRTOQ 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_strtoq" = x""yes; then - HAVE_STRTOQ_DEFINE=1 -else - HAVE_STRTOQ_DEFINE=0 -fi - - -for ac_func in strtouq -do : - ac_fn_c_check_func "$LINENO" "strtouq" "ac_cv_func_strtouq" -if test "x$ac_cv_func_strtouq" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STRTOUQ 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_strtouq" = x""yes; then - HAVE_STRTOUQ_DEFINE=1 -else - HAVE_STRTOUQ_DEFINE=0 -fi - - -for ac_func in __strtoll -do : - ac_fn_c_check_func "$LINENO" "__strtoll" "ac_cv_func___strtoll" -if test "x$ac_cv_func___strtoll" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE___STRTOLL 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func___strtoll" = x""yes; then - HAVE___STRTOLL_DEFINE=1 -else - HAVE___STRTOLL_DEFINE=0 -fi - - -for ac_func in __strtoull -do : - ac_fn_c_check_func "$LINENO" "__strtoull" "ac_cv_func___strtoull" -if test "x$ac_cv_func___strtoull" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE___STRTOULL 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func___strtoull" = x""yes; then - HAVE___STRTOULL_DEFINE=1 -else - HAVE___STRTOULL_DEFINE=0 -fi - - -for ac_func in _strtoui64 -do : - ac_fn_c_check_func "$LINENO" "_strtoui64" "ac_cv_func__strtoui64" -if test "x$ac_cv_func__strtoui64" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE__STRTOUI64 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func__strtoui64" = x""yes; then - HAVE__STRTOUI64_DEFINE=1 -else - HAVE__STRTOUI64_DEFINE=0 -fi - - -for ac_func in pselect -do : - ac_fn_c_check_func "$LINENO" "pselect" "ac_cv_func_pselect" -if test "x$ac_cv_func_pselect" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_PSELECT 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_pselect" = x""yes; then - HAVE_PSELECT_DEFINE=1 -else - HAVE_PSELECT_DEFINE=0 -fi - - -for ac_func in gettimeofday -do : - ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" -if test "x$ac_cv_func_gettimeofday" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETTIMEOFDAY 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_gettimeofday" = x""yes; then - HAVE_GETTIMEOFDAY_DEFINE=1 -else - HAVE_GETTIMEOFDAY_DEFINE=0 -fi - - -for ac_func in localtime_r -do : - ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r" -if test "x$ac_cv_func_localtime_r" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LOCALTIME_R 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_localtime_r" = x""yes; then - HAVE_LOCALTIME_R_DEFINE=1 -else - HAVE_LOCALTIME_R_DEFINE=0 -fi - - -for ac_func in gmtime_r -do : - ac_fn_c_check_func "$LINENO" "gmtime_r" "ac_cv_func_gmtime_r" -if test "x$ac_cv_func_gmtime_r" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GMTIME_R 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_gmtime_r" = x""yes; then - HAVE_GMTIME_R_DEFINE=1 -else - HAVE_GMTIME_R_DEFINE=0 -fi - - -for ac_func in strcasecmp -do : - ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" -if test "x$ac_cv_func_strcasecmp" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STRCASECMP 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_strcasecmp" = x""yes; then - HAVE_STRCASECMP_DEFINE=1 -else - HAVE_STRCASECMP_DEFINE=0 -fi - - -for ac_func in stricmp -do : - ac_fn_c_check_func "$LINENO" "stricmp" "ac_cv_func_stricmp" -if test "x$ac_cv_func_stricmp" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STRICMP 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_stricmp" = x""yes; then - HAVE_STRICMP_DEFINE=1 -else - HAVE_STRICMP_DEFINE=0 -fi - - -for ac_func in _stricmp -do : - ac_fn_c_check_func "$LINENO" "_stricmp" "ac_cv_func__stricmp" -if test "x$ac_cv_func__stricmp" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE__STRICMP 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func__stricmp" = x""yes; then - HAVE__STRICMP_DEFINE=1 -else - HAVE__STRICMP_DEFINE=0 -fi - - - -case "$host_os" in - *mingw*) - DIRECTORY_SEPARATOR="\\\\" - ;; - *) - DIRECTORY_SEPARATOR="/" - ;; -esac - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use Abyss pthread function" >&5 -$as_echo_n "checking whether to use Abyss pthread function... " >&6; } -# Check whether --enable-abyss-threads was given. -if test "${enable_abyss_threads+set}" = set; then : - enableval=$enable_abyss_threads; -else - enable_abyss_threads=yes -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_abyss_threads" >&5 -$as_echo "$enable_abyss_threads" >&6; } - -ENABLE_ABYSS_THREADS=$enable_abyss_threads - - -if test x"$enable_abyss_threads" != xno; then - CFLAGS="$CFLAGS -D_THREAD" -fi - - - -if test $MUST_BUILD_WININET_CLIENT = yes; then - - for ac_prog in wininet-xmlrpc-config wininet-config -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_WININET_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $WININET_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_WININET_CONFIG="$WININET_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_WININET_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -WININET_CONFIG=$ac_cv_path_WININET_CONFIG -if test -n "$WININET_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WININET_CONFIG" >&5 -$as_echo "$WININET_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$WININET_CONFIG" && break -done -test -n "$WININET_CONFIG" || WININET_CONFIG="no" - - if test "x$WININET_CONFIG" = "xno"; then - as_fn_error then not found "Configure INTERNAL ERROR - first wininet-config found" "$LINENO" 5 - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wininet version >= 1.0.0" >&5 -$as_echo_n "checking for wininet version >= 1.0.0... " >&6; } - W3VER=$($WININET_CONFIG --version) - WININET_MAJOR=\ -$(echo $W3VER|sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/') - WININET_MINOR=\ -$(echo $W3VER|sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/') - WININET_MICRO=\ -$(echo $W3VER|sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/') - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WININET_MAJOR.$WININET_MINOR.$WININET_MICRO" >&5 -$as_echo "$WININET_MAJOR.$WININET_MINOR.$WININET_MICRO" >&6; } - - WININET_VERSION_OK=yes - if test $WININET_MAJOR -lt 1; then - WININET_VERSION_OK=no - else - if test $WININET_MAJOR -eq 1 -a $WININET_MINOR -lt 0; then - WININET_VERSION_OK=no - else - if test $WININET_MAJOR -eq 1 -a $WININET_MINOR -eq 0 \ - -a $WININET_MICRO -lt 0; then - WININET_VERSION_OK=no - fi - fi - fi - if test "x$WININET_VERSION_OK" = "xno"; then - as_fn_error $? "wininet version >= 1.0.0 required" "$LINENO" 5 - fi - - WININET_CFLAGS=$($WININET_CONFIG --cflags) - - CFLAGS="$CFLAGS $WININET_CFLAGS" - - WININET_LDADD=$($WININET_CONFIG --libs) - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wininet library directory" >&5 -$as_echo_n "checking for wininet library directory... " >&6; } - WININET_LIBDIR="$($WININET_CONFIG --prefix)/lib" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WININET_LIBDIR" >&5 -$as_echo "$WININET_LIBDIR" >&6; } - - -fi # MUST_BUILD_WININET_CLIENT - - -if test $MUST_BUILD_LIBWWW_CLIENT = yes; then - - for ac_prog in libwww-xmlrpc-config libwww-config -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LIBWWW_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $LIBWWW_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_LIBWWW_CONFIG="$LIBWWW_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LIBWWW_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -LIBWWW_CONFIG=$ac_cv_path_LIBWWW_CONFIG -if test -n "$LIBWWW_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBWWW_CONFIG" >&5 -$as_echo "$LIBWWW_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$LIBWWW_CONFIG" && break -done -test -n "$LIBWWW_CONFIG" || LIBWWW_CONFIG="no" - - if test "x$LIBWWW_CONFIG" = "xno"; then - as_fn_error then not found "Configure INTERNAL ERROR - first libwww-config found" "$LINENO" 5 - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for w3c-libwww version >= 5.2.8" >&5 -$as_echo_n "checking for w3c-libwww version >= 5.2.8... " >&6; } - W3VER=$($LIBWWW_CONFIG --version) - LIBWWW_MAJOR=\ -$(echo $W3VER|sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/') - LIBWWW_MINOR=\ -$(echo $W3VER|sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/') - LIBWWW_MICRO=\ -$(echo $W3VER|sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/') - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBWWW_MAJOR.$LIBWWW_MINOR.$LIBWWW_MICRO" >&5 -$as_echo "$LIBWWW_MAJOR.$LIBWWW_MINOR.$LIBWWW_MICRO" >&6; } - - LIBWWW_VERSION_OK=yes - if test $LIBWWW_MAJOR -lt 5; then - LIBWWW_VERSION_OK=no - else - if test $LIBWWW_MAJOR -eq 5 -a $LIBWWW_MINOR -lt 2; then - LIBWWW_VERSION_OK=no - else - if test $LIBWWW_MAJOR -eq 5 -a $LIBWWW_MINOR -eq 2 \ - -a $LIBWWW_MICRO -lt 8; then - LIBWWW_VERSION_OK=no - fi - fi - fi - if test "x$LIBWWW_VERSION_OK" = "xno"; then - as_fn_error $? "w3c-libwww version >= 5.2.8 required" "$LINENO" 5 - fi - - LIBWWW_LDADD=$($LIBWWW_CONFIG --libs) - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libwww library directory" >&5 -$as_echo_n "checking for libwww library directory... " >&6; } - LIBWWW_LIBDIR="$($LIBWWW_CONFIG --prefix)/lib" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBWWW_LIBDIR" >&5 -$as_echo "$LIBWWW_LIBDIR" >&6; } - - -fi # MUST_BUILD_LIBWWW_CLIENT - - - -if test $MUST_BUILD_CURL_CLIENT = yes; then - - for ac_prog in curl-xmlrpc-config curl-config -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CURL_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $CURL_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_CURL_CONFIG="$CURL_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_CURL_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -CURL_CONFIG=$ac_cv_path_CURL_CONFIG -if test -n "$CURL_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CURL_CONFIG" >&5 -$as_echo "$CURL_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CURL_CONFIG" && break -done -test -n "$CURL_CONFIG" || CURL_CONFIG="no" - - if test "x$CURL_CONFIG" = "xno"; then - as_fn_error then not found "Configure INTERNAL ERROR - first curl-config found" "$LINENO" 5 - fi - - - - - CURL_LDADD=$($CURL_CONFIG --libs) - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Curl library directory" >&5 -$as_echo_n "checking for Curl library directory... " >&6; } - CURL_LIBDIR="$($CURL_CONFIG --prefix)/lib" - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CURL_LIBDIR" >&5 -$as_echo "$CURL_LIBDIR" >&6; } - - -fi # MUST_BUILD_CURL_CLIENT - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL library" >&5 -$as_echo_n "checking for OpenSSL library... " >&6; } - -if pkg-config openssl; then - HAVE_OPENSSL=yes - OPENSSL_LDADD=$(pkg-config openssl --libs) - - OPENSSL_CFLAGS=$(pkg-config openssl --cflags) - -else - HAVE_OPENSSL=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_OPENSSL" >&5 -$as_echo "$HAVE_OPENSSL" >&6; } - -# One really annoying case where the user needs to disable building of -# Openssl-based parts explicitly is where there is no Openssl for the target -# platform but there is for the native platform. In that case, Pkg-config -# finds the openssl.pc in /usr/lib, ignoring the fact that /usr/lib is not in -# the search path specified by the PKG_CONFIG environment variable. This is -# a major design flaw in Pkg-config. - -# Check whether --enable-abyss-openssl was given. -if test "${enable_abyss_openssl+set}" = set; then : - enableval=$enable_abyss_openssl; -else - enable_abyss_openssl=maybe -fi - - -if test $enable_abyss_openssl = maybe; then - if test $HAVE_OPENSSL = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: You don't appear to Openssl installed (no pkg-config file for it in your pkg-config search path), so we will not build the Abyss Openssl channel module" >&5 -$as_echo "$as_me: You don't appear to Openssl installed (no pkg-config file for it in your pkg-config search path), so we will not build the Abyss Openssl channel module" >&6;} - MUST_BUILD_ABYSS_OPENSSL=no - else - MUST_BUILD_ABYSS_OPENSSL=yes - fi -else - MUST_BUILD_ABYSS_OPENSSL=$enable_abyss_openssl -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Abyss Openssl channel module" >&5 -$as_echo_n "checking whether to build Abyss Openssl channel module... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MUST_BUILD_ABYSS_OPENSSL" >&5 -$as_echo "$MUST_BUILD_ABYSS_OPENSSL" >&6; } - - -if test $MUST_BUILD_ABYSS_OPENSSL = yes; then - HAVE_ABYSS_OPENSSL_DEFINE=1 -else - HAVE_ABYSS_OPENSSL_DEFINE=0 -fi - - - - - - -# Check whether --with-libwww-ssl was given. -if test "${with_libwww_ssl+set}" = set; then : - withval=$with_libwww_ssl; -fi - - -if test x"$enable_libwww_client" != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use SSL with libwww" >&5 -$as_echo_n "checking whether to use SSL with libwww... " >&6; } - if test x"$with_libwww_ssl" = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - HAVE_LIBWWW_SSL_DEFINE=1 - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - HAVE_LIBWWW_SSL_DEFINE=0 - fi -else - HAVE_LIBWWW_SSL_DEFINE=0 -fi - - -# Check whether --enable-libxml2-backend was given. -if test "${enable_libxml2_backend+set}" = set; then : - enableval=$enable_libxml2_backend; -else - enable_libxml2_backend=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build the libxml2 backend" >&5 -$as_echo_n "checking whether to build the libxml2 backend... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_libxml2_backend" >&5 -$as_echo "$enable_libxml2_backend" >&6; } - -if test $enable_libxml2_backend = yes; then - # Extract the first word of "xml2-config", so it can be a program name with args. -set dummy xml2-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_have_xml2_config+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$have_xml2_config"; then - ac_cv_prog_have_xml2_config="$have_xml2_config" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_have_xml2_config="yes" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_have_xml2_config" && ac_cv_prog_have_xml2_config="no" -fi -fi -have_xml2_config=$ac_cv_prog_have_xml2_config -if test -n "$have_xml2_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_xml2_config" >&5 -$as_echo "$have_xml2_config" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test $have_xml2_config = no; then - as_fn_error $? "You specified --enable-libxml2_backend, but don't appear to have libxml2 installed (no working xml2-config in your command search path), so we cannot not build for libxml2" "$LINENO" 5 - fi -fi -ENABLE_LIBXML2_BACKEND=$enable_libxml2_backend - - -C_COMPILER_GNU=$ac_cv_c_compiler_gnu - -CXX_COMPILER_GNU=$ac_cv_cxx_compiler_gnu - - -CC_WARN_FLAGS= - -CPP_WARN_FLAGS= - - - -BUILDDIR=$(pwd) - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="${ac_tool_prefix}ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_AR"; then - ac_ct_AR=$AR - # Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_AR" = x; then - AR="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -else - AR="$ac_cv_prog_AR" -fi - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - - - - -ac_config_files="$ac_config_files srcdir.mk config.mk xmlrpc_config.h" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -ac_script=' -:mline -/\\$/{ - N - s,\\\n,, - b mline -} -t clear -:clear -s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g -t quote -s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g -t quote -b any -:quote -s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g -s/\[/\\&/g -s/\]/\\&/g -s/\$/$$/g -H -:any -${ - g - s/^\n// - s/\n/ /g - p -} -' -DEFS=`sed -n "$ac_script" confdefs.h` - - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by $as_me, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Report bugs to the package provider." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h | --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "srcdir.mk") CONFIG_FILES="$CONFIG_FILES srcdir.mk" ;; - "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; - "xmlrpc_config.h") CONFIG_FILES="$CONFIG_FILES xmlrpc_config.h" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - - -eval set X " :F $CONFIG_FILES " -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - - - - esac - -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - - -if test ! -f GNUmakefile; then - ln -s "${srcdir}/GNUmakefile" . -fi -if test ! -f Makefile; then - ln -s "${srcdir}/Makefile" . -fi -if test ! -f transport_config.mk; then - ln -s "${srcdir}/transport_config.mk" . -fi - - -if test "$MUST_BUILD_WININET_CLIENT $MUST_BUILD_CURL_CLIENT $MUST_BUILD_LIBWWW_CLIENT" = "no no no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: ==>" >&5 -$as_echo "$as_me: ==>" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: ==>We are not building any client XML transport (see earlier messages explaining why), therefore WE WILL NOT BUILD THE CLIENT LIBRARY." >&5 -$as_echo "$as_me: ==>We are not building any client XML transport (see earlier messages explaining why), therefore WE WILL NOT BUILD THE CLIENT LIBRARY." >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: ==>" >&5 -$as_echo "$as_me: ==>" >&6;} -fi - - diff --git a/trunk/configure.in b/trunk/configure.in deleted file mode 100644 index 3b71efe5c..000000000 --- a/trunk/configure.in +++ /dev/null @@ -1,837 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. - -AC_INIT(include/xmlrpc-c/base.h) - -dnl ======================================================================= -dnl Define PACKAGE, VERSION, @PACKAGE@, @VERSION@ -dnl ======================================================================= - -dnl "x.xx" is supposed to be a version number, but is meaningless here. -dnl The real version number is in Makefile.version. -AM_INIT_AUTOMAKE(xmlrpc-c, x.xx) - -dnl Define @build@, @build_cpu@, @build_vendor@, @build_os, -dnl @host, @host_cpu@, @host_vender, and @host_os@ substitutions. -dnl "host" means the target system -- the one for which we are building. -dnl "build" means the system that will do the building. -AC_CANONICAL_HOST - -dnl ======================================================================= -dnl Decide What To Build -dnl ======================================================================= - -FEATURE_LIST= - -AC_ARG_ENABLE(wininet-client, - [ --disable-wininet-client Don't build the Wininet client transport], , -enable_wininet_client=maybe) - -if test $enable_wininet_client = maybe; then - AC_CHECK_PROG(have_wininet_config, wininet-config, yes, no) - if test $have_wininet_config = no; then - AC_MSG_NOTICE([You don't appear to have Wininet installed (no working wininet-config in your command search path), so we will not build the Wininet client XML transport]) - MUST_BUILD_WININET_CLIENT=no - else - MUST_BUILD_WININET_CLIENT=yes - fi -else - MUST_BUILD_WININET_CLIENT=$enable_wininet_client -fi - -AC_MSG_CHECKING(whether to build Wininet client XML transport module) -AC_MSG_RESULT($MUST_BUILD_WININET_CLIENT) -AC_SUBST(MUST_BUILD_WININET_CLIENT) - - -AC_ARG_ENABLE(curl-client, - [ --disable-curl-client Don't build the Curl client transport], , -enable_curl_client=maybe) - -if test $enable_curl_client = maybe; then - AC_CHECK_PROG(have_curl_config, curl-config, yes, no) - if test $have_curl_config = no; then - AC_MSG_NOTICE([You don't appear to have Curl installed (no working curl-config in your command search path), so we will not build the Curl client XML transport]) - MUST_BUILD_CURL_CLIENT=no - else - MUST_BUILD_CURL_CLIENT=yes - fi -else - MUST_BUILD_CURL_CLIENT=$enable_curl_client -fi - -AC_MSG_CHECKING(whether to build Curl client XML transport module) -AC_MSG_RESULT($MUST_BUILD_CURL_CLIENT) -AC_SUBST(MUST_BUILD_CURL_CLIENT) - - -AC_ARG_ENABLE(libwww-client, - [ --disable-libwww-client Don't build the Libwww client transport], , -enable_libwww_client=maybe) - -if test $enable_libwww_client = maybe; then - AC_CHECK_PROG(have_libwww_config, libwww-config, yes, no) - if test $have_libwww_config = no; then - AC_MSG_NOTICE([You don't appear to have Libwww installed (no working libwww-config in your command search path), so we will not build the Libwww client XML transport]) - MUST_BUILD_LIBWWW_CLIENT=no - else - MUST_BUILD_LIBWWW_CLIENT=yes - fi -else - MUST_BUILD_LIBWWW_CLIENT=$enable_libwww_client -fi - -AC_MSG_CHECKING(whether to build Libwww client XML transport module) -AC_MSG_RESULT($MUST_BUILD_LIBWWW_CLIENT) -AC_SUBST(MUST_BUILD_LIBWWW_CLIENT) - - -# The first AC_CHECK_LIB has to be in unconditional code because as a -# side effect, it determines what the object file suffix is on this system, -# and if it is statically present even though not actually executed, Autoconf -# later thinks it has already computed the object file suffix and uses it -# without computing it. This was with Autoconf 2.59 -AC_CHECK_LIB(ncurses, main, [have_libncurses=yes], [have_libncurses=no]) -AC_CHECK_LIB(readline, main, [have_libreadline=yes], [have_libreadline=no]) - -AC_MSG_CHECKING(whether to build tools) - -BUILD_XMLRPC_PSTREAM=no - -if ! test "$MUST_BUILD_WININET_CLIENT $MUST_BUILD_CURL_CLIENT $MUST_BUILD_LIBWWW_CLIENT" = "no no no"; then - if test $have_libreadline = yes && test $have_libncurses = yes; then - BUILD_XMLRPC_PSTREAM=yes - fi - BUILD_TOOLS=yes -else - BUILD_TOOLS=no -fi - -AC_MSG_RESULT($BUILD_TOOLS) -AC_SUBST(BUILD_TOOLS) - -if test $BUILD_TOOLS = yes; then - AC_MSG_CHECKING(whether to build the xmlrpc_pstream tool) - AC_MSG_RESULT($BUILD_XMLRPC_PSTREAM) - AC_SUBST(BUILD_XMLRPC_PSTREAM) -fi - - -dnl Set up the appropriate Makefile substitutions. - -CLIENTTEST=clienttest -AC_SUBST(CLIENTTEST) -XMLRPC_CLIENT_H=xmlrpc_client.h -AC_SUBST(XMLRPC_CLIENT_H) -XMLRPC_TRANSPORT_H=xmlrpc_transport.h -AC_SUBST(XMLRPC_TRANSPORT_H) -SYNCH_CLIENT=synch_client -AC_SUBST(SYNCH_CLIENT) -ASYNCH_CLIENT=asynch_client -AC_SUBST(ASYNCH_CLIENT) -AUTH_CLIENT=auth_client -AC_SUBST(AUTH_CLIENT) -QUERY_MEERKAT=query-meerkat -AC_SUBST(QUERY_MEERKAT) - -if test $MUST_BUILD_WININET_CLIENT = yes; then - FEATURE_LIST="wininet-client $FEATURE_LIST" -fi -if test $MUST_BUILD_CURL_CLIENT = yes; then - FEATURE_LIST="curl-client $FEATURE_LIST" -fi -if test $MUST_BUILD_LIBWWW_CLIENT = yes; then - FEATURE_LIST="libwww-client $FEATURE_LIST" -fi - -dnl Check to see if we should build our Abyss server module. -AC_MSG_CHECKING(whether to build Abyss server module) -AC_ARG_ENABLE(abyss-server, - [ --disable-abyss-server Don't build the Abyss server module], , -enable_abyss_server=yes) -AC_MSG_RESULT($enable_abyss_server) -ENABLE_ABYSS_SERVER=$enable_abyss_server -AC_SUBST(ENABLE_ABYSS_SERVER) - -dnl Set up the appropriate Makefile substitutions. -ABYSS_SUBDIR= -SERVERTEST= -VALIDATEE= -XMLRPC_ABYSS_H= -SERVER= -if test x"$enable_abyss_server" != xno; then - FEATURE_LIST="abyss-server $FEATURE_LIST" - ABYSS_SUBDIR=abyss - SERVERTEST=servertest - VALIDATEE=validatee - XMLRPC_ABYSS_H=xmlrpc_abyss.h - SERVER=server -fi -AC_SUBST(ABYSS_SUBDIR) -AC_SUBST(SERVERTEST) -AC_SUBST(VALIDATEE) -AC_SUBST(XMLRPC_ABYSS_H) -AC_SUBST(SERVER) - -dnl Check to see if we should build our CGI server module. -AC_MSG_CHECKING(whether to build CGI server module) -AC_ARG_ENABLE(cgi-server, - [ --disable-cgi-server Don't build the CGI server module], , -enable_cgi_server=yes) -AC_MSG_RESULT($enable_cgi_server) -ENABLE_CGI_SERVER=$enable_cgi_server -AC_SUBST(ENABLE_CGI_SERVER) - -dnl Check to see if we should build our C++ stuff. -AC_MSG_CHECKING(whether to build C++ wrappers and tools) -AC_ARG_ENABLE(cplusplus, - [ --disable-cplusplus Don't build the C++ wrapper classes or tools], , -enable_cplusplus=yes) -AC_MSG_RESULT($enable_cplusplus) -ENABLE_CPLUSPLUS=$enable_cplusplus -AC_SUBST(ENABLE_CPLUSPLUS) - -dnl Set up the appropriate Makefile substitutions. -LIBXMLRPC_CPP_A= -CPPTEST= -XMLRPCCPP_H= -XML_RPC_API2CPP_SUBDIR= -MEERKAT_APP_LIST= -INTEROP_CLIENT_SUBDIR= -if test x"$enable_cplusplus" != xno; then - FEATURE_LIST="c++ $FEATURE_LIST" - LIBXMLRPC_CPP_A=libxmlrpc_cpp.a - CPPTEST=cpptest - XMLRPCCPP_H=XmlRpcCpp.h - - if test $MUST_BUILD_LIBWWW_CLIENT = yes; then - XML_RPC_API2CPP_SUBDIR=xml-rpc-api2cpp - elif test $MUST_BUILD_CURL_CLIENT = yes; then - XML_RPC_API2CPP_SUBDIR=xml-rpc-api2cpp - fi -fi -AC_SUBST(LIBXMLRPC_CPP_A) -AC_SUBST(CPPTEST) -AC_SUBST(XMLRPCCPP_H) -AC_SUBST(XML_RPC_API2CPP_SUBDIR) - - -AC_SUBST(FEATURE_LIST) - - -dnl ======================================================================= -dnl Checks for programs. -dnl ======================================================================= - -AC_PROG_CC -if test x"$enable_cplusplus" != xno; then - AC_PROG_CXX -fi - - -dnl ======================================================================= -dnl Checks for libraries. -dnl ======================================================================= - -# Code by albert chin to check for various -# oddball networking libraries. Solaris and some other operating systems -# hide their networking code in various places. (Yes, this links too many -# of our libraries against -lsocket, but a finer-grained mechanism would -# require too much testing.) -AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket)) - -# Above sets LIBS, which is not all that useful because we don't want -# to include every library in every link. It also sets -# ac_cv_lib_socket_socket, which we use to pass more specific information -# to the configuration files. - -if test x"$ac_cv_lib_socket_socket" = xyes; then - LSOCKET=-lsocket -else - LSOCKET= -fi -AC_SUBST(LSOCKET) - -# For some reason, we don't seem to need this on Solaris. If you do -# need it, go ahead and try it. -# AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) - - -dnl ======================================================================= -dnl Checks for header files. -dnl ======================================================================= - -AC_STDC_HEADERS - -dnl We don't use AM_CONFIG_HEADER to define HAVE_WCHAR_H, etc. because -dnl the following is more straightforward and easier to understand, -dnl especially for a newcomer. Furthermore, AM_CONFIG_HEADER represents -dnl false as undefined, whereas our scheme represents it as 0. undefined -dnl is a poor choice because it often means just that you neglected to -dnl choose a value for some reason. - -dnl defines ac_cv_header_wchar_h, etc: -AC_CHECK_HEADERS(wchar.h) - -if test x"$ac_cv_header_wchar_h" = xyes; then - HAVE_WCHAR_H_DEFINE=1 -else - HAVE_WCHAR_H_DEFINE=0 -fi -AC_SUBST(HAVE_WCHAR_H_DEFINE) - -# Needed by Abyss on Solaris: - -AC_CHECK_HEADERS(sys/filio.h) -if test x"$ac_cv_header_sys_filio_h" = xyes; then - HAVE_SYS_FILIO_H_DEFINE=1 -else - HAVE_SYS_FILIO_H_DEFINE=0 -fi -AC_SUBST(HAVE_SYS_FILIO_H_DEFINE) - -# Needed by Abyss on Solaris: - -AC_CHECK_HEADERS(sys/ioctl.h) -if test x"$ac_cv_header_sys_ioctl_h" = xyes; then - HAVE_SYS_IOCTL_H_DEFINE=1 -else - HAVE_SYS_IOCTL_H_DEFINE=0 -fi -AC_SUBST(HAVE_SYS_IOCTL_H_DEFINE) - -AC_CHECK_HEADERS(sys/select.h) -if test x"$ac_cv_header_sys_select_h" = xyes; then - HAVE_SYS_SELECT_H_DEFINE=1 -else - HAVE_SYS_SELECT_H_DEFINE=0 -fi -AC_SUBST(HAVE_SYS_SELECT_H_DEFINE) - - -AC_CHECK_HEADERS(stdarg.h, , [ -AC_MSG_ERROR(stdarg.h is required to build this library) -]) - - -dnl ======================================================================= -dnl Checks for typedefs, structures, and compiler characteristics. -dnl ======================================================================= - -dnl AC_C_BIGENDIAN -AC_TYPE_SIZE_T - -dnl This check is borrowed from Python 1.5.2. -va_list_is_array=no -AC_MSG_CHECKING(whether va_list is an array) -AC_TRY_COMPILE([ -#include -], [va_list list1, list2; list1 = list2;], , -va_list_is_array=yes) -AC_MSG_RESULT($va_list_is_array) -if test x"$va_list_is_array" = xyes; then - VA_LIST_IS_ARRAY_DEFINE=1 -else - VA_LIST_IS_ARRAY_DEFINE=0 -fi -AC_SUBST(VA_LIST_IS_ARRAY_DEFINE) - -AC_MSG_CHECKING(whether compiler has __attribute__) -AC_TRY_COMPILE(, [int x __attribute__((__unused__));], -compiler_has_attribute=yes, -compiler_has_attribute=no) -AC_MSG_RESULT($compiler_has_attribute) -if test x"$compiler_has_attribute" = xyes; then - ATTR_UNUSED="__attribute__((__unused__))" -else - ATTR_UNUSED= -fi -AC_SUBST(ATTR_UNUSED) - - -dnl ======================================================================= -dnl Checks for library functions. -dnl ======================================================================= - -AC_CHECK_FUNC(vsnprintf, , [ -AC_MSG_ERROR(your C library does not provide vsnprintf) -]) - -dnl Unicode function needed by test suites. -AC_CHECK_FUNCS(wcsncmp) -if test "x$ac_cv_func_wcsncmp" = x""yes; then - HAVE_WCSNCMP_DEFINE=1 -else - HAVE_WCSNCMP_DEFINE=0 -fi -AC_SUBST(HAVE_WCSNCMP_DEFINE) - -dnl CygWin doesn't provide setgroups. -AC_CHECK_FUNCS(setgroups) -if test "x$ac_cv_func_setgroups" = x""yes; then - HAVE_SETGROUPS_DEFINE=1 -else - HAVE_SETGROUPS_DEFINE=0 -fi -AC_SUBST(HAVE_SETGROUPS_DEFINE) - -AC_CHECK_FUNCS(asprintf) -if test "x$ac_cv_func_asprintf" = x""yes; then - HAVE_ASPRINTF_DEFINE=1 -else - HAVE_ASPRINTF_DEFINE=0 -fi -AC_SUBST(HAVE_ASPRINTF_DEFINE) - -AC_CHECK_FUNCS(setenv) -if test "x$ac_cv_func_setenv" = x""yes; then - HAVE_SETENV_DEFINE=1 -else - HAVE_SETENV_DEFINE=0 -fi -AC_SUBST(HAVE_SETENV_DEFINE) - -AC_CHECK_FUNCS(strtoll) -if test "x$ac_cv_func_strtoll" = x""yes; then - HAVE_STRTOLL_DEFINE=1 -else - HAVE_STRTOLL_DEFINE=0 -fi -AC_SUBST(HAVE_STRTOLL_DEFINE) - -AC_CHECK_FUNCS(strtoull) -if test "x$ac_cv_func_strtoull" = x""yes; then - HAVE_STRTOULL_DEFINE=1 -else - HAVE_STRTOULL_DEFINE=0 -fi -AC_SUBST(HAVE_STRTOULL_DEFINE) - -AC_CHECK_FUNCS(strtoq) -if test "x$ac_cv_func_strtoq" = x""yes; then - HAVE_STRTOQ_DEFINE=1 -else - HAVE_STRTOQ_DEFINE=0 -fi -AC_SUBST(HAVE_STRTOQ_DEFINE) - -AC_CHECK_FUNCS(strtouq) -if test "x$ac_cv_func_strtouq" = x""yes; then - HAVE_STRTOUQ_DEFINE=1 -else - HAVE_STRTOUQ_DEFINE=0 -fi -AC_SUBST(HAVE_STRTOUQ_DEFINE) - -AC_CHECK_FUNCS(__strtoll) -if test "x$ac_cv_func___strtoll" = x""yes; then - HAVE___STRTOLL_DEFINE=1 -else - HAVE___STRTOLL_DEFINE=0 -fi -AC_SUBST(HAVE___STRTOLL_DEFINE) - -AC_CHECK_FUNCS(__strtoull) -if test "x$ac_cv_func___strtoull" = x""yes; then - HAVE___STRTOULL_DEFINE=1 -else - HAVE___STRTOULL_DEFINE=0 -fi -AC_SUBST(HAVE___STRTOULL_DEFINE) - -AC_CHECK_FUNCS(_strtoui64) -if test "x$ac_cv_func__strtoui64" = x""yes; then - HAVE__STRTOUI64_DEFINE=1 -else - HAVE__STRTOUI64_DEFINE=0 -fi -AC_SUBST(HAVE__STRTOUI64_DEFINE) - -dnl uclib doesn't have pselect -AC_CHECK_FUNCS(pselect) -if test "x$ac_cv_func_pselect" = x""yes; then - HAVE_PSELECT_DEFINE=1 -else - HAVE_PSELECT_DEFINE=0 -fi -AC_SUBST(HAVE_PSELECT_DEFINE) - -dnl Windows doesn't have gettimeofday, localtime_r, or gmtime_r -AC_CHECK_FUNCS(gettimeofday) -if test "x$ac_cv_func_gettimeofday" = x""yes; then - HAVE_GETTIMEOFDAY_DEFINE=1 -else - HAVE_GETTIMEOFDAY_DEFINE=0 -fi -AC_SUBST(HAVE_GETTIMEOFDAY_DEFINE) - -AC_CHECK_FUNCS(localtime_r) -if test "x$ac_cv_func_localtime_r" = x""yes; then - HAVE_LOCALTIME_R_DEFINE=1 -else - HAVE_LOCALTIME_R_DEFINE=0 -fi -AC_SUBST(HAVE_LOCALTIME_R_DEFINE) - -AC_CHECK_FUNCS(gmtime_r) -if test "x$ac_cv_func_gmtime_r" = x""yes; then - HAVE_GMTIME_R_DEFINE=1 -else - HAVE_GMTIME_R_DEFINE=0 -fi -AC_SUBST(HAVE_GMTIME_R_DEFINE) - -dnl Windows doesn't have strcasecmp; -AC_CHECK_FUNCS(strcasecmp) -if test "x$ac_cv_func_strcasecmp" = x""yes; then - HAVE_STRCASECMP_DEFINE=1 -else - HAVE_STRCASECMP_DEFINE=0 -fi -AC_SUBST(HAVE_STRCASECMP_DEFINE) - -AC_CHECK_FUNCS(stricmp) -if test "x$ac_cv_func_stricmp" = x""yes; then - HAVE_STRICMP_DEFINE=1 -else - HAVE_STRICMP_DEFINE=0 -fi -AC_SUBST(HAVE_STRICMP_DEFINE) - -AC_CHECK_FUNCS(_stricmp) -if test "x$ac_cv_func__stricmp" = x""yes; then - HAVE__STRICMP_DEFINE=1 -else - HAVE__STRICMP_DEFINE=0 -fi -AC_SUBST(HAVE__STRICMP_DEFINE) - -dnl ======================================================================= -dnl Checks for operating system features. -dnl ======================================================================= - -dnl Non-Unix systems will need to set up their platform configuration file -dnl by hand. -case "$host_os" in - *mingw*) - DIRECTORY_SEPARATOR="\\\\" - ;; - *) - DIRECTORY_SEPARATOR="/" - ;; -esac -AC_SUBST(DIRECTORY_SEPARATOR) - - -dnl ======================================================================= -dnl ABYSS Configuration -dnl ======================================================================= - -AC_MSG_CHECKING(whether to use Abyss pthread function) -AC_ARG_ENABLE(abyss-threads, - [ --disable-abyss-threads Use fork in Abyss instead of pthreads], , - enable_abyss_threads=yes) -AC_MSG_RESULT($enable_abyss_threads) - -ENABLE_ABYSS_THREADS=$enable_abyss_threads -AC_SUBST(ENABLE_ABYSS_THREADS) - -if test x"$enable_abyss_threads" != xno; then - CFLAGS="$CFLAGS -D_THREAD" -fi - - -dnl ======================================================================= -dnl Finding wininet stubs -dnl ======================================================================= -dnl If you implement the parts of wininet.h the wininet_transport uses, -dnl you will need to configure this way.. - -if test $MUST_BUILD_WININET_CLIENT = yes; then - - dnl You can control which of these gets chosen by controlling PATH. - AC_PATH_PROGS(WININET_CONFIG, wininet-xmlrpc-config wininet-config, no) - if test "x$WININET_CONFIG" = "xno"; then - AC_MSG_ERROR(Configure INTERNAL ERROR - first wininet-config found, then not found) - fi - - dnl Get our wininet version. - dnl Adapted from a macro which called gtk-config. - AC_MSG_CHECKING(for wininet version >= 1.0.0) - W3VER=$($WININET_CONFIG --version) - WININET_MAJOR=\ -$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/') - WININET_MINOR=\ -$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/') - WININET_MICRO=\ -$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/') - AC_MSG_RESULT($WININET_MAJOR.$WININET_MINOR.$WININET_MICRO) - - dnl Check to make sure our version is OK. - WININET_VERSION_OK=yes - if test $WININET_MAJOR -lt 1; then - WININET_VERSION_OK=no - else - if test $WININET_MAJOR -eq 1 -a $WININET_MINOR -lt 0; then - WININET_VERSION_OK=no - else - if test $WININET_MAJOR -eq 1 -a $WININET_MINOR -eq 0 \ - -a $WININET_MICRO -lt 0; then - WININET_VERSION_OK=no - fi - fi - fi - if test "x$WININET_VERSION_OK" = "xno"; then - AC_MSG_ERROR(wininet version >= 1.0.0 required) - fi - - dnl Get the necessary CFLAGS, and merge them into our master list. - WININET_CFLAGS=$($WININET_CONFIG --cflags) - AC_SUBST(WININET_CFLAGS) - CFLAGS="$CFLAGS $WININET_CFLAGS" - - dnl Get the huge list of libraries we need to link against. - WININET_LDADD=$($WININET_CONFIG --libs) - AC_SUBST(WININET_LDADD) - - AC_MSG_CHECKING(for wininet library directory) - WININET_LIBDIR="$($WININET_CONFIG --prefix)/lib" - AC_MSG_RESULT($WININET_LIBDIR) - AC_SUBST(WININET_LIBDIR) - -fi # MUST_BUILD_WININET_CLIENT - -dnl ======================================================================= -dnl Finding w3c-libwww -dnl ======================================================================= - -if test $MUST_BUILD_LIBWWW_CLIENT = yes; then - - dnl First of all, locate the libwww config program. - dnl You can control which of these gets chosen by controlling PATH. - AC_PATH_PROGS(LIBWWW_CONFIG, libwww-xmlrpc-config libwww-config, no) - if test "x$LIBWWW_CONFIG" = "xno"; then - AC_MSG_ERROR(Configure INTERNAL ERROR - first libwww-config found, then not found) - fi - - dnl Get our libwww version. - dnl Adapted from a macro which called gtk-config. - AC_MSG_CHECKING(for w3c-libwww version >= 5.2.8) - W3VER=$($LIBWWW_CONFIG --version) - LIBWWW_MAJOR=\ -$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/') - LIBWWW_MINOR=\ -$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/') - LIBWWW_MICRO=\ -$(echo $W3VER|sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/') - AC_MSG_RESULT($LIBWWW_MAJOR.$LIBWWW_MINOR.$LIBWWW_MICRO) - - dnl Check to make sure our version is OK. - LIBWWW_VERSION_OK=yes - if test $LIBWWW_MAJOR -lt 5; then - LIBWWW_VERSION_OK=no - else - if test $LIBWWW_MAJOR -eq 5 -a $LIBWWW_MINOR -lt 2; then - LIBWWW_VERSION_OK=no - else - if test $LIBWWW_MAJOR -eq 5 -a $LIBWWW_MINOR -eq 2 \ - -a $LIBWWW_MICRO -lt 8; then - LIBWWW_VERSION_OK=no - fi - fi - fi - if test "x$LIBWWW_VERSION_OK" = "xno"; then - AC_MSG_ERROR(w3c-libwww version >= 5.2.8 required) - fi - - dnl Get the huge list of libraries we need to link against. - LIBWWW_LDADD=$($LIBWWW_CONFIG --libs) - AC_SUBST(LIBWWW_LDADD) - - AC_MSG_CHECKING(for libwww library directory) - LIBWWW_LIBDIR="$($LIBWWW_CONFIG --prefix)/lib" - AC_MSG_RESULT($LIBWWW_LIBDIR) - AC_SUBST(LIBWWW_LIBDIR) - -fi # MUST_BUILD_LIBWWW_CLIENT - - -dnl ======================================================================= -dnl Finding Curl -dnl ======================================================================= - -if test $MUST_BUILD_CURL_CLIENT = yes; then - - dnl First of all, locate the Curl config program. - dnl You can control which of these gets chosen by controlling PATH. - AC_PATH_PROGS(CURL_CONFIG, curl-xmlrpc-config curl-config, no) - if test "x$CURL_CONFIG" = "xno"; then - AC_MSG_ERROR(Configure INTERNAL ERROR - first curl-config found, then not found) - fi - - dnl There used to be code here to check the Curl version and make sure - dnl it is at least 7.8. But there were bugs both in the code and in - dnl curl (curl-config --vernum, at least in older versions of Curl, - dnl omits the leading zero). So it didn't work. Plus, checking version - dnl numbers isn't a good idea. Better to check for feature presence. - dnl So we don't do any check now. If we find out there's a problem with - dnl older Curls, we will revisit that. - - AC_SUBST(CURL_CONFIG) - - CURL_LDADD=$($CURL_CONFIG --libs) - AC_SUBST(CURL_LDADD) - - AC_MSG_CHECKING(for Curl library directory) - CURL_LIBDIR="$($CURL_CONFIG --prefix)/lib" - - AC_MSG_RESULT($CURL_LIBDIR) - AC_SUBST(CURL_LIBDIR) - -fi # MUST_BUILD_CURL_CLIENT - - -dnl ======================================================================= -dnl Finding OpenSSL -dnl ======================================================================= - -AC_MSG_CHECKING(for OpenSSL library) - -if pkg-config openssl; then - HAVE_OPENSSL=yes - OPENSSL_LDADD=$(pkg-config openssl --libs) - AC_SUBST(OPENSSL_LDADD) - OPENSSL_CFLAGS=$(pkg-config openssl --cflags) - AC_SUBST(OPENSSL_CFLAGS) -else - HAVE_OPENSSL=no -fi - -AC_MSG_RESULT($HAVE_OPENSSL) - -# One really annoying case where the user needs to disable building of -# Openssl-based parts explicitly is where there is no Openssl for the target -# platform but there is for the native platform. In that case, Pkg-config -# finds the openssl.pc in /usr/lib, ignoring the fact that /usr/lib is not in -# the search path specified by the PKG_CONFIG environment variable. This is -# a major design flaw in Pkg-config. - -AC_ARG_ENABLE(abyss-openssl, - [ --disable-abyss-openssl Don't build Abyss Openssl channel function], - , - enable_abyss_openssl=maybe) - -if test $enable_abyss_openssl = maybe; then - if test $HAVE_OPENSSL = no; then - AC_MSG_NOTICE([You don't appear to Openssl installed (no pkg-config file for it in your pkg-config search path), so we will not build the Abyss Openssl channel module]) - MUST_BUILD_ABYSS_OPENSSL=no - else - MUST_BUILD_ABYSS_OPENSSL=yes - fi -else - MUST_BUILD_ABYSS_OPENSSL=$enable_abyss_openssl -fi - -AC_MSG_CHECKING(whether to build Abyss Openssl channel module) -AC_MSG_RESULT($MUST_BUILD_ABYSS_OPENSSL) -AC_SUBST(MUST_BUILD_ABYSS_OPENSSL) - -if test $MUST_BUILD_ABYSS_OPENSSL = yes; then - HAVE_ABYSS_OPENSSL_DEFINE=1 -else - HAVE_ABYSS_OPENSSL_DEFINE=0 -fi - -AC_SUBST(HAVE_ABYSS_OPENSSL_DEFINE) - - -dnl ======================================================================= -dnl Checks for build options. -dnl ======================================================================= - -AC_ARG_WITH(libwww-ssl, - [ --with-libwww-ssl Include libwww SSL capability.] - ) - -if test x"$enable_libwww_client" != xno; then - AC_MSG_CHECKING(whether to use SSL with libwww) - if test x"$with_libwww_ssl" = xyes; then - AC_MSG_RESULT(yes) - HAVE_LIBWWW_SSL_DEFINE=1 - else - AC_MSG_RESULT(no) - HAVE_LIBWWW_SSL_DEFINE=0 - fi -else - HAVE_LIBWWW_SSL_DEFINE=0 -fi -AC_SUBST(HAVE_LIBWWW_SSL_DEFINE) - -dnl Check to see if we should build the libxml2 backend. -AC_ARG_ENABLE(libxml2-backend, - [ --enable-libxml2-backend Use libxml2 instead of built-in expat], , -enable_libxml2_backend=no) -AC_MSG_CHECKING(whether to build the libxml2 backend) -AC_MSG_RESULT($enable_libxml2_backend) - -if test $enable_libxml2_backend = yes; then - AC_CHECK_PROG(have_xml2_config, xml2-config, yes, no) - if test $have_xml2_config = no; then - AC_MSG_ERROR([You specified --enable-libxml2_backend, but don't appear to have libxml2 installed (no working xml2-config in your command search path), so we cannot not build for libxml2]) - fi -fi -ENABLE_LIBXML2_BACKEND=$enable_libxml2_backend -AC_SUBST(ENABLE_LIBXML2_BACKEND) - -dnl ======================================================================= -dnl Compiler information -dnl ======================================================================= -C_COMPILER_GNU=$ac_cv_c_compiler_gnu -AC_SUBST(C_COMPILER_GNU) -CXX_COMPILER_GNU=$ac_cv_cxx_compiler_gnu -AC_SUBST(CXX_COMPILER_GNU) - -dnl obsolete variables, need to be removed from Makefile.in: -CC_WARN_FLAGS= -AC_SUBST(CC_WARN_FLAGS) -CPP_WARN_FLAGS= -AC_SUBST(CPP_WARN_FLAGS) - - -BUILDDIR=$(pwd) -AC_SUBST(BUILDDIR) - -AC_CHECK_TOOL([AR], [ar]) -AC_PROG_RANLIB - -dnl ======================================================================= -dnl Output our results. -dnl ======================================================================= - -dnl Note that AM_CONFIG_HEADER at the top of this file outputs another -dnl result: xmlrpc_amconfig.h . - -AC_OUTPUT( \ - srcdir.mk \ - config.mk \ - xmlrpc_config.h \ - ) - - -if test ! -f GNUmakefile; then - ln -s "${srcdir}/GNUmakefile" . -fi -if test ! -f Makefile; then - ln -s "${srcdir}/Makefile" . -fi -if test ! -f transport_config.mk; then - ln -s "${srcdir}/transport_config.mk" . -fi - - -if test "$MUST_BUILD_WININET_CLIENT $MUST_BUILD_CURL_CLIENT $MUST_BUILD_LIBWWW_CLIENT" = "no no no"; then - AC_MSG_NOTICE([==>]) - AC_MSG_NOTICE([==>We are not building any client XML transport (see earlier messages explaining why), therefore WE WILL NOT BUILD THE CLIENT LIBRARY.]) - AC_MSG_NOTICE([==>]) -fi - - diff --git a/trunk/dll-common.mk b/trunk/dll-common.mk deleted file mode 100644 index 9840709b5..000000000 --- a/trunk/dll-common.mk +++ /dev/null @@ -1,22 +0,0 @@ -# -*-makefile-*- <-- an Emacs control - -# See unix-common.mk for an explanation of this file. This file is -# analogous to unix-common.mk, but is for a Windows system - -SONAME = $@ -IMPLIB = $(@:%:%.dll.a) - -SHLIB_CMD = $(CCLD) $(LDFLAGS_SHLIB) -o $@ $^ $(LADD) - -.PHONY: $(SHLIB_INSTALL_TARGETS) -.PHONY: install-shared-libraries - -SHLIB_INSTALL_TARGETS = $(SHARED_LIBS_TO_INSTALL:%=%/install) - -#SHLIB_INSTALL_TARGETS is like "libfoo/install libbar/install" - -install-shared-libraries: $(SHLIB_INSTALL_TARGETS) - -$(SHLIB_INSTALL_TARGETS):%/install:%.$(SHLIB_SUFFIX) -# $< is a library file name, e.g. libfoo.dll . - $(INSTALL_SHLIB) $< $(DESTDIR)$(LIBINST_DIR)/$< diff --git a/trunk/doc/COPYING b/trunk/doc/COPYING deleted file mode 100644 index 60f77a510..000000000 --- a/trunk/doc/COPYING +++ /dev/null @@ -1,143 +0,0 @@ -The copyright owners of this package license the public to copy it -(and do other things with it which are controlled by copyright law) -under a few simple conditions. - -Each source file describes the copyright license for that particular -file. This file summarizes the licenses for your convenience. - -All the code written specifically for Xmlrpc-c, which is most -of the code, and the aggregation, is licensed under the -XML-RPC FOR C/C++ license shown below. - -Some of the code was written for another purpose and copied into -Xmlrpc-c. Its copyright owners license the code under a different -license: - -The Expat Licence applies to the contents of the directory lib/expat, -the ABYSS Web Server License applies to the contents of the directory -lib/abyss and parts of the file src/xmlrpc_abyss.c. - -The Python 1.5.2 license applies to parts of the file -src/xmlrpc_base64.c. - -And as for the tools/ directory, you'll have to examine the licenses -on your own. - -These same licenses have been offered throughout Xmlrpc-c's history. - - - XML-RPC For C/C++ License - ------------------------- - -Copyright (C) 2001 by First Peer, Inc. All rights reserved. -Copyright (C) 2001 by Eric Kidd. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - - - Expat License - ------------- - -Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - - ABYSS Web Server License - ------------------------ - -Copyright (C) 2000 by Moez Mahfoudh . All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - - - - Python 1.5.2 License - -------------------- - -Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum, -Amsterdam, The Netherlands. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Stichting Mathematisch -Centrum or CWI or Corporation for National Research Initiatives or -CNRI not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -While CWI is the initial source for this software, a modified version -is made available by the Corporation for National Research Initiatives -(CNRI) at the Internet address ftp://ftp.python.org. - -STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH -CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. diff --git a/trunk/doc/CREDITS b/trunk/doc/CREDITS deleted file mode 100644 index 050113a2c..000000000 --- a/trunk/doc/CREDITS +++ /dev/null @@ -1,19 +0,0 @@ -Funding for the project that created the original Xmlrpc-c was -provided in part by the good folks at First Peer, Inc., producers of -P2P applications. - -Eric Kidd developed the original Xmlrpc-c in 2000 and maintained it up -through June 2001. - -Bryan Henderson took over as maintainer in October 2004. - -Xmlrpc-c contains (and relies on for some server functions) a derivation -of the Abyss web server by Moez Mahfoudh. - -Xmlrpc-c contains (and relies on) a derivation of the Expat XML -parser, written by James Clark. - -The base64 code was derived from what Jack Jansen developed for Python. - -For more history, including credits for more minor contributions, see -the HISTORY file. diff --git a/trunk/doc/DEVELOPING b/trunk/doc/DEVELOPING deleted file mode 100644 index d5c53b0e8..000000000 --- a/trunk/doc/DEVELOPING +++ /dev/null @@ -1,82 +0,0 @@ -Here are some notes to help you develop code for Xmlrpc-c. I include -as "developing" debugging to figure out why Xmlrpc-c doesn't work for -you. - -CODE LIBRARY ------------- - -The master Xmlrpc-c source code tree is the CVS repository on -Sourceforge. Anybody can read it; only the maintainer can commit to -it. If you're not the maintainer, simply use a 'cvs diff' command in -your CVS working directory to create a patch file that embodies your -changes and email that to the maintainer. He can easily apply that -patch to his own CVS working directory and then commit the changes. - - -MAKE VARIABLES --------------- - -You can pass make variable values to GNU Make to change the build. -There are two common ways to do this: - - 1) Like this: - - $ make MYVAR=myvalue - - 2) Via an environment variable, like this: - - $ MYVAR=myvalue make - - or - - $ export MYVAR=myvalue - $ make - -See GNU Make and shell documentation for details. - -In Xmlrpc-c make files, there are two make variables that add -arbitrary options to every compile command: CADD and CFLAGS_PERSONAL. - -They both do the same thing. CADD is meant to be set on an individual -make command, whereas CFLAGS_PERSONAL is meant to be a long-lived -environment variable. CFLAGS_PERSONAL is for flags you like on all -your compiles, but maybe others don't. - -One of my favorite CADD settings is CADD=--save-temps. To the GNU -Compiler, --save-temps means to create, in addition to the object -code, a file containing the intermediate preprocessed C code and a -file containing the intermediate assembler source code. I can use -that to debug certain things. - -The Xmlrpc-c build uses -g by default with Gcc, so you don't need to -use CADD to get debugging symbols in your object code. - - -There's also LADD for linker options. - - -CODE STYLE ----------- - -The maintainer is pretty particular about coding style, but doesn't -require anyone to submit code in any particular style. He changes -what he thinks isn't maintainable enough as submitted. You could do -him a big favor, though, and reduce the chance of him introducing bugs -into your code, but trying to copy the style you see in existing code. -The major theme is high level programming -- closer to English prose -and further from machine instructions. - -Probably the most important thing is not to use tabs. Tabs are -actually quite common in Unix C programming, but apart from tradition, -they are a bad idea. They don't look the same to everyone. A person -must suffer an additional configuration step -- setting up tab stops -in order to see the code the right way. Spaces, on the other hand, -look the same to everyone. Very old editors made it easier to compose -with tabs than with spaces, but with modern ones, there is no -difference. - -The maintainer tries to catch all tabs in code submitted to him and -convert them to spaces, but this often leaves the code incorrectly -indented. Better to give him code that already has the right number -of spaces explicitly. - diff --git a/trunk/doc/HISTORY b/trunk/doc/HISTORY deleted file mode 100644 index c591993ec..000000000 --- a/trunk/doc/HISTORY +++ /dev/null @@ -1,61 +0,0 @@ -For a release-by-release change history, see -. - -XML-RPC For C/C++ was created by Eric Kidd in 2000, when XML-RPC was -new and vital. Its development was funded in significant part by -First Peer, Inc. Eric released the package in January 2001 and set up -an extensive project to maintain it. The project used virtually every -feature on Sourceforge, had about 8 official developers, and -distributed code in various formats. There were mailing lists, -trackers, CVS branches, RPMs, and a full PHP-based web site, just to -name a few features of the project. - -Then everything ground to a halt in June 2001, with the disappearance -of Eric. We don't know what happened to him, but Google searches in -late 2004 indicated he dropped off the face of the web at that time. -While people continued to use Xmlrpc-c, and some developed fixes and -enhancements and posted them to the Sourceforge trackers, the release -remained frozen at 0.9.10. The web site also became frozen in time. - -In the years that followed the great freeze, XML-RPC became -marginalized by more sophisticated alternatives such as SOAP. XML-RPC -consequently became rather stable and interest in Xmlrpc-c levelled -off. - -This dark age of Xmlrpc-c lasted until October 2004, when Bryan Henderson -set out to find an RPC mechanism to use in one of his projects. Bryan -found XML-RPC and then Xmlrpc-c. He decided that the two were almost right -for his needs, but he needed some small extensions. - -On finding out that the project was orphaned, Bryan decided to take it -over. Bryan became the Sourceforge project administrator through -Sourceforge's abandonned project process, then gathered the patches -that had been submitted over the years and made a come-back release -called 1.0. - -Bryan then proceeded to add a lot of features in subsequent releases -about every two months. Most of it was code Bryan wrote himself, but -significant parts were contributed by others, as you can see in the -detailed history below. Among the larger enhancements was a new -C++ interface; the old one was a fairly weak wrapper around the -C interface and required the user to manage memory and access the -underlying C structures; the new one used pure C++ principles with -automatic memory management. - -Bryan also wrote a complete user's manual. Surprisingly, in spite of -the wide array of features the project had, documentation wasn't one -of them. There was only a smattering of information available on how -to use the package. - -One significant change Bryan made to the project was to strip it down -considerably. In order to concentrate the small amount of time Bryan -had available for Xmlrpc-c development on actual code and -documentation, Bryan had to greatly reduce the amount of bureaucracy -involved in administering the project and making releases, and reduce -the set of skills required to do it. Bryan made static make files -(for GNU Make) to replace the two extra build stages that originally -generated make files. Bryan moved away from Libtool and toward simple -compiling and linking. Bryan eliminated all pre-built distributions; -each of his releases consisted of a single source code tarball, and -that tarball was not signed. Bryan removed some redundant sources of -information from the package and the web site. diff --git a/trunk/doc/INSTALL b/trunk/doc/INSTALL deleted file mode 100644 index 2779b3aea..000000000 --- a/trunk/doc/INSTALL +++ /dev/null @@ -1,246 +0,0 @@ -These are instructions for building Xmlrpc-c from source and installing -it on a system. - -See the README file for information on prerequisites (things you need to -have installed before you can build). - - -Essentially, it's just the conventional - - $ ./configure - $ make - $ make install - -And on Linux systems, you'll usually also need: - - $ ldconfig - -To build handy tools such as the 'xmlrpc' command line XML-RPC client: - - $ cd tools - $ make - $ make install - -You can also do - - $ make check - -to run a battery of tests before you install. But note that it's as common -for the tests to fail because the tests are broken as because the product -is broken, so consider the results carefully. - -To see it work, build and run a simple server like this: - - $ cd examples - $ make - $ ./xmlrpc_sample_add_server 8080 - -That runs forever, serving clients as they arrive. Now, from another -shell, run a client that does an RPC to this server: - - $ ./xmlrpc_sample_add_client - -Also try other example servers and clients, described in examples/README. - - -You may want to pass a '--prefix' argument to 'configure'. See -'./configure --help' for details. - -You may also want to disable client XML transports that you won't be -using. In particular, the Libwww transport can be inconvenient, because -it typically uses about 20 shared libraries. Any XML-RPC client -program that uses Xmlrpc-c, whether or not the program uses any of the -libwww facilities, must attach all those libraries, and that can take -a significant amount of time. - -See './configure --help' for the options that disable certain transports. - - -LDCONFIG --------- - -On systems that use the GNU C Library (usually Linux), you often have to run -the program 'ldconfig' after installing the shared libraries of Xmlrpc-c. If -you don't, when you try to run a program that uses an Xmlrpc-c library, you -get an error message telling you it can't find the library. - -This is because the usual way that the dynamic (shared) library loader finds -libraries is through the file /etc/ld.so.cache, which is a directory of most -of the shared libraries on the system. 'ldconfig' is what updates that -directory. It searches various places that shared libraries might be, -including the place you probably installed the Xmlrpc-c shared libraries, and -records all their locations, indexed by the library's soname. - -If you suspect a problem with your shared library lookup, you can use the -command - - $ ldconfig -p - -to list out the directory (i.e. the information in /etc/ld.so.cache). - -But this directory is not the only way the OS can find a shared library, so -'ldconfig' may not be required or helpful in your circumstance. Another way -to tell the OS how to find shared libraries is through the environment -variable LD_LIBRARY_PATH. If that value includes the directory in which you -installed the Xmlrpc-c libraries, the OS should be able to find them -regardless of what is in the directory. - - -SEPARATE BUILD TREE -------------------- - -While it's traditional to build a Unix package by adding object files -to the same tree with the source files, it's actually much cleaner to -keep your source tree exactly as you got it and put the built files in -a separate directory, called the build tree. - -To do this, just create an empty directory and run 'configure' in it, -then 'make': - - mkdir xmlrpcbuild - cd xmlrpcbuild - /usr/src/xmlrpc-c/configure - ... - make - -But if you plan to work on Xmlrpc-c source code, you'll probably find -it more convenient to build the traditional way, with a single tree -for source and build. - -In the source tree, you can type 'make' in any directory to do the -default make for that directory, or make FILENAME to make the file of -that name there. In the separate build tree, there are special -facilities to allow you to do a simple make from the _top level -directory_, but if you want to make a subcomponent or individual part, -you have to have a -f option and set SRCDIR and BLDDIR on your 'make' -command. - - -CROSS-COMPILING ---------------- - -Cross compiling is building code on one machine to be run on another, -particularly when the two machines are different enough that it matters, -e.g. one executes x86 instructions and the other executes PowerPC -instructions. - -The machine that will run the code is called the target machine. The one -that will build the code is the build machine. - -To cross-compile, you set up nearly all of the build environment for the -target machine (that includes such things as the default include file search -path for the compiler and library search path for the linker). On your -'configure' command, you use a --host option to identify the kind of target -machine (rather than let it default to the kind of machine on which -'configure' is running). It's a nontrivial task, and beyond the scope of -this document as it is not specific to Xmlrpc-c, to determine what value -to use for --host. - -There is one area that requires special attention and is specific to Xmlrpc-c: -The Xmlrpc-c build does part of its job by compiling a program from C source -code and running that program as part of the build. That compile, unlike all -the regular ones, must be done for the build machine, not the target -machine. - -To facilitate that, there are the make variables CC_FOR_BUILD, -CFLAGS_FOR_BUILD, and LDFLAGS_FOR_BUILD. - -CC_FOR_BUILD is the command name for the appropriate compiler with which to -build a build tool, i.e. a compiler that generates code to run on the build -system. It is also the command name for the linker, which obviously has to be -the the kind of linker command that invokes a combined compiler/linker, -e.g. "gcc" instead of "ld". - -CFLAGS_FOR_BUILD and LD_FLAGS_FOR_BUILD are options for the compile and -link commands, respectively, used to build build tools. - -You can set these make variables on the Make command line, or if you prefer, -by modifying the file 'config.mk' after 'configure' creates it. The default -value of these variables (as set in 'config.mk') are the same as for building -target code. - -(There is probably a way to do this with GNU Autoconf facilities, using -'configure --build=XXX' and avoid the CC_FOR_BUILD complication. If you know -how (without using Automake), tell the Xmlrpc-c maintainer and he will change -the build system to use it). - - -SKIPPING SHARED LIBRARY BUILD/INSTALL -------------------------------------- - -To build just the static libraries, not the shared (dynamically linked) -libraries, set make variable MUST_BUILD_SHLIB to "N": - - $ make MUST_BUILD_SHLIB=N - -You can add this setting to the bottom of the 'config.mk' file that -'configure' generates if that is more convenient. - -Alternatively, you could just build and install normally and delete the shared -libraries afterward. That normally works. - - -COMMON PROBLEMS ---------------- - -Improper -config files ----------------------- - -The most common problem building Xmlrpc-c is one of improperly installed -prerequisite libraries, namely Libwww and Curl. These libraries are -designed to be installed along with a -config program (libwww-config -and curl-config) that tells builders of dependent packages (such as -Xmlrpc-c) how to use them. When the -config program is wrong, you get -Xmlrpc-c build failures with messages about undefined references. - -The exact nature of the problems with -config programs can be quite -involved, especially since there is no guarantee that a -config -program can do what's required of it in every situation. But I'll -explain the basic problem. For simplicity, I'll talk specifically -about Curl, but the principles apply to any library that has a -config -program. - -The point of curl-config is to describe how Curl is installed on your -particular system. You have choices of where to install the various parts -and what prerequisites to build into them, and curl-config is how you -communicate those choices to the Xmlrpc-c make files. - -Curl's builder automatically creates a curl-config program for you, -but you should not think of it as part of Curl. It's really a -configuration file -- something that tells how your particular system -is put together. The Curl builder is not smart enough to know exactly -what to put in curl-config; it just builds one that works for most -people. The local system administrator is actually responsible for -the contents of curl-config. - -One rather complex way in which the curl-config that the Curl builder -builds can be wrong is that it often indicates that to link to the -Curl library, you need a "-L /usr/lib" option (or something like that --- an option that adds to the linker's search path a directory that is -already in it). This is usually unnecessary because the directory is -already in the search path, and often breaks things because it puts -the directory too early in the search path. If your curl-config says to -link with -L /usr/lib, you should normally edit it to remove that. - -As an example of how -L /usr/lib breaks things, here is a problem that -is often reported: The user has Xmlrpc-c installed on his system, but -wants to build a new one to replace it, or to use for a particular -project instead of the system version. But the build of the new -version fails with undefined references to symbol "xmlrpc_foo". -xmlrpc_foo is a new symbol - it was added to Xmlrpc-c in a recent -release. The version of Xmlrpc-c installed on the system is too old -to have it. The make file obviously specifies the path to the current -libraries that the user just built in the link library search order, -but the link is picking up the old system version instead. Why? -Because the link options say to search /usr/lib _before_ the local -build directory. And they do that because curl-config erroneously -says that you need a -L /usr/lib link option to find the Curl library. - - -WINDOWS -------- - -All of the above is essentially for Unix-type operating systems. To -build and use Xmlrpc-c on Windows, see the file -Windows/ReadMeWin32.txt. - diff --git a/trunk/doc/SECURITY b/trunk/doc/SECURITY deleted file mode 100644 index c3566c2c4..000000000 --- a/trunk/doc/SECURITY +++ /dev/null @@ -1,50 +0,0 @@ -Security Advisories -=================== - -The Xmlrpc-c maintainer will normally post security advisories related -to xmlrpc-c to the xmlrpc-c-announce mailing list. You can subscribe -to this using the web: - - http://xmlrpc-c.sourceforge.net/lists.php - -You will also find a list of all known bugs including those with -security ramifications, in the release notes on Sourceforge. To see -the release notes for a release, go to the file download page and -click on the release name. The list is current only for the most -current release -- i.e. we stop adding to the list for release N after -we release N+1. - - -XML-RPC Security -================ - -There are some security issues inherent in XML-RPC: - - 1) XML-RPC messages are not encrypted at the XML-RPC level. This - means that unless you encrypt them at some lower level, someone - with sufficient access to the network can see them with standard - packet-sniffing and network administration tools. - - This is especially dangerous because XML-RPC is a stateless protocol. - If you include reusable authentication tokens in an XML-RPC call, they - can probably be sniffed and used by attackers. - - You can solve this problem by using SSL under HTTP. This is possible - with Xmlrpc-c, but it's nontrivial to set up and the Xmlrpc-c - documentation doesn't tell you how. - - 2) There are no permission restrictions and no authentication built - into Xmlrpc-c by default -- any client can call any method on any - visible server and neither can know for sure to whom it is talking. - - If you need permission and authentication, you either have to put - it above the XML-RPC layer or below. For a server, above means in - the method code you supply and register with the Xmlrpc-c server - facilities; below means something like a firewall that lets clients - only from a certain IP address connect to your server. - - 3) XML-RPC is a complex protocol based on complex data structures. - Layers and layers of potentially buggy code gets run between the - time network data is received, and the time it is understood; and - conversely between the time data is conceived and the time it - gets sent. diff --git a/trunk/doc/TESTING b/trunk/doc/TESTING deleted file mode 100644 index 50d785d4a..000000000 --- a/trunk/doc/TESTING +++ /dev/null @@ -1,96 +0,0 @@ -In general, we want to run as many automated test tools on the -Xmlrpc-c libraries as possible. Before releasing a new release, -please run as many of these tests as possible. - - -Included Test Suites --------------------- - -The 'test' program tests core functions. These are functions that -don't involve HTTP communications. So obviously, it doesn't do any -end-to-end client/server tests. - -The program is in src/test/test. You have to build that explicitly (with -src/test/ as your current directory, do a 'make'); a top level 'make all' -doesn't build it. (Reason: it's a tricky build, and we don't a user's -build to fail just because of this program that a user doesn't need). - -src/cpp/cpptest is similar for the C++ libraries. - -Note: Before Release 1.03, 'test' was called 'rpctest' and both it -and 'cpptest' were in the src/ directory and were built by 'make all'. - - -Memory Leaks ------------- - -(Linux only?) Install Owen Taylor's 'memprof' utility. This program -includes a malloc debugger and a conservative garbage collector. To run it, -type: - - memprof test - -This should report any memory leaks which occur while the test suites are -running. - - -Electric Fence --------------- - -(Most Unix platforms.) Install Bruce Perens' Electric Fence library, and -read the man pages carefully. Link 'test' against '-lefence', and run it -with the following sets of environment variables: - - 1) (Default environment.) - Test for heap block overruns. - - 2) EF_PROTECT_BELOW=1 - Test for heap block underruns. - - 3) EF_PROTECT_FREE=1 - Test for doubly-freed memory and illegal accesses to freed memory. - - 4) EF_ALIGNMENT=0 - Test for very small block overruns. This is an important test, but - it may not work on some platforms. Please see the efence manpage for - more information. - -(After each run, unset the environment variables from the previous run.) - -Using a Bourne shell (such as bash) you can run all these tests as follows: - - test - EF_PROTECT_BELOW=1 test - EF_PROTECT_FREE=1 test - EF_ALIGNMENT=0 test - -Alternatively, if you have a copy of Purify installed, please run that. - - -End-to-End Tests ----------------- - -To test Abyss and the client XML transports, use the example -programs examples/sample_add_server and examples/sample_add_client: - - $ export XMLRPC_TRACE_XML=1 - $ examples/sample_add_server 8080& - $ examples/sample_add_client - -Note that we use XMLRPC_TRACE_XML so we can see the XML flying by on -both sides of the connection. - -Note that the Port 8080 is hardcoded in sample_add_client. - -Note that sample_add_client uses only the default XML transport. - - -You can do more extensive client testing with the 'xmlrpc' program -(tools/xmlrpc/xmlrpc). - - -Tips ----- - -To debug Abyss without threads, don't pass -D_UNIX or -D_WIN32. The server -will run in a single-threaded mode. diff --git a/trunk/doc/TODO b/trunk/doc/TODO deleted file mode 100644 index 8fa279958..000000000 --- a/trunk/doc/TODO +++ /dev/null @@ -1,60 +0,0 @@ -Here are some changes we'd like to see to Xmlrpc-c. While it's unlikely -anyone will ever do them, the list is at least useful as an indication of -what direction the maintainer wants the package to take, and that should -be useful to anyone proposing changes of any kind. - - -FUNCTIONAL CHANGES ------------------- - -Put details in the manual for the xmlrpc-c/server_abyss.hpp interface: -libxmlrpc_server_abyss++.html. - -Implement pluggable XML transports on the server side like on the -client side. - -Create a non-XML non-HTTP efficient transport, client and server. -The tools/binmode-rpc-kit/ directory might be useful. Consider XDR. - -Change the argument order of asynchronous response callbacks to be -more consistent with the xmlrpc_client_call_asynch function. Also -take a look at the server method callback. - -Make an optional destructor function for XMLRPC_TYPE_C_PTR. - -Return XMLRPC_LIMIT_EXCEEDED_ERROR when nesting limits are exceeded. -This will break binary and source API compatibility in a very minor -way. - -Expand the Perl interface to Xmlrpc-c libraries to do server functions. -Maybe match some other features of RPC::XML. - -Don't use xmlrpc_value for things that aren't part of an XML-RPC call or -response. It's confusing. In particular, we use an xmlrpc_value -array to pass the parameters of an RPC to xmlrpc_client_call(), and it -should instead be a normal C array plus count, or variable argument list. - -Don't use XML-RPC fault codes internally. It's confusing. Plus, there's -no need for fault codes at all. Just use the string descriptions. - -Add a function to deregister a method from a method registry. - -Add a "registry" type that works via a filesystem directory. There is -a .so file for each method with its code, and probably a configuration -file. Make it dynamically updatable. - - -IMPLEMENTATION CHANGES ----------------------- - -Use function pointers to access cleanup code in xmlrpc_DECREF? - -Or even better: Should we create some kind of class-like system to declare -XML-RPC types, with a per-type dispatch table? - -Fix abstract XML parser API to access children via functions named -xml_element_child(env,elem,index) and xml_element_child_count(env,elem). -Clean up corresponding client code. - -Make the C++ server implementation less based on the C functions. - diff --git a/trunk/doc/configure_doc b/trunk/doc/configure_doc deleted file mode 100644 index 953a9044a..000000000 --- a/trunk/doc/configure_doc +++ /dev/null @@ -1,189 +0,0 @@ -Xmlrpc-c's 'configure' program is a GNU Autoconf configurator -- i.e. -it is created by GNU Autoconf. This is the standard configurator you -find throughout the open source software world. Here are the instructions -for 'configure' from GNU Autoconf; in most packages, you find these in -a file called INSTALL. - - -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, a file -`config.cache' that saves the results of its tests to speed up -reconfiguring, and a file `config.log' containing compiler output -(useful mainly for debugging `configure'). - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If at some point `config.cache' -contains results you don't want to keep, you may remove or edit it. - - The file `configure.in' is used to create `configure' by a program -called `autoconf'. You only need `configure.in' if you want to change -it or regenerate `configure' using a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. You can give `configure' -initial values for variables by setting them in the environment. Using -a Bourne-compatible shell, you can do that on the command line like -this: - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure - -Or on systems that have the `env' program, you can do it like this: - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not supports the `VPATH' -variable, you have to compile the package for one architecture at a time -in the source code directory. After you have installed the package for -one architecture, use `make distclean' before reconfiguring for another -architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' can not figure out -automatically, but needs to determine by the type of host the package -will run on. Usually `configure' can figure that out, but if it prints -a message saying it can not guess the host type, give it the -`--host=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name with three fields: - CPU-COMPANY-SYSTEM - -See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the host type. - - If you are building compiler tools for cross-compiling, you can also -use the `--target=TYPE' option to select the type of system they will -produce code for and the `--build=TYPE' option to select the type of -system on which you are compiling the package. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Operation Controls -================== - - `configure' recognizes the following options to control how it -operates. - -`--cache-file=FILE' - Use and save the results of the tests in FILE instead of - `./config.cache'. Set FILE to `/dev/null' to disable caching, for - debugging `configure'. - -`--help' - Print a summary of the options to `configure', and exit. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--version' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`configure' also accepts some other, not widely useful, options. diff --git a/trunk/dylib-common.mk b/trunk/dylib-common.mk deleted file mode 100644 index ee5f47f11..000000000 --- a/trunk/dylib-common.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -*-makefile-*- <-- an Emacs control - -# See unix-common.mk for an explanation of this file. This file is -# analogous to unix-common.mk, but is for a Darwin/Mac OSX system. - -SONAME = $(@:%.$(MIN)=%) - -SHLIB_CMD = $(CCLD) $(LADD) $(LDFLAGS_SHLIB) -o $@ $^ - -SHLIBPP_CMD = $(CXXLD) $(LADD) $(LDFLAGS_SHLIB) -o $@ $^ - -SHLIB_LE_TARGETS = $(call shliblefn, $(SHARED_LIBS_TO_BUILD)) - -$(SHLIB_LE_TARGETS):%.$(SHLIB_SUFFIX):%.$(MAJ).$(MIN).$(SHLIB_SUFFIX) - rm -f $@ - $(LN_S) $< $@ - - -.PHONY: $(SHLIB_INSTALL_TARGETS) -.PHONY: install-shared-libraries - -SHLIB_INSTALL_TARGETS = $(SHARED_LIBS_TO_INSTALL:%=%/install) - -#SHLIB_INSTALL_TARGETS is like "libfoo/install libbar/install" - -install-shared-libraries: $(SHLIB_INSTALL_TARGETS) - -$(SHLIB_INSTALL_TARGETS):%/install:%.$(MAJ).$(MIN).$(SHLIB_SUFFIX) -# $< is a library file name, e.g. libfoo.so.3.1 . - $(INSTALL_SHLIB) $< $(DESTDIR)$(LIBINST_DIR)/$< - cd $(DESTDIR)$(LIBINST_DIR); \ - rm -f $(<:%.$(MIN).$(SHLIB_SUFFIX)=%.$(SHLIB_SUFFIX)); \ - $(LN_S) $< $(<:%.$(MIN).$(SHLIB_SUFFIX)=%.$(SHLIB_SUFFIX)) - cd $(DESTDIR)$(LIBINST_DIR); \ - rm -f $(<:%.$(MAJ).$(MIN).$(SHLIB_SUFFIX)=%.$(SHLIB_SUFFIX)); \ - $(LN_S) $(<:%.$(MIN).$(SHLIB_SUFFIX)=%.$(SHLIB_SUFFIX)) \ - $(<:%.$(MAJ).$(MIN).$(SHLIB_SUFFIX)=%.$(SHLIB_SUFFIX)) diff --git a/trunk/examples/Makefile b/trunk/examples/Makefile deleted file mode 100644 index 9221491c8..000000000 --- a/trunk/examples/Makefile +++ /dev/null @@ -1,158 +0,0 @@ -# Since the programs in this directory are examples for the user, this make -# file should be as ordinary as possible. It should not rely heavily on -# included make files or configuration parameters. Also, we don't try to -# build or rebuild the libraries on which these programs depend or even -# recognize that they've changed on their own. - - -ifeq ($(SRCDIR),) -SRCDIR = $(CURDIR)/.. -BLDDIR = $(SRCDIR) -endif -SUBDIR = examples - -include $(BLDDIR)/config.mk - -default: all - -CFLAGS_ALL = $(CFLAGS_PERSONAL) $(CFLAGS) $(CADD) -LDFLAGS_ALL = $(LDFLAGS_PERSONAL) $(LDFLAGS) $(LADD) - -# If this were a real application, working from an installed copy of -# Xmlrpc-c, XMLRPC_C_CONFIG would just be 'xmlrpc-c-config'. It would be -# found in the user's PATH. -XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test - -CLIENTPROGS = \ - auth_client \ - compound_value_client \ - synch_client \ - xmlrpc_sample_add_client \ - xmlrpc_asynch_client \ - -ifeq ($(MUST_BUILD_CURL_CLIENT),yes) - ifneq ($(MSVCRT),yes) - CLIENTPROGS += curl_client - CLIENTPROGS += interrupted_client - endif -endif - -SERVERPROGS_CGI = \ - xmlrpc_sample_add_server.cgi - -SERVERPROGS_ABYSS = \ - compound_value_server \ - xmlrpc_inetd_server \ - xmlrpc_socket_server \ - xmlrpc_loop_server \ - xmlrpc_sample_add_server \ - xmlrpc_server_validatee \ - -ifneq ($(MSVCRT),yes) - SERVERPROGS_ABYSS += interrupted_server -endif - -ifeq ($(MUST_BUILD_ABYSS_OPENSSL),yes) - SERVERPROGS_ABYSS += ssl_server ssl_secure_server -endif - -BASIC_PROGS = \ - json \ - gen_sample_add_xml \ - -# Build up PROGS: -PROGS = - -PROGS += $(BASIC_PROGS) - -ifeq ($(ENABLE_ABYSS_SERVER),yes) - PROGS += $(SERVERPROGS_ABYSS) -endif - -ifeq ($(MUST_BUILD_CLIENT),yes) - PROGS += $(CLIENTPROGS) -endif - -ifeq ($(ENABLE_CGI_SERVER),yes) - PROGS += $(SERVERPROGS_CGI) -endif - -INCLUDES = -I. $(shell $(XMLRPC_C_CONFIG) client abyss-server --cflags) - -LIBS_CLIENT = \ - $(shell $(XMLRPC_C_CONFIG) client --libs) - -LIBS_SERVER_ABYSS = \ - $(shell $(XMLRPC_C_CONFIG) abyss-server --libs) - -LIBS_SERVER_CGI = \ - $(shell $(XMLRPC_C_CONFIG) cgi-server --libs) - -LIBS_BASE = \ - $(shell $(XMLRPC_C_CONFIG) --libs) - -all: $(PROGS) - -ifeq ($(ENABLE_CPLUSPLUS),yes) - all: cpp/all -endif - -.PHONY: cpp/all -cpp/all: $(BLDDIR)/examples/cpp - $(MAKE) -C cpp -f $(SRCDIR)/examples/cpp/Makefile all - -# When building in separate tree, directory won't exist yet -$(BLDDIR)/examples/cpp: - mkdir $@ - -$(CLIENTPROGS):%:%.o - $(CCLD) -o $@ $^ $(LIBS_CLIENT) $(LDFLAGS_ALL) - -$(SERVERPROGS_CGI):%.cgi:%_cgi.o - $(CCLD) -o $@ $^ $(LIBS_SERVER_CGI) $(LDFLAGS_ALL) - -$(SERVERPROGS_ABYSS):%:%.o - $(CCLD) -o $@ $^ $(LIBS_SERVER_ABYSS) $(LDFLAGS_ALL) - -$(BASIC_PROGS):%:%.o - $(CCLD) -o $@ $^ $(LIBS_BASE) $(LDFLAGS_ALL) - - -OBJECTS = $(patsubst %,%.o,$(patsubst %.cgi,%_cgi,$(PROGS))) - -$(OBJECTS):%.o:%.c - $(CC) -c $(INCLUDES) $(CFLAGS_ALL) $< - -# config.h just describes the build environment. We use it so that the -# example programs will build in users' various environments. If you're -# copying these examples, you can just remove this header from the programs -# and hardcode whatever is right for your build environment. - -$(OBJECTS): config.h - -config.h: - $(LN_S) $(BLDDIR)/xmlrpc_config.h $@ - -.PHONY: clean -clean: - rm -f $(PROGS) *.o config.h - $(MAKE) -C cpp clean - -.PHONY: distclean -distclean: clean - -.PHONY: install -install: - -.PHONY: uninstall -uninstall: - -.PHONY: check -check: - -.PHONY: dep depend -dep depend: -# We don't do dependencies in this directory, because it's supposed to be -# an example of what a program outside this package would do, so we can't -# go weaving it into the rest of the package. Ergo, a developer must -# carefully clean and remake examples as he updates other parts of the tree. diff --git a/trunk/examples/README b/trunk/examples/README deleted file mode 100644 index f5fb5bf94..000000000 --- a/trunk/examples/README +++ /dev/null @@ -1,35 +0,0 @@ -This directory contains working examples of uses of XML-RPC-c. There are -XML-RPC server programs and XML-RPC client programs that use the Xmlrpc-c -libraries. - -The make file is a combination of an example of how to build programs that use -Xmlrpc-c libraries and something that actually does build the programs in this -directory. As such, it isn't perfect for either of those purposes. To build -the examples, you must first build the libraries (make dependencies will not -take care of that for you). Do that by running a default 'make' in the top -level source directory. Then you can issue a simple 'make' in this directory. - -A default make in the root of the Xmlrpc-c source directory does not build -this directory, but a 'make all' does. - - -The simplest server program is 'xmlrpc_sample_add_server'. This -implements a single XML-RPC method called 'sample.add'. All it does is -add two numbers and return the sum. You can run such a server like -this: - - $ ./xmlrpc_sample_add_server 8080 - -The server this runs is based on the Abyss HTTP server. file. The -argument tell it to listen on TCP Port 8080 for RPCs. It puts log -information in /tmp, so be sure to look there. - -A client program that goes along with this server is -'xmlrpc_sample_add_client'. All this client does is make an XML-RPC -request to Port 8080 of 'localhost' to add the numbers 5 and 7 and -print the result on Standard Output. - -You can run such a client like this: - - $ ./xmlrpc_sample_add_client - diff --git a/trunk/examples/auth_client.c b/trunk/examples/auth_client.c deleted file mode 100644 index 70f26636e..000000000 --- a/trunk/examples/auth_client.c +++ /dev/null @@ -1,84 +0,0 @@ -/* A demonstration of using HTTP basic authentication with XML-RPC. -** -** In general, you shouldn't write XML-RPC servers which require basic -** authenticaion. (Few XML-RPC clients are capable of it, and it's not part of -** any standard.) Instead, you should pass any authentication information -** as a regular XML-RPC parameter (or look into using SSL). -** -** But certain XML-RPC servers, including Zope, rely heavily on HTTP -** basic authentication. Here's how to talk to them. */ - -#include -#include - -#include -#include - -#include "config.h" /* information about this build environment */ - -#define NAME "XML-RPC C Auth Client" -#define VERSION "1.0" -#define SERVER_URL "http://localhost:8080/RPC2" - - - -static void -die_if_fault_occurred(xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "XML-RPC Fault: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -int -main(int const argc, - const char ** const argv) { - - xmlrpc_env env; - xmlrpc_server_info * serverP; - xmlrpc_value * resultP; - xmlrpc_int sum; - - if (argc-1 > 0) { - fprintf(stderr, "There are no arguments. You specified %d", argc-1); - exit(1); - } - - /* Start up our XML-RPC client library. */ - xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION); - xmlrpc_env_init(&env); - - /* Make a new object to represent our XML-RPC server. */ - serverP = xmlrpc_server_info_new(&env, SERVER_URL); - die_if_fault_occurred(&env); - - /* Set up our authentication information. */ - xmlrpc_server_info_set_basic_auth(&env, serverP, "jrandom", "secret"); - die_if_fault_occurred(&env); - - resultP = - xmlrpc_client_call_server( - &env, serverP, "sample.add", "(ii)", - (xmlrpc_int32) 5, (xmlrpc_int32) 7); - die_if_fault_occurred(&env); - - /* Dispose of our server object. */ - xmlrpc_server_info_free(serverP); - - /* Get the result of the RPC and print it out. */ - xmlrpc_read_int(&env, resultP, &sum); - die_if_fault_occurred(&env); - printf("The sum is %d\n", sum); - - /* Dispose of our result value. */ - xmlrpc_DECREF(resultP); - - /* Shut down our XML-RPC client library. */ - xmlrpc_env_clean(&env); - xmlrpc_client_cleanup(); - - return 0; -} diff --git a/trunk/examples/compound_value_client.c b/trunk/examples/compound_value_client.c deleted file mode 100644 index e46eef4d1..000000000 --- a/trunk/examples/compound_value_client.c +++ /dev/null @@ -1,160 +0,0 @@ -/* An XML-RPC client program written in C, as an example of using - compound XML-RPC values. - - For a simple client program that just deals with integer values, - see xmlrpc_sample_add_client.c. This example focuses just on the - compound XML-RPC values and not the client functions. - - This client invokes the example.divide XML-RPC method that the example - server program compound_value_server.c provides. That method takes a - list of pairs of numbers and returns the list of their quotients. - - Compound XML-RPC values are arrays and structures. We call them compound - because they are made up of other XML-RPC values (e.g. an array of XML-RPC - integers). - - The arguments to the example.divide method are specified as follows: - - There are two arguments: - - Argument 0: Integer. Version number of this argument protocol. Must - be 1. - - Argument 1: Array. One element for each pair of numbers you want the - server to divide. Each element is structure, with these - members: - - KEY: "dividend" - VALUE: floating point number. The dividend. - - KEY: "divisor" - VALUE: floating point number. The divisor. - - The result of the method is an array. It has one member for each pair of - numbers in the arguments (So it is the same size as Argument 1). That - member is a floating point number. It is the quotient of the numbers - in the corresponding element of Argument 1. - - The client sends the RPC to the server running on the local system - ("localhost"), HTTP Port 8080. -*/ - -#include -#include - -#include -#include - -#include "config.h" /* information about this build environment */ - -#define NAME "Xmlrpc-c Test Client" -#define VERSION "1.0" - -static void -dieIfFaultOccurred (xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "ERROR: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -struct ratio { - double dividend; - double divisor; -}; - - - -int -main(int const argc, - const char ** const argv) { - - const char * const serverUrl = "http://localhost:8080/RPC2"; - const char * const methodName = "example.divide"; - unsigned int const argVersion = 1; - struct ratio const data[] = {{1,2},{12,3},{10,3},{89,3000}}; - xmlrpc_env env; - xmlrpc_value * resultP; - unsigned int i; - xmlrpc_value * ratioArrayP; - unsigned int quotientCt; - - if (argc-1 > 0) { - fprintf(stderr, "This program has no arguments\n"); - exit(1); - } - - xmlrpc_env_init(&env); - - xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0); - dieIfFaultOccurred(&env); - - /* Build the 2nd method argument: the array of ratios */ - - ratioArrayP = xmlrpc_array_new(&env); - dieIfFaultOccurred(&env); - - for (i = 0; i < 4; ++i) { - xmlrpc_value * dividendP; - xmlrpc_value * divisorP; - xmlrpc_value * ratioP; - - dividendP = xmlrpc_double_new(&env, data[i].dividend); - dieIfFaultOccurred(&env); - divisorP = xmlrpc_double_new(&env, data[i].divisor); - dieIfFaultOccurred(&env); - - ratioP = xmlrpc_struct_new(&env); - dieIfFaultOccurred(&env); - - xmlrpc_struct_set_value(&env, ratioP, "DIVIDEND", dividendP); - dieIfFaultOccurred(&env); - xmlrpc_struct_set_value(&env, ratioP, "DIVISOR", divisorP); - dieIfFaultOccurred(&env); - - xmlrpc_array_append_item(&env, ratioArrayP, ratioP); - dieIfFaultOccurred(&env); - - xmlrpc_DECREF(ratioP); - xmlrpc_DECREF(divisorP); - xmlrpc_DECREF(dividendP); - } - - /* Make the call */ - - resultP = xmlrpc_client_call(&env, serverUrl, methodName, "(iA)", - (xmlrpc_int32) argVersion, ratioArrayP); - dieIfFaultOccurred(&env); - - /* Print out the quotients returned */ - - quotientCt = xmlrpc_array_size(&env, resultP); - dieIfFaultOccurred(&env); - - for (i = 0; i < quotientCt; ++i) { - xmlrpc_value * quotientP; - xmlrpc_double quotient; - - xmlrpc_array_read_item(&env, resultP, i, "ientP); - dieIfFaultOccurred(&env); - - xmlrpc_read_double(&env, quotientP, "ient); - dieIfFaultOccurred(&env); - - printf("Server says quotient %u is %f\n", i, quotient); - - xmlrpc_DECREF(quotientP); - } - - xmlrpc_DECREF(resultP); - - xmlrpc_env_clean(&env); - - xmlrpc_client_cleanup(); - - return 0; -} - diff --git a/trunk/examples/compound_value_server.c b/trunk/examples/compound_value_server.c deleted file mode 100644 index 15a9808c3..000000000 --- a/trunk/examples/compound_value_server.c +++ /dev/null @@ -1,201 +0,0 @@ -/* An XML-RPC server program written in C, as an example of using - compound XML-RPC values. - - For a simple server program that just deals with integer values, - see xmlrpc_sample_add_server.c. This example focuses just on the - compound XML-RPC values and not the server functions. - - This server provides the example.divide XML-RPC method that the example - client program compound_value_client.c invokes. See that program for - details on what the method does. - - The program takes one argument: the HTTP port number on which the server - is to accept connections, in decimal. - - Example: - - $ ./compound_value_server 8080& - $ ./compound_value_client -*/ - -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ - -#include -#include - -#include -#include -#include - -#include "config.h" /* information about this build environment */ - - - -static void -computeQuotient(xmlrpc_env * const envP, - xmlrpc_value * const ratioP, - xmlrpc_double * const quotientP) { - - xmlrpc_value * dividendP; - - xmlrpc_struct_find_value(envP, ratioP, "DIVIDEND", ÷ndP); - - if (!envP->fault_occurred) { - if (!dividendP) - xmlrpc_env_set_fault( - envP, 0, "Structure is missing 'DIVIDEND' member"); - else { - xmlrpc_value * divisorP; - - xmlrpc_struct_find_value(envP, ratioP, "DIVISOR", &divisorP); - - if (!envP->fault_occurred) { - if (!divisorP) - xmlrpc_env_set_fault( - envP, 0, "Structure is missing 'DIVISOR' member"); - else { - xmlrpc_double dividend; - - xmlrpc_read_double(envP, dividendP, ÷nd); - - if (!envP->fault_occurred) { - xmlrpc_double divisor; - - xmlrpc_read_double(envP, divisorP, &divisor); - - if (!envP->fault_occurred) - *quotientP = dividend / divisor; - } - xmlrpc_DECREF(divisorP); - } - } - xmlrpc_DECREF(dividendP); - } - } -} - - - -static void -computeQuotients(xmlrpc_env * const envP, - xmlrpc_value * const ratioArrayP, - xmlrpc_value ** const quotientArrayPP) { - - xmlrpc_value * quotientArrayP; - - quotientArrayP = xmlrpc_array_new(envP); - if (!envP->fault_occurred) { - - unsigned int const ratioCt = xmlrpc_array_size(envP, ratioArrayP); - - unsigned int i; - - for (i = 0; i < ratioCt && !envP->fault_occurred; ++i) { - xmlrpc_value * ratioP; - - xmlrpc_array_read_item(envP, ratioArrayP, i, &ratioP); - - if (!envP->fault_occurred) { - xmlrpc_double quotient; - - computeQuotient(envP, ratioP, "ient); - - if (!envP->fault_occurred) { - xmlrpc_value * quotientP; - - quotientP = xmlrpc_double_new(envP, quotient); - - if (!envP->fault_occurred) { - xmlrpc_array_append_item(envP, quotientArrayP, - quotientP); - - xmlrpc_DECREF(quotientP); - } - } - xmlrpc_DECREF(ratioP); - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(quotientArrayP); - else - *quotientArrayPP = quotientArrayP; - } -} - - - -static xmlrpc_value * -example_divide(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const channelInfo) { - - xmlrpc_value * retvalP; - xmlrpc_int32 argVersion; - xmlrpc_value * ratioArrayP; - - xmlrpc_decompose_value(envP, paramArrayP, "(iA)", - &argVersion, &ratioArrayP); - if (envP->fault_occurred) - return NULL; - - if (argVersion != 1) { - xmlrpc_env_set_fault(envP, 0, "Parameter list version must be 1"); - return NULL; - } - - computeQuotients(envP, ratioArrayP, &retvalP); - - xmlrpc_DECREF(ratioArrayP); - - if (envP->fault_occurred) - return NULL; - - return retvalP; -} - - - -int -main(int const argc, - const char ** const argv) { - - struct xmlrpc_method_info3 const methodInfo = { - /* .methodName = */ "example.divide", - /* .methodFunction = */ &example_divide, - }; - xmlrpc_server_abyss_parms serverparm; - xmlrpc_registry * registryP; - xmlrpc_env env; - - if (argc-1 != 1) { - fprintf(stderr, "You must specify 1 argument: The TCP port " - "number on which the server will accept connections " - "for RPCs (8080 is a common choice). " - "You specified %d arguments.\n", argc-1); - exit(1); - } - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - - xmlrpc_registry_add_method3(&env, registryP, &methodInfo); - - /* In the modern form of the Abyss API, we supply parameters in memory - like a normal API. We select the modern form by setting - config_file_name to NULL: - */ - serverparm.config_file_name = NULL; - serverparm.registryP = registryP; - serverparm.port_number = atoi(argv[1]); - serverparm.log_file_name = "/tmp/xmlrpc_log"; - - printf("Running XML-RPC server...\n"); - - xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name)); - - /* xmlrpc_server_abyss() never returns */ - - return 0; -} diff --git a/trunk/examples/cpp/Makefile b/trunk/examples/cpp/Makefile deleted file mode 100644 index 172a899a3..000000000 --- a/trunk/examples/cpp/Makefile +++ /dev/null @@ -1,124 +0,0 @@ -# Since the programs in this directories are examples for the user, this -# make file should be as ordinary as possible. It should not rely heavily -# on included make files or configuration parameters. It should not use -# libtool. Also, we don't try to build or rebuild the libraries on which -# these programs depend. - - -ifeq ($(SRCDIR),) -SRCDIR = $(CURDIR)/../.. -BLDDIR = $(SRCDIR) -endif -SUBDIR=examples/cpp - -include $(BLDDIR)/config.mk - -default: all - -CXXFLAGS_ALL = $(CFLAGS_PERSONAL) $(CXXFLAGS) $(CADD) -LDFLAGS_ALL = $(LDFLAGS_PERSONAL) $(LDFLAGS) $(LADD) - -# If this were a real application, working from an installed copy of -# Xmlrpc-c, XMLRPC_C_CONFIG would just be 'xmlrpc-c-config'. It would be -# found in the user's PATH. -XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test - - -SERVERPROGS_CGI = \ - xmlrpc_sample_add_server.cgi - -SERVERPROGS_ABYSS = \ - xmlrpc_inetd_server \ - xmlrpc_loop_server \ - xmlrpc_sample_add_server \ - callinfo_abyss_server \ - -CLIENTPROGS = \ - xmlrpc_sample_add_client \ - sample_add_client_complex \ - asynch_client \ - -# Build up PROGS: -PROGS = - -ifeq ($(ENABLE_ABYSS_SERVER),yes) - PROGS += $(SERVERPROGS_ABYSS) -endif - -ifeq ($(MUST_BUILD_CLIENT),yes) - PROGS += $(CLIENTPROGS) -endif - -ifeq ($(ENABLE_CGI_SERVER),yes) - PROGS += $(SERVERPROGS_CGI) -endif - -PROGS += pstream_inetd_server pstream_serial_server - -ifeq ($(MUST_BUILD_CLIENT),yes) - PROGS += pstream_client -endif - -INCLUDES = -I. $(shell $(XMLRPC_C_CONFIG) c++2 client abyss-server --cflags) - -LIBS_SERVER_ABYSS = \ - $(shell $(XMLRPC_C_CONFIG) c++2 abyss-server --libs) - -LIBS_SERVER_CGI = \ - $(shell $(XMLRPC_C_CONFIG) c++2 cgi-server --libs) - -LIBS_CLIENT = \ - $(shell $(XMLRPC_C_CONFIG) c++2 client --libs) - -LIBS_BASE = \ - $(shell $(XMLRPC_C_CONFIG) c++2 --libs) - -all: $(PROGS) - -$(SERVERPROGS_CGI):%.cgi:%_cgi.o - $(CXXLD) -o $@ $^ $(LIBS_SERVER_CGI) $(LDFLAGS_ALL) - -$(SERVERPROGS_ABYSS):%:%.o - $(CXXLD) -o $@ $^ $(LIBS_SERVER_ABYSS) $(LDFLAGS_ALL) - -$(CLIENTPROGS):%:%.o - $(CXXLD) -o $@ $^ $(LIBS_CLIENT) $(LDFLAGS_ALL) - - -LIBS_PSTREAM_CLIENT = \ - $(shell $(XMLRPC_C_CONFIG) c++2 client --libs) - -pstream_client:%:%.o - $(CXXLD) -o $@ $^ $(LIBS_PSTREAM_CLIENT) $(LDFLAGS_ALL) - -LIBS_PSTREAM_SERVER = \ - $(shell $(XMLRPC_C_CONFIG) c++2 pstream-server --libs) - -pstream_inetd_server pstream_serial_server:%:%.o - $(CXXLD) -o $@ $^ $(LIBS_PSTREAM_SERVER) $(LDFLAGS_ALL) - -OBJECTS = $(patsubst %,%.o,$(patsubst %.cgi,%_cgi,$(PROGS))) - -$(OBJECTS):%.o:%.cpp - $(CXX) -c $(INCLUDES) $(CXXFLAGS_ALL) $< - -# See example/Makefile for an explanation of config.h - -$(OBJECTS): config.h - -config.h: - $(LN_S) $(BLDDIR)/xmlrpc_config.h $@ - -.PHONY: clean -clean: - rm -f $(PROGS) *.o config.h - -.PHONY: distclean -distclean: clean - -.PHONY: dep depend -dep depend: -# We don't do dependencies in this directory, because it's supposed to be -# an example of what a program outside this package would do, so we can't -# go weaving it into the rest of the package. Ergo, a developer must -# carefully clean and remake examples as he updates other parts of the tree. diff --git a/trunk/examples/cpp/asynch_client.cpp b/trunk/examples/cpp/asynch_client.cpp deleted file mode 100644 index 9b32b2e88..000000000 --- a/trunk/examples/cpp/asynch_client.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/*============================================================================= - asynch_client.cpp -=============================================================================== - This is an example of an XML-RPC client that uses XML-RPC for C/C++ - (Xmlrpc-c). - - In particular, it does multiple RPCs asynchronously, running - simultaneously. -=============================================================================*/ - -#include -#include -#include -#include - -using namespace std; - -#include -#include -#include - -int -main(int argc, char **) { - - if (argc-1 > 0) { - cerr << "This program has no arguments" << endl; - exit(1); - } - - try { - xmlrpc_c::clientXmlTransport_curl myTransport; - - xmlrpc_c::client_xml myClient(&myTransport); - - string const methodName("sample.add"); - - xmlrpc_c::paramList sampleAddParms1; - sampleAddParms1.add(xmlrpc_c::value_int(3)); - sampleAddParms1.add(xmlrpc_c::value_int(1)); - - xmlrpc_c::rpcPtr rpc1P(methodName, sampleAddParms1); - - xmlrpc_c::paramList sampleAddParms2; - sampleAddParms2.add(xmlrpc_c::value_int(5)); - sampleAddParms2.add(xmlrpc_c::value_int(7)); - - xmlrpc_c::rpcPtr rpc2P(methodName, sampleAddParms2); - - string const serverUrl("http://localhost:8080/RPC2"); - - xmlrpc_c::carriageParm_curl0 myCarriageParm(serverUrl); - - rpc1P->start(&myClient, &myCarriageParm); - rpc2P->start(&myClient, &myCarriageParm); - - cout << "Two RPCs started. Waiting for them to finish." << endl; - - myClient.finishAsync(xmlrpc_c::timeout()); // infinite timeout - - assert(rpc1P->isFinished()); - assert(rpc2P->isFinished()); - - int const sum1(xmlrpc_c::value_int(rpc1P->getResult())); - int const sum2(xmlrpc_c::value_int(rpc2P->getResult())); - - cout << "Result of RPC 1 (sum of 3 and 1): " << sum1 << endl; - cout << "Result of RPC 2 (sum of 5 and 7): " << sum2 << endl; - - } catch (exception const& e) { - cerr << "Client threw error: " << e.what() << endl; - } catch (...) { - cerr << "Client threw unexpected error." << endl; - } - - return 0; -} diff --git a/trunk/examples/cpp/callinfo_abyss_server.cpp b/trunk/examples/cpp/callinfo_abyss_server.cpp deleted file mode 100644 index e4fd6de0f..000000000 --- a/trunk/examples/cpp/callinfo_abyss_server.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// A simple standalone XML-RPC server written in C++. -// -// This server returns to the caller his IP address and port number, -// as a demonstration of how to access such information. -// -// This works only on Unix (to wit, something that uses Abyss's -// ChanSwitchUnix channel switch to accept TCP connections from clients). -// -// See xmlrpc_sample_add_server.cpp for a more basic example. -// -// To run this: -// -// $ ./callinfo_abyss_server & -// $ xmlrpc localhost:8080 getCallInfo - -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.hpp */ - -#include -#include -#include -#include -#include -#ifndef _WIN32 -#include -#include -#endif - -using namespace std; - -#include -#include -#include -#include - - -struct tcpPortAddr { - unsigned char ipAddr[4]; - unsigned short portNumber; -}; - - -static struct tcpPortAddr -tcpAddrFromSockAddr(struct sockaddr const sockAddr) { - - const struct sockaddr_in * const sockAddrInP( - static_cast((void *)&sockAddr)); - - const unsigned char * const ipAddr( - static_cast( - (const void *)&sockAddrInP->sin_addr.s_addr) - ); // 4 byte array - - assert(sockAddrInP->sin_family == AF_INET); - - struct tcpPortAddr retval; - - retval.ipAddr[0] = ipAddr[0]; - retval.ipAddr[1] = ipAddr[1]; - retval.ipAddr[2] = ipAddr[2]; - retval.ipAddr[3] = ipAddr[3]; - retval.portNumber = ntohs(sockAddrInP->sin_port); - - return retval; -} - - - -/* On Windows, we have struct abyss_win_chaninfo, while on Unix we have - struct abyss_unix_chaninfo, but for what we're doing here, they're - fungible -- we use only members that exist in both. So we refer to the - generically with macro CHANINFO_TYPE. -*/ - -#ifdef _WIN32 - #define CHANINFO_TYPE abyss_win_chaninfo -#else - #define CHANINFO_TYPE abyss_unix_chaninfo -#endif - -static string -rpcIpAddrMsg(xmlrpc_c::callInfo_serverAbyss const& callInfo) { - - void * chanInfoPtr; - SessionGetChannelInfo(callInfo.abyssSessionP, &chanInfoPtr); - - struct CHANINFO_TYPE * const chanInfoP( - static_cast(chanInfoPtr)); - - struct tcpPortAddr const tcpAddr(tcpAddrFromSockAddr(chanInfoP->peerAddr)); - - char msg[128]; - - sprintf(msg, "RPC is from IP address %u.%u.%u.%u, Port %hu", - tcpAddr.ipAddr[0], - tcpAddr.ipAddr[1], - tcpAddr.ipAddr[2], - tcpAddr.ipAddr[3], - tcpAddr.portNumber); - - return string(msg); -} - - - -class getCallInfoMethod : public xmlrpc_c::method2 { -public: - void - execute(xmlrpc_c::paramList const& paramList, - const xmlrpc_c::callInfo * const callInfoPtr, - xmlrpc_c::value * const retvalP) { - - const xmlrpc_c::callInfo_serverAbyss * const callInfoP( - dynamic_cast(callInfoPtr)); - - paramList.verifyEnd(0); - - // Because this gets called via a xmlrpc_c::serverAbyss: - assert(callInfoP != NULL); - - *retvalP = xmlrpc_c::value_string(rpcIpAddrMsg(*callInfoP)); - } -}; - - - -int -main(int const, - const char ** const) { - - try { - xmlrpc_c::registry myRegistry; - - xmlrpc_c::methodPtr const getCallInfoMethodP(new getCallInfoMethod); - - myRegistry.addMethod("getCallInfo", getCallInfoMethodP); - - xmlrpc_c::serverAbyss myAbyssServer(xmlrpc_c::serverAbyss::constrOpt() - .registryP(&myRegistry) - .portNumber(8080) - ); - - myAbyssServer.run(); - // xmlrpc_c::serverAbyss.run() never returns - assert(false); - } catch (exception const& e) { - cerr << "Something failed. " << e.what() << endl; - } - return 0; -} diff --git a/trunk/examples/cpp/pstream_client.cpp b/trunk/examples/cpp/pstream_client.cpp deleted file mode 100644 index f352dc4fe..000000000 --- a/trunk/examples/cpp/pstream_client.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/*============================================================================= - pstream_client.cpp -=============================================================================== - This is an example of a client that uses XML-RPC for C/C++ - (Xmlrpc-c). - - In particular, it uses the simple "packet stream" XML transport mechanism - instead of HTTP as specified by XML-RPC (so this is not an XML-RPC - client). - - You have to supply as Standard Input a stream (TCP) socket whose other - end is hooked up to the RPC server. The 'socketexec' program is a - good way to arrange that. - - The sample program pstream_serial_server.cpp is compatible with this client. - - Example: - - $ socketexec -connect -remote_host=localhost -remote_port=8080 \ - ./pstream_client -=============================================================================*/ - -#include -#include -#include -#include -#include -#include - -using namespace std; - -#include -#include -#include -#include - - - -int -main(int argc, char **) { - - if (argc-1 > 0) { - cerr << "This program has no arguments" << endl; - exit(1); - } - -#ifndef _WIN32 - // It's a good idea to disable SIGPIPE signals; if server closes his end - // of the pipe/socket, we'd rather see a failure to send a call than - // get killed by the OS. - signal(SIGPIPE, SIG_IGN); -#endif - - try { - xmlrpc_c::clientXmlTransport_pstream myTransport( - xmlrpc_c::clientXmlTransport_pstream::constrOpt() - .fd(STDIN_FILENO)); - - xmlrpc_c::client_xml myClient(&myTransport); - - string const methodName("sample.add"); - - xmlrpc_c::paramList sampleAddParms; - sampleAddParms.add(xmlrpc_c::value_int(5)); - sampleAddParms.add(xmlrpc_c::value_int(7)); - - xmlrpc_c::rpcPtr myRpcP(methodName, sampleAddParms); - - xmlrpc_c::carriageParm_pstream myCarriageParm; - // Empty; transport doesn't need any information - - myRpcP->call(&myClient, &myCarriageParm); - - assert(myRpcP->isFinished()); - - int const sum(xmlrpc_c::value_int(myRpcP->getResult())); - // Assume the method returned an integer; throws error if not - - cout << "Result of RPC (sum of 5 and 7): " << sum << endl; - - } catch (exception const& e) { - cerr << "Client threw error: " << e.what() << endl; - } catch (...) { - cerr << "Client threw unexpected error." << endl; - } - - return 0; -} diff --git a/trunk/examples/cpp/pstream_inetd_server.cpp b/trunk/examples/cpp/pstream_inetd_server.cpp deleted file mode 100644 index db1af0cd0..000000000 --- a/trunk/examples/cpp/pstream_inetd_server.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* A simple standalone RPC server based on an Xmlrpc-c packet socket. - - This program expects the invoker to provide an established connection - to a client as Standard Input (E.g. Inetd can do this). It processes - RPCs from that connection until the client closes the connection. - - This is not an XML-RPC server, because it uses a simple packet socket - instead of HTTP. See xmlrpc_sample_add_server.cpp for an example of - an XML-RPC server. - - The advantage of this example over XML-RPC is that it has a connection - concept. The client can be connected indefinitely and the server gets - notified when the client terminates, even if it gets aborted by its OS. - - Here's an example of running this: - - $ socketexec -accept -local_port=8080 ./pstream_inetd_server -*/ - -#ifndef _WIN32 -#include -#endif -#include -#include -#include - -using namespace std; - -#include -#include -#include - - -class sampleAddMethod : public xmlrpc_c::method { -public: - sampleAddMethod() { - // signature and help strings are documentation -- the client - // can query this information with a system.methodSignature and - // system.methodHelp RPC. - this->_signature = "i:ii"; // method's arguments are two integers - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - xmlrpc_c::value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = xmlrpc_c::value_int(addend + adder); - } -}; - - - -int -main(int const, - const char ** const) { - -#ifndef _WIN32 - // It's a good idea to disable SIGPIPE signals; if client closes his end - // of the pipe/socket, we'd rather see a failure to send a response than - // get killed by the OS. - signal(SIGPIPE, SIG_IGN); -#endif - - try { - xmlrpc_c::registry myRegistry; - - xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod); - - myRegistry.addMethod("sample.add", sampleAddMethodP); - - xmlrpc_c::serverPstreamConn server( - xmlrpc_c::serverPstreamConn::constrOpt() - .socketFd(STDIN_FILENO) - .registryP(&myRegistry)); - - server.run(); - - } catch (exception const& e) { - cerr << "Something threw an error: " << e.what() << endl; - } - return 0; -} diff --git a/trunk/examples/cpp/pstream_serial_server.cpp b/trunk/examples/cpp/pstream_serial_server.cpp deleted file mode 100644 index ae73a819b..000000000 --- a/trunk/examples/cpp/pstream_serial_server.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* A simple standalone RPC server based on an Xmlrpc-c packet socket. - - This program expects the invoker to provide a socket in listen mode - as Standard Input. - - This is not an XML-RPC server, because it uses a simple packet socket - instead of HTTP. See xmlrpc_sample_add_server.cpp for an example of - an XML-RPC server. - - The advantage of this example over XML-RPC is that it has a connection - concept. The client can be connected indefinitely and the server gets - notified when the client terminates, even if it gets aborted by its OS. - - Here's an example of running this: - - $ socketexec -listen -local_port=8080 ./pstream_serial_server -*/ - -#ifndef WIN32 -#include -#endif -#include -#include -#include - -using namespace std; - -#include -#include -#include - - -class sampleAddMethod : public xmlrpc_c::method { -public: - sampleAddMethod() { - // signature and help strings are documentation -- the client - // can query this information with a system.methodSignature and - // system.methodHelp RPC. - this->_signature = "i:ii"; // method's arguments are two integers - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - xmlrpc_c::value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = xmlrpc_c::value_int(addend + adder); - } -}; - - - -int -main(int const, - const char ** const) { - -#ifndef _WIN32 - // It's a good idea to disable SIGPIPE signals; if client closes his end - // of the pipe/socket, we'd rather see a failure to send a response than - // get killed by the OS. - signal(SIGPIPE, SIG_IGN); -#endif - - try { - xmlrpc_c::registry myRegistry; - - xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod); - - myRegistry.addMethod("sample.add", sampleAddMethodP); - - xmlrpc_c::serverPstream server( - xmlrpc_c::serverPstream::constrOpt() - .socketFd(STDIN_FILENO) - .registryP(&myRegistry)); - - server.runSerial(); - - } catch (exception const& e) { - cerr << "Something threw an error: " << e.what() << endl; - } - return 0; -} diff --git a/trunk/examples/cpp/sample_add_client_complex.cpp b/trunk/examples/cpp/sample_add_client_complex.cpp deleted file mode 100644 index 7efbbbb6c..000000000 --- a/trunk/examples/cpp/sample_add_client_complex.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/*============================================================================= - sample_add_client_complex.cpp -=============================================================================== - This is an example of an XML-RPC client that uses XML-RPC for C/C++ - (Xmlrpc-c). - - In particular, it uses the complex lower-level interface that gives you - lots of flexibility but requires lots of code. Also see - xmlrpc_sample_add_server, which does the same thing as this program, - but with much simpler code because it uses a simpler facility of - Xmlrpc-c. - - This program actually gains nothing from using the more difficult - facility. It is for demonstration purposes. -=============================================================================*/ - -#include -#include -#include -#include - -using namespace std; - -#include -#include -#include - -int -main(int argc, char **) { - - if (argc-1 > 0) { - cerr << "This program has no arguments" << endl; - exit(1); - } - - try { - xmlrpc_c::clientXmlTransport_curl myTransport( - xmlrpc_c::clientXmlTransport_curl::constrOpt() - .timeout(10000) // milliseconds - .user_agent("sample_add/1.0")); - - xmlrpc_c::client_xml myClient(&myTransport); - - string const methodName("sample.add"); - - xmlrpc_c::paramList sampleAddParms; - sampleAddParms.add(xmlrpc_c::value_int(5)); - sampleAddParms.add(xmlrpc_c::value_int(7)); - - xmlrpc_c::rpcPtr myRpcP(methodName, sampleAddParms); - - string const serverUrl("http://localhost:8080/RPC2"); - - xmlrpc_c::carriageParm_curl0 myCarriageParm(serverUrl); - - myRpcP->call(&myClient, &myCarriageParm); - - assert(myRpcP->isFinished()); - - int const sum(xmlrpc_c::value_int(myRpcP->getResult())); - // Assume the method returned an integer; throws error if not - - cout << "Result of RPC (sum of 5 and 7): " << sum << endl; - - } catch (exception const& e) { - cerr << "Client threw error: " << e.what() << endl; - } catch (...) { - cerr << "Client threw unexpected error." << endl; - } - - return 0; -} diff --git a/trunk/examples/cpp/xmlrpc_inetd_server.cpp b/trunk/examples/cpp/xmlrpc_inetd_server.cpp deleted file mode 100644 index 3fa3af876..000000000 --- a/trunk/examples/cpp/xmlrpc_inetd_server.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* A simple XML-RPC server that runs under Inetd. I.e. it lets the invoking - program handle all the connection switching and simply processes one - RPC on the provided connection (Standard Input) and exits. - - A typical example of where this would be useful is with an Inetd - "super server." - - xmlrpc_sample_add_server.cpp is a server that does the same thing, - but you give it a TCP port number and it listens for TCP connections - and processes RPCs ad infinitum. xmlrpc_socket_server.c is halfway - in between those -- you give it an already bound and listening - socket, and it listens for TCP connections and processes RPCs ad - infinitum. - - Here is an easy way to test this program: - - socketexec --accept --local_port=8080 --stdin -- ./xmlrpc_inetd_server - - Now run the client program 'xmlrpc_sample_add_client'. Socketexec - will accept the connection that the client program requests and pass it - to this program on Standard Input. This program will perform the RPC, - respond to the client, then exit. -*/ - -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.hpp */ - -#ifndef _WIN32 -# include -#endif -#include - -using namespace std; - -#include -#include -#include - -class sampleAddMethod : public xmlrpc_c::method { -public: - sampleAddMethod() { - // signature and help strings are documentation -- the client - // can query this information with a system.methodSignature and - // system.methodHelp RPC. - this->_signature = "i:ii"; // method's arguments are two integers - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - xmlrpc_c::value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = xmlrpc_c::value_int(addend + adder); - } -}; - - - -int -main(int const, - const char ** const) { - - xmlrpc_c::registry myRegistry; - - xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod); - - myRegistry.addMethod("sample.add", sampleAddMethodP); - - xmlrpc_c::serverAbyss myAbyssServer( - xmlrpc_c::serverAbyss::constrOpt() - .registryP(&myRegistry)); - - myAbyssServer.runConn(STDIN_FILENO); - /* This reads the HTTP POST request from Standard Input and - executes the indicated RPC. - */ - return 0; -} diff --git a/trunk/examples/cpp/xmlrpc_loop_server.cpp b/trunk/examples/cpp/xmlrpc_loop_server.cpp deleted file mode 100644 index f62f7038f..000000000 --- a/trunk/examples/cpp/xmlrpc_loop_server.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* A simple standalone XML-RPC server based on Abyss that contains a - simple one-thread request processing loop. - - xmlrpc_sample_add_server.cpp is a server that does the same thing, but - does it by running a full Abyss daemon in the background, so it has - less control over how the requests are served. -*/ - -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.hpp */ - -#include -#include - -using namespace std; - -#include -#include -#include - -class sampleAddMethod : public xmlrpc_c::method { -public: - sampleAddMethod() { - // signature and help strings are documentation -- the client - // can query this information with a system.methodSignature and - // system.methodHelp RPC. - this->_signature = "i:ii"; // method's arguments, result are integers - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - xmlrpc_c::value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = xmlrpc_c::value_int(addend + adder); - } -}; - - - -int -main(int const, - const char ** const) { - - try { - xmlrpc_c::registry myRegistry; - - xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod); - - myRegistry.addMethod("sample.add", sampleAddMethodP); - - xmlrpc_c::serverAbyss myAbyssServer( - xmlrpc_c::serverAbyss::constrOpt() - .registryP(&myRegistry) - .portNumber(8080) - .logFileName("/tmp/xmlrpc_log")); - - while (true) { - cout << "Waiting for next RPC..." << endl; - - myAbyssServer.runOnce(); - /* This waits for the next connection, accepts it, reads the - HTTP POST request, executes the indicated RPC, and closes - the connection. - */ - } - } catch (exception const& e) { - cerr << "Something failed. " << e.what() << endl; - } - return 0; -} diff --git a/trunk/examples/cpp/xmlrpc_sample_add_client.cpp b/trunk/examples/cpp/xmlrpc_sample_add_client.cpp deleted file mode 100644 index eb7387dc8..000000000 --- a/trunk/examples/cpp/xmlrpc_sample_add_client.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include - -using namespace std; - -#include -#include -#include - -int -main(int argc, char **) { - - if (argc-1 > 0) { - cerr << "This program has no arguments" << endl; - exit(1); - } - - try { - string const serverUrl("http://localhost:8080/RPC2"); - string const methodName("sample.add"); - - xmlrpc_c::clientSimple myClient; - xmlrpc_c::value result; - - myClient.call(serverUrl, methodName, "ii", &result, 5, 7); - - int const sum = xmlrpc_c::value_int(result); - // Assume the method returned an integer; throws error if not - - cout << "Result of RPC (sum of 5 and 7): " << sum << endl; - - } catch (exception const& e) { - cerr << "Client threw error: " << e.what() << endl; - } catch (...) { - cerr << "Client threw unexpected error." << endl; - } - - return 0; -} diff --git a/trunk/examples/cpp/xmlrpc_sample_add_server.cpp b/trunk/examples/cpp/xmlrpc_sample_add_server.cpp deleted file mode 100644 index c8d93a57f..000000000 --- a/trunk/examples/cpp/xmlrpc_sample_add_server.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.hpp */ - -#include -#include -#include -#ifdef _WIN32 -# include -#else -# include -#endif - -using namespace std; - -#include -#include -#include - -#ifdef _WIN32 - #define SLEEP(seconds) SleepEx(seconds * 1000); -#else - #define SLEEP(seconds) sleep(seconds); -#endif - - -class sampleAddMethod : public xmlrpc_c::method { -public: - sampleAddMethod() { - // signature and help strings are documentation -- the client - // can query this information with a system.methodSignature and - // system.methodHelp RPC. - this->_signature = "i:ii"; - // method's result and two arguments are integers - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - xmlrpc_c::value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = xmlrpc_c::value_int(addend + adder); - - // Sometimes, make it look hard (so client can see what it's like - // to do an RPC that takes a while). - if (adder == 1) - SLEEP(2); - } -}; - - - -int -main(int const, - const char ** const) { - - try { - xmlrpc_c::registry myRegistry; - - xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod); - - myRegistry.addMethod("sample.add", sampleAddMethodP); - - xmlrpc_c::serverAbyss myAbyssServer( - xmlrpc_c::serverAbyss::constrOpt() - .registryP(&myRegistry) - .portNumber(8080)); - - myAbyssServer.run(); - // xmlrpc_c::serverAbyss.run() never returns - assert(false); - } catch (exception const& e) { - cerr << "Something failed. " << e.what() << endl; - } - return 0; -} diff --git a/trunk/examples/cpp/xmlrpc_sample_add_server_cgi.cpp b/trunk/examples/cpp/xmlrpc_sample_add_server_cgi.cpp deleted file mode 100644 index 9989f5c1d..000000000 --- a/trunk/examples/cpp/xmlrpc_sample_add_server_cgi.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* A CGI script that effects a simple XML-RPC server, written in C++. - - See the identically named C program source code for hints on running - this example. - -*/ - -#include -#include - -using namespace std; - -#include -#include -#include - -class sampleAddMethod : public xmlrpc_c::method { -public: - sampleAddMethod() { - // signature and help strings are documentation -- the client - // can query this information with a system.methodSignature and - // system.methodHelp RPC. - this->_signature = "i:ii"; // method's arguments, result are integers - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - xmlrpc_c::value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = xmlrpc_c::value_int(addend + adder); - } -}; - - - -int -main(int const, - const char ** const) { - - try { - xmlrpc_c::registry myRegistry; - - xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod); - - myRegistry.addMethod("sample.add", sampleAddMethodP); - - xmlrpc_c::serverCgi myServer( - xmlrpc_c::serverCgi::constrOpt() - .registryP(&myRegistry)); - - myServer.processCall(); - - } catch (exception const& e) { - cerr << "Something failed. " << e.what() << endl; - } - return 0; -} diff --git a/trunk/examples/curl_client.c b/trunk/examples/curl_client.c deleted file mode 100644 index 691afc046..000000000 --- a/trunk/examples/curl_client.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Same as xmlrpc_sample_add_client.c, except it demonstrates use of Curl - transport parameters, including timeout and SSL stuff. - - You specify the server URL as an argument, which can be an "http:" URL for - true XML-RPC or "https:" for the secure SSL/TLS variation of XML-RPC. - - Example that works with 'xmlrpc_sample_add_server' example server: - - $ ./curl_client http::/localhost:8080/RPC2 - - Example that works with 'ssl_server' example server: - - $ ./curl_client https::/localhost:8080/RPC2 - -*/ - -#define _XOPEN_SOURCE 600 -#include -#include -#include - -#include -#include - -#include "config.h" /* information about this build environment */ - - - -static void -die_if_fault_occurred (xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "XML-RPC Fault: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -static void -add(xmlrpc_client * const clientP, - const char * const serverUrl, - int const addend, - int const adder) { - - const char * const methodName = "sample.add"; - - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_int32 sum; - - xmlrpc_env_init(&env); - - printf("Making XMLRPC call to server url '%s' method '%s' " - "to request the sum " - "of %d and %d...\n", serverUrl, methodName, addend, adder); - - /* Make the remote procedure call */ - - xmlrpc_client_call2f(&env, clientP, serverUrl, methodName, &resultP, - "(ii)", (xmlrpc_int32) addend, (xmlrpc_int32) adder); - die_if_fault_occurred(&env); - - /* Get our sum and print it out. */ - xmlrpc_read_int(&env, resultP, &sum); - die_if_fault_occurred(&env); - printf("The sum is %d\n", sum); - - /* Dispose of our result value. */ - xmlrpc_DECREF(resultP); - - xmlrpc_env_clean(&env); -} - - - -int -main(int const argc, - const char ** const argv) { - - const char * serverUrl; - - xmlrpc_env env; - struct xmlrpc_curl_xportparms transportParms; - struct xmlrpc_clientparms clientParms; - xmlrpc_client * clientP; - - if (argc-1 < 1) { - fprintf(stderr, "You must specify the server URL as an argument. " - "Example: http://localhost:8080/RPC2\n"); - exit(1); - } else { - serverUrl = argv[1]; - } - - /* Initialize our error-handling environment. */ - xmlrpc_env_init(&env); - - /* Required before any use of Xmlrpc-c client library: */ - xmlrpc_client_setup_global_const(&env); - die_if_fault_occurred(&env); - - transportParms.network_interface = NULL; - transportParms.no_ssl_verifypeer = 1; - transportParms.no_ssl_verifyhost = 1; - transportParms.user_agent = NULL; - transportParms.ssl_cert = NULL; - transportParms.sslcerttype = NULL; - transportParms.sslcertpasswd = NULL; - transportParms.sslkey = NULL; - transportParms.sslkeytype = NULL; - transportParms.sslengine = NULL; - transportParms.sslengine_default = 0; - transportParms.sslversion = XMLRPC_SSLVERSION_DEFAULT; - transportParms.cainfo = NULL; - transportParms.capath = NULL; - transportParms.randomfile = NULL; - transportParms.egdsocket= NULL; - transportParms.ssl_cipher_list= "ALL:eNULL:aNULL"; - transportParms.timeout = 2000; /* milliseconds */ - - clientParms.transport = "curl"; - clientParms.transportparmsP = &transportParms; - clientParms.transportparm_size = XMLRPC_CXPSIZE(timeout); - - /* Create a client object */ - xmlrpc_client_create(&env, 0, NULL, NULL, - &clientParms, XMLRPC_CPSIZE(transportparm_size), - &clientP); - - die_if_fault_occurred(&env); - - /* If our server is running 'xmlrpc_sample_add_server' normally, the - RPC will finish almost instantly. UNLESS the adder is 1, in which - case said server is programmed to take 3 seconds to do the - computation, thus allowing us to demonstrate a timeout. - */ - - add(clientP, serverUrl, 5, 7); - /* Should finish instantly */ - - add(clientP, serverUrl, 5, 1); - /* Should time out after 2 seconds */ - - xmlrpc_env_clean(&env); - xmlrpc_client_destroy(clientP); - xmlrpc_client_teardown_global_const(); - - return 0; -} - diff --git a/trunk/examples/gen_sample_add_xml.c b/trunk/examples/gen_sample_add_xml.c deleted file mode 100644 index dd65699f8..000000000 --- a/trunk/examples/gen_sample_add_xml.c +++ /dev/null @@ -1,73 +0,0 @@ -/* This program generates on Standard Output the XML for an XML-RPC - call suitable for the xmlrpc_sample_add_server program. - - This is the same XML that the xmlrpc_sample_add_client program sends. - - Use this either as an example of how to use the Xmlrpc-c XML-generating - functions or to generate XML that you can use to test an XML-RPC - server. -*/ - -#include -#include - -#include - -#include "config.h" - -static void -die_if_fault_occurred(xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "XML-RPC Fault: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -int -main(int const argc, - const char ** const argv) { - - char * const methodName = "sample.add"; - - xmlrpc_env env; - xmlrpc_value * params; - xmlrpc_mem_block * xmlmemblockP; - - if (argc-1 > 0) { - fprintf(stderr, "This program has no arguments\n"); - exit(1); - } - - /* Initialize our error-handling environment. */ - xmlrpc_env_init(&env); - - params = xmlrpc_build_value(&env, "(ii)", - (xmlrpc_int32) 5, (xmlrpc_int32) 7); - - die_if_fault_occurred(&env); - - xmlmemblockP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - - xmlrpc_serialize_call(&env, xmlmemblockP, methodName, params); - - die_if_fault_occurred(&env); - - fwrite(XMLRPC_MEMBLOCK_CONTENTS(char, xmlmemblockP), - sizeof(char), - XMLRPC_MEMBLOCK_SIZE(char, xmlmemblockP), - stdout); - - XMLRPC_MEMBLOCK_FREE(char, xmlmemblockP); - - /* Dispose of our parameter array. */ - xmlrpc_DECREF(params); - - /* Clean up our error-handling environment. */ - xmlrpc_env_clean(&env); - - return 0; -} - diff --git a/trunk/examples/interrupted_client.c b/trunk/examples/interrupted_client.c deleted file mode 100644 index 1652be239..000000000 --- a/trunk/examples/interrupted_client.c +++ /dev/null @@ -1,165 +0,0 @@ -/* Same as xmlrpc_sample_add_client.c, except the call is interruptible, - both by timeout and by control-C. -*/ - -#define _XOPEN_SOURCE 600 -#include -#include -#include -#include - -#include -#include - -#include "config.h" /* information about this build environment */ - -static int interrupt; - /* This is a flag telling libxmlrpc_client to abort whatever it's - doing. It's global because we set it with a signal handler. - */ - -static void -die_if_fault_occurred (xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "XML-RPC Fault: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -static void -interruptRpc(int const signalClass) { - - switch (signalClass) { - case SIGINT: - printf("SIGINT signal received.\n"); - break; - case SIGALRM: - printf("SIGALRM signal received.\n"); - break; - default: - printf("Internal error: signal of class %u caught even though " - "we didn't set up a handler for that class\n", signalClass); - }; - - interrupt = 1; -} - - - -static void -setupSignalHandlers(void) { - - struct sigaction mysigaction; - - sigemptyset(&mysigaction.sa_mask); - mysigaction.sa_flags = 0; - - /* Usually, this signal indicates the user pressed Ctl-C */ - mysigaction.sa_handler = interruptRpc; - sigaction(SIGINT, &mysigaction, NULL); - /* This signal indicates a timed alarm you requested happened */ - sigaction(SIGALRM, &mysigaction, NULL); -} - - - -static void -addInterruptibly(xmlrpc_client * const clientP, - const char * const serverUrl, - int const addend, - int const adder) { - - const char * const methodName = "sample.add"; - - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_int32 sum; - - xmlrpc_env_init(&env); - - printf("Making XMLRPC call to server url '%s' method '%s' " - "to request the sum " - "of %d and %d...\n", serverUrl, methodName, addend, adder); - - interrupt = 0; /* Global variable */ - - alarm(2); /* Interrupt the call if it hasn't finished 2 seconds from now */ - - /* Make the remote procedure call */ - - xmlrpc_client_call2f(&env, clientP, serverUrl, methodName, &resultP, - "(ii)", (xmlrpc_int32) addend, (xmlrpc_int32) adder); - die_if_fault_occurred(&env); - - alarm(0); /* Cancel alarm, if it hasn't happened yet */ - - /* Get our sum and print it out. */ - xmlrpc_read_int(&env, resultP, &sum); - die_if_fault_occurred(&env); - printf("The sum is %d\n", sum); - - /* Dispose of our result value. */ - xmlrpc_DECREF(resultP); - - xmlrpc_env_clean(&env); -} - - - -int -main(int const argc, - const char ** const argv) { - - const char * const serverUrl = "http://localhost:8080/RPC2"; - - xmlrpc_env env; - struct xmlrpc_clientparms clientParms; - xmlrpc_client * clientP; - - if (argc-1 > 0) { - fprintf(stderr, "This program has no arguments\n"); - exit(1); - } - - setupSignalHandlers(); - - /* Initialize our error-handling environment. */ - xmlrpc_env_init(&env); - - /* Required before any use of Xmlrpc-c client library: */ - xmlrpc_client_setup_global_const(&env); - die_if_fault_occurred(&env); - - clientParms.transport = "curl"; - - /* Create a client object */ - xmlrpc_client_create(&env, 0, NULL, NULL, - &clientParms, XMLRPC_CPSIZE(transport), - &clientP); - - die_if_fault_occurred(&env); - - xmlrpc_client_set_interrupt(clientP, &interrupt); - - /* If our server is running 'xmlrpc_sample_add_server' normally, the - RPC will finish almost instantly. UNLESS the adder is 1, in which - case said server is programmed to take 3 seconds to do the - computation, thus allowing us to demonstrate a timeout or CTL-C. - */ - - addInterruptibly(clientP, serverUrl, 5, 7); - /* Should finish instantly */ - - addInterruptibly(clientP, serverUrl, 5, 1); - /* Should time out after 2 seconds */ - - xmlrpc_env_clean(&env); - xmlrpc_client_destroy(clientP); - xmlrpc_client_teardown_global_const(); - - return 0; -} - diff --git a/trunk/examples/interrupted_server.c b/trunk/examples/interrupted_server.c deleted file mode 100644 index 9da2b12c9..000000000 --- a/trunk/examples/interrupted_server.c +++ /dev/null @@ -1,168 +0,0 @@ -/* A simple standalone XML-RPC server program based on Abyss. - - You can terminate this server in controlled fashion with a SIGTERM - signal. - - xmlrpc_sample_add_server.c is a server that does the same thing with - simpler code, but it is not interruptible with SIGTERM. -*/ - -#define _XOPEN_SOURCE 600 -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "config.h" /* information about this build environment */ - - -static void -dieIfFailed(const char * const description, - xmlrpc_env const env) { - - if (env.fault_occurred) { - fprintf(stderr, "%s failed. %s\n", description, env.fault_string); - exit(1); - } -} - - - -static xmlrpc_server_abyss_t * serverToTerminateP; - -static void -sigtermHandler(int const signalClass) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - xmlrpc_server_abyss_terminate(&env, serverToTerminateP); - - dieIfFailed("xmlrpc_server_abyss_terminate", env); - - xmlrpc_env_clean(&env); -} - - - -static void -setupSigtermHandler(xmlrpc_server_abyss_t * const serverP) { - - struct sigaction mysigaction; - - serverToTerminateP = serverP; - - sigemptyset(&mysigaction.sa_mask); - mysigaction.sa_flags = 0; - mysigaction.sa_handler = sigtermHandler; - sigaction(SIGTERM, &mysigaction, NULL); -} - - - -static void -restoreSigtermHandler(void){ - - struct sigaction mysigaction; - - sigemptyset(&mysigaction.sa_mask); - mysigaction.sa_flags = 0; - mysigaction.sa_handler = SIG_DFL; - sigaction(SIGTERM, &mysigaction, NULL); -} - - - -static xmlrpc_value * -sample_add(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const channelInfo) { - - xmlrpc_int x, y, z; - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - if (envP->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Return our result. */ - return xmlrpc_build_value(envP, "i", z); -} - - - -int -main(int const argc, - const char ** const argv) { - - struct xmlrpc_method_info3 const methodInfo = { - .methodName = "sample.add", - .methodFunction = &sample_add, - .serverInfo = NULL - }; - xmlrpc_server_abyss_parms serverparm; - xmlrpc_server_abyss_t * serverP; - xmlrpc_registry * registryP; - xmlrpc_env env; - xmlrpc_server_abyss_sig * oldHandlersP; - - if (argc-1 != 1) { - fprintf(stderr, "You must specify 1 argument: The TCP port number " - "on which to listen for XML-RPC calls. " - "You specified %d.\n", argc-1); - exit(1); - } - - xmlrpc_env_init(&env); - - xmlrpc_server_abyss_global_init(&env); - dieIfFailed("xmlrpc_server_abyss_global_init", env); - - registryP = xmlrpc_registry_new(&env); - dieIfFailed("xmlrpc_registry_new", env); - - xmlrpc_registry_add_method3(&env, registryP, &methodInfo); - dieIfFailed("xmlrpc_registry_add_method2", env); - - serverparm.config_file_name = NULL; - serverparm.registryP = registryP; - serverparm.port_number = atoi(argv[1]); - - xmlrpc_server_abyss_create(&env, &serverparm, XMLRPC_APSIZE(port_number), - &serverP); - dieIfFailed("xmlrpc_server_abyss_create", env); - - xmlrpc_server_abyss_setup_sig(&env, serverP, &oldHandlersP); - dieIfFailed("xmlrpc_server_abyss_setup_sig", env); - - setupSigtermHandler(serverP); - - printf("Running XML-RPC server...\n"); - - xmlrpc_server_abyss_run_server(&env, serverP); - dieIfFailed("xmlrpc_server_abyss_run_server", env); - - printf("Server has terminated\n"); - - restoreSigtermHandler(); - xmlrpc_server_abyss_restore_sig(oldHandlersP); - xmlrpc_server_abyss_destroy(serverP); - xmlrpc_registry_free(registryP); - xmlrpc_server_abyss_global_term(); - xmlrpc_env_clean(&env); - - return 0; -} diff --git a/trunk/examples/json.c b/trunk/examples/json.c deleted file mode 100644 index a3b6f90f9..000000000 --- a/trunk/examples/json.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - This example program demonstrates the JSON parsing and generating - capabilities of Xmlrpc-c. - - The program reads JSON text from Standard Input and displays its value as - XML-RPC XML text. It then re-generates JSON from the intermediate - parsed information and displays that. -*/ -#include -#include - -#include -#include - - - -static void -dieIfFaultOccurred(xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "ERROR: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -void -printAsXml(xmlrpc_value * const valP) { - - xmlrpc_env env; - xmlrpc_mem_block * outP; - - xmlrpc_env_init(&env); - - outP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - - dieIfFaultOccurred(&env); - - xmlrpc_serialize_value(&env, outP, valP); - - printf("XML-RPC XML:\n"); - - printf("%.*s\n", - XMLRPC_MEMBLOCK_SIZE(char, outP), - XMLRPC_MEMBLOCK_CONTENTS(char, outP)); - - XMLRPC_MEMBLOCK_FREE(char, outP); - xmlrpc_env_clean(&env); -} - - - -void -printAsJson(xmlrpc_value * const valP) { - - xmlrpc_env env; - xmlrpc_mem_block * outP; - xmlrpc_value * val2P; - - xmlrpc_env_init(&env); - - outP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - - dieIfFaultOccurred(&env); - - xmlrpc_serialize_json(&env, valP, outP); - - dieIfFaultOccurred(&env); - - printf("JSON:\n"); - - printf("%.*s\n", - XMLRPC_MEMBLOCK_SIZE(char, outP), - XMLRPC_MEMBLOCK_CONTENTS(char, outP)); - - XMLRPC_MEMBLOCK_FREE(char, outP); - xmlrpc_env_clean(&env); -} - - - -int -main(int argc, const char *argv[]) { - - xmlrpc_env env; - char buf[65536]; - xmlrpc_value * valP; - size_t bytesReadCt; - - xmlrpc_env_init(&env); - - if (argc-1 > 0) { - fprintf(stderr, "This program has no arguments. " - "JSON input is from Standard Input\n"); - exit(1); - } - - bytesReadCt = fread(buf, 1, sizeof(buf)-1, stdin); - buf[bytesReadCt] = '\0'; - - valP = xmlrpc_parse_json(&env, buf); - - dieIfFaultOccurred(&env); - - printAsXml(valP); - - printAsJson(valP); - - xmlrpc_DECREF(valP); - xmlrpc_env_clean(&env); - - return 0; -} - - diff --git a/trunk/examples/ssl_secure_server.c b/trunk/examples/ssl_secure_server.c deleted file mode 100644 index 0ef533cb8..000000000 --- a/trunk/examples/ssl_secure_server.c +++ /dev/null @@ -1,242 +0,0 @@ -/* A simple standalone XML-RPC server program based on Abyss that uses SSL - (Secure Sockets Layer) via OpenSSL, with authentication. - - This is like the 'ssl_server' example, except that it requires - authentication, which means it is much harder to use - you have to set up a - certificate, private key, DSA parameters, and Diffie-Hellman parameters. - - Example: - - $ ./ssl_secure_server 8080 & - $ ./curl_client https://localhost:8080/RPC2 - - Before the above will work, you have to create a variety of files and put - them where this program expects to find them. Example: - - $ mkdir /tmp/ssltest - $ cd /tmp/ssltest - $ openssl genpkey -genparam -algorithm DSA >dsap.pem - $ openssl genpkey -paramfile dsap.pem >dsakey.pem - $ openssl req -new dsakey.pem >csr.csr - $ openssl x509 -req -in csr.csr -signkey dsakey.pem >certificate.pem - $ openssl dhparam -in dsap.pem -dsaparam -outform PEM >dhparam.pem - - - You can drive the most difficult part of this example (initial SSL - handshake) with the 'openssl' program that comes with OpenSSL, as follows. - - $ ./ssl_secure_server 8080 & - $ openssl -connect localhost:8080 -state - - The 'openssl' command connects and handshakes with the server, then waits - for you to type stuff to send to the server. You would have to type a - complete HTTP header followed by a valid XML-RPC call to complete the - demonstration. - - This uses the "provide your own Abyss server" mode of operation, - as opposed to other Xmlrpc-c facilities that create an Abyss server under - the covers, because this is the only way to get SSL. - - NOTE: We deliberately don't check error indications here to make the code - easier to read. If you're having trouble getting this code to run, by all - means add checks of the "error" and "env" variables! -*/ - -#define _XOPEN_SOURCE 600 -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ - -#include -#include -#include -#ifndef _WIN32 -#include -#include -#endif - -#include - -#include -#include -#include -#include -#include - -#include "config.h" /* information about this build environment */ - - -static void -sslInfoCallback(const SSL * const sslP, - int const where, - int const ret) { - - const char * str; - int const w = where & ~SSL_ST_MASK; - - if (w & SSL_ST_CONNECT) - str = "SSL_connect"; - else if (w & SSL_ST_ACCEPT) - str = "SSL_accept"; - else - str = "undefined"; - - if (where & SSL_CB_LOOP) { - fprintf(stderr, "%s:%s\n", str, SSL_state_string_long(sslP)); - } else if (where & SSL_CB_ALERT) { - str = (where & SSL_CB_READ) ? "read" : "write"; - fprintf(stderr, "SSL3 alert %s:%s:%s\n", - str, - SSL_alert_type_string_long(ret), - SSL_alert_desc_string_long(ret)); - } else if (where & SSL_CB_EXIT) { - if (ret == 0) - fprintf(stderr, "%s:failed in %s\n", - str, SSL_state_string_long(sslP)); - else if (ret < 0) { - fprintf(stderr, "%s:error in %s\n", - str, SSL_state_string_long(sslP)); - } - } -} - - - -static void -printPeerIpAddr(TSession * const abyssSessionP) { - -#ifdef _WIN32 - struct abyss_win_chaninfo * channelInfoP; -#else - struct abyss_unix_chaninfo * channelInfoP; -#endif - struct sockaddr_in * sockAddrInP; - unsigned char * ipAddr; /* 4 byte array */ - - SessionGetChannelInfo(abyssSessionP, (void*)&channelInfoP); - - sockAddrInP = (struct sockaddr_in *) &channelInfoP->peerAddr; - - ipAddr = (unsigned char *)&sockAddrInP->sin_addr.s_addr; - - printf("RPC is from IP address %u.%u.%u.%u\n", - ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]); -} - - - -static xmlrpc_server_shutdown_fn requestShutdown; - -static void -shutdownAbyss(xmlrpc_env * const faultP, - void * const context, - const char * const comment, - void * const callInfo) { - - TServer * const abyssServerP = context; - - xmlrpc_env_init(faultP); - - ServerTerminate(abyssServerP); -} - - - -static xmlrpc_value * -sample_add(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const channelInfo) { - - xmlrpc_int x, y, z; - - printPeerIpAddr(channelInfo); - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - if (envP->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Return our result. */ - return xmlrpc_build_value(envP, "i", z); -} - - - -int -main(int const argc, - const char ** const argv) { - - struct xmlrpc_method_info3 const methodInfo = { - .methodName = "sample.add", - .methodFunction = &sample_add, - .serverInfo = NULL - }; - - SSL_CTX * sslCtxP; - FILE * certFileP; - TChanSwitch * chanSwitchP; - TServer abyssServer; - xmlrpc_registry * registryP; - xmlrpc_env env; - const char * error; - - if (argc-1 != 1) { - fprintf(stderr, "You must specify 1 argument: The TCP port number " - "on which to listen for XML-RPC calls. " - "You specified %d.\n", argc-1); - exit(1); - } - - AbyssInit(&error); - - xmlrpc_env_init(&env); - - sslCtxP = SSL_CTX_new(SSLv23_server_method()); - - SSL_CTX_set_cipher_list(sslCtxP, "ALL:!aNULL"); - - SSL_CTX_use_certificate_chain_file(sslCtxP, - "/tmp/ssltest/certificate.pem"); - - SSL_CTX_use_PrivateKey_file(sslCtxP, "/tmp/ssltest/dsakey.pem", - SSL_FILETYPE_PEM); - - certFileP = fopen("/tmp/ssltest/dhparam.pem", "r"); - - DH * const dhP = PEM_read_DHparams(certFileP, NULL, NULL, NULL); - - SSL_CTX_set_tmp_dh(sslCtxP, dhP); - - SSL_CTX_set_info_callback(sslCtxP, sslInfoCallback); - - ChanSwitchOpenSslCreateIpV4Port(atoi(argv[1]), sslCtxP, - &chanSwitchP, &error); - - ServerCreateSwitch(&abyssServer, chanSwitchP, &error); - - registryP = xmlrpc_registry_new(&env); - - xmlrpc_registry_add_method3(&env, registryP, &methodInfo); - - xmlrpc_registry_set_shutdown(registryP, &shutdownAbyss, &abyssServer); - - xmlrpc_server_abyss_set_handlers2(&abyssServer, "/RPC2", registryP); - - ServerInit(&abyssServer); - - printf("Running server...\n"); - - ServerRun(&abyssServer); - /* This waits for TCP connections and processes them as XML-RPC - RPCs indefinitely (until system.shutdown method performed). - */ - - ServerFree(&abyssServer); - ChanSwitchDestroy(chanSwitchP); - SSL_CTX_free(sslCtxP); - AbyssTerm(); - - return 0; -} diff --git a/trunk/examples/ssl_server.c b/trunk/examples/ssl_server.c deleted file mode 100644 index cfadfd983..000000000 --- a/trunk/examples/ssl_server.c +++ /dev/null @@ -1,230 +0,0 @@ -/* A simple standalone XML-RPC server program based on Abyss that uses SSL - (Secure Sockets Layer) via OpenSSL. - - This server is not sophisticated enough to do any actual verification of - client or server, but it works with a client that is willing to do an - HTTPS connection using a non-authenticating cipher. The 'curl_client' - example program is one way to run such a client. - - Example: - - $ ./ssl_server 8080 & - $ ./curl_client https://localhost:8080/RPC2 - - You can drive the most difficult part of this example (initial SSL - handshake) with the 'openssl' program that comes with OpenSSL, as follows. - - $ ./ssl_server 8080 & - $ openssl -connect localhost:8080 -cipher ALL:aNULL:eNULL -state - - The 'openssl' command connects and handshakes with the server, then waits - for you to type stuff to send to the server. You would have to type a - complete HTTP header followed by a valid XML-RPC call to complete the - demonstration. - - Note that the examples above do no authentication, so you don't have to - supply certificates and keys to the server. See the 'ssl_secure_server' - example for that. - - This uses the "provide your own Abyss server" mode of operation, - as opposed to other Xmlrpc-c facilities that create an Abyss server under - the covers, because this is the only way to get SSL. - - NOTE: We deliberately don't check error indications here to make the code - easier to read. If you're having trouble getting this code to run, by all - means add checks of the "error" and "env" variables! -*/ - -#define _XOPEN_SOURCE 600 -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ - -#include -#include -#include -#ifndef _WIN32 -#include -#include -#endif - -#include - -#include -#include -#include -#include -#include - -#include "config.h" /* information about this build environment */ - - -static void -sslInfoCallback(const SSL * const sslP, - int const where, - int const ret) { - - const char * str; - int const w = where & ~SSL_ST_MASK; - - if (w & SSL_ST_CONNECT) - str = "SSL_connect"; - else if (w & SSL_ST_ACCEPT) - str = "SSL_accept"; - else - str = "undefined"; - - if (where & SSL_CB_LOOP) { - fprintf(stderr, "%s:%s\n", str, SSL_state_string_long(sslP)); - } else if (where & SSL_CB_ALERT) { - str = (where & SSL_CB_READ) ? "read" : "write"; - fprintf(stderr, "SSL3 alert %s:%s:%s\n", - str, - SSL_alert_type_string_long(ret), - SSL_alert_desc_string_long(ret)); - } else if (where & SSL_CB_EXIT) { - if (ret == 0) - fprintf(stderr, "%s:failed in %s\n", - str, SSL_state_string_long(sslP)); - else if (ret < 0) { - fprintf(stderr, "%s:error in %s\n", - str, SSL_state_string_long(sslP)); - } - } -} - - - -static void -printPeerIpAddr(TSession * const abyssSessionP) { - -#ifdef _WIN32 - struct abyss_win_chaninfo * channelInfoP; -#else - struct abyss_unix_chaninfo * channelInfoP; -#endif - struct sockaddr_in * sockAddrInP; - unsigned char * ipAddr; /* 4 byte array */ - - SessionGetChannelInfo(abyssSessionP, (void*)&channelInfoP); - - sockAddrInP = (struct sockaddr_in *) &channelInfoP->peerAddr; - - ipAddr = (unsigned char *)&sockAddrInP->sin_addr.s_addr; - - printf("RPC is from IP address %u.%u.%u.%u\n", - ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]); -} - - - -static xmlrpc_server_shutdown_fn requestShutdown; - -static void -shutdownAbyss(xmlrpc_env * const faultP, - void * const context, - const char * const comment, - void * const callInfo) { - - TServer * const abyssServerP = context; - - xmlrpc_env_init(faultP); - - ServerTerminate(abyssServerP); -} - - - -static xmlrpc_value * -sample_add(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const channelInfo) { - - xmlrpc_int x, y, z; - - printPeerIpAddr(channelInfo); - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - if (envP->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Return our result. */ - return xmlrpc_build_value(envP, "i", z); -} - - - -int -main(int const argc, - const char ** const argv) { - - struct xmlrpc_method_info3 const methodInfo = { - .methodName = "sample.add", - .methodFunction = &sample_add, - .serverInfo = NULL - }; - - SSL_CTX * sslCtxP; - TChanSwitch * chanSwitchP; - TServer abyssServer; - xmlrpc_registry * registryP; - xmlrpc_env env; - const char * error; - - if (argc-1 != 1) { - fprintf(stderr, "You must specify 1 argument: The TCP port number " - "on which to listen for XML-RPC calls. " - "You specified %d.\n", argc-1); - exit(1); - } - - AbyssInit(&error); - - xmlrpc_env_init(&env); - - sslCtxP = SSL_CTX_new(SSLv23_server_method()); - - SSL_CTX_set_cipher_list(sslCtxP, "ALL:aNULL:eNULL"); - - EC_KEY * const ecdhP = EC_KEY_new_by_curve_name(NID_sect163r2); - - // The following makes ECDH ciphers available. Without it (or some - // alternative), no ciphers are available - SSL_CTX_set_tmp_ecdh(sslCtxP, ecdhP); - EC_KEY_free(ecdhP); - - // Provide handy tracing to Standard Error of the SSL handshake - SSL_CTX_set_info_callback(sslCtxP, sslInfoCallback); - - ChanSwitchOpenSslCreateIpV4Port(atoi(argv[1]), sslCtxP, - &chanSwitchP, &error); - - ServerCreateSwitch(&abyssServer, chanSwitchP, &error); - - registryP = xmlrpc_registry_new(&env); - - xmlrpc_registry_add_method3(&env, registryP, &methodInfo); - - xmlrpc_registry_set_shutdown(registryP, &shutdownAbyss, &abyssServer); - - xmlrpc_server_abyss_set_handlers2(&abyssServer, "/RPC2", registryP); - - ServerInit(&abyssServer); - - printf("Running server...\n"); - - ServerRun(&abyssServer); - /* This waits for TCP connections and processes them as XML-RPC - RPCs indefinitely (until system.shutdown method performed). - */ - - ServerFree(&abyssServer); - ChanSwitchDestroy(chanSwitchP); - SSL_CTX_free(sslCtxP); - AbyssTerm(); - - return 0; -} diff --git a/trunk/examples/synch_client.c b/trunk/examples/synch_client.c deleted file mode 100644 index b9b62a2d6..000000000 --- a/trunk/examples/synch_client.c +++ /dev/null @@ -1,66 +0,0 @@ -/* A simple synchronous XML-RPC client program written in C. */ - -#include -#include - -#include -#include - -#include "config.h" /* information about this build environment */ - -#define NAME "XML-RPC C Test Client synch_client" -#define VERSION "1.0" - -static void -die_if_fault_occurred(xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "XML-RPC Fault: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -int -main(int const argc, - const char ** const argv) { - - xmlrpc_env env; - xmlrpc_value * resultP; - const char * stateName; - - if (argc-1 > 0) { - fprintf(stderr, "No arguments"); - exit(0); - } - - /* Start up our XML-RPC client library. */ - xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION); - - /* Initialize our error-handling environment. */ - xmlrpc_env_init(&env); - - /* Call the famous server at UserLand. */ - resultP = xmlrpc_client_call(&env, "http://betty.userland.com/RPC2", - "examples.getStateName", - "(i)", (xmlrpc_int32) 41); - die_if_fault_occurred(&env); - - /* Get our state name and print it out. */ - xmlrpc_read_string(&env, resultP, &stateName); - die_if_fault_occurred(&env); - printf("%s\n", stateName); - free((char*)stateName); - - /* Dispose of our result value. */ - xmlrpc_DECREF(resultP); - - /* Clean up our error-handling environment. */ - xmlrpc_env_clean(&env); - - /* Shutdown our XML-RPC client library. */ - xmlrpc_client_cleanup(); - - return 0; -} diff --git a/trunk/examples/xmlrpc_asynch_client.c b/trunk/examples/xmlrpc_asynch_client.c deleted file mode 100644 index ff56dfdb8..000000000 --- a/trunk/examples/xmlrpc_asynch_client.c +++ /dev/null @@ -1,123 +0,0 @@ -/* A simple asynchronous XML-RPC client program written in C, as an example of - Xmlrpc-c asynchronous RPC facilities. This is the same as the - simpler synchronous client xmlprc_sample_add_client.c, except that - it adds 3 different pairs of numbers with the summation RPCs going on - simultaneously. - - Use this with xmlrpc_sample_add_server. Note that that server - intentionally takes extra time to add 1 to anything, so you can see - our 5+1 RPC finish after our 5+0 and 5+2 RPCs. -*/ - -#include -#include - -#include -#include - -#include "config.h" /* information about this build environment */ - -#define NAME "Xmlrpc-c Asynchronous Test Client" -#define VERSION "1.0" - -static void -die_if_fault_occurred(xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "Something failed. %s (XML-RPC fault code %d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -static void -handle_sample_add_response(const char * const serverUrl, - const char * const methodName, - xmlrpc_value * const paramArrayP, - void * const user_data, - xmlrpc_env * const faultP, - xmlrpc_value * const resultP) { - - xmlrpc_env env; - xmlrpc_int addend, adder; - - /* Initialize our error environment variable */ - xmlrpc_env_init(&env); - - /* Our first four arguments provide helpful context. Let's grab the - addends from our parameter array. - */ - xmlrpc_decompose_value(&env, paramArrayP, "(ii)", &addend, &adder); - die_if_fault_occurred(&env); - - printf("RPC with method '%s' at URL '%s' to add %d and %d " - "has completed\n", methodName, serverUrl, addend, adder); - - if (faultP->fault_occurred) - printf("The RPC failed. %s\n", faultP->fault_string); - else { - xmlrpc_int sum; - - xmlrpc_read_int(&env, resultP, &sum); - die_if_fault_occurred(&env); - - printf("The sum is %d\n", sum); - } -} - - - -int -main(int const argc, - const char ** const argv) { - - const char * const serverUrl = "http://localhost:8080/RPC2"; - const char * const methodName = "sample.add"; - - xmlrpc_env env; - xmlrpc_client * clientP; - xmlrpc_int adder; - - if (argc-1 > 0) { - fprintf(stderr, "This program has no arguments\n"); - exit(1); - } - - /* Initialize our error environment variable */ - xmlrpc_env_init(&env); - - /* Required before any use of Xmlrpc-c client library: */ - xmlrpc_client_setup_global_const(&env); - die_if_fault_occurred(&env); - - xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0, - &clientP); - die_if_fault_occurred(&env); - - for (adder = 0; adder < 3; ++adder) { - printf("Making XMLRPC call to server url '%s' method '%s' " - "to request the sum " - "of 5 and %d...\n", serverUrl, methodName, adder); - - /* request the remote procedure call */ - xmlrpc_client_start_rpcf(&env, clientP, serverUrl, methodName, - handle_sample_add_response, NULL, - "(ii)", (xmlrpc_int32) 5, adder); - die_if_fault_occurred(&env); - } - - printf("RPCs all requested. Waiting for & handling responses...\n"); - - /* Wait for all RPCs to be done. With some transports, this is also - what causes them to go. - */ - xmlrpc_client_event_loop_finish(clientP); - - printf("All RPCs finished.\n"); - - xmlrpc_client_destroy(clientP); - xmlrpc_client_teardown_global_const(); - - return 0; -} diff --git a/trunk/examples/xmlrpc_inetd_server.c b/trunk/examples/xmlrpc_inetd_server.c deleted file mode 100644 index 8f51142c3..000000000 --- a/trunk/examples/xmlrpc_inetd_server.c +++ /dev/null @@ -1,128 +0,0 @@ -/* A simple standalone XML-RPC server program based on Abyss that processes a - single RPC from an existing TCP connection on Standard Input. - - A typical example of where this would be useful is with an Inetd - "super server." - - xmlrpc_sample_add_server.c is a server that does the same thing, - but you give it a TCP port number and it listens for TCP connecitons - and processes RPCs ad infinitum. xmlrpc_socket_server.c is halfway - in between those -- you give it an already bound and listening - socket, and it lists for TCP connections and processes RPCs ad - infinitum. - - Here is an easy way to test this program: - - socketexec --accept --local_port=8080 --stdin -- ./xmlrpc_inetd_server - - Now run the client program 'xmlrpc_sample_add_client'. Socketexec - will accept the connection that the client program requests and pass it - to this program on Standard Input. This program will perform the RPC, - respond to the client, then exit. -*/ - -#define _XOPEN_SOURCE 600 -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ - -#include -#include -#include -#ifndef _WIN32 -# include -#endif - -#include -#include -#include -#include - -#include "config.h" /* information about this build environment */ - - -static void -setupSignalHandlers(void) { - - /* In UNIX, when you try to write to a socket that has been closed - from the other end, your write fails, but you also get a SIGPIPE - signal. That signal will kill you before you even have a chance - to see the write fail unless you catch, block, or ignore it. - If a client should connect to us and then disconnect before we've - sent our response, we see this socket-closed behavior. We - obviously don't want to die just because a client didn't complete - an RPC, so we ignore SIGPIPE. - */ -#ifndef _WIN32 - struct sigaction mysigaction; - - sigemptyset(&mysigaction.sa_mask); - mysigaction.sa_flags = 0; - mysigaction.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &mysigaction, NULL); -#endif -} - - - -static xmlrpc_value * -sample_add(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const channelInfo) { - - xmlrpc_int x, y, z; - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - if (envP->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Return our result. */ - return xmlrpc_build_value(envP, "i", z); -} - - - -int -main(int const argc, - const char ** const argv) { - - struct xmlrpc_method_info3 const methodInfo = { - .methodName = "sample.add", - .methodFunction = &sample_add, - .serverInfo = NULL - }; - TServer abyssServer; - xmlrpc_registry * registryP; - xmlrpc_env env; - - if (argc-1 != 0) { - fprintf(stderr, "There are no arguments. You must supply a " - "bound socket on which to listen for client connections " - "as Standard Input\n"); - if (argv) {} /* silence unused parameter warning */ - exit(1); - } - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - - xmlrpc_registry_add_method3(&env, registryP, &methodInfo); - - ServerCreateNoAccept(&abyssServer, "XmlRpcServer", NULL, NULL); - - xmlrpc_server_abyss_set_handlers(&abyssServer, registryP); - - setupSignalHandlers(); - - ServerRunConn(&abyssServer, STDIN_FILENO); - /* This reads the HTTP POST request from Standard Input and - executes the indicated RPC. - */ - - ServerFree(&abyssServer); - - return 0; -} diff --git a/trunk/examples/xmlrpc_loop_server.c b/trunk/examples/xmlrpc_loop_server.c deleted file mode 100644 index 742fc3bab..000000000 --- a/trunk/examples/xmlrpc_loop_server.c +++ /dev/null @@ -1,185 +0,0 @@ -/* A simple standalone XML-RPC server program based on Abyss that contains a - simple one-thread request processing loop. - - This uses the "provide your own Abyss server" mode of operation. - - xmlrpc_sample_add_server.c is a server that does the same thing, but - does it by running a full Abyss daemon in the background, so it has - less control over how the requests are served. -*/ - -#define _XOPEN_SOURCE 600 -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ - -#include -#include -#include -#ifndef _WIN32 -#include -#include -#endif - -#include -#include -#include -#include - -#include "config.h" /* information about this build environment */ - - -static void -setupSignalHandlers(void) { - - /* In UNIX, when you try to write to a socket that has been closed - from the other end, your write fails, but you also get a SIGPIPE - signal. That signal will kill you before you even have a chance - to see the write fail unless you catch, block, or ignore it. - If a client should connect to us and then disconnect before we've - sent our response, we see this socket-closed behavior. We - obviously don't want to die just because a client didn't complete - an RPC, so we ignore SIGPIPE. - */ -#ifndef _WIN32 - struct sigaction mysigaction; - - sigemptyset(&mysigaction.sa_mask); - mysigaction.sa_flags = 0; - mysigaction.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &mysigaction, NULL); -#endif -} - - - -static void -printPeerIpAddr(TSession * const abyssSessionP) { - -#ifdef _WIN32 - struct abyss_win_chaninfo * channelInfoP; -#else - struct abyss_unix_chaninfo * channelInfoP; -#endif - struct sockaddr_in * sockAddrInP; - unsigned char * ipAddr; /* 4 byte array */ - - SessionGetChannelInfo(abyssSessionP, (void*)&channelInfoP); - - sockAddrInP = (struct sockaddr_in *) &channelInfoP->peerAddr; - - ipAddr = (unsigned char *)&sockAddrInP->sin_addr.s_addr; - - printf("RPC is from IP address %u.%u.%u.%u\n", - ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]); -} - - - -static xmlrpc_value * -sample_add(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const channelInfo) { - - xmlrpc_int x, y, z; - - printPeerIpAddr(channelInfo); - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - if (envP->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Return our result. */ - return xmlrpc_build_value(envP, "i", z); -} - - - -static xmlrpc_server_shutdown_fn requestShutdown; - -static void -requestShutdown(xmlrpc_env * const faultP, - void * const context, - const char * const comment, - void * const callInfo) { - - /* You make this run by executing the system method 'system.shutdown'. - This function is registered in the method registry as the thing to call - for that. - */ - int * const terminationRequestedP = context; - TSession * const abyssSessionP = callInfo; - - xmlrpc_env_init(faultP); - - fprintf(stderr, "Termination requested: %s\n", comment); - - printPeerIpAddr(abyssSessionP); - - *terminationRequestedP = 1; -} - - - -int -main(int const argc, - const char ** const argv) { - - struct xmlrpc_method_info3 const methodInfo = { - .methodName = "sample.add", - .methodFunction = &sample_add, - .serverInfo = NULL - }; - TServer abyssServer; - xmlrpc_registry * registryP; - xmlrpc_env env; - int terminationRequested; /* A boolean value */ - const char * error; - - if (argc-1 != 1) { - fprintf(stderr, "You must specify 1 argument: The TCP port number " - "on which to listen for XML-RPC calls. " - "You specified %d.\n", argc-1); - exit(1); - } - - AbyssInit(&error); - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - - xmlrpc_registry_add_method3(&env, registryP, &methodInfo); - - xmlrpc_registry_set_shutdown(registryP, - &requestShutdown, &terminationRequested); - - ServerCreate(&abyssServer, "XmlRpcServer", atoi(argv[1]), NULL, NULL); - - xmlrpc_server_abyss_set_handlers2(&abyssServer, "/RPC2", registryP); - - ServerInit(&abyssServer); - - setupSignalHandlers(); - - terminationRequested = 0; - - while (!terminationRequested) { - printf("Waiting for next RPC...\n"); - - ServerRunOnce(&abyssServer); - /* This waits for the next connection, accepts it, reads the - HTTP POST request, executes the indicated RPC, and closes - the connection. - */ - } - - ServerFree(&abyssServer); - - AbyssTerm(); - - return 0; -} diff --git a/trunk/examples/xmlrpc_sample_add_client.c b/trunk/examples/xmlrpc_sample_add_client.c deleted file mode 100644 index d80a44e5c..000000000 --- a/trunk/examples/xmlrpc_sample_add_client.c +++ /dev/null @@ -1,84 +0,0 @@ -/* A simple synchronous XML-RPC client program written in C, as an example of - an Xmlrpc-c client. This invokes the sample.add procedure that the - Xmlrpc-c example xmlrpc_sample_add_server.c server provides. I.e. it adds - two numbers together, the hard way. - - This sends the RPC to the server running on the local system ("localhost"), - HTTP Port 8080. - - This program uses the Xmlrpc-c global client, which uses the default - client XML transport. -*/ - -#include -#include - -#include -#include - -#include "config.h" /* information about this build environment */ - -#define NAME "Xmlrpc-c Test Client" -#define VERSION "1.0" - -static void -dieIfFaultOccurred (xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "ERROR: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -int -main(int const argc, - const char ** const argv) { - - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_int32 sum; - const char * const serverUrl = "http://localhost:8080/RPC2"; - const char * const methodName = "sample.add"; - - if (argc-1 > 0) { - fprintf(stderr, "This program has no arguments\n"); - exit(1); - } - - /* Initialize our error-handling environment. */ - xmlrpc_env_init(&env); - - /* Create the global XML-RPC client object. */ - xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0); - dieIfFaultOccurred(&env); - - printf("Making XMLRPC call to server url '%s' method '%s' " - "to request the sum " - "of 5 and 7...\n", serverUrl, methodName); - - /* Make the remote procedure call */ - resultP = xmlrpc_client_call(&env, serverUrl, methodName, - "(ii)", (xmlrpc_int32) 5, (xmlrpc_int32) 7); - dieIfFaultOccurred(&env); - - /* Get our sum and print it out. */ - xmlrpc_read_int(&env, resultP, &sum); - dieIfFaultOccurred(&env); - printf("The sum is %d\n", sum); - - /* Dispose of our result value. */ - xmlrpc_DECREF(resultP); - - /* Clean up our error-handling environment. */ - xmlrpc_env_clean(&env); - - /* Shutdown our XML-RPC client library. */ - xmlrpc_client_cleanup(); - - return 0; -} - - - diff --git a/trunk/examples/xmlrpc_sample_add_server.c b/trunk/examples/xmlrpc_sample_add_server.c deleted file mode 100644 index d0edd29df..000000000 --- a/trunk/examples/xmlrpc_sample_add_server.c +++ /dev/null @@ -1,128 +0,0 @@ -/* A simple standalone XML-RPC server program written in C. */ - -/* This server knows one RPC class (besides the system classes): - "sample.add". - - The program takes one argument: the HTTP port number on which the server - is to accept connections, in decimal. - - You can use the example program 'xmlrpc_sample_add_client' to send an RPC - to this server. - - Example: - - $ ./xmlrpc_sample_add_server 8080& - $ ./xmlrpc_sample_add_client - - For more fun, run client and server in separate terminals and turn on - tracing for each: - - $ export XMLRPC_TRACE_XML=1 -*/ - -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ - -#include -#include -#ifdef _WIN32 -# include -# include -#else -# include -#endif - -#include -#include -#include - -#include "config.h" /* information about this build environment */ - - -#ifdef _WIN32 - #define SLEEP(seconds) SleepEx(seconds * 1000, 1); -#else - #define SLEEP(seconds) sleep(seconds); -#endif - - -static xmlrpc_value * -sample_add(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const channelInfo) { - - xmlrpc_int32 x, y, z; - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - if (envP->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Sometimes, make it look hard (so client can see what it's like - to do an RPC that takes a while). - */ - if (y == 1) - SLEEP(5); - - /* Return our result. */ - return xmlrpc_build_value(envP, "i", z); -} - - - -int -main(int const argc, - const char ** const argv) { - - struct xmlrpc_method_info3 const methodInfo = { - /* .methodName = */ "sample.add", - /* .methodFunction = */ &sample_add, - }; - xmlrpc_server_abyss_parms serverparm; - xmlrpc_registry * registryP; - xmlrpc_env env; - - if (argc-1 != 1) { - fprintf(stderr, "You must specify 1 argument: The TCP port " - "number on which the server will accept connections " - "for RPCs (8080 is a common choice). " - "You specified %d arguments.\n", argc-1); - exit(1); - } - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - if (env.fault_occurred) { - printf("xmlrpc_registry_new() failed. %s\n", env.fault_string); - exit(1); - } - - xmlrpc_registry_add_method3(&env, registryP, &methodInfo); - if (env.fault_occurred) { - printf("xmlrpc_registry_add_method3() failed. %s\n", - env.fault_string); - exit(1); - } - - serverparm.config_file_name = NULL; /* Select the modern normal API */ - serverparm.registryP = registryP; - serverparm.port_number = atoi(argv[1]); - serverparm.log_file_name = "/tmp/xmlrpc_log"; - - printf("Running XML-RPC server...\n"); - - xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name)); - if (env.fault_occurred) { - printf("xmlrpc_server_abyss() failed. %s\n", env.fault_string); - exit(1); - } - /* xmlrpc_server_abyss() never returns unless it fails */ - - return 0; -} - - diff --git a/trunk/examples/xmlrpc_sample_add_server_cgi.c b/trunk/examples/xmlrpc_sample_add_server_cgi.c deleted file mode 100644 index e34c4d7ae..000000000 --- a/trunk/examples/xmlrpc_sample_add_server_cgi.c +++ /dev/null @@ -1,75 +0,0 @@ -/* A CGI script written in C to effect a simple XML-RPC server. - - Example of use: - - - Compile this as the executable 'xmlrpc_sample_add_server.cgi' - - - Place the .cgi file in web server www.example.com's /cgi-bin - directory. - - - Configure the web server to permit CGI scripts in /cgi-bin - (Apache ExecCgi directory option). - - - Configure the web server to recognize this .cgi file as a CGI - script (Apache "AddHandler cgi-script ..." or ScriptAlias). - - - $ xmlrpc http://www.example.com/cgi-bin/xmlrpc_sample_add_server.cgi \ - sample.add i/5 i/7 -*/ - - -#include -#include - -#include -#include -#include - -#include "config.h" /* information about this build environment */ - -static xmlrpc_value * -sample_add(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const user_data) { - - xmlrpc_int32 x, y, z; - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - if (envP->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Return our result. */ - return xmlrpc_build_value(envP, "i", z); -} - - - -int -main(int const argc, - const char ** const argv) { - - xmlrpc_registry * registryP; - xmlrpc_env env; - - if (argc-1 > 0 && argv==argv) { - fprintf(stderr, "There are no arguments to a CGI script\n"); - exit(1); - } - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - - xmlrpc_registry_add_method( - &env, registryP, NULL, "sample.add", &sample_add, NULL); - - xmlrpc_server_cgi_process_call(registryP); - - xmlrpc_registry_free(registryP); - - return 0; -} diff --git a/trunk/examples/xmlrpc_sample_add_server_w32httpsys.c b/trunk/examples/xmlrpc_sample_add_server_w32httpsys.c deleted file mode 100644 index 44e128b46..000000000 --- a/trunk/examples/xmlrpc_sample_add_server_w32httpsys.c +++ /dev/null @@ -1,190 +0,0 @@ -/* 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. -*/ - -#include -#include -#include -#include -#include - - -/* SECURITY NOTE: Using HTTP Authorization - -The current implementation of HTTP Authorization in the win32httpsys -server only uses basic Authorization. This means the userid and password -is sent in clear-text over the network (Technically, it is Base64 encoded, -but this is essentially clear text). This method is not secure, as it -can be captured and decoded. The use of HTTP Basic Authorization with SSL -is considered much more secure. See the note below for configuring SSL -support. -*/ - - -/* -HOWTO: Configure SSL for the XMLRPC-C Server - -To use SSL you need an SSL certificate. For testing purposes, -it is possible to create a self-signed SSL certificate. To do so, -you must download the IIS 6.0 Resource Kit tools. The current -URL to get the download link is http://support.microsoft.com/kb/840671 -We will be using the SelfSSL version 1.0 from this toolkit for -this example. The other tool you will need is httpcfg.exe, which -can be compiled from the sources in the Windows XP SP2 (or newer) Platform SDK, -or downloaded as part of the Windows XP SP2 Support Tools at the following URL: -http://www.microsoft.com/downloads/details.aspx?FamilyID=49ae8576-9bb9-4126-9761-ba8011fabf38&displaylang=en -The last assumption is that this procedure is being done on the machine that is -hosting the XMLRPC-C server application. - -1) Make sure that IIS is installed, and you are running at least Windows XP SP2 -or Windows Server 2003. WARNING: This process will replace any existing IIS SSL -certificates currently installed. - -2) In a command prompt, navigate to the directory of the -IIS Support Tools where the selfssl program exists (usually -C:\Program Files\IIS Resources\SelfSSL). Assuming (as we are for this example) -that we are going to run on port 8443, use the following command line (see the -documentation for all the flags): - -selfssl /T /V:365 /P:8443 - -3) In the Control Panel, Administrative tools, run the Internet Information Services -program. Drill down to the Default Web Site. Right-click it and choose Properties. -On the "Web Site" tab, you will notice that the SSL port is now set to 8443. Change -it back to 443. On the Directory Security tab, pick "View Certificate". In the -"Details" tab, select the "Thumbprint" line. The edit box below the listbox will -display a series of hex numbers. Copy these to the clipboard and paste into notepad. -OK yourself out of the IIS program. - -4) Remove all the spaces in the hex string so you are left with a string with no spaces. -This is your SSL Thumbprint hash which you will need in the next step. - -5) At your command prompt, navigate to the support tools directory (or the location -where you built httpcfg.exe) - usually C:\Program Files\Support Tools. Run the following -command line, replacing both the brackets and text with your thumbprint hash from step 4 above: - -httpcfg.exe set ssl -i 0.0.0.0:8443 -h -g "{2bb50d9c-7f6a-4d6f-873d-5aee7fb43290}" -c "MY" -t "" -n "" - -6) You can check the setup by performing a "httpcfg.exe query ssl" if you wish. - -7) Modify the example server code below to use SSL. Set the xmlrpc_server_httpsys_parms.useSSL -to '1' and the xmlrpc_server_httpsys_parms.portNum to be '8443'. You can test the server by using -IE to browse to the URL https://127.0.0.1:8443/rpc2. An error 405 (Resource not allowed) is the -expected result if everything is working properly. - -NOTE: Testing clients with a 'test' or not real SSL certificate involves changing some of the default -code in the client samples, as by default the transports will fail if there are any issues with the -certificate. The WinInet transport as of 1.2 has a transport-specific setting to allow -invalid SSL certificates. See the libxmlrpc_client.html documentation for more details. - -NOTE: Failure to follow all the steps listed above correctly will result in no application -errors, event log messages, or HTTP.SYS log messages indicating failure or the cause. If -anyone can provide information on debugging SSL certificate issues in HTTP.SYS, please -submit to us! -*/ - - -static xmlrpc_value * -sample_add(xmlrpc_env * const env, - xmlrpc_value * const param_array, - void * const user_data ) { - - xmlrpc_int32 x, y, z; - - /* Parse our argument array. */ - xmlrpc_decompose_value(env, param_array, "(ii)", &x, &y); - if (env->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Return our result. */ - return xmlrpc_build_value(env, "i", z); -} - -static void handleAuthorization( - xmlrpc_env * envP, - char * userid, - char * password) -{ - if (strcmp(userid,"jrandom")==0 && strcmp(password,"secret")==0) - return; - - xmlrpc_env_set_fault( envP, XMLRPC_REQUEST_REFUSED_ERROR, - "Username and/or password do not match."); -} - -int __cdecl wmain( int argc, wchar_t * argv[]) -{ - xmlrpc_server_httpsys_parms serverparm; - xmlrpc_registry * registryP; - xmlrpc_env env; - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - - xmlrpc_registry_add_method( - &env, registryP, NULL, "sample.add", &sample_add, NULL); - - wprintf(L"Starting XML-RPC server...\n"); - - //Sets the port number we are listening on - serverparm.portNum=8080; - - //if this is set, we will use the authorization function - //serverparm.authfn=NULL; - serverparm.authfn=&handleAuthorization; - - //set the logging level and log file - serverparm.logLevel=2; - serverparm.logFile="C:\\httpsysserverlog.txt"; - - //set the use of SSL - serverparm.useSSL=0; - - serverparm.registryP = registryP; - - xmlrpc_server_httpsys(&env, &serverparm, XMLRPC_HSSIZE(authfn)); - - wprintf(L"Stopping XML-RPC server...\n"); - - xmlrpc_registry_free(registryP); - xmlrpc_env_clean(&env); - - return 0; -} diff --git a/trunk/examples/xmlrpc_server_validatee.c b/trunk/examples/xmlrpc_server_validatee.c deleted file mode 100644 index 309a0fa36..000000000 --- a/trunk/examples/xmlrpc_server_validatee.c +++ /dev/null @@ -1,412 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -/*============================================================================ - xmlrpc_server_validatee -============================================================================== - - This program runs an XMLRPC server, using the Xmlrpc-c libraries. - - The server implements the methods that the Userland Validator1 test suite - invokes, which are supposed to exercise a broad range of XMLRPC server - function. - - Coments here used to say you could get information about Validator1 - from , but as of 2004.09.25, there's nothing - there (there's a web server, but it is not configured to serve that - particular URL). - -============================================================================*/ - -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ - -#include -#include -#include - -#include -#include -#include - -#include "config.h" /* information about this build environment */ - -#define RETURN_IF_FAULT(envP) \ - do { \ - if ((envP)->fault_occurred) \ - return NULL; \ - } while (0) - - -/*========================================================================= -** validator1.arrayOfStructsTest -**========================================================================= -*/ - -static xmlrpc_value * -array_of_structs(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const user_data) { - - xmlrpc_value * arrayP; - xmlrpc_value * retval; - - xmlrpc_decompose_value(envP, paramArrayP, "(A)", &arrayP); - if (envP->fault_occurred) - retval = NULL; - else { - /* Add up all the struct elements named "curly". */ - size_t size; - size = xmlrpc_array_size(envP, arrayP); - if (envP->fault_occurred) - retval = NULL; - else { - unsigned int sum; - unsigned int i; - sum = 0; - for (i = 0; i < size && !envP->fault_occurred; ++i) { - xmlrpc_value * strctP; - strctP = xmlrpc_array_get_item(envP, arrayP, i); - if (!envP->fault_occurred) { - xmlrpc_int32 curly; - xmlrpc_decompose_value(envP, strctP, "{s:i,*}", - "curly", &curly); - if (!envP->fault_occurred) - sum += curly; - } - } - xmlrpc_DECREF(arrayP); - if (envP->fault_occurred) - retval = NULL; - else - retval = xmlrpc_build_value(envP, "i", sum); - } - } - return retval; -} - - -/*========================================================================= -** validator1.countTheEntities -**========================================================================= -*/ - -static xmlrpc_value * -count_entities(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const user_data) { - - const char * str; - size_t len, i; - xmlrpc_int32 left, right, amp, apos, quote; - - xmlrpc_decompose_value(envP, paramArrayP, "(s#)", &str, &len); - RETURN_IF_FAULT(envP); - - left = right = amp = apos = quote = 0; - for (i = 0; i < len; ++i) { - switch (str[i]) { - case '<': ++left; break; - case '>': ++right; break; - case '&': ++amp; break; - case '\'': ++apos; break; - case '\"': ++quote; break; - default: break; - } - } - free((void*)str); - - return xmlrpc_build_value(envP, "{s:i,s:i,s:i,s:i,s:i}", - "ctLeftAngleBrackets", left, - "ctRightAngleBrackets", right, - "ctAmpersands", amp, - "ctApostrophes", apos, - "ctQuotes", quote); -} - - - -/*========================================================================= -** validator1.easyStructTest -**========================================================================= -*/ - -static xmlrpc_value * -easy_struct(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const user_data) { - - xmlrpc_int32 larry, moe, curly; - - /* Parse our argument array and get the stooges. */ - xmlrpc_decompose_value(envP, paramArrayP, "({s:i,s:i,s:i,*})", - "larry", &larry, - "moe", &moe, - "curly", &curly); - RETURN_IF_FAULT(envP); - - /* Return our result. */ - return xmlrpc_build_value(envP, "i", larry + moe + curly); -} - - - -/*========================================================================= -** validator1.echoStructTest -**========================================================================= -*/ - -static xmlrpc_value * -echo_struct(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const user_data) { - - xmlrpc_value * sP; - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(S)", &sP); - RETURN_IF_FAULT(envP); - - return sP; /* We transfer our reference on '*sP' to Caller */ -} - - - -/*========================================================================= -** validator1.manyTypesTest -**========================================================================= -*/ - -static xmlrpc_value * -many_types(xmlrpc_env * const env, - xmlrpc_value * const param_array, - void * const user_data) { - - /* Create another reference to our argument array and return it as is. */ - xmlrpc_INCREF(param_array); - return param_array; -} - - - -/*========================================================================= -** validator1.moderateSizeArrayCheck -**========================================================================= -*/ - -static void -concatenate(xmlrpc_env * const envP, - const char * const str1, - size_t const str1_len, - const char * const str2, - size_t const str2_len, - xmlrpc_value ** const resultPP) { - - /* Concatenate the two strings. */ - - char * buffer; - - buffer = (char*) malloc(str1_len + str2_len); - if (!buffer) { - xmlrpc_env_set_fault(envP, 1, - "Couldn't allocate concatenated string"); - } else { - memcpy(buffer, str1, str1_len); - memcpy(&buffer[str1_len], str2, str2_len); - *resultPP = xmlrpc_build_value(envP, "s#", - buffer, str1_len + str2_len); - free(buffer); - } -} - - - -static xmlrpc_value * -moderate_array(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const user_data) { - - xmlrpc_value * retval; - xmlrpc_value * arrayP; - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(A)", &arrayP); - if (!envP->fault_occurred) { - int const size = xmlrpc_array_size(envP, arrayP); - if (!envP->fault_occurred) { - /* Get our first string. */ - xmlrpc_value * const firstItemP = - xmlrpc_array_get_item(envP, arrayP, 0); - if (!envP->fault_occurred) { - const char * str1; - size_t str1_len; - xmlrpc_read_string_lp(envP, firstItemP, &str1_len, &str1); - if (!envP->fault_occurred) { - /* Get our last string. */ - xmlrpc_value * const lastItemP = - xmlrpc_array_get_item(envP, arrayP, size - 1); - if (!envP->fault_occurred) { - const char * str2; - size_t str2_len; - xmlrpc_read_string_lp(envP, lastItemP, - &str2_len, &str2); - if (!envP->fault_occurred) { - concatenate(envP, str1, str1_len, str2, str2_len, - &retval); - free((char*)str2); - } - } - free((char*)str1); - } - } - } - xmlrpc_DECREF(arrayP); - } - return retval; -} - - - -/*========================================================================= -** validator1.nestedStructTest -**========================================================================= -*/ - -static xmlrpc_value * -nested_struct(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const user_data) { - - xmlrpc_value * yearsP; - xmlrpc_value * retval; - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(S)", &yearsP); - if (envP->fault_occurred) - retval = NULL; - else { - /* Get values of larry, moe and curly for 2000-04-01. */ - xmlrpc_int32 larry, moe, curly; - xmlrpc_decompose_value(envP, yearsP, - "{s:{s:{s:{s:i,s:i,s:i,*},*},*},*}", - "2000", "04", "01", - "larry", &larry, - "moe", &moe, - "curly", &curly); - if (envP->fault_occurred) - retval = NULL; - else - retval = xmlrpc_build_value(envP, "i", larry + moe + curly); - - xmlrpc_DECREF(yearsP); - } - return retval; -} - - - -/*========================================================================= -** validator1.simpleStructReturnTest -**========================================================================= -*/ - -static xmlrpc_value * -struct_return(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const user_data) { - - xmlrpc_int32 i; - - xmlrpc_decompose_value(envP, paramArrayP, "(i)", &i); - RETURN_IF_FAULT(envP); - - return xmlrpc_build_value(envP, "{s:i,s:i,s:i}", - "times10", (xmlrpc_int32) i * 10, - "times100", (xmlrpc_int32) i * 100, - "times1000", (xmlrpc_int32) i * 1000); -} - - - -/*========================================================================= -** main -**========================================================================= -*/ - -int main(int const argc, - const char ** const argv) { - - xmlrpc_server_abyss_parms serverparm; - xmlrpc_registry * registryP; - xmlrpc_env env; - - if (argc-1 != 1) { - fprintf(stderr, "You must specify 1 argument: The TCP port " - "number on which the server will accept connections " - "for RPCs. You specified %d arguments.\n", argc-1); - exit(1); - } - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - - xmlrpc_registry_add_method( - &env, registryP, NULL, "validator1.arrayOfStructsTest", - &array_of_structs, NULL); - xmlrpc_registry_add_method( - &env, registryP, NULL, "validator1.countTheEntities", - &count_entities, NULL); - xmlrpc_registry_add_method( - &env, registryP, NULL, "validator1.easyStructTest", - &easy_struct, NULL); - xmlrpc_registry_add_method( - &env, registryP, NULL, "validator1.echoStructTest", - &echo_struct, NULL); - xmlrpc_registry_add_method( - &env, registryP, NULL, "validator1.manyTypesTest", - &many_types, NULL); - xmlrpc_registry_add_method( - &env, registryP, NULL, "validator1.moderateSizeArrayCheck", - &moderate_array, NULL); - xmlrpc_registry_add_method( - &env, registryP, NULL, "validator1.nestedStructTest", - &nested_struct, NULL); - xmlrpc_registry_add_method( - &env, registryP, NULL, "validator1.simpleStructReturnTest", - &struct_return, NULL); - - serverparm.config_file_name = NULL; - serverparm.registryP = registryP; - serverparm.port_number = atoi(argv[1]); - serverparm.log_file_name = NULL; - - printf("Running XML-RPC server...\n"); - - xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(log_file_name)); - - /* This never gets executed. */ - return 0; -} diff --git a/trunk/examples/xmlrpc_socket_server.c b/trunk/examples/xmlrpc_socket_server.c deleted file mode 100644 index 51280d925..000000000 --- a/trunk/examples/xmlrpc_socket_server.c +++ /dev/null @@ -1,113 +0,0 @@ -/* A simple standalone XML-RPC server program written in C as an example of - use of the Xmlrpc-c libraries. - - This example expects an already bound socket on Standard Input, ready to - be listened on for client connections. Also see xmlrpc_sample_add_server, - which is the same thing, except you tell it a TCP port number and it - creates the socket itself. Also see xmlrpc_inetd_server.c, which is - the same thing except you give it a socket which is already connected - to a client. - - Example: - - $ socketexec -local_port=8080 ./xmlrpc_socket_server -*/ - -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/server_abyss.h */ - -#include -#include -#ifdef _WIN32 -# include -#else -# include -#endif - -#include -#include -#include - -#include "config.h" /* information about this build environment */ - -#ifdef _WIN32 - #define SLEEP(seconds) SleepEx(seconds * 1000, 1); -#else - #define SLEEP(seconds) sleep(seconds); -#endif - - -static xmlrpc_value * -sample_add(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const channelInfo) { - - xmlrpc_int32 x, y, z; - - /* Parse our argument array. */ - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - if (envP->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Sometimes, make it look hard (so client can see what it's like - to do an RPC that takes a while). - */ - if (y == 1) - SLEEP(2); - - /* Return our result. */ - return xmlrpc_build_value(envP, "i", z); -} - - - -int -main(int const argc, - const char ** const argv) { - - struct xmlrpc_method_info3 const methodInfo = { - .methodName = "sample.add", - .methodFunction = &sample_add, - .serverInfo = NULL - }; - xmlrpc_server_abyss_parms serverparm; - xmlrpc_registry * registryP; - xmlrpc_env env; - - if (argc-1 != 0) { - fprintf(stderr, "There are no arguments. You must supply a " - "bound socket on which to listen for client connections " - "as Standard Input\n"); - if (argv) {} /* silence unused parameter warning */ - exit(1); - } - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - - xmlrpc_registry_add_method3(&env, registryP, &methodInfo); - - /* In the modern form of the Abyss API, we supply parameters in memory - like a normal API. We select the modern form by setting - config_file_name to NULL: - */ - serverparm.config_file_name = NULL; - serverparm.registryP = registryP; - serverparm.log_file_name = "/tmp/xmlrpc_log"; - serverparm.keepalive_timeout = 0; - serverparm.keepalive_max_conn = 0; - serverparm.timeout = 0; - serverparm.dont_advertise = 0; /* false */ - serverparm.socket_bound = 1; /* true */ - serverparm.socket_handle = STDIN_FILENO; - - printf("Running XML-RPC server...\n"); - - xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(socket_handle)); - - return 0; -} diff --git a/trunk/include/Makefile b/trunk/include/Makefile deleted file mode 100644 index 3b4a37b81..000000000 --- a/trunk/include/Makefile +++ /dev/null @@ -1,178 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - SRCDIR := $(call updir,$(CURDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := include - -include $(BLDDIR)/config.mk - -default: all - -all: xmlrpc-c/config.h - -xmlrpc-c/config.h: $(BLDDIR)/$(SUBDIR)/xmlrpc-c - >$@ - @echo "Lots of echoes to '$@' suppressed here ..." - @echo '#ifndef XMLRPC_C_CONFIG_H_INCLUDED' >>$@ - @echo '#define XMLRPC_C_CONFIG_H_INCLUDED' >>$@ - @echo '' >>$@ - @echo '/* This file, part of XML-RPC For C/C++, is meant to ' >>$@ - @echo ' define characteristics of this particular installation '>>$@ - @echo ' that the other header files need in ' >>$@ - @echo ' order to compile correctly when #included in Xmlrpc-c' >>$@ - @echo ' user code.' >>$@ - @echo '' >>$@ - @echo ' Those header files #include this one.' >>$@ - @echo '' >>$@ - @echo ' This file was created by a make rule.' >>$@ - @echo '*/' >>$@ - @echo '#define XMLRPC_HAVE_WCHAR $(HAVE_WCHAR_H_DEFINE)' >>$@ - @echo '#ifdef _WIN32' >>$@ - @echo ' /* SOCKET is a type defined by . Anyone who' >>$@ - @echo ' uses XMLRPC_SOCKET on a WIN32 system must #include' >>$@ - @echo ' ' >>$@ - @echo ' */' >>$@ - @echo ' #define XMLRPC_SOCKET SOCKET' >>$@ - @echo ' #define XMLRPC_HAVE_TIMEVAL 0' >>$@ - @echo ' #define XMLRPC_HAVE_TIMESPEC 0' >>$@ - @echo ' #define XMLRPC_HAVE_PTHREAD 0' >>$@ - @echo ' #define XMLRPC_HAVE_WINTHREAD 1' >>$@ - @echo '#else' >>$@ - @echo ' #define XMLRPC_SOCKET int' >>$@ - @echo ' #define XMLRPC_HAVE_TIMEVAL 1' >>$@ - @echo ' #define XMLRPC_HAVE_TIMESPEC 1' >>$@ - @echo ' #define XMLRPC_HAVE_PTHREAD 1' >>$@ - @echo ' #define XMLRPC_HAVE_WINTHREAD 0' >>$@ - @echo '#endif' >>$@ - @echo '' >>$@ - @echo '#if defined(_MSC_VER)' >>$@ - @echo ' /* Newer MSVC has long long, but MSVC 6 does not */' >>$@ - @echo ' #define XMLRPC_INT64 __int64' >>$@ - @echo ' #define XMLRPC_PRId64 "I64"' >>$@ - @echo ' #define XMLRPC_INT32 __int32' >>$@ - @echo '#else' >>$@ - @echo ' #define XMLRPC_INT64 long long' >>$@ - @echo ' #define XMLRPC_PRId64 "lld"' >>$@ - @echo ' #define XMLRPC_INT32 int' >>$@ - @echo '#endif' >>$@ - @echo '#endif' >>$@ - -$(BLDDIR)/$(SUBDIR)/xmlrpc-c: - mkdir $@ - -COMPAT_LINK_CMDS = \ - $(LN_S) xmlrpc-c/oldxmlrpc.h xmlrpc.h; \ - $(LN_S) xmlrpc-c/server.h xmlrpc_server.h; \ - $(LN_S) xmlrpc-c/server_abyss.h xmlrpc_abyss.h; \ - $(LN_S) xmlrpc-c/server_w32httpsys.h xmlrpc_server_w32httpsys.h; \ - -HEADERS_TO_INSTALL = \ - xmlrpc-c/config.h \ - xmlrpc-c/inttypes.h \ - xmlrpc-c/c_util.h \ - xmlrpc-c/util.h \ - xmlrpc-c/base.h \ - xmlrpc-c/json.h \ - xmlrpc-c/abyss.h \ - xmlrpc-c/abyss_unixsock.h \ - xmlrpc-c/abyss_winsock.h \ - xmlrpc-c/server.h \ - xmlrpc-c/server_abyss.h \ - xmlrpc-c/server_w32httpsys.h \ - xmlrpc-c/oldxmlrpc.h \ - -ifeq ($(ENABLE_CPLUSPLUS),yes) - HEADERS_TO_INSTALL += \ - xmlrpc-c/oldcppwrapper.hpp \ - xmlrpc-c/girerr.hpp \ - xmlrpc-c/girmem.hpp \ - xmlrpc-c/base.hpp \ - xmlrpc-c/base64.hpp \ - xmlrpc-c/timeout.hpp \ - xmlrpc-c/xml.hpp \ - xmlrpc-c/registry.hpp \ - xmlrpc-c/server_abyss.hpp \ - xmlrpc-c/packetsocket.hpp \ - xmlrpc-c/server_pstream.hpp \ - xmlrpc-c/AbyssEnvironment.hpp \ - xmlrpc-c/AbyssServer.hpp \ - xmlrpc-c/abyss_reqhandler_xmlrpc.hpp \ - xmlrpc-c/AbyssChanSwitch.hpp \ - xmlrpc-c/AbyssChanSwitchUnix.hpp \ - - COMPAT_LINK_CMDS += $(LN_S) xmlrpc-c/oldcppwrapper.hpp XmlRpcCpp.h; -endif - -HEADERINST_PREFIX = /xmlrpc-c - -ifeq ($(MUST_BUILD_CLIENT),yes) - HEADERS_TO_INSTALL += \ - xmlrpc-c/client.h \ - xmlrpc-c/transport.h \ - xmlrpc-c/client_global.h \ - - COMPAT_LINK_CMDS += $(LN_S) xmlrpc-c/client.h xmlrpc_client.h; - - ifeq ($(ENABLE_CPLUSPLUS),yes) - HEADERS_TO_INSTALL += \ - xmlrpc-c/client.hpp \ - xmlrpc-c/client_transport.hpp \ - xmlrpc-c/client_simple.hpp \ - - endif -endif - -ifeq ($(ENABLE_CGI_SERVER),yes) - HEADERS_TO_INSTALL += xmlrpc-c/server_cgi.h - COMPAT_LINK_CMDS += $(LN_S) xmlrpc-c/server_cgi.h xmlrpc_cgi.h; -endif - -ifeq ($(MUST_BUILD_OPENSSL),Y) - HEADERS_TO_INSTALL += xmlrpc-c/openssl_thread.h -endif - -default: all - -all: - -.PHONY: install-compat-hdr -install-compat-hdr: install-headers -# Install old names of header files for backward compatibility - cd $(DESTDIR)$(HEADERINST_DIR); \ - rm -f xmlrpc.h xmlrpc_client.h xmlrpc_server.h xmlrpc_cgi.h \ - xmlrpc_server_abyss.h xmlrpc_abyss.h \ - xmlrpc_server_w32httpsys.h \ - XmlRpcCpp.h; \ - $(COMPAT_LINK_CMDS) - -.PHONY: uninstall-compat-hdr -uninstall-compat-hdr: - cd $(DESTDIR)$(HEADERINST_DIR); \ - rm -f xmlrpc.h xmlrpc_client.h xmlrpc_server.h xmlrpc_cgi.h \ - xmlrpc_server_abyss.h xmlrpc_abyss.h \ - xmlrpc_server_w32httpsys.h \ - XmlRpcCpp.h; \ - -.PHONY: install -install: install-common install-compat-hdr - -.PHONY: uninstall -uninstall: uninstall-common uninstall-compat-hdr - -.PHONY: clean -clean: - rm -f xmlrpc-c/config.h - -.PHONY: distclean -distclean: clean - -.PHONY: check -check: - -.PHONY: dep -dep: - -OMIT_CONFIG_H_RULE = Y - -include $(SRCDIR)/common.mk diff --git a/trunk/include/xmlrpc-c/AbyssChanSwitch.hpp b/trunk/include/xmlrpc-c/AbyssChanSwitch.hpp deleted file mode 100644 index baf047001..000000000 --- a/trunk/include/xmlrpc-c/AbyssChanSwitch.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/*============================================================================ - AbyssChanSwitch.hpp -============================================================================== - - This declares class AbyssChanSwitch, which provides communication facilities - for use with an AbyssServer object. - -============================================================================*/ -#ifndef ABYSS_CHAN_SWITCH_HPP_INCLUDED -#define ABYSS_CHAN_SWITCH_HPP_INCLUDED - -#include - -namespace xmlrpc_c { - -#ifdef XMLRPC_BUILDING_ABYSSPP -#define XMLRPC_ABYSSPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_ABYSSPP_EXPORTED -#endif - -class XMLRPC_ABYSSPP_EXPORTED AbyssChanSwitch { -/*---------------------------------------------------------------------------- - An object of this class is a channel switch for use with an AbyssServer - object, which means it listens for and accepts requests from clients to - open a communication channel to the server (in its most popular form, - it is an interface to a Unix stream socket in listen mode). - - This is an abstract base class. There are derived classes for specific - kinds of underlying communication media, such as Unix sockets. ------------------------------------------------------------------------------*/ -public: - ~AbyssChanSwitch(); - - TChanSwitch * - cChanSwitchP() const; - -protected: - AbyssChanSwitch(); - - TChanSwitch * _cChanSwitchP; - // NULL when derived class constructor has not yet created the - // TChanSwitch object. -}; - -} // namespace -#endif diff --git a/trunk/include/xmlrpc-c/AbyssChanSwitchOpenSsl.hpp b/trunk/include/xmlrpc-c/AbyssChanSwitchOpenSsl.hpp deleted file mode 100644 index 95e3d1c98..000000000 --- a/trunk/include/xmlrpc-c/AbyssChanSwitchOpenSsl.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/*============================================================================ - AbyssChanSwitchOpenSsl.hpp -============================================================================== - - This declares class AbyssChanSwitchOpenSsl, which provides communication - facilities for use with an AbyssServer object that uses Unix sockets. - -============================================================================*/ -#ifndef ABYSS_CHAN_SWITCH_OPEN_SSL_HPP_INCLUDED -#define ABYSS_CHAN_SWITCH_OPEN_SSL_HPP_INCLUDED - -#include -#include - -#include - -namespace xmlrpc_c { - -class AbyssChanSwitchOpenSsl : public AbyssChanSwitch { - -public: - - AbyssChanSwitchOpenSsl( - int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - SSL_CTX * const sslCtxP); - - AbyssChanSwitchOpenSsl( - unsigned short const listenPortNum, - SSL_CTX * const sslCtxP); -}; - -} // namespace -#endif diff --git a/trunk/include/xmlrpc-c/AbyssChanSwitchUnix.hpp b/trunk/include/xmlrpc-c/AbyssChanSwitchUnix.hpp deleted file mode 100644 index 4afd81e1f..000000000 --- a/trunk/include/xmlrpc-c/AbyssChanSwitchUnix.hpp +++ /dev/null @@ -1,23 +0,0 @@ -/*============================================================================ - AbyssChanSwitchUnix.hpp -============================================================================== - - This declares class AbyssChanSwitchUnix, which provides communication - facilities for use with an AbyssServer object that uses Unix sockets. - -============================================================================*/ -#ifndef ABYSS_CHAN_SWITCH_UNIX_HPP_INCLUDED -#define ABYSS_CHAN_SWITCH_UNIX_HPP_INCLUDED - -#include - -namespace xmlrpc_c { - -class AbyssChanSwitchUnix : public AbyssChanSwitch { - -public: - AbyssChanSwitchUnix(unsigned short const listenPortNum); -}; - -} // namespace -#endif diff --git a/trunk/include/xmlrpc-c/AbyssChanSwitchWin.hpp b/trunk/include/xmlrpc-c/AbyssChanSwitchWin.hpp deleted file mode 100644 index e357d84fc..000000000 --- a/trunk/include/xmlrpc-c/AbyssChanSwitchWin.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/*============================================================================ - AbyssChanSwitchWin.hpp -============================================================================== - - This declares class AbyssChanSwitchWin, which provides communication - facilities for use with an AbyssServer object that uses Windows - Winsock2 sockets. - -============================================================================*/ -#ifndef ABYSS_CHAN_SWITCH_WIN_HPP_INCLUDED -#define ABYSS_CHAN_SWITCH_WIN_HPP_INCLUDED - -#include - -namespace xmlrpc_c { - -#ifdef XMLRPC_BUILDING_ABYSSPP -#define XMLRPC_ABYSSPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_ABYSSPP_EXPORTED -#endif - -class XMLRPC_ABYSSPP_EXPORTED AbyssChanSwitchWin : public AbyssChanSwitch { - -public: - AbyssChanSwitchWin(unsigned short const listenPortNum); -}; - -} // namespace -#endif diff --git a/trunk/include/xmlrpc-c/AbyssEnvironment.hpp b/trunk/include/xmlrpc-c/AbyssEnvironment.hpp deleted file mode 100644 index 1e41a8269..000000000 --- a/trunk/include/xmlrpc-c/AbyssEnvironment.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/*============================================================================ - AbyssEnvironment.hpp -============================================================================== - This declares class AbyssEnvironment, which is an essential part of a - program that uses other classes in libxmlrpc_abyss++. -============================================================================*/ -#ifndef ABYSS_ENVIRONMENT_HPP_INCLUDED -#define ABYSS_ENVIRONMENT_HPP_INCLUDED - -namespace xmlrpc_c { - -#ifdef XMLRPC_BUILDING_ABYSSPP -#define XMLRPC_ABYSSPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_ABYSSPP_EXPORTED -#endif - -class XMLRPC_ABYSSPP_EXPORTED AbyssEnvironment { -/*---------------------------------------------------------------------------- - A program that uses libxmlrpc_abyss++ should contain exactly one object - of this class, as a global static object. - - This is necessary because the library depends upon other libraries that - have global variables. ------------------------------------------------------------------------------*/ -public: - AbyssEnvironment(); - - ~AbyssEnvironment(); -}; -} // namespace -#endif diff --git a/trunk/include/xmlrpc-c/AbyssServer.hpp b/trunk/include/xmlrpc-c/AbyssServer.hpp deleted file mode 100644 index 08e9fddf9..000000000 --- a/trunk/include/xmlrpc-c/AbyssServer.hpp +++ /dev/null @@ -1,252 +0,0 @@ -/*============================================================================ - AbyssServer.hpp -============================================================================== - This declares class AbyssServer, which provides facilities for running an - Abyss server, which is a simple HTTP server -============================================================================*/ -#ifndef ABYSS_SERVER_HPP_INCLUDED -#define ABYSS_SERVER_HPP_INCLUDED - -#include - -#include -#include -#include -#if defined(__GNUC__) && __GNUC__ < 3 -#include -#else -#include -#endif -#include -#include - -namespace xmlrpc_c { - -#ifdef XMLRPC_BUILDING_ABYSSPP -#define XMLRPC_ABYSSPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_ABYSSPP_EXPORTED -#endif - -class XMLRPC_ABYSSPP_EXPORTED AbyssServer { -/*---------------------------------------------------------------------------- - An object of this class represents an Abyss HTTP server. - - The class does not provide any specific HTTP service, such as web service - from files or XML-RPC. Rather, it provides a basic framework that handles - the details of the HTTP protocol and the user provides request handlers - that do the real work. For example, the user can provide an XML-RPC - request handler and then the server is an XML-RPC server. ------------------------------------------------------------------------------*/ -public: - - class XMLRPC_ABYSSPP_EXPORTED Exception : public std::runtime_error { - public: - Exception(unsigned short const httpStatusCode, - std::string const& explanation); - - unsigned short - httpStatusCode() const; - - private: - unsigned short _httpStatusCode; - }; - - class XMLRPC_ABYSSPP_EXPORTED Session { - public: - class Impl; - - Session(TSession * const cSessionP); - - ~Session(); - - enum Method { - METHOD_UNKNOWN, - METHOD_GET, - METHOD_PUT, - METHOD_HEAD, - METHOD_POST, - METHOD_DELETE, - METHOD_TRACE, - METHOD_OPTIONS - }; - - Method - method() const; - - std::string const - requestLine() const; - - std::string const - uriPathName() const; - - std::vector const - uriPathNameSegment() const; - - bool - uriHasQuery() const; - - std::string const - uriQuery() const; - - std::map const - formInput() const; - - bool - hasHost() const; - - std::string const - host() const; - - bool - hasFrom() const; - - std::string const - from() const; - - bool - hasUseragent() const; - - std::string const - useragent() const; - - bool - hasReferer() const; - - std::string const - referer() const; - - bool - userIsAuthenticated() const; - - std::string const - user() const; - - unsigned short - port() const; - - bool - keepalive() const; - - bool - hasContentLength() const; - - size_t - contentLength() const; - - std::string const - body(); - - void - readRequestBody(unsigned char * const buffer, - size_t const size); - - void - readSomeRequestBody(size_t const max, - unsigned char * const buffer, - bool * const eofP, - size_t * const byteCtP); - - void - getHeaderField(std::string const& fieldName, - bool * const isPresentP, - std::string * const valueP) const; - - std::string const - headerFieldValue(std::string const& fieldName) const; - - void - setRespStatus(unsigned short const statusCode); - - void - setRespContentType(std::string const& contentType); - - void - setRespContentLength(uint64_t const contentLength); - - void - startWriteResponse(); - - void - endWriteResponse(); - - void - writeResponseBody(const unsigned char * const data, - size_t const size); - - void - writeResponse(std::string const& body); - - void - sendErrorResponse(std::string const& explanation); - - void - sendErrorResponse(Exception const& e); - - private: - - Impl * const implP; - }; - - class XMLRPC_ABYSSPP_EXPORTED ReqHandler { - /*------------------------------------------------------------------------ - An object of this class handles HTTP requests, which essentially means - it provides responses to them. An AbyssServer object calls methods of - objects of this class to execute HTTP requests. - - The object also decides and reports whether a particular request is - appropriate for this object to handle. An AbyssServer object may have - multiple ReqHandler objects on which it can call, each specializing in - different kinds of requests. - - This is an abstract base class. A derived class knows how to handle, - for example, HTTP requests that are XML-RPC RPCs. - -------------------------------------------------------------------------*/ - public: - virtual - ~ReqHandler(); - - virtual void - handleRequest(Session * const sessionP, - bool * const handledP) = 0; - - virtual size_t - handleReqStackSize() const; - - virtual void - terminate(); - }; - - AbyssServer(AbyssChanSwitch * const chanSwitchP); - - ~AbyssServer(); - - void - addRequestHandler(ReqHandler * const handlerP); - - void - init(); - - void - run(); - - void - runOnce(); - - void - terminate(); - - void - resetTerminate(); - -private: - TServer cServer; -}; - -} // namespace - -XMLRPC_ABYSSPP_EXPORTED -std::ostream& operator<<(std::ostream & out, - xmlrpc_c::AbyssServer::Session::Method const& method); - -#endif diff --git a/trunk/include/xmlrpc-c/Lock.hpp b/trunk/include/xmlrpc-c/Lock.hpp deleted file mode 100644 index 4a1f9509b..000000000 --- a/trunk/include/xmlrpc-c/Lock.hpp +++ /dev/null @@ -1,32 +0,0 @@ -struct lock; - -namespace xmlrpc_c { - -class Lock { -public: - class Holder { - public: - Holder(Lock * const lockP); - - ~Holder(); - - private: - Lock * const lockP; - }; - - Lock(); - - ~Lock(); - - void - acquire(); - - void - release(); - -private: - - struct lock * const c_lockP; -}; - -} // namespace diff --git a/trunk/include/xmlrpc-c/abyss.h b/trunk/include/xmlrpc-c/abyss.h deleted file mode 100644 index 0011c5c6f..000000000 --- a/trunk/include/xmlrpc-c/abyss.h +++ /dev/null @@ -1,696 +0,0 @@ -/***************************************************************************** - 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. - - Nothing may include this header file that also includes , - because it conflicts with this file's use of . Furthermore, - nothing including this file may include without previously - defining WIN32_LEAN_AND_MEAN, because without that macro - includes automatically. (see abyss_winsock.h). - - Copyright information is at the end of the file. -****************************************************************************/ - -#ifndef XMLRPC_ABYSS_H_INCLUDED -#define XMLRPC_ABYSS_H_INCLUDED - - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include /* For XMLRPC_DLLEXPORT */ -#include - -/* - XMLRPC_ABYSS_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_abyss. - - XMLRPC_BUILDING_ABYSS says this compilation is part of libxmlrpc_abyss, as - opposed to something that _uses_ libxmlrpc_abyss. -*/ -#ifdef XMLRPC_BUILDING_ABYSS -#define XMLRPC_ABYSS_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_ABYSS_EXPORTED -#endif - -/**************************************************************************** - STUFF FOR THE OUTER CONTROL PROGRAM TO USE -****************************************************************************/ - -typedef int abyss_bool; - -/**************************************************************************** - GLOBAL (STATIC) PROGRAM STUFF -****************************************************************************/ - -XMLRPC_ABYSS_EXPORTED -void -AbyssInit(const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -void -AbyssTerm(void); - -/********************************************************************* -** MIMEType -*********************************************************************/ - -typedef struct MIMEType MIMEType; - -XMLRPC_ABYSS_EXPORTED -MIMEType * -MIMETypeCreate(void); - -XMLRPC_ABYSS_EXPORTED -void -MIMETypeDestroy(MIMEType * const MIMETypeP); - -XMLRPC_ABYSS_EXPORTED -void -MIMETypeInit(void); - -XMLRPC_ABYSS_EXPORTED -void -MIMETypeTerm(void); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -MIMETypeAdd2(MIMEType * const MIMETypeP, - const char * const type, - const char * const ext); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -MIMETypeAdd(const char * const type, - const char * const ext); - - -enum abyss_foreback {ABYSS_FOREGROUND, ABYSS_BACKGROUND}; - -#define HAVE_CHANSWITCH - -typedef struct _TChanSwitch TChanSwitch; -typedef struct _TChannel TChannel; -typedef struct _TSocket TSocket; - -#ifdef _WIN32 - #include -#else - #include -#endif - -XMLRPC_ABYSS_EXPORTED -void -ChanSwitchInit(const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -void -ChanSwitchTerm(void); - -/* If you're wondering where the constructors for TChanSwitch, - TChannel, and TSocket are: They're implementation-specific, so look - in abyss_unixsock.h, etc. -*/ - -XMLRPC_ABYSS_EXPORTED -void -ChanSwitchDestroy(TChanSwitch * const chanSwitchP); - -XMLRPC_ABYSS_EXPORTED -void -ChannelInit(const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -void -ChannelTerm(void); - -XMLRPC_ABYSS_EXPORTED -void -ChannelDestroy(TChannel * const channelP); - -XMLRPC_ABYSS_EXPORTED -void -SocketDestroy(TSocket * const socketP); - - -typedef struct { - /* Before Xmlrpc-c 1.04, the internal server representation, - struct _TServer, was exposed to users and was the only way to - set certain parameters of the server. Now, use the (new) - ServerSet...() functions. Use the HAVE_ macros to determine - which method you have to use. - */ - struct _TServer * srvP; -} TServer; - -typedef struct _TSession TSession; - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ServerCreate(TServer * const serverP, - const char * const name, - xmlrpc_uint16_t const port, - const char * const filespath, - const char * const logfilename); - -XMLRPC_ABYSS_EXPORTED -void -ServerCreateSwitch(TServer * const serverP, - TChanSwitch * const chanSwitchP, - const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ServerCreateSocket(TServer * const serverP, - const char * const name, - TOsSocket const socketFd, - const char * const filespath, - const char * const logfilename); - -#define HAVE_SERVER_CREATE_SOCKET_2 -XMLRPC_ABYSS_EXPORTED -void -ServerCreateSocket2(TServer * const serverP, - TSocket * const socketP, - const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ServerCreateNoAccept(TServer * const serverP, - const char * const name, - const char * const filespath, - const char * const logfilename); - -XMLRPC_ABYSS_EXPORTED -void -ServerFree(TServer * const serverP); - -XMLRPC_ABYSS_EXPORTED -void -ServerSetName(TServer * const serverP, - const char * const name); - -XMLRPC_ABYSS_EXPORTED -void -ServerSetFilesPath(TServer * const serverP, - const char * const filesPath); - -XMLRPC_ABYSS_EXPORTED -void -ServerSetLogFileName(TServer * const serverP, - const char * const logFileName); - -#define HAVE_SERVER_SET_KEEPALIVE_TIMEOUT 1 -XMLRPC_ABYSS_EXPORTED -void -ServerSetKeepaliveTimeout(TServer * const serverP, - xmlrpc_uint32_t const keepaliveTimeout); - -#define HAVE_SERVER_SET_KEEPALIVE_MAX_CONN 1 -XMLRPC_ABYSS_EXPORTED -void -ServerSetKeepaliveMaxConn(TServer * const serverP, - xmlrpc_uint32_t const keepaliveMaxConn); - -#define HAVE_SERVER_SET_TIMEOUT 1 -XMLRPC_ABYSS_EXPORTED -void -ServerSetTimeout(TServer * const serverP, - xmlrpc_uint32_t const timeout); - -#define HAVE_SERVER_SET_ADVERTISE 1 -XMLRPC_ABYSS_EXPORTED -void -ServerSetAdvertise(TServer * const serverP, - abyss_bool const advertise); - -#define HAVE_SERVER_SET_MIME_TYPE 1 -XMLRPC_ABYSS_EXPORTED -void -ServerSetMimeType(TServer * const serverP, - MIMEType * const MIMETypeP); - -#define HAVE_SERVER_SET_MAX_CONN 1 -XMLRPC_ABYSS_EXPORTED -void -ServerSetMaxConn(TServer * const serverP, - unsigned int const maxConn); - -#define HAVE_SERVER_SET_MAX_CONN_BACKLOG 1 -XMLRPC_ABYSS_EXPORTED -void -ServerSetMaxConnBacklog(TServer * const serverP, - unsigned int const maxConnBacklog); - -#define HAVE_SERVER_SET_MAX_SESSION_MEM 1 -XMLRPC_ABYSS_EXPORTED -void -ServerSetMaxSessionMem(TServer * const serverP, - size_t const size); - -XMLRPC_ABYSS_EXPORTED -void -ServerInit2(TServer * const serverP, - const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -void -ServerInit(TServer * const serverP); - -XMLRPC_ABYSS_EXPORTED -void -ServerRun(TServer * const serverP); - -XMLRPC_ABYSS_EXPORTED -void -ServerRunOnce(TServer * const serverP); - -/* ServerRunOnce2() is obsolete. See user's guide. */ -XMLRPC_ABYSS_EXPORTED -void -ServerRunOnce2(TServer * const serverP, - enum abyss_foreback const foregroundBackground); - -XMLRPC_ABYSS_EXPORTED -void -ServerRunChannel(TServer * const serverP, - TChannel * const channelP, - void * const channelInfoP, - const char ** const errorP); - -#define HAVE_SERVER_RUN_CONN_2 -XMLRPC_ABYSS_EXPORTED -void -ServerRunConn2(TServer * const serverP, - TSocket * const connectedSocketP, - const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -void -ServerRunConn(TServer * const serverP, - TOsSocket const connectedSocket); - -XMLRPC_ABYSS_EXPORTED -void -ServerDaemonize(TServer * const serverP); - -XMLRPC_ABYSS_EXPORTED -void -ServerTerminate(TServer * const serverP); - -XMLRPC_ABYSS_EXPORTED -void -ServerResetTerminate(TServer * const serverP); - -XMLRPC_ABYSS_EXPORTED -void -ServerUseSigchld(TServer * const serverP); - -#ifndef _WIN32 -void -ServerHandleSigchld(pid_t const pid); -#endif - -typedef abyss_bool (*URIHandler) (TSession *); /* deprecated */ - -struct URIHandler2; - -typedef void (*initHandlerFn)(struct URIHandler2 *, abyss_bool *); - -typedef void (*termHandlerFn)(void *); - -typedef void (*handleReq3Fn)(void *, - TSession *, - abyss_bool *); - -typedef void (*handleReq2Fn)(struct URIHandler2 *, - TSession *, - abyss_bool *); - -struct ServerReqHandler3 { - termHandlerFn term; - handleReq3Fn handleReq; - void * userdata; - size_t handleReqStackSize; /* zero = default */ -}; - -XMLRPC_ABYSS_EXPORTED -void -ServerAddHandler3(TServer * const serverP, - const struct ServerReqHandler3 * const handlerP, - abyss_bool * const successP); - -typedef struct URIHandler2 { - initHandlerFn init; - termHandlerFn term; - handleReq2Fn handleReq2; - URIHandler handleReq1; /* deprecated */ - void * userdata; -} URIHandler2; - -XMLRPC_ABYSS_EXPORTED -void -ServerAddHandler2(TServer * const srvP, - URIHandler2 * const handlerP, - abyss_bool * const successP); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ServerAddHandler(TServer * const srvP, - URIHandler const handler); - -typedef abyss_bool (*THandlerDflt) (TSession *); - -/* Note: 'handler' used to be URIHandler; THandlerDflt is a newer name - for the same type -*/ - -XMLRPC_ABYSS_EXPORTED -void -ServerDefaultHandler(TServer * const srvP, - THandlerDflt const handler); - -/* ConfReadServerFile() is inappropriately named; it was a mistake. - But then, so is having this function at all. The config file is - inappropriate for an API. -*/ - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ConfReadServerFile(const char * const filename, - TServer * const srvP); - -XMLRPC_ABYSS_EXPORTED -void -LogWrite(TServer * const srvP, - const char * const c); - -/**************************************************************************** - STUFF FOR HTTP REQUEST HANDLERS TO USE -****************************************************************************/ - -typedef enum { - m_unknown, m_get, m_put, m_head, m_post, m_delete, m_trace, m_options -} TMethod; - -typedef struct { - /* Note that some common or important information from the HTTP request - header is in the members of this structure, but all header information - is available via the RequestHeaderValue method of Tsession. - */ - TMethod method; - const char * uri; - /* This is NOT the URI. It is the pathname part of the URI. - We really should fix that and put the pathname in another - member. If the URI does not contain a pathname, this is "*". - */ - const char * query; - /* The query part of the URI (stuff after '?'). NULL if none. */ - const char * host; - /* NOT the value of the host: header field. Rather, the name of the - target host (could be part of the host: value; could be from the - URI). No port number. NULL if request does not specify a host - name. - */ - const char * from; - const char * useragent; - const char * referer; - const char * requestline; - const char * user; - /* Requesting user (from authorization: header field). NULL if - request doesn't specify or handler has not authenticated it. - */ - xmlrpc_uint16_t port; - /* The port number from the URI, or default 80 if the URI doesn't - specify a port. - */ - abyss_bool keepalive; -} TRequestInfo; - -XMLRPC_ABYSS_EXPORTED -void -SessionGetBody(TSession * const sessionP, - size_t const max, - abyss_bool * const eofP, - const char ** const outStartP, - size_t * const outLenP, - const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -SessionRefillBuffer(TSession * const sessionP); - -XMLRPC_ABYSS_EXPORTED -size_t -SessionReadDataAvail(TSession * const sessionP); - -XMLRPC_ABYSS_EXPORTED -void -SessionGetReadData(TSession * const sessionP, - size_t const max, - const char ** const outStartP, - size_t * const outLenP); - -XMLRPC_ABYSS_EXPORTED -void -SessionGetRequestInfo(TSession * const sessionP, - const TRequestInfo ** const requestInfoPP); - -XMLRPC_ABYSS_EXPORTED -void -SessionGetChannelInfo(TSession * const sessionP, - void ** const channelInfoPP); - -XMLRPC_ABYSS_EXPORTED -void * -SessionGetDefaultHandlerCtx(TSession * const sessionP); - -XMLRPC_ABYSS_EXPORTED -const char * -RequestHeaderValue(TSession * const sessionP, - const char * const name); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -RequestAuth(TSession * const sessionP, - const char * const credential, - const char * const user, - const char * const pass); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ResponseAddField(TSession * const sessionP, - const char * const name, - const char * const value); - -XMLRPC_ABYSS_EXPORTED -void -ResponseWriteStart(TSession * const sessionP); - -/* For backward compatibility: */ -#define ResponseWrite ResponseWriteStart - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ResponseWriteBody(TSession * const sessionP, - const char * const data, - xmlrpc_uint32_t const len); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ResponseWriteEnd(TSession * const sessionP); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ResponseChunked(TSession * const sessionP); - -XMLRPC_ABYSS_EXPORTED -xmlrpc_uint16_t -ResponseStatusFromErrno(int const errnoArg); - -XMLRPC_ABYSS_EXPORTED -void -ResponseStatus(TSession * const sessionP, - xmlrpc_uint16_t const code); - -XMLRPC_ABYSS_EXPORTED -void -ResponseStatusErrno(TSession * const sessionP); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ResponseContentType(TSession * const serverP, - const char * const type); - -XMLRPC_ABYSS_EXPORTED -abyss_bool -ResponseContentLength(TSession * const sessionP, - xmlrpc_uint64_t const len); - -typedef struct { -/*---------------------------------------------------------------------------- - These are parameters to control the HTTP "Access Control" functions. That's - where the client asks whether it is OK to send a request that some other - server asked the client to send (e.g. a person web browses a page at - a.example.com, and it sends a script that executes on the user's computer - and tries to perform an XML-RPC RPC on b.example.com. The user's browser - first asks b.example.com if it is OK to do an RPC that is really initiated - by a.example.com. - - These parameters tell the server how to respond to such a request. ------------------------------------------------------------------------------*/ - const char * allowOrigin; - /* This tells what original servers (a.example.com in the example - above) are allowed to submit RPCs indirectly to us. The value is a - verbatim value for an HTTP Access-Control-Allow-Origin header field - (just the value part of the field, not the whole field). "*" - therefore means everyone is allowed. "" means no one. - - NULL means not to say anything about access control to the client. - */ - abyss_bool expires; - /* The permissions herein expire after a certain period from now. - 'maxAge' is that period. - */ - unsigned int maxAge; - /* Meaningful only when 'expires' is true. The expiration period - in seconds. Zero is valid. - */ -} ResponseAccessCtl; - -XMLRPC_ABYSS_EXPORTED -void -ResponseAccessControl(TSession * const abyssSessionP, - ResponseAccessCtl const accessControl); - -XMLRPC_ABYSS_EXPORTED -void -ResponseError2(TSession * const sessionP, - const char * const explanation); - -XMLRPC_ABYSS_EXPORTED -void -ResponseError(TSession * const sessionP); - -XMLRPC_ABYSS_EXPORTED -const char * -MIMETypeFromExt(const char * const ext); - -XMLRPC_ABYSS_EXPORTED -const char * -MIMETypeFromExt2(MIMEType * const MIMETypeP, - const char * const ext); - -XMLRPC_ABYSS_EXPORTED -const char * -MIMETypeFromFileName2(MIMEType * const MIMETypeP, - const char * const fileName); - -XMLRPC_ABYSS_EXPORTED -const char * -MIMETypeFromFileName(const char * const fileName); - -XMLRPC_ABYSS_EXPORTED -const char * -MIMETypeGuessFromFile2(MIMEType * const MIMETypeP, - const char * const fileName); - -XMLRPC_ABYSS_EXPORTED -const char * -MIMETypeGuessFromFile(const char * const filename); - - -/**************************************************************************** - STUFF THAT PROBABLY DOESN'T BELONG IN THIS FILE BECAUSE IT IS INTERNAL - - Some day, we sort this out. -****************************************************************************/ - - -/********************************************************************* -** Paths and so on... -*********************************************************************/ - -#ifdef _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 - -/********************************************************************* -** Range -*********************************************************************/ - -XMLRPC_ABYSS_EXPORTED -abyss_bool -RangeDecode(char * const str, - xmlrpc_uint64_t const filesize, - xmlrpc_uint64_t * const start, - xmlrpc_uint64_t * const end); - -XMLRPC_ABYSS_EXPORTED -abyss_bool DateInit(void); - -/********************************************************************* -** Session -*********************************************************************/ - -XMLRPC_ABYSS_EXPORTED -abyss_bool SessionLog(TSession * const 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 . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ -#endif diff --git a/trunk/include/xmlrpc-c/abyss_openssl.h b/trunk/include/xmlrpc-c/abyss_openssl.h deleted file mode 100644 index cb4bc12d2..000000000 --- a/trunk/include/xmlrpc-c/abyss_openssl.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef ABYSS_OPENSSL_H_INCLUDED -#define ABYSS_OPENSSL_H_INCLUDED -/*============================================================================= - abyss_openssl.h -=============================================================================== - Declarations to be used with an Abyss server that can server HTTPS URLs - via OpenSSL. - - Note that there is no equivalent of this file for the original two Abyss - channel types, "Unix" and "Windows". Those are built into - , for historical reasons. -=============================================================================*/ -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -struct abyss_openSsl_chaninfo { - size_t peerAddrLen; - /* Length of 'peerAddr' (which is effectively polymorphic, so could - have any of various lengths depending upon the type of socket - address - */ - struct sockaddr peerAddr; - - SSL * sslP; - /* The handle of the OpenSSL connection object underlying this channel. - - You can use this to get all sort of neat information about the - connection, such as the verified certification the client - presented, using the OpenSSL library. (For example, to find out - the authenticated name of the client, use - SSL_get_peer_certificate(), and use X509_get_subject name() with - the result of that). - - This is kind of a modularity violation, which we don't mind because - it is so easy and flexible. But note that it is the Abyss design - intent that you use the SSL object _only_ to get information about - the channel. - */ -}; - -void -ChanSwitchOpenSslCreate(int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChanSwitchOpenSslCreateIpV4Port(unsigned short const portNumber, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChanSwitchOpenSslCreateIpV6Port(unsigned short const portNumber, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChanSwitchOpenSslCreateFd(int const fd, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChannelOpenSslCreateSsl(SSL * const sslP, - TChannel ** const channelPP, - struct abyss_openSsl_chaninfo ** const channelInfoPP, - const char ** const errorP); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/abyss_reqhandler_xmlrpc.hpp b/trunk/include/xmlrpc-c/abyss_reqhandler_xmlrpc.hpp deleted file mode 100644 index 84216075d..000000000 --- a/trunk/include/xmlrpc-c/abyss_reqhandler_xmlrpc.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef ABYSS_REQHANDLER_XMLRPC_HPP_INCLUDED -#define ABYSS_REQHANDLER_XMLRPC_HPP_INCLUDED - -#include -#include -#include - -namespace xmlrpc_c { - -class abyssReqhandlerXmlrpc : public xmlrpc_c::AbyssServer::ReqHandler { -/*----------------------------------------------------------------------------- - An object of this class is an Abyss request handler that you can - use with an Abyss HTTP server object to make it an XML-RPC server. - - One way to use this is to make a derived class that represents a handler - for a certain set of XML-RPC methods. The derived class' constructor - creates an appropriate registry to pass to this base class' constructor. - - The derived class can also have a 'handleUnreportableFailure' method to - deal with RPC failures that the server is unable to report as RPC - responses. - - Note: class abyssServer does not use this class; it uses a C Abyss server - instead. ------------------------------------------------------------------------------*/ -public: - abyssReqhandlerXmlrpc(xmlrpc_c::registryPtr const& registryP); - - void - handleRequest(xmlrpc_c::AbyssServer::Session * const sessionP, - bool * const handledP); - -private: - xmlrpc_c::registryPtr const registryP; - - void - abortRequest(AbyssServer::Session * const sessionP, - bool const responseStarted, - AbyssServer::Exception const& e); - - virtual void - handleUnreportableFailure(AbyssServer::Exception const& e); - // This method does whatever is appropriate when an RPC fails and the - // server is unable to tell the caller. Logging is typically all one - // can do. The default method, in the base class, does nothing. -}; - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/abyss_unixsock.h b/trunk/include/xmlrpc-c/abyss_unixsock.h deleted file mode 100644 index 5ffe924b6..000000000 --- a/trunk/include/xmlrpc-c/abyss_unixsock.h +++ /dev/null @@ -1,61 +0,0 @@ -/* This is just a sub-file for abyss.h */ - -#include -#include - -struct abyss_unix_chaninfo { - size_t peerAddrLen; - struct sockaddr peerAddr; -}; - -void -ChanSwitchUnixCreate(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChanSwitchUnixCreate2(int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChanSwitchUnixCreateIpV6Port(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChanSwitchUnixCreateFd(int const fd, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -void -ChanSwitchUnixGetListenName(TChanSwitch * const chanSwitchP, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP); - -void -ChannelUnixCreateFd(int const fd, - TChannel ** const channelPP, - struct abyss_unix_chaninfo ** const channelInfoPP, - const char ** const errorP); - -void -ChannelUnixGetPeerName(TChannel * const channelP, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP); - -void -SocketUnixCreateFd(int const fd, - TSocket ** const socketPP); - -typedef int TOsSocket; - /* TOsSocket is the type of a conventional socket offered by our OS. - This is for backward compatibility; everyone should use TChanSwitch - and TChannel instead today. - */ - - diff --git a/trunk/include/xmlrpc-c/abyss_winsock.h b/trunk/include/xmlrpc-c/abyss_winsock.h deleted file mode 100644 index 6c069d8ac..000000000 --- a/trunk/include/xmlrpc-c/abyss_winsock.h +++ /dev/null @@ -1,48 +0,0 @@ -/* This is just a sub-file for abyss.h */ - -/* See restrictions on including and at the top - of abyss.h. -*/ -#include -#include - -struct abyss_win_chaninfo { - size_t peerAddrLen; - struct sockaddr peerAddr; -}; - -XMLRPC_ABYSS_EXPORTED -void -ChanSwitchWinCreate2(int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -void -ChanSwitchWinCreate(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -void -ChanSwitchWinCreateWinsock(SOCKET const winsock, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -void -ChannelWinCreateWinsock(SOCKET const fd, - TChannel ** const channelPP, - struct abyss_win_chaninfo ** const channelInfoPP, - const char ** const errorP); - -XMLRPC_ABYSS_EXPORTED -void -ChanSwitchWinGetListenName(TChanSwitch * const chanSwitchP, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP); - -typedef SOCKET TOsSocket; diff --git a/trunk/include/xmlrpc-c/base.h b/trunk/include/xmlrpc-c/base.h deleted file mode 100644 index e74e2c51c..000000000 --- a/trunk/include/xmlrpc-c/base.h +++ /dev/null @@ -1,955 +0,0 @@ -/* Copyright and license information is at the end of the file */ - -#ifndef XMLRPC_H_INCLUDED -#define XMLRPC_H_INCLUDED - -#include -#include -#include -#include /* For XMLRPC_DLLEXPORT */ -#include -#include - /* Defines XMLRPC_HAVE_WCHAR, XMLRPC_INT64, XMLRPC_HAVE_TIMEVAL */ - -#if XMLRPC_HAVE_WCHAR -#include -#endif - -#if XMLRPC_HAVE_TIMEVAL -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - XMLRPC_LIB_EXPORTED marks a symbol in this file that is exported from - libxmlrpc. - - XMLRPC_BUILDING_LIB says this compilation is part of libxmlrpc, as - opposed to something that _uses_ libxmlrpc. -*/ -#ifdef XMLRPC_BUILDING_LIB -#define XMLRPC_LIB_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_LIB_EXPORTED -#endif - -/*========================================================================= -** Global static library initialization -**=======================================================================*/ - -void -xmlrpc_init(xmlrpc_env * const envP); - -void -xmlrpc_term(void); - -/*========================================================================= -** Version of libxmlrpc -**=======================================================================*/ - -/* These are for backward compatibility -- they can't be exported from a - Windows DLL. xmlrpc_server_version() is preferred. -*/ -extern unsigned int const xmlrpc_version_major; -extern unsigned int const xmlrpc_version_minor; -extern unsigned int const xmlrpc_version_point; - -XMLRPC_LIB_EXPORTED -void -xmlrpc_version(unsigned int * const majorP, - unsigned int * const minorP, - unsigned int * const pointP); - -/*========================================================================= -** C types equivalent to XML-RPC types -**=======================================================================*/ - -/* We define names for these types, because they may change from platform - to platform. -*/ - -typedef signed int xmlrpc_int; - /* An integer of the type defined by XML-RPC ; i.e. 32 bit */ -typedef XMLRPC_INT32 xmlrpc_int32; - /* An integer of the type defined by XML-RPC ; i.e. 32 bit */ -typedef XMLRPC_INT64 xmlrpc_int64; - /* An integer of the type defined by "XML-RPC" ; i.e. 64 bit */ -typedef int xmlrpc_bool; - /* A boolean (of the type defined by XML-RPC , but there's - really only one kind) - */ -typedef double xmlrpc_double; - /* A double precision floating point number as defined by - XML-RPC . But the C "double" type is universally the same, - so it's probably clearer just to use that. This typedef is here - for mathematical completeness. - */ -typedef struct { - /* A datetime of the type defined by XML-RPC with - a few extensions. I.e. in the range 1-9999 AD with microsecond - resolution. - */ - unsigned int Y; /* 1-? */ - unsigned int M; /* 1-12 */ - unsigned int D; /* 1-31 */ - unsigned int h; /* 0-23 */ - unsigned int m; /* 0-59 */ - unsigned int s; /* 0-59 */ - unsigned int u; /* 0-999999 */ -} xmlrpc_datetime; - -/* xmlrpc_socket is just for backward compatibility, in case someone decided - to use this in user code. New code should use the native type for a - socket (e.g. int or SOCKET). (We stopped using this because for winsock - users, we would have to #include in every file that - #includes and we don't want that). -*/ -typedef int xmlrpc_socket; - -#define XMLRPC_INT32_MAX 0x7fffffff -#define XMLRPC_INT32_MIN (-XMLRPC_INT32_MAX - 1) - -#define XMLRPC_INT64_MAX 0x7fffffffffffffffll -#define XMLRPC_INT64_MIN (-XMLRPC_INT64_MAX - 1) - - -/*========================================================================= -** 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_I8 = 10, - XMLRPC_TYPE_DEAD = 0xDEAD -} xmlrpc_type; - -#define XMLRPC_HAVE_I8 1 - -typedef struct _xmlrpc_value xmlrpc_value; - -XMLRPC_LIB_EXPORTED -const char * -xmlrpc_type_name(xmlrpc_type const type); - -XMLRPC_LIB_EXPORTED -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. */ -XMLRPC_LIB_EXPORTED -extern void xmlrpc_INCREF(xmlrpc_value* const value); - -/* Decrement the reference count of an xmlrpc_value. If there -** are no more references, free it. */ -XMLRPC_LIB_EXPORTED -extern void xmlrpc_DECREF(xmlrpc_value* const value); - -/* Get the type of an XML-RPC value. */ -XMLRPC_LIB_EXPORTED -extern xmlrpc_type xmlrpc_value_type (xmlrpc_value* const value); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_value_new(xmlrpc_env * const envP, - xmlrpc_value * const sourceValP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_int_new(xmlrpc_env * const envP, - int const intValue); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_int_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_int(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - int * const intValueP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_i8_new(xmlrpc_env * const envP, - xmlrpc_int64 const value); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_i8_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_i8(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_int64 * const intValueP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_bool_new(xmlrpc_env * const envP, - xmlrpc_bool const boolValue); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_bool_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_bool(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_bool * const boolValueP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_double_new(xmlrpc_env * const envP, - double const doubleValue); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_double_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_double(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_double * const doubleValueP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_datetime_new(xmlrpc_env * const envP, - xmlrpc_datetime const dt); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_datetime_new_str(xmlrpc_env * const envP, - const char * const value); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_datetime_new_sec(xmlrpc_env * const envP, - time_t const value); - -XMLRPC_LIB_EXPORTED -xmlrpc_value* -xmlrpc_datetime_new_usec(xmlrpc_env * const envP, - time_t const secs, - unsigned int const usecs); - -#if XMLRPC_HAVE_TIMEVAL -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_datetime_new_timeval(xmlrpc_env * const envP, - struct timeval const value); -#endif - -#if XMLRPC_HAVE_TIMESPEC -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_datetime_new_timespec(xmlrpc_env * const envP, - struct timespec const value); -#endif - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_datetime_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -void -XMLRPC_LIB_EXPORTED -xmlrpc_read_datetime(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_datetime * const dtP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_datetime_sec(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - time_t * const timeValueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_datetime_usec(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - time_t * const secsP, - unsigned int * const usecsP); - -#if XMLRPC_HAVE_TIMEVAL -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_datetime_timeval(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - struct timeval * const timeValueP); -#endif - -#if XMLRPC_HAVE_TIMESPEC -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_datetime_timespec(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - struct timespec * const timeValueP); -#endif - -void -XMLRPC_LIB_EXPORTED -xmlrpc_read_datetime_8601(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const iso8601ValueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_datetime_str(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_new(xmlrpc_env * const envP, - const char * const stringValue); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_new_lp(xmlrpc_env * const envP, - size_t const length, - const char * const stringValue); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_new_va(xmlrpc_env * const envP, - const char * const format, - va_list args); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_new_f(xmlrpc_env * const envP, - const char * const format, - ...); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_new_lp_cr(xmlrpc_env * const envP, - size_t const length, - const char * const value); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_new_cr(xmlrpc_env * const envP, - const char * const value); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_string_validate(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_string(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP); - - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_string_crlf(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_string_lp_crlf(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const char ** const stringValueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_string_lp(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const char ** const stringValueP); - -#if XMLRPC_HAVE_WCHAR -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_w_new(xmlrpc_env * const envP, - const wchar_t * const stringValue); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_w_new_lp(xmlrpc_env * const envP, - size_t const length, - const wchar_t * const stringValue); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_string_w(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const wchar_t ** const stringValueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_string_w_crlf(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const wchar_t ** const stringValueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_string_w_lp(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - size_t * const lengthP, - const wchar_t ** const stringValueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_string_w_lp_crlf(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - size_t * const lengthP, - const wchar_t ** const stringValueP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_w_new_lp_cr(xmlrpc_env * const envP, - size_t const length, - const wchar_t * const value); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_w_new_cr(xmlrpc_env * const envP, - const wchar_t * const value); - -#endif /* XMLRPC_HAVE_WCHAR */ - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_string_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_base64_new(xmlrpc_env * const envP, - size_t const length, - const unsigned char * const value); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_base64_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_base64(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const unsigned char ** const bytestringValueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_base64_size(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_array_new(xmlrpc_env * const envP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_array_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -int -xmlrpc_array_size(xmlrpc_env * const env, - const xmlrpc_value * const array); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_array_append_item(xmlrpc_env * const envP, - xmlrpc_value * const arrayP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -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_LIB_EXPORTED -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. -XMLRPC_LIB_EXPORTED -int -xmlrpc_array_set_item(xmlrpc_env * const envP, - xmlrpc_value * const arrayP, - unsigned int const index, - xmlrpc_value * const valueP); -*/ - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_struct_new(xmlrpc_env * const env); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_struct_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -int -xmlrpc_struct_size (xmlrpc_env * const env, - xmlrpc_value * const strct); - -/* Returns true iff 'strct' contains 'key'. -** Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct. */ -XMLRPC_LIB_EXPORTED -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. -*/ -XMLRPC_LIB_EXPORTED -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. */ -XMLRPC_LIB_EXPORTED -int -xmlrpc_struct_has_key_v(xmlrpc_env * env, - xmlrpc_value * strct, - xmlrpc_value * const keyval); -#endif - - -XMLRPC_LIB_EXPORTED -void -xmlrpc_struct_find_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - xmlrpc_value ** const valuePP); - - -XMLRPC_LIB_EXPORTED -void -xmlrpc_struct_find_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_struct_read_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - xmlrpc_value ** const valuePP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_struct_read_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP); - -/* The "get_value" functions are deprecated. Use the "find_value" - and "read_value" functions instead. -*/ -XMLRPC_LIB_EXPORTED -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_LIB_EXPORTED -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. -*/ -XMLRPC_LIB_EXPORTED -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. -*/ -XMLRPC_LIB_EXPORTED -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. */ -XMLRPC_LIB_EXPORTED -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. */ - -XMLRPC_LIB_EXPORTED -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. -*/ -XMLRPC_LIB_EXPORTED -void -xmlrpc_struct_get_key_and_value(xmlrpc_env * const env, - xmlrpc_value * const strct, - int const index, - xmlrpc_value ** const out_keyval, - xmlrpc_value ** const out_value); - -/* The "C pointer" type has no relation to XML-RPC. It is here for the - convenience of programs that use xmlrpc_value for XML-RPC purposes - and can benefit from using it for non-XML-RPC purposes as well. - - Also, some people use libxmlrpc for xmlrpc_value alone, because sometimes - you need to work with basic data types in richer ways than the C types - (int, time_t, etc) allow. -*/ - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_cptr_new(xmlrpc_env * const envP, - void * const value); - -typedef void (*xmlrpc_cptr_dtor_fn)(void *, void *); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_cptr_new_dtor(xmlrpc_env * const envP, - void * const value, - xmlrpc_cptr_dtor_fn const dtor, - void * const dtorContext); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_cptr_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_cptr(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - void ** const ptrValueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_read_nil(xmlrpc_env * const envP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_nil_new(xmlrpc_env * const envP); - -/* Build an xmlrpc_value from a format string. */ - -XMLRPC_LIB_EXPORTED -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 */ -XMLRPC_LIB_EXPORTED -void -xmlrpc_build_value_va(xmlrpc_env * const env, - const char * const format, - va_list const args, - xmlrpc_value ** const valPP, - const char ** const tailP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_decompose_value(xmlrpc_env * const envP, - xmlrpc_value * const value, - const char * const format, - ...); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_decompose_value_va(xmlrpc_env * const envP, - xmlrpc_value * const value, - const char * const format, - va_list const 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. -*/ -XMLRPC_LIB_EXPORTED -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. */ -XMLRPC_LIB_EXPORTED -void -xmlrpc_parse_value_va(xmlrpc_env * const envP, - xmlrpc_value * const value, - const char * const format, - va_list const args); - -/*========================================================================= -** Encoding XML -**=======================================================================*/ - -typedef enum xmlrpc_dialect { - xmlrpc_dialect_i8, - xmlrpc_dialect_apache -} xmlrpc_dialect; - -XMLRPC_LIB_EXPORTED -void -xmlrpc_serialize_value2(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP, - xmlrpc_dialect const dialect); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_serialize_value(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_serialize_params2(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const paramArrayP, - xmlrpc_dialect const dialect); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_serialize_params(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const paramArrayP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_serialize_call2(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_dialect const dialect); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_serialize_call(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - const char * const methodName, - xmlrpc_value * const paramArrayP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_serialize_response2(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP, - xmlrpc_dialect const dialect); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_serialize_response(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_serialize_fault(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - const xmlrpc_env * const faultP); - - -/*========================================================================= -** Decoding XML -**=======================================================================*/ - -XMLRPC_LIB_EXPORTED -void -xmlrpc_parse_value_xml(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_value ** const valuePP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_parse_call(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - const char ** const methodNameP, - xmlrpc_value ** const paramArrayPP); - -XMLRPC_LIB_EXPORTED -void -xmlrpc_parse_response2(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_value ** const resultPP, - int * const faultCodeP, - const char ** const faultStringP); - - -/* xmlrpc_parse_response() is for backward compatibility */ - -XMLRPC_LIB_EXPORTED -xmlrpc_value * -xmlrpc_parse_response(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen); - - -/*========================================================================= -** 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.) -**/ - -XMLRPC_LIB_EXPORTED -extern void xmlrpc_authcookie_set(xmlrpc_env * const env, - const char * const username, - const char * const password); - -XMLRPC_LIB_EXPORTED -char *xmlrpc_authcookie(void); - -/*========================================================================= - Resource Limits - - Ideally, there would be enough resource limits to ensure that - XML-RPC partners cannot cause libxmlrpc objects and routines to use - more resource than is available for them (either by accident or - malice). We have a long way to go to get there. - -=========================================================================*/ -/* These functions are _not_ re-entrant and the limits are per-process - (i.e. their values live in static global variables). -*/ - -/* 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. */ -XMLRPC_LIB_EXPORTED -extern void xmlrpc_limit_set (int const limit_id, size_t const value); - -/* Get the value of a specified limit. */ -XMLRPC_LIB_EXPORTED -extern size_t xmlrpc_limit_get (int const limit_id); - - -#ifdef __cplusplus -} -#endif - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#endif - diff --git a/trunk/include/xmlrpc-c/base.hpp b/trunk/include/xmlrpc-c/base.hpp deleted file mode 100644 index fa7ca31a6..000000000 --- a/trunk/include/xmlrpc-c/base.hpp +++ /dev/null @@ -1,588 +0,0 @@ -#ifndef XMLRPC_BASE_HPP_INCLUDED -#define XMLRPC_BASE_HPP_INCLUDED - -#include - -#include -#include -#include -#include -#include -#include -#if defined(__GNUC__) && __GNUC__ < 3 -#include -#else -#include -#endif -#if XMLRPC_HAVE_TIMEVAL -#include -#endif - -#include -#include - -/* - XMLRPC_LIBPP_EXPORTED marks a symbol in this file that is exported from - libxmlrpc++. - - XMLRPC_BUILDING_LIBPP says this compilation is part of libxmlrpc++, as - opposed to something that _uses_ libxmlrpc++. -*/ -#ifdef XMLRPC_BUILDING_LIBPP -#define XMLRPC_LIBPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_LIBPP_EXPORTED -#endif - -namespace xmlrpc_c { - -class XMLRPC_LIBPP_EXPORTED 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 { - // These are designed to be identical to the values for - // enum xmlrpc_type in the C library. - 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_I8 = 10, - TYPE_DEAD = 0xDEAD - }; - - type_t type() const; - - xmlrpc_c::value& - operator=(xmlrpc_c::value const&); - - bool - isInstantiated() 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; - // Not to be confused with public 'cvalue' method that all the derived - // classes have. - - value(xmlrpc_value * const valueP); - - void - instantiate(xmlrpc_value * const valueP); - // Works only on a placeholder object created by the no-argument - // constructor. - - xmlrpc_value * cValueP; - // NULL means this is merely a placeholder object. - -protected: - void - validateInstantiated() const; -}; - - -std::ostream& operator<<(std::ostream& out, - xmlrpc_c::value::type_t const& type); - - -class XMLRPC_LIBPP_EXPORTED value_int : public value { -public: - value_int(int const cvalue); - - value_int(xmlrpc_c::value const baseValue); - - operator int() const; - - int cvalue() const; -}; - - -class XMLRPC_LIBPP_EXPORTED value_boolean : public value { -public: - value_boolean(bool const cvalue); - - value_boolean(xmlrpc_c::value const baseValue); - - operator bool() const; - - bool cvalue() const; -}; - - -class XMLRPC_LIBPP_EXPORTED value_string : public value { -public: - enum nlCode {nlCode_all, nlCode_lf}; - - value_string(std::string const& cppvalue, - nlCode const nlCode); - - value_string(std::string const& cppvalue); - - value_string(xmlrpc_c::value const baseValue); - - std::string - crlfValue() const; - - void - validate() const; - - operator std::string() const; - - std::string cvalue() const; -}; - - -class XMLRPC_LIBPP_EXPORTED value_double : public value { -public: - value_double(double const cvalue); - - value_double(xmlrpc_c::value const baseValue); - - operator double() const; - - double cvalue() const; -}; - - -class XMLRPC_LIBPP_EXPORTED value_datetime : public value { -public: - value_datetime(std::string const cvalue); - - value_datetime(xmlrpc_datetime const cvalue); - operator xmlrpc_datetime() const; - - value_datetime(time_t const cvalue); - operator time_t() const; - -#if XMLRPC_HAVE_TIMEVAL - value_datetime(struct timeval const& cvalue); - operator timeval() const; -#endif -#if XMLRPC_HAVE_TIMESPEC - value_datetime(struct timespec const& cvalue); - operator timespec() const; -#endif - - value_datetime(xmlrpc_c::value const baseValue); - - time_t cvalue() const; - - std::string iso8601Value() const; -}; - - -typedef std::vector cbytestring; - -class XMLRPC_LIBPP_EXPORTED value_bytestring : public value { -public: - value_bytestring(cbytestring 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: - cbytestring - vectorUcharValue() const; - - cbytestring cvalue() const; - - size_t - length() const; -}; - - - -typedef std::map cstruct; - -class XMLRPC_LIBPP_EXPORTED value_struct : public value { -public: - value_struct(cstruct const& cvalue); - - value_struct(xmlrpc_c::value const baseValue); - - operator cstruct() const; - - cstruct cvalue() const; -}; - - - -typedef std::vector carray; - -class XMLRPC_LIBPP_EXPORTED value_array : public value { -public: - value_array(carray const& cvalue); - - value_array(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: - carray - vectorValueValue() const; - - carray cvalue() const; - - size_t - size() const; -}; - - - -class XMLRPC_LIBPP_EXPORTED value_nil : public value { -public: - value_nil(); - - value_nil(xmlrpc_c::value const baseValue); - - void * cvalue() const; -}; - - -class XMLRPC_LIBPP_EXPORTED value_i8 : public value { -public: - value_i8(xmlrpc_int64 const cvalue); - - value_i8(xmlrpc_c::value const baseValue); - - operator xmlrpc_int64() const; - - xmlrpc_int64 cvalue() const; -}; - - -inline xmlrpc_c::value_string -toValue(const char * const x) { - return xmlrpc_c::value_string(x); -} - -inline xmlrpc_c::value_string -toValue(std::string const& x) { - return xmlrpc_c::value_string(x); -} - -inline xmlrpc_c::value_int -toValue(int const x) { - return xmlrpc_c::value_int(x); -} - -inline xmlrpc_c::value_i8 -toValue(xmlrpc_int64 const x) { - return xmlrpc_c::value_i8(x); -} - -inline xmlrpc_c::value_boolean -toValue(bool const x) { - return xmlrpc_c::value_boolean(x); -} - -inline xmlrpc_c::value_double -toValue(double const x) { - return xmlrpc_c::value_double(x); -} - -inline xmlrpc_c::value_bytestring -toValue(cbytestring const& x) { - return xmlrpc_c::value_bytestring(x); -} - -inline const xmlrpc_c::value & -toValue(xmlrpc_c::value const& v) { -/*---------------------------------------------------------------------------- - This does a null conversion; you use it to catch all the XML-RPC types that - have no usable C++ equivalent, so you can do a toValue() of any XML-RPC - type at all. In particular: 'value_datetime', 'value_nil'. ------------------------------------------------------------------------------*/ - return v; -} - -/* Forward declarations to make it possible to do 'toValue' of a vector of - vectors, map of vectors, etc. -*/ - -template inline xmlrpc_c::value_array -toValue(std::vector const& in); - -template xmlrpc_c::value_struct -toValue(std::map const& in); - -template xmlrpc_c::value_struct -toValue(std::map const& in) { -/*---------------------------------------------------------------------------- - convert C++ map to XML-RPC structure ------------------------------------------------------------------------------*/ - cstruct ret; - for (typename std::map::const_iterator p = in.begin(); - p != in.end(); - ++p) { - ret[p->first] = toValue(p->second); - } - return xmlrpc_c::value_struct(ret); -} - -template xmlrpc_c::value_array -arrayValueSlice(InputIterator begin, - InputIterator end) { -/*---------------------------------------------------------------------------- - convert C++ iterator pair to XML-RPC array ------------------------------------------------------------------------------*/ - carray ret; - for (InputIterator p = begin; p != end; ++p) { - ret.push_back(toValue(*p)); - } - return xmlrpc_c::value_array(ret); -} - -template inline xmlrpc_c::value_array -toValue(std::vector const& in) { -/*---------------------------------------------------------------------------- - convert C++ vector to XML-RPC array ------------------------------------------------------------------------------*/ - return arrayValueSlice(in.begin(), in.end()); -} - -// fromValue() returns via reference argument instead of by return value -// so the compiler can tell which version of it to invoke based on the -// desired output type. - -inline void -fromValue(std::string & y, xmlrpc_c::value const& x) { - y = xmlrpc_c::value_string(x); -} - -inline void -fromValue(int & y, xmlrpc_c::value const& x) { - y = xmlrpc_c::value_int(x); -} - -inline void -fromValue(xmlrpc_int64 & y, xmlrpc_c::value const& x) { - y = xmlrpc_c::value_i8(x); -} - -inline void -fromValue(bool & y, xmlrpc_c::value const& x) { - y = xmlrpc_c::value_boolean(x); -} - -inline void -fromValue(double & y, xmlrpc_c::value const& x) { - y = xmlrpc_c::value_double(x); -} - -inline void -fromValue(cbytestring & y, xmlrpc_c::value const& x) { - y = xmlrpc_c::value_bytestring(x).vectorUcharValue(); -} - -inline void -fromValue(xmlrpc_c::value & y, xmlrpc_c::value const& x) { -/*---------------------------------------------------------------------------- - This does a null conversion; it's so you can use fromValue() with - an XML-RPC value or C++ value without having to know which it is. - One reason you would have an XML-RPC value lying around with C++ values - is that some XML-RPC values don't have a common C++ equivalent. ------------------------------------------------------------------------------*/ - y = x; -} - -template inline void -fromValue(std::map & y, xmlrpc_c::value const& x) { -/*---------------------------------------------------------------------------- - Convert XML-RPC structure to C++ map. ------------------------------------------------------------------------------*/ - cstruct m = xmlrpc_c::value_struct(x); - y.clear(); - for (std::map::const_iterator p = m.begin(); - p != m.end(); - ++p) { - fromValue(y[p->first], p->second); - } -} - -template inline void -fromValue(std::vector & y, xmlrpc_c::value const& x) { -/*---------------------------------------------------------------------------- - Convert XML-RPC array to C++ vector. ------------------------------------------------------------------------------*/ - carray v = xmlrpc_c::value_array(x).vectorValueValue(); - y.resize(v.size()); - for (unsigned int i = 0; i < v.size(); ++i) { - fromValue(y[i], v[i]); - } -} - -template inline xmlrpc_c::value_array -arrayValueArray(const MemberClass * const in, - size_t const size) { -/*---------------------------------------------------------------------------- - convert C++ array to XML-RPC array ------------------------------------------------------------------------------*/ - return arrayValueSlice(in, in + size); -} - -class XMLRPC_LIBPP_EXPORTED 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 XMLRPC_LIBPP_EXPORTED 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 XMLRPC_LIBPP_EXPORTED paramList { -/*---------------------------------------------------------------------------- - A parameter list of an XML-RPC call. ------------------------------------------------------------------------------*/ -public: - paramList(unsigned int const paramCount = 0); - - paramList& - add(xmlrpc_c::value const param); - - paramList& - addx(xmlrpc_c::value const param); - - template paramList& addc(const T & x) { - xmlrpc_c::paramList::add(toValue(x)); - return *this; - } - - 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; - - cbytestring - getBytestring(unsigned int const paramNumber) const; - - carray - getArray(unsigned int const paramNumber, - unsigned int const minSize = 0, - unsigned int const maxSize = UINT_MAX) const; - - cstruct - getStruct(unsigned int const paramNumber) const; - - void - getNil(unsigned int const paramNumber) const; - - xmlrpc_int64 - getI8(unsigned int const paramNumber, - xmlrpc_int64 const minimum = XMLRPC_INT64_MIN, - xmlrpc_int64 const maximum = XMLRPC_INT64_MAX) const; - - void - verifyEnd(unsigned int const paramNumber) const; - -private: - std::vector paramVector; -}; - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/base64.hpp b/trunk/include/xmlrpc-c/base64.hpp deleted file mode 100644 index 85684214b..000000000 --- a/trunk/include/xmlrpc-c/base64.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef XMLRPC_BASE64_HPP_INCLUDED -#define XMLRPC_BASE64_HPP_INCLUDED - -#include -#include - -#include - -/* -XMLRPC_LIBUTILPP_EXPORTED marks a symbol in this file that is exported from -libxmlrpc_util++. - -XMLRPC_BUILDING_LIBUTILPP says this compilation is part of libxmlrpc_util++, as -opposed to something that _uses_ libxmlrpc_util++. -*/ -#ifdef XMLRPC_BUILDING_LIBUTILPP -#define XMLRPC_LIBUTILPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_LIBUTILPP_EXPORTED -#endif - -namespace xmlrpc_c { - - -enum newlineCtl {NEWLINE_NO, NEWLINE_YES}; - -XMLRPC_LIBUTILPP_EXPORTED -std::string -base64FromBytes( - std::vector const& bytes, - xmlrpc_c::newlineCtl const newlineCtl = xmlrpc_c::NEWLINE_YES); - - -XMLRPC_LIBUTILPP_EXPORTED -std::vector -bytesFromBase64(std::string const& base64); - - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/base64_int.h b/trunk/include/xmlrpc-c/base64_int.h deleted file mode 100644 index 64af4a82b..000000000 --- a/trunk/include/xmlrpc-c/base64_int.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef BASE64_INT_H_INCLUDED -#define BASE64_INT_H_INCLUDED - -#include "xmlrpc-c/c_util.h" /* For XMLRPC_DLLEXPORT */ - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_base64Encode(const char * const chars, - char * const base64); - -#endif diff --git a/trunk/include/xmlrpc-c/base_int.h b/trunk/include/xmlrpc-c/base_int.h deleted file mode 100644 index 17d2d6cf9..000000000 --- a/trunk/include/xmlrpc-c/base_int.h +++ /dev/null @@ -1,238 +0,0 @@ -/*============================================================================ - base_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_C_BASE_INT_H_INCLUDED -#define XMLRPC_C_BASE_INT_H_INCLUDED - -#include "xmlrpc_config.h" -#include "bool.h" -#include "int.h" - -#include /* For XMLRPC_DLLEXPORT */ -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - XMLRPC_LIB_EXPORTED marks a symbol in this file that is exported from - libxmlrpc. - - XMLRPC_BUILDING_LIB says this compilation is part of libxmlrpc, as - opposed to something that _uses_ libxmlrpc. -*/ -#ifdef XMLRPC_BUILDING_LIB -#define XMLRPC_LIBINT_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_LIBINT_EXPORTED -#endif - -struct _xmlrpc_value { - xmlrpc_type _type; - struct lock * lockP; - unsigned int refcount; - - /* Certain data types store their data directly in the xmlrpc_value. */ - union { - xmlrpc_int32 i; - xmlrpc_int64 i8; - xmlrpc_bool b; - double d; - xmlrpc_datetime dt; - /* NOTE: may be invalid! e.g. February 30 */ - struct { - void * objectP; - xmlrpc_cptr_dtor_fn dtor; // NULL if none - void * dtorContext; - } cptr; - } _value; - - /* Other data types use a memory block. - - For a string, this is the characters of the lines of the string - in UTF-8, with lines delimited by either CR, LF, or CRLF, plus - a NUL added to the end. The characters of the lines may be any - character representable in UTF-8, even the ones that are not - legal XML (XML doesn't allow ASCII control characters except - tab, CR, LF). But note that a line can't contain CR or LF - because that would form a line delimiter. To disambiguate: - CRLF together is always one line delimiter. - - This format for string is quite convenient because it is also - the format of that part of an XML document which is the - contents of a element (except of course that for the - non-XML characters, we have to stretch the definition of XML). - - For base64, this is bytes of the byte string, directly. - */ - xmlrpc_mem_block * blockP; - - 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. - - This member is always NULL on a system that does not have - Unicode wchar functions. - */ - void * _cache; - /* This is a hack to support the old style memory management in which - one gets a pointer into memory that belongs to the xmlrpc_value - object; i.e. the caller of xmlrpc_read_datetime_str_old() doesn't - get memory that he is responsible for freeing. - - This is essentially a cached value of the result of a - xmlrpc_read_datetime_str_old(). NULL means nothing cached. - */ -}; - -#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 { - uint32_t keyHash; - xmlrpc_value * key; - xmlrpc_value * value; -} _struct_member; - - -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_createXmlrpcValue(xmlrpc_env * const envP, - xmlrpc_value ** const valPP); - -XMLRPC_LIBINT_EXPORTED -const char * -xmlrpc_typeName(xmlrpc_type const type); - -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_traceXml(const char * const label, - const char * const xml, - size_t const xmlLength); - -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_destroyString(xmlrpc_value * const stringP); - -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_destroyDatetime(xmlrpc_value * const datetimeP); - -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_destroyStruct(xmlrpc_value * const structP); - -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP); - -/*---------------------------------------------------------------------------- - 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. ------------------------------------------------------------------------------*/ - -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_read_datetime_str_old(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP); - -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_read_string_old(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP); - -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_read_string_lp_old(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const char ** const stringValueP); - -#if XMLRPC_HAVE_WCHAR -XMLRPC_LIBINT_EXPORTED -void -xmlrpc_read_string_w_old(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const wchar_t ** const stringValueP); - -XMLRPC_LIBINT_EXPORTED -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 - -XMLRPC_LIBINT_EXPORTED -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 - -#endif diff --git a/trunk/include/xmlrpc-c/c_util.h b/trunk/include/xmlrpc-c/c_util.h deleted file mode 100644 index 9a7bf4405..000000000 --- a/trunk/include/xmlrpc-c/c_util.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef XMLRPC_C_C_UTIL_H_INCLUDED -#define XMLRPC_C_C_UTIL_H_INCLUDED - -/* C language stuff. Doesn't involve any libraries that aren't part of - the compiler. -*/ - -/* XMLRPC_PRINTF_ATTR lets the GNU compiler check printf-type - calls to be sure the arguments match the format string, thus preventing - runtime segmentation faults and incorrect messages. -*/ -#ifdef __GNUC__ -#define XMLRPC_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b))) -#define XMLRPC_NORETURN_ATTR __attribute__((noreturn)) -#else -#define XMLRPC_PRINTF_ATTR(a,b) -#define XMLRPC_NORETURN_ATTR -#endif - -/* XMLRPC_DLLEXPORT is an attribute of an external symbol that says it - is to be exported from a library that contains it. - - XMLRPC_BUILD_DLL says the compilation at hand is for use in an Xmlrpc-c - DLL. This is meant to be defined via compiler option. -*/ -#if defined(XMLRPC_BUILD_DLL) && defined(_MSC_VER) -#define XMLRPC_DLLEXPORT __declspec(dllexport) -#else -#define XMLRPC_DLLEXPORT -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/client.h b/trunk/include/xmlrpc-c/client.h deleted file mode 100644 index ad637312e..000000000 --- a/trunk/include/xmlrpc-c/client.h +++ /dev/null @@ -1,439 +0,0 @@ -/*============================================================================ - xmlrpc_client.h -============================================================================== - This header file defines the interface between xmlrpc.c and its users, - related to clients. - - Copyright information is at the end of the file. -============================================================================*/ - -#ifndef XMLRPC_CLIENT_H_INCLUDED -#define XMLRPC_CLIENT_H_INCLUDED - -#include -#include /* For XMLRPC_DLLEXPORT */ -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct xmlrpc_client; -struct xmlrpc_client_transport; -struct xmlrpc_client_transport_ops; -#ifndef __cplusplus -typedef struct xmlrpc_client xmlrpc_client; -typedef struct xmlrpc_client_transport xmlrpc_client_transport; -typedef struct xmlrpc_client_transport_ops xmlrpc_client_transport_ops; -#endif - -/* - XMLRPC_CLIENT_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_client. - - XMLRPC_BUILDING_CLIENT says this compilation is part of libxmlrpc_client, as - opposed to something that _uses_ libxmlrpc_client. -*/ -#ifdef XMLRPC_BUILDING_CLIENT -#define XMLRPC_CLIENT_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_CLIENT_EXPORTED -#endif - -/* libxmlrpc_client typically does _not_ actually include all of the - XML transports declared here by xmlrpc_*_transport_ops. - - Use 'xmlrpc-c-config --features' to determine which features are - installed. -*/ - -/* Before Xmlrpc-c 1.13 (December 2007), we declared struct - xmlrpc_xportparms, as a sort of "base class." The struct was never - complete -- you just cast pointer to it it to pointers to other - types. It turned out not to be really helpful and casts are ugly, - so now we just use void * as a base class pointer. -*/ - -XMLRPC_CLIENT_EXPORTED -extern struct xmlrpc_client_transport_ops xmlrpc_libwww_transport_ops; -XMLRPC_CLIENT_EXPORTED -extern struct xmlrpc_client_transport_ops xmlrpc_wininet_transport_ops; -XMLRPC_CLIENT_EXPORTED -extern struct xmlrpc_client_transport_ops xmlrpc_curl_transport_ops; - -enum xmlrpc_sslversion { - XMLRPC_SSLVERSION_DEFAULT, - XMLRPC_SSLVERSION_TLSv1, - XMLRPC_SSLVERSION_SSLv2, - XMLRPC_SSLVERSION_SSLv3 -}; - - -enum xmlrpc_httpauthtype { - /* These are just constants. They can be or'ed as integers to create - a set. - */ - XMLRPC_HTTPAUTH_BASIC = (1<<0), - XMLRPC_HTTPAUTH_DIGEST = (1<<1), - XMLRPC_HTTPAUTH_GSSNEGOTIATE = (1<<2), - XMLRPC_HTTPAUTH_NTLM = (1<<3) -}; - -/* The following are useful combinations of the HTTP authentication types - above. -*/ -#define XMLRPC_HTTPAUTH_NONE 0 -#define XMLRPC_HTTPAUTH_ANY ~0 -#define XMLRPC_HTTPAUTH_ANYSAFE (~XMLRPC_HTTPAUTH_BASIC) - -enum xmlrpc_httpproxytype { - XMLRPC_HTTPPROXY_HTTP = 0, - XMLRPC_HTTPPROXY_SOCKS5 = 5 -}; - -struct xmlrpc_curl_xportparms { - /* This is designed so that zero values are always the defaults. */ - const char * network_interface; - xmlrpc_bool no_ssl_verifypeer; - xmlrpc_bool no_ssl_verifyhost; - const char * user_agent; - const char * ssl_cert; - const char * sslcerttype; - const char * sslcertpasswd; - const char * sslkey; - const char * sslkeytype; - const char * sslkeypasswd; - const char * sslengine; - xmlrpc_bool sslengine_default; - enum xmlrpc_sslversion sslversion; - const char * cainfo; - const char * capath; - const char * randomfile; - const char * egdsocket; - const char * ssl_cipher_list; - unsigned int timeout; - xmlrpc_bool dont_advertise; - const char * proxy; - unsigned int proxy_port; - enum xmlrpc_httpproxytype proxy_type; - unsigned int proxy_auth; - /* A set of authentication schemes -- an OR of - enum xmlrpc_httpproxyauth values - */ - const char * proxy_userpwd; - xmlrpc_bool gssapi_delegation; - const char * referer; - unsigned int connect_timeout; -}; - - -#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_transfer_progress { - double total; - double now; -}; - -struct xmlrpc_progress_data { - struct xmlrpc_transfer_progress call; - struct xmlrpc_transfer_progress response; -}; - -typedef void xmlrpc_progress_fn(void * const, - struct xmlrpc_progress_data const); - -struct xmlrpc_clientparms { - /* (transport, transportparmsP, transportparm_size) and - (transportOpsP, transportP) are mutually exclusive. - */ - const char * transport; - const void * transportparmsP; - /* This should be type "const struct ..._xportparms *" */ - size_t transportparm_size; - - const struct xmlrpc_client_transport_ops * transportOpsP; - xmlrpc_client_transport * transportP; - xmlrpc_dialect dialect; - xmlrpc_progress_fn * progressFn; -}; - -#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 compatibility, 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. -*/ - -XMLRPC_CLIENT_EXPORTED -const char * -xmlrpc_client_get_default_transport(xmlrpc_env * const env); - -/* A user's function to handle the response to an asynchronous call. -** If 'fault->fault_occurred' is true, then response will be NULL. All -** arguments except 'userHandle' will be deallocated internally; please do -** not free any of them yourself. -** WARNING: 'paramArray' 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 * serverUrl, - const char * methodName, - xmlrpc_value * paramArray, - void * userHandle, - 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_CLIENT_EXPORTED -xmlrpc_server_info * -xmlrpc_server_info_new(xmlrpc_env * const envP, - const char * const serverUrl); - -/* Create a new server info record, with a copy of the old server. */ -XMLRPC_CLIENT_EXPORTED -extern xmlrpc_server_info * -xmlrpc_server_info_copy(xmlrpc_env * const envP, - xmlrpc_server_info * const srcP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_server_info_free(xmlrpc_server_info * const serverP); - - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_server_info_set_user(xmlrpc_env * const envP, - xmlrpc_server_info * const serverInfoP, - const char * const username, - const char * const password); - -XMLRPC_CLIENT_EXPORTED -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_EXPORTED -void -xmlrpc_server_info_allow_auth_basic(xmlrpc_env * const envP, - xmlrpc_server_info * const sP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_server_info_disallow_auth_basic(xmlrpc_env * const envP, - xmlrpc_server_info * const sP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_server_info_allow_auth_digest(xmlrpc_env * const envP, - xmlrpc_server_info * const sP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_server_info_disallow_auth_digest(xmlrpc_env * const envP, - xmlrpc_server_info * const sP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_server_info_allow_auth_negotiate(xmlrpc_env * const envP, - xmlrpc_server_info * const sP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_server_info_disallow_auth_negotiate(xmlrpc_env * const envP, - xmlrpc_server_info * const sP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_server_info_allow_auth_ntlm(xmlrpc_env * const envP, - xmlrpc_server_info * const sP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_server_info_disallow_auth_ntlm(xmlrpc_env * const envP, - xmlrpc_server_info * const sP); - -/* These are for backward compatibility -- they can't be exported from a - Windows DLL. xmlrpc_server_version() is preferred. -*/ -extern unsigned int const xmlrpc_client_version_major; -extern unsigned int const xmlrpc_client_version_minor; -extern unsigned int const xmlrpc_client_version_point; - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_version(unsigned int * const majorP, - unsigned int * const minorP, - unsigned int * const pointP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_setup_global_const(xmlrpc_env * const envP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_teardown_global_const(void); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_create(xmlrpc_env * const envP, - int const flags, - const char * const appname, - const char * const appversion, - const struct xmlrpc_clientparms * const clientparmsP, - unsigned int const parmSize, - xmlrpc_client ** const clientPP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_destroy(xmlrpc_client * const clientP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_transport_call2( - xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block ** const respXmlPP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_call2(xmlrpc_env * const envP, - struct xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const resultPP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_call2f(xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_value ** const resultPP, - const char * const format, - ...); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_call2f_va(xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const char * const serverUrl, - const char * const methodName, - const char * const format, - xmlrpc_value ** const resultPP, - va_list args); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_event_loop_finish(xmlrpc_client * const clientP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_event_loop_finish_timeout(xmlrpc_client * const clientP, - unsigned long const milliseconds); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_start_rpc(xmlrpc_env * const envP, - struct xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_response_handler responseHandler, - void * const userData); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_start_rpcf(xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - const char * const format, - ...); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_start_rpcf_va(xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - const char * const format, - va_list args); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_set_interrupt(xmlrpc_client * const clientP, - int * const interruptP); - -#include - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _XMLRPC_CLIENT_H_ */ diff --git a/trunk/include/xmlrpc-c/client.hpp b/trunk/include/xmlrpc-c/client.hpp deleted file mode 100644 index a7825fc56..000000000 --- a/trunk/include/xmlrpc-c/client.hpp +++ /dev/null @@ -1,312 +0,0 @@ -#ifndef CLIENT_HPP_INCLUDED -#define CLIENT_HPP_INCLUDED - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* - XMLRPC_CLIENTPP_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_client++. - - XMLRPC_BUILDING_CLIENTPP says this compilation is part of - libxmlrpc_client++, as opposed to something that _uses_ libxmlrpc_client++. -*/ -#ifdef XMLRPC_BUILDING_CLIENTPP -#define XMLRPC_CLIENTPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_CLIENTPP_EXPORTED -#endif - -namespace xmlrpc_c { - -class XMLRPC_CLIENTPP_EXPORTED clientTransactionPtr; - -class XMLRPC_CLIENTPP_EXPORTED 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; - - virtual void - progress(struct xmlrpc_progress_data const& progressData) const = 0; - -protected: - clientTransaction(); -}; - -class XMLRPC_CLIENTPP_EXPORTED clientTransactionPtr : public girmem::autoObjectPtr { - -public: - clientTransactionPtr(); - - clientTransactionPtr(clientTransaction * const transP); - - virtual ~clientTransactionPtr(); - - virtual xmlrpc_c::clientTransaction * - operator->() const; -}; - -class XMLRPC_CLIENTPP_EXPORTED clientPtr; - -class XMLRPC_CLIENTPP_EXPORTED client : public girmem::autoObject { -/*---------------------------------------------------------------------------- - 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. ------------------------------------------------------------------------------*/ - friend class clientTransactionPtr; - -public: - virtual ~client(); - - virtual void - call(xmlrpc_c::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); - - void - finishAsync(xmlrpc_c::timeout const timeout); - - virtual void - setInterrupt(int *); -}; - -class XMLRPC_CLIENTPP_EXPORTED clientPtr : public girmem::autoObjectPtr { -public: - clientPtr(); - - explicit clientPtr(xmlrpc_c::client * const clientP); - - xmlrpc_c::client * - operator->() const; - - xmlrpc_c::client * - get() const; -}; - -class XMLRPC_CLIENTPP_EXPORTED serverAccessor : public girmem::autoObject { - -public: - serverAccessor(xmlrpc_c::clientPtr const clientP, - xmlrpc_c::carriageParmPtr const carriageParmP); - - void - call(std::string const& methodName, - xmlrpc_c::paramList const& paramList, - xmlrpc_c::rpcOutcome * const outcomeP) const; - -private: - xmlrpc_c::clientPtr const clientP; - xmlrpc_c::carriageParmPtr const carriageParmP; -}; - -class XMLRPC_CLIENTPP_EXPORTED serverAccessorPtr : public girmem::autoObjectPtr { -public: - serverAccessorPtr(); - - explicit - serverAccessorPtr(xmlrpc_c::serverAccessor * const serverAccessorP); - - xmlrpc_c::serverAccessor * - operator->() const; - - xmlrpc_c::serverAccessor * - get() const; -}; - -class XMLRPC_CLIENTPP_EXPORTED 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 XMLRPC_CLIENTPP_EXPORTED 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); - - client_xml(xmlrpc_c::clientXmlTransport * const transportP, - xmlrpc_dialect const dialect); - - client_xml(xmlrpc_c::clientXmlTransportPtr const transportP); - - client_xml(xmlrpc_c::clientXmlTransportPtr const transportP, - xmlrpc_dialect const dialect); - - ~client_xml(); - - 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); - - virtual void - setInterrupt(int * interruptP); - -private: - struct client_xml_impl * implP; -}; - -class XMLRPC_CLIENTPP_EXPORTED 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; - - void - progress(xmlrpc_progress_data const& progressData) const; - -private: - xmlrpc_c::clientTransactionPtr const tranP; -}; - -class XMLRPC_CLIENTPP_EXPORTED xmlTransaction_clientPtr : public xmlTransactionPtr { -public: - xmlTransaction_clientPtr(); - - xmlTransaction_clientPtr(xmlrpc_c::clientTransactionPtr const& tranP); - - xmlrpc_c::xmlTransaction_client * - operator->() const; -}; - -class rpcPtr; - -class XMLRPC_CLIENTPP_EXPORTED 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 normally create or reference an object of this class directly, - but rather via an 'rpcPtr' object. That takes care of deleting the object - when you are done with it (but not before). This is critical if you plan - to use the 'start' method, because without an rpcPtr reference, the system - will destroy the object under the covers when the RPC finishes, and there - is no way for you to guarantee you won't still access it after it finishes - (because of accesses within Xmlrpc-c calls such as the call that finishes - the RPC or just rpc::start). - - In order to do asynchronous RPCs, you normally have to create a derived - class that defines a useful notifyComplete(). ------------------------------------------------------------------------------*/ - 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(); - - virtual void - progress(struct xmlrpc_progress_data const& progressData) const; - - bool - isFinished() const; - - bool - isSuccessful() const; - - xmlrpc_c::value - getResult() const; - - xmlrpc_c::fault - getFault() const; - - rpc(std::string const methodName, - xmlrpc_c::paramList const& paramList); - - virtual ~rpc(); - -private: - struct rpc_impl * implP; -}; - -class XMLRPC_CLIENTPP_EXPORTED rpcPtr : public clientTransactionPtr { -public: - rpcPtr(); - - explicit rpcPtr(xmlrpc_c::rpc * const rpcP); - - rpcPtr(std::string const methodName, - xmlrpc_c::paramList const& paramList); - - xmlrpc_c::rpc * - operator->() const; -}; - -} // namespace -#endif diff --git a/trunk/include/xmlrpc-c/client_global.h b/trunk/include/xmlrpc-c/client_global.h deleted file mode 100644 index fb18be369..000000000 --- a/trunk/include/xmlrpc-c/client_global.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef CLIENT_GLOBAL_H_INCLUDED -#define CLIENT_GLOBAL_H_INCLUDED - -#include /* For XMLRPC_DLLEXPORT */ -#include - -/* - XMLRPC_CLIENT_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_client. - - XMLRPC_BUILDING_CLIENT says this compilation is part of libxmlrpc_client, as - opposed to something that _uses_ libxmlrpc_client. -*/ -#ifdef XMLRPC_BUILDING_CLIENT -#define XMLRPC_CLIENT_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_CLIENT_EXPORTED -#endif - -/*========================================================================= -** 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) - -XMLRPC_CLIENT_EXPORTED -extern void -xmlrpc_client_init(int const flags, - const char * const appname, - const char * const appversion); - -XMLRPC_CLIENT_EXPORTED -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); - -XMLRPC_CLIENT_EXPORTED -extern void -xmlrpc_client_cleanup(void); - -/*========================================================================= -** xmlrpc_client_call -**=======================================================================*/ - -XMLRPC_CLIENT_EXPORTED -xmlrpc_value * -xmlrpc_client_call(xmlrpc_env * const envP, - const char * const server_url, - const char * const method_name, - const char * const format, - ...); - -XMLRPC_CLIENT_EXPORTED -xmlrpc_value * -xmlrpc_client_call_params(xmlrpc_env * const envP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_value * const paramArrayP); - -XMLRPC_CLIENT_EXPORTED -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_CLIENT_EXPORTED -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); - -XMLRPC_CLIENT_EXPORTED -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. -*/ - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_call_asynch(const char * const server_url, - const char * const method_name, - xmlrpc_response_handler responseHandler, - void * const user_data, - const char * const format, - ...); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_call_server_asynch(xmlrpc_server_info * const server, - const char * const method_name, - xmlrpc_response_handler responseHandler, - void * const user_data, - const char * const format, - ...); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_call_asynch_params(const char * const server_url, - const char * const method_name, - xmlrpc_response_handler responseHandler, - void * const user_data, - xmlrpc_value * const paramArrayP); - -XMLRPC_CLIENT_EXPORTED -void -xmlrpc_client_call_server_asynch_params( - xmlrpc_server_info * const server, - const char * const method_name, - xmlrpc_response_handler responseHandler, - void * const user_data, - xmlrpc_value * const paramArrayP); - -XMLRPC_CLIENT_EXPORTED -extern void -xmlrpc_client_event_loop_finish_asynch(void); - -XMLRPC_CLIENT_EXPORTED -extern void -xmlrpc_client_event_loop_finish_asynch_timeout( - unsigned long const milliseconds); - -#endif diff --git a/trunk/include/xmlrpc-c/client_int.h b/trunk/include/xmlrpc-c/client_int.h deleted file mode 100644 index 2a1b545bc..000000000 --- a/trunk/include/xmlrpc-c/client_int.h +++ /dev/null @@ -1,152 +0,0 @@ -/*============================================================================ - xmlrpc_client_int.h -============================================================================== - This header file defines the interface between client modules inside - xmlrpc-c. - - Use this in addition to xmlrpc_client.h, which defines the external - interface. - - Copyright information is at the end of the file. -============================================================================*/ - -#ifndef XMLRPC_CLIENT_INT_H_INCLUDED -#define XMLRPC_CLIENT_INT_H_INCLUDED - -#include "xmlrpc_config.h" -#include "bool.h" - -#include "xmlrpc-c/util.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct _xmlrpc_server_info { - const char * serverUrl; - struct { - bool basic; - bool digest; - bool gssnegotiate; - bool ntlm; - } allowedAuth; - const char * userNamePw; - /* The username/password value for HTTP, i.e. in - "user:password" form - - This can be NULL to indicate "none", but only if 'allowedAuth' - doesn't allow any form of authentication. - */ - const char * basicAuthHdrValue; - /* A complete value for an HTTP Authorization: header that - requests HTTP basic authentication. This exists whether - or not 'allowedAuth' allows basic authentication, and is - completely redundant with 'userNamePw'. It exists mainly - for historical reasons, and may also save some computation - when the same xmrpc_server_info is used for multiple - HTTP connections. - - This is NULL exactly when 'userNamePw' is NULL. - */ -}; - -/*========================================================================= -** 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); - - - -/*========================================================================= -** Interface between global client and general client functions. -** (These are necessary because there are some global client functions -** that don't have exported private client versions because we don't like -** them and have them for global functions only for backward compatibility. -** The global client functions existed before any private client ones did). -**========================================================================= */ -void -xmlrpc_client_call_server2_va(xmlrpc_env * const envP, - struct xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - const char * const format, - va_list args, - xmlrpc_value ** const resultPP); - -void -xmlrpc_client_start_rpcf_server_va( - xmlrpc_env * const envP, - struct xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - const char * const format, - va_list args); - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif - - - diff --git a/trunk/include/xmlrpc-c/client_simple.hpp b/trunk/include/xmlrpc-c/client_simple.hpp deleted file mode 100644 index f57d03fa5..000000000 --- a/trunk/include/xmlrpc-c/client_simple.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef CLIENT_SIMPLE_HPP_INCLUDED -#define CLIENT_SIMPLE_HPP_INCLUDED - -#include - -#include -#include -#include - -/* - XMLRPC_CLIENTPP_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_client++. - - XMLRPC_BUILDING_CLIENTPP says this compilation is part of - libxmlrpc_client++, as opposed to something that _uses_ libxmlrpc_client++. -*/ -#ifdef XMLRPC_BUILDING_CLIENTPP -#define XMLRPC_CLIENTPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_CLIENTPP_EXPORTED -#endif - -namespace xmlrpc_c { - -class XMLRPC_CLIENTPP_EXPORTED clientSimple { - -public: - 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::clientPtr clientP; -}; - -} // namespace -#endif - - - - diff --git a/trunk/include/xmlrpc-c/client_transport.hpp b/trunk/include/xmlrpc-c/client_transport.hpp deleted file mode 100644 index 9b1bdd9e4..000000000 --- a/trunk/include/xmlrpc-c/client_transport.hpp +++ /dev/null @@ -1,449 +0,0 @@ -#ifndef CLIENT_TRANSPORT_HPP_INCLUDED -#define CLIENT_TRANSPORT_HPP_INCLUDED - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace xmlrpc_c { - -/* - XMLRPC_CLIENTPP_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_client++. - - XMLRPC_BUILDING_CLIENTPP says this compilation is part of - libxmlrpc_client++, as opposed to something that _uses_ libxmlrpc_client++. -*/ -#ifdef XMLRPC_BUILDING_CLIENTPP -#define XMLRPC_CLIENTPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_CLIENTPP_EXPORTED -#endif - -class XMLRPC_CLIENTPP_EXPORTED carriageParmPtr; - -class XMLRPC_CLIENTPP_EXPORTED carriageParm : public girmem::autoObject { -/*---------------------------------------------------------------------------- - 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 XMLRPC_CLIENTPP_EXPORTED carriageParmPtr : public girmem::autoObjectPtr { - -public: - carriageParmPtr(); - - explicit carriageParmPtr(xmlrpc_c::carriageParm * const carriageParmP); - - xmlrpc_c::carriageParm * - operator->() const; - - xmlrpc_c::carriageParm * - get() const; -}; - -//---------------------------------------------------------------------------- - -class XMLRPC_CLIENTPP_EXPORTED xmlTransactionPtr; - -class XMLRPC_CLIENTPP_EXPORTED xmlTransaction : public girmem::autoObject { - - friend class xmlTransactionPtr; - -public: - virtual void - finish(std::string const& responseXml) const; - - virtual void - finishErr(girerr::error const& error) const; - - virtual void - progress(struct xmlrpc_progress_data const& progressData) const; - -protected: - xmlTransaction(); -}; - -class XMLRPC_CLIENTPP_EXPORTED xmlTransactionPtr : public girmem::autoObjectPtr { -public: - xmlTransactionPtr(); - - xmlTransactionPtr(xmlTransaction * xmlTransP); - - xmlrpc_c::xmlTransaction * - operator->() const; -}; - -//---------------------------------------------------------------------------- - -class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport : public girmem::autoObject { -/*---------------------------------------------------------------------------- - 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); - - static void - progress( - struct xmlrpc_call_info * const callInfoP, - struct xmlrpc_progress_data const progressData); - - virtual void - setInterrupt(int * const interruptP); -}; - -class XMLRPC_CLIENTPP_EXPORTED clientXmlTransportPtr : public girmem::autoObjectPtr { - -public: - clientXmlTransportPtr(); - - clientXmlTransportPtr(xmlrpc_c::clientXmlTransport * const transportP); - - xmlrpc_c::clientXmlTransport * - operator->() const; - - xmlrpc_c::clientXmlTransport * - get() const; -}; - -/*=========================================================================== - HTTP -===========================================================================*/ - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_http0 : public xmlrpc_c::carriageParm { - -public: - carriageParm_http0(std::string const serverUrl); - - ~carriageParm_http0(); - - void - setUser(std::string const userid, - std::string const password); - - void - allowAuthBasic(); - - void - disallowAuthBasic(); - - void - allowAuthDigest(); - - void - disallowAuthDigest(); - - void - allowAuthNegotiate(); - - void - disallowAuthNegotiate(); - - void - allowAuthNtlm(); - - void - disallowAuthNtlm(); - - 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 is expected to follow it up - // with an instantiate() to establish the server URL. - - carriageParm_http0(); - - void - instantiate(std::string const serverUrl); -}; - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_http0Ptr : public xmlrpc_c::carriageParmPtr { - -public: - carriageParm_http0Ptr(); - carriageParm_http0Ptr(xmlrpc_c::carriageParm_http0 * const carriageParmP); - - xmlrpc_c::carriageParm_http0 * - operator->() const; -}; - -class XMLRPC_CLIENTPP_EXPORTED 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); - - virtual void - setInterrupt(int * const interruptP); - - static std::vector - availableTypes(); - - static clientXmlTransportPtr - create(); - -protected: - clientXmlTransport_http() {} // ensure no one can create - struct xmlrpc_client_transport * c_transportP; - const struct xmlrpc_client_transport_ops * c_transportOpsP; -}; - - -/*=========================================================================== - curl -===========================================================================*/ - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_curl0 : public xmlrpc_c::carriageParm_http0 { - -public: - carriageParm_curl0(std::string const serverUrl); -}; - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_curl0Ptr : public xmlrpc_c::carriageParm_http0Ptr { - -public: - carriageParm_curl0Ptr(); - carriageParm_curl0Ptr(xmlrpc_c::carriageParm_curl0 * const carriageParmP); - - xmlrpc_c::carriageParm_curl0 * - operator->() const; -}; - -class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_curl : public xmlrpc_c::clientXmlTransport_http { - -public: - struct constrOpt_impl; - - class XMLRPC_CLIENTPP_EXPORTED constrOpt { - public: - constrOpt(); - ~constrOpt(); - constrOpt(constrOpt&); - - constrOpt & network_interface (std::string const& arg); - constrOpt & no_ssl_verifypeer (bool const& arg); - constrOpt & no_ssl_verifyhost (bool const& arg); - constrOpt & dont_advertise (bool const& arg); - constrOpt & user_agent (std::string const& arg); - constrOpt & referer (std::string const& arg); - constrOpt & ssl_cert (std::string const& arg); - constrOpt & sslcerttype (std::string const& arg); - constrOpt & sslcertpasswd (std::string const& arg); - constrOpt & sslkey (std::string const& arg); - constrOpt & sslkeytype (std::string const& arg); - constrOpt & sslkeypasswd (std::string const& arg); - constrOpt & sslengine (std::string const& arg); - constrOpt & sslengine_default (bool const& arg); - constrOpt & sslversion (xmlrpc_sslversion const& arg); - constrOpt & cainfo (std::string const& arg); - constrOpt & capath (std::string const& arg); - constrOpt & randomfile (std::string const& arg); - constrOpt & egdsocket (std::string const& arg); - constrOpt & ssl_cipher_list (std::string const& arg); - constrOpt & timeout (unsigned int const& arg); - constrOpt & proxy (std::string const& arg); - constrOpt & proxy_port (unsigned int const& arg); - constrOpt & proxy_auth (unsigned int const& arg); - constrOpt & proxy_userpwd (std::string const& arg); - constrOpt & proxy_type (xmlrpc_httpproxytype const& arg); - constrOpt & gssapi_delegation (bool const& arg); - constrOpt & connect_timeout (unsigned int const& arg); - - private: - struct constrOpt_impl * implP; - friend class clientXmlTransport_curl; - }; - - clientXmlTransport_curl(constrOpt const& opt); - - clientXmlTransport_curl(std::string const networkInterface = "", - bool const noSslVerifyPeer = false, - bool const noSslVerifyHost = false, - std::string const userAgent = ""); - - ~clientXmlTransport_curl(); - -private: - void - initialize(constrOpt const& opt); -}; - -/*=========================================================================== - libwww -===========================================================================*/ - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_libwww0 : public xmlrpc_c::carriageParm_http0 { - -public: - carriageParm_libwww0(std::string const serverUrl); - -}; - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_libwww0Ptr : public xmlrpc_c::carriageParm_http0Ptr { - -public: - carriageParm_libwww0Ptr(); - carriageParm_libwww0Ptr(xmlrpc_c::carriageParm_libwww0 * const); - - xmlrpc_c::carriageParm_libwww0 * - operator->() const; -}; - -class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_libwww : public xmlrpc_c::clientXmlTransport_http { - -public: - clientXmlTransport_libwww(std::string const appname = "", - std::string const appversion = ""); - - ~clientXmlTransport_libwww(); -}; - -/*=========================================================================== - wininet -===========================================================================*/ - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_wininet0 : public xmlrpc_c::carriageParm_http0 { - -public: - carriageParm_wininet0(std::string const serverUrl); - -}; - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_wininet0Ptr : public xmlrpc_c::carriageParm_http0Ptr { - -public: - carriageParm_wininet0Ptr(); - carriageParm_wininet0Ptr(xmlrpc_c::carriageParm_wininet0 * const); - - xmlrpc_c::carriageParm_wininet0 * - operator->() const; -}; - -class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_wininet : public xmlrpc_c::clientXmlTransport_http { - -public: - clientXmlTransport_wininet(bool const allowInvalidSslCerts = false); - - ~clientXmlTransport_wininet(); -}; - -/*=========================================================================== - pstream -===========================================================================*/ - -class XMLRPC_CLIENTPP_EXPORTED packetSocket; - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_pstream : public xmlrpc_c::carriageParm { - - // There are no parameters for carrying an RPC on a packet stream. - // There's only one way to carry it. -}; - -class XMLRPC_CLIENTPP_EXPORTED carriageParm_pstreamPtr : public xmlrpc_c::carriageParmPtr { - -public: - carriageParm_pstreamPtr(); - carriageParm_pstreamPtr( - xmlrpc_c::carriageParm_pstream * const carriageParmP); - - xmlrpc_c::carriageParm_pstream * - operator->() const; -}; - -class XMLRPC_CLIENTPP_EXPORTED clientXmlTransport_pstream : public xmlrpc_c::clientXmlTransport { - -public: - struct constrOpt_impl; - - class XMLRPC_CLIENTPP_EXPORTED constrOpt { - public: - constrOpt(); - ~constrOpt(); - constrOpt(constrOpt&); - - constrOpt & fd (int const& arg); - constrOpt & useBrokenConnEx (bool const& arg); - - private: - struct constrOpt_impl * implP; - friend class clientXmlTransport_pstream; - }; - - clientXmlTransport_pstream(constrOpt const& opt); - - ~clientXmlTransport_pstream(); - - void - call(xmlrpc_c::carriageParm * const carriageParmP, - std::string const& callXml, - std::string * const responseXmlP); - - class BrokenConnectionEx {}; - -private: - class clientXmlTransport_pstream_impl * const implP; -}; - - -} // namespace -#endif diff --git a/trunk/include/xmlrpc-c/env_wrap.hpp b/trunk/include/xmlrpc-c/env_wrap.hpp deleted file mode 100644 index 7c405c667..000000000 --- a/trunk/include/xmlrpc-c/env_wrap.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef ENV_INT_HPP_INCLUDED -#define ENV_INT_HPP_INCLUDED - -#include "xmlrpc-c/c_util.h" -#include "xmlrpc-c/util.h" - -#ifdef XMLRPC_BUILDING_LIBUTILPP -#define XMLRPC_LIBUTILPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_LIBUTILPP_EXPORTED -#endif - -namespace xmlrpc_c { - -class XMLRPC_LIBUTILPP_EXPORTED env_wrap { -/*---------------------------------------------------------------------------- - A wrapper to assist in using the Xmlrpc-c C libraries in - Xmlrpc-c C++ code. - - To use the C libraries, you have to use type xmlrpc_env, but that type - does not have an automatic destructor (because it's C), so it's hard - to throw an error from a context in which a variable of that type - exists. This wrapper provides that automatic destructor. ------------------------------------------------------------------------------*/ -public: - env_wrap(); - ~env_wrap(); - xmlrpc_env env_c; -}; - - -} // namespace -#endif diff --git a/trunk/include/xmlrpc-c/girerr.hpp b/trunk/include/xmlrpc-c/girerr.hpp deleted file mode 100644 index ee499c6d1..000000000 --- a/trunk/include/xmlrpc-c/girerr.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef GIRERR_HPP_INCLUDED -#define GIRERR_HPP_INCLUDED - -#include -#include - -#include - -/* -XMLRPC_LIBUTILPP_EXPORTED marks a symbol in this file that is exported from -libxmlrpc_util++. - -XMLRPC_BUILDING_LIBUTILPP says this compilation is part of libxmlrpc_util++, as -opposed to something that _uses_ libxmlrpc_util++. -*/ -#ifdef XMLRPC_BUILDING_LIBUTILPP -#define XMLRPC_LIBUTILPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_LIBUTILPP_EXPORTED -#endif - -#define HAVE_GIRERR_ERROR - -namespace girerr { - -class XMLRPC_LIBUTILPP_EXPORTED 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; -}; - -// throwf() always throws a girerr::error . - -XMLRPC_LIBUTILPP_EXPORTED -void -throwf(const char * const format, ...) - XMLRPC_PRINTF_ATTR(1,2) - XMLRPC_NORETURN_ATTR; - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/girmem.hpp b/trunk/include/xmlrpc-c/girmem.hpp deleted file mode 100644 index 014464196..000000000 --- a/trunk/include/xmlrpc-c/girmem.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/*============================================================================ - girmem.hpp -============================================================================== - This declares the user interface to memory management facilities (smart - pointers, basically) in libxmlrpc. They are used in interfaces to various - classes in XML For C/C++. -============================================================================*/ -#ifndef GIRMEM_HPP_INCLUDED -#define GIRMEM_HPP_INCLUDED - -#include -#include - -/* -XMLRPC_LIBUTILPP_EXPORTED marks a symbol in this file that is exported from -libxmlrpc_util++. - -XMLRPC_BUILDING_LIBUTILPP says this compilation is part of libxmlrpc_util++, as -opposed to something that _uses_ libxmlrpc_util++. -*/ -#ifdef XMLRPC_BUILDING_LIBUTILPP -#define XMLRPC_LIBUTILPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_LIBUTILPP_EXPORTED -#endif - -namespace girmem { - -class XMLRPC_LIBUTILPP_EXPORTED autoObjectPtr; - -class XMLRPC_LIBUTILPP_EXPORTED autoObject { - friend class autoObjectPtr; - -public: - void incref(); - void decref(bool * const unreferencedP); - -protected: - autoObject(); - virtual ~autoObject(); - -private: - class Impl; - - std::auto_ptr const implP; - - // Because of 'implP', we cannot allow copy construction, so this is - // private: - autoObject(autoObject const&); -}; - -class XMLRPC_LIBUTILPP_EXPORTED autoObjectPtr { -public: - autoObjectPtr(); - autoObjectPtr(girmem::autoObject * objectP); - autoObjectPtr(girmem::autoObjectPtr const& autoObjectPtr); - - ~autoObjectPtr(); - - void - point(girmem::autoObject * const objectP); - - void - unpoint(); - - autoObjectPtr - operator=(girmem::autoObjectPtr const& objectPtr); - - girmem::autoObject * - operator->() const; - - girmem::autoObject * - get() const; - -protected: - girmem::autoObject * objectP; -}; - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/inttypes.h b/trunk/include/xmlrpc-c/inttypes.h deleted file mode 100644 index 1e470e515..000000000 --- a/trunk/include/xmlrpc-c/inttypes.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef XMLRPC_INTTYPES_H_INCLUDED -#define XMLRPC_INTTYPES_H_INCLUDED - -#ifdef _MSC_VER - -typedef unsigned short xmlrpc_uint16_t; -typedef unsigned int xmlrpc_uint32_t; -typedef unsigned __int64 xmlrpc_uint64_t; - -#else -#include -#ifdef __INTERIX -# include -#endif - -typedef uint16_t xmlrpc_uint16_t; -typedef uint32_t xmlrpc_uint32_t; -typedef uint64_t xmlrpc_uint64_t; - -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/json.h b/trunk/include/xmlrpc-c/json.h deleted file mode 100644 index d7b84538c..000000000 --- a/trunk/include/xmlrpc-c/json.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef XMLRPC_JSON_H_INCLUDED -#define XMLRPC_JSON_H_INCLUDED - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - Parse a given string as JSON and return its value as an XML-RPC value - object. - - @param envP xmlrpc environment for error handling - @param buf holds a pointer to a ziro terminated string - @return the value generated or NULL (check error) -*/ -xmlrpc_value * -xmlrpc_parse_json(xmlrpc_env * const envP, - const char * const json); - - -/* - Serialize an XML-RPC value object into JSON. - - @param envP holds the xmlrpc execution environment - @param valP holds the value to serialize - @param out holds a mem block containing the result -*/ -void -xmlrpc_serialize_json(xmlrpc_env * const envP, - xmlrpc_value * const valP, - xmlrpc_mem_block * const jsonP); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* XMLRPC_JSON_H_INCLUDED */ diff --git a/trunk/include/xmlrpc-c/lock.h b/trunk/include/xmlrpc-c/lock.h deleted file mode 100644 index cc773361c..000000000 --- a/trunk/include/xmlrpc-c/lock.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef LOCK_H_INCLUDED -#define LOCK_H_INCLUDED - -struct lock; - -/* GCC 2.95.3 defines a function called 'lock', so we cannot - typedef struct lock to 'lock' here. -*/ - -typedef void lockAcquireFn(struct lock *); -typedef void lockReleaseFn(struct lock *); -typedef void lockDestroyFn(struct lock *); - -struct lock { - /* To finish the job of making an abstract lock class that can use locks - other than pthread mutexes, we need to replace 'theLock' with a - "void * implementationP" and make curlLock_create_pthread() malloc - the mutex. - */ - void * implementationP; - lockAcquireFn * acquire; - lockReleaseFn * release; - lockDestroyFn * destroy; -}; - -#endif diff --git a/trunk/include/xmlrpc-c/lock_none.h b/trunk/include/xmlrpc-c/lock_none.h deleted file mode 100644 index 0a2e32e04..000000000 --- a/trunk/include/xmlrpc-c/lock_none.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef LOCK_NONE_H_INCLUDED -#define LOCK_NONE_H_INCLUDED - -#include "lock.h" - -struct lock * -xmlrpc_lock_create_none(void); - -#endif diff --git a/trunk/include/xmlrpc-c/lock_platform.h b/trunk/include/xmlrpc-c/lock_platform.h deleted file mode 100644 index f98dc4478..000000000 --- a/trunk/include/xmlrpc-c/lock_platform.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef LOCK_PLATFORM_H_INCLUDED -#define LOCK_PLATFORM_H_INCLUDED - -#include "xmlrpc-c/c_util.h" /* For XMLRPC_DLLEXPORT */ -#include "xmlrpc-c/lock.h" - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -XMLRPC_UTIL_EXPORTED -struct lock * -xmlrpc_lock_create(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/lock_pthread.h b/trunk/include/xmlrpc-c/lock_pthread.h deleted file mode 100644 index c7f320125..000000000 --- a/trunk/include/xmlrpc-c/lock_pthread.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef LOCK_PTHREAD_H_INCLUDED -#define LOCK_PTHREAD_H_INCLUDED - -#include "xmlrpc-c/c_util.h" /* For XMLRPC_DLLEXPORT */ -#include "lock.h" - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -XMLRPC_UTIL_EXPORTED -struct lock * -xmlrpc_lock_create_pthread(void); - -#endif diff --git a/trunk/include/xmlrpc-c/lock_windows.h b/trunk/include/xmlrpc-c/lock_windows.h deleted file mode 100644 index a1df2889f..000000000 --- a/trunk/include/xmlrpc-c/lock_windows.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef LOCK_WINDOWS_H_INCLUDED -#define LOCK_WINDOWS_H_INCLUDED - -#include "xmlrpc-c/c_util.h" /* For XMLRPC_DLLEXPORT */ -#include "lock.h" - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -XMLRPC_UTIL_EXPORTED -struct lock * -xmlrpc_lock_create_windows(void); - -#endif diff --git a/trunk/include/xmlrpc-c/oldcppwrapper.hpp b/trunk/include/xmlrpc-c/oldcppwrapper.hpp deleted file mode 100644 index 9ea2c4a22..000000000 --- a/trunk/include/xmlrpc-c/oldcppwrapper.hpp +++ /dev/null @@ -1,418 +0,0 @@ -// -*- 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 - -/* - XMLRPC_OLDCPPWRAPPER_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_cpp. - - XMLRPC_BUILDING_OLDCPPWRAPPER says this compilation is part of - libxmlrpc_cpp, as opposed to something that _uses_ libxmlrpc_cpp. -*/ -#ifdef XMLRPC_BUILDING_OLDCPPWRAPPER -#define XMLRPC_OLDCPPWRAPPER_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_OLDCPPWRAPPER_EXPORTED -#endif - -#include -#include - -#include -#include -#include -#include - -//========================================================================= -// XmlRpcFault -//========================================================================= -// A C++ exception class representing an XML-RPC fault. - -class XMLRPC_OLDCPPWRAPPER_EXPORTED 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); - - inline int getFaultCode (void) const; - std::string getFaultString (void) const; - inline 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 XMLRPC_OLDCPPWRAPPER_EXPORTED 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 != 0);}; - 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 XMLRPC_OLDCPPWRAPPER_EXPORTED 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 XMLRPC_OLDCPPWRAPPER_EXPORTED 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 XMLRPC_OLDCPPWRAPPER_EXPORTED 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_ */ diff --git a/trunk/include/xmlrpc-c/oldxmlrpc.h b/trunk/include/xmlrpc-c/oldxmlrpc.h deleted file mode 100644 index 2a5d3bf44..000000000 --- a/trunk/include/xmlrpc-c/oldxmlrpc.h +++ /dev/null @@ -1,2 +0,0 @@ -#include -#include diff --git a/trunk/include/xmlrpc-c/openssl_thread.h b/trunk/include/xmlrpc-c/openssl_thread.h deleted file mode 100644 index e751aed0f..000000000 --- a/trunk/include/xmlrpc-c/openssl_thread.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef XMLRPC_OPENSS_THREAD_H_INCLUDED -#define XMLRPC_OPENSS_THREAD_H_INCLUDED - -void -xmlrpc_openssl_thread_setup(const char ** const errorP); - -void -xmlrpc_openssl_thread_cleanup(void); - -#endif diff --git a/trunk/include/xmlrpc-c/packetsocket.hpp b/trunk/include/xmlrpc-c/packetsocket.hpp deleted file mode 100644 index 2f715ac0d..000000000 --- a/trunk/include/xmlrpc-c/packetsocket.hpp +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef PACKETSOCKET_HPP_INCLUDED -#define PACKETSOCKET_HPP_INCLUDED - -/*============================================================================ - packetsocket -============================================================================== - This is a facility for communicating socket-style, with defined - packets like a datagram socket but with reliable delivery like a - stream socket. It's like a POSIX "sequential packet" socket, except - it is built on top of a stream socket, so it is usable on the many - systems that have stream sockets but not sequential packet sockets. -============================================================================*/ - -#include -#include -#include - -#include -#include - -/* - XMLRPC_PACKETSOCKET_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_packetsocket. - - XMLRPC_BUILDING_PACKETSOCKET says this compilation is part of - libxmlrpc_packetsocket, as opposed to something that _uses_ - libxmlrpc_packetsocket. -*/ -#ifdef XMLRPC_BUILDING_PACKETSOCKET -#define XMLRPC_PACKETSOCKET_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_PACKETSOCKET_EXPORTED -#endif - -namespace xmlrpc_c { - -class XMLRPC_PACKETSOCKET_EXPORTED packet : public girmem::autoObject { - -public: - packet(); - - packet(const unsigned char * const data, - size_t const dataLength); - - packet(const char * const data, - size_t const dataLength); - - ~packet(); - - unsigned char * - getBytes() const { return this->bytes; } - - size_t - getLength() const { return this->length; } - - void - addData(const unsigned char * const data, - size_t const dataLength); - -private: - unsigned char * bytes; // malloc'ed - size_t length; - size_t allocSize; - - void - initialize(const unsigned char * const data, - size_t const dataLength); -}; - - - -class XMLRPC_PACKETSOCKET_EXPORTED packetPtr: public girmem::autoObjectPtr { - -public: - packetPtr(); - - explicit packetPtr(packet * const packetP); - - packet * - operator->() const; -}; - - - -class XMLRPC_PACKETSOCKET_EXPORTED packetSocket_impl; - -class XMLRPC_PACKETSOCKET_EXPORTED packetSocket { -/*---------------------------------------------------------------------------- - This is an Internet communication vehicle that transmits individual - variable-length packets of text. - - It is based on a stream socket. - - It would be much better to use a kernel SOCK_SEQPACKET socket, but - Linux 2.4 does not have them. ------------------------------------------------------------------------------*/ -public: - packetSocket(int sockFd); - - ~packetSocket(); - - void - writeWait(packetPtr const& packetPtr) const; - - void - writeWait(packetPtr const& packetPtr, - bool * const brokenConnP) const; - - void - read(bool * const eofP, - bool * const gotPacketP, - packetPtr * const packetPP); - - void - readWait(volatile const int * const interruptP, - bool * const eofP, - bool * const gotPacketP, - packetPtr * const packetPP); - - void - readWait(volatile const int * const interruptP, - bool * const eofP, - packetPtr * const packetPP); - - void - readWait(bool * const eofP, - packetPtr * const packetPP); - - void - useBrokenConnEx(); - -private: - packetSocket_impl * implP; -}; - - - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/registry.hpp b/trunk/include/xmlrpc-c/registry.hpp deleted file mode 100644 index 0dc5e3f15..000000000 --- a/trunk/include/xmlrpc-c/registry.hpp +++ /dev/null @@ -1,242 +0,0 @@ -#ifndef REGISTRY_HPP_INCLUDED -#define REGISTRY_HPP_INCLUDED - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace xmlrpc_c { - - -/* - XMLRPC_SERVERPP_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_server++. - - XMLRPC_BUILDING_SERVERPP says this compilation is part of - libxmlrpc_server++, as opposed to something that _uses_ - libxmlrpc_server++. -*/ -#ifdef XMLRPC_BUILDING_SERVERPP -#define XMLRPC_SERVERPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_SERVERPP_EXPORTED -#endif - -class XMLRPC_SERVERPP_EXPORTED callInfo { -/*---------------------------------------------------------------------------- - Information about how an XML-RPC call arrived. - - This base class carries no information; Servers that don't have any - call information to provide might use this. Servers that do have call - information to provide define a derived class of this that contains - information pertinent to that kind of server. ------------------------------------------------------------------------------*/ -public: - virtual ~callInfo(); // This makes it polymorphic - - callInfo(); -}; - -class XMLRPC_SERVERPP_EXPORTED 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; }; - -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_int(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 XMLRPC_SERVERPP_EXPORTED method2 : public method { -/*---------------------------------------------------------------------------- - 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. - - This differs from class 'method' in that the execute() method gets - call information ('callInfo'). ------------------------------------------------------------------------------*/ -public: - method2(); - - virtual ~method2(); - - virtual void - execute(xmlrpc_c::paramList const& paramList, - const xmlrpc_c::callInfo * const callInfoP, - xmlrpc_c::value * const resultP) = 0; - - void - execute(xmlrpc_c::paramList const& paramList, - xmlrpc_c::value * const resultP); - -}; - -class XMLRPC_SERVERPP_EXPORTED methodPtr : public girmem::autoObjectPtr { - -public: - methodPtr(xmlrpc_c::method * const methodP); - - xmlrpc_c::method * - operator->() const; -}; - -class XMLRPC_SERVERPP_EXPORTED 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; -}; - -class XMLRPC_SERVERPP_EXPORTED defaultMethodPtr : public girmem::autoObjectPtr { - -public: - defaultMethodPtr(); - - defaultMethodPtr(xmlrpc_c::defaultMethod * const methodP); - - xmlrpc_c::defaultMethod * - operator->() const; - - xmlrpc_c::defaultMethod * - get() const; -}; - -struct registry_impl; - -class XMLRPC_SERVERPP_EXPORTED registry : public girmem::autoObject { -/*---------------------------------------------------------------------------- - 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::method * const methodP); - - void - addMethod(std::string const name, - xmlrpc_c::methodPtr const methodP); - - void - setDefaultMethod(xmlrpc_c::defaultMethod * const methodP); - - void - setDefaultMethod(xmlrpc_c::defaultMethodPtr const methodP); - - void - disableIntrospection(); - - class XMLRPC_SERVERPP_EXPORTED shutdown { - public: - virtual ~shutdown() = 0; - virtual void - doit(std::string const& comment, - void * const callInfo) const = 0; - }; - - void - setShutdown(const shutdown * const shutdownP); - - void - setDialect(xmlrpc_dialect const dialect); - - void - processCall(std::string const& callXml, - std::string * const responseXmlP) const; - - void - processCall(std::string const& callXml, - const xmlrpc_c::callInfo * const callInfoP, - std::string * const responseXmlP) const; - - size_t - maxStackSize() const; - -private: - - registry_impl * implP; -}; - - -class XMLRPC_SERVERPP_EXPORTED registryPtr : public girmem::autoObjectPtr { - -public: - registryPtr(); - - registryPtr(xmlrpc_c::registry * const registryP); - - xmlrpc_c::registry * - operator->() const; - - xmlrpc_c::registry * - get() const; -}; - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/select_int.h b/trunk/include/xmlrpc-c/select_int.h deleted file mode 100644 index 8dd0e072a..000000000 --- a/trunk/include/xmlrpc-c/select_int.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************** - select_int.h -****************************************************************************** - This file is the interface header for the OS-independent abstraction of the - "select" OS services (i.e. services for waiting for events). - - Nothing may include this header file that also includes , - because it conflicts with this file's use of . Furthermore, - nothing including this file may include without previously - defining WIN32_LEAN_AND_MEAN, because without that macro - includes automatically. - -*****************************************************************************/ -#ifndef SELECT_INT_H_INCLUDED -#define SELECT_INT_H_INCLUDED - -#include - -#include "xmlrpc-c/c_util.h" /* For XMLRPC_DLLEXPORT */ -#include "xmlrpc-c/time_int.h" -#if MSVCRT - #include - - #ifndef sigset_t - typedef int sigset_t; - #endif -#endif - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -XMLRPC_UTIL_EXPORTED -int -xmlrpc_pselect(int const n, - fd_set * const readfdsP, - fd_set * const writefdsP, - fd_set * const exceptfdsP, - const xmlrpc_timespec * const timeoutP, - sigset_t * const sigmaskP); - -#endif diff --git a/trunk/include/xmlrpc-c/server.h b/trunk/include/xmlrpc-c/server.h deleted file mode 100644 index 2d32eda32..000000000 --- a/trunk/include/xmlrpc-c/server.h +++ /dev/null @@ -1,210 +0,0 @@ -/* Copyright and license information is at the end of the file */ - -#ifndef XMLRPC_SERVER_H_INCLUDED -#define XMLRPC_SERVER_H_INCLUDED - -#include /* For XMLRPC_DLLEXPORT */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - XMLRPC_SERVER_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_server. - - XMLRPC_BUILDING_SERVER says this compilation is part of libxmlrpc_server, as - opposed to something that _uses_ libxmlrpc_server. -*/ -#ifdef XMLRPC_BUILDING_SERVER -#define XMLRPC_SERVER_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_SERVER_EXPORTED -#endif - -typedef struct xmlrpc_registry xmlrpc_registry; - -typedef void -(*xmlrpc_preinvoke_method)(xmlrpc_env * const envP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - void * const userData); - -typedef xmlrpc_value * -(*xmlrpc_method1)(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo); - -typedef xmlrpc_value * -(*xmlrpc_method2)(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo); - -typedef xmlrpc_method1 xmlrpc_method; /* backward compatibility */ - -typedef xmlrpc_value * -(*xmlrpc_default_method)(xmlrpc_env * const envP, - const char * const callInfoP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - void * const serverInfo); - -/* These are for backward compatibility -- they can't be exported from a - Windows DLL. xmlrpc_server_version() is preferred. -*/ -extern unsigned int const xmlrpc_server_version_major; -extern unsigned int const xmlrpc_server_version_minor; -extern unsigned int const xmlrpc_server_version_point; - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_server_version(unsigned int * const majorP, - unsigned int * const minorP, - unsigned int * const pointP); - -XMLRPC_SERVER_EXPORTED -xmlrpc_registry * -xmlrpc_registry_new(xmlrpc_env * const envP); - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_free(xmlrpc_registry * const registryP); - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_disable_introspection(xmlrpc_registry * const registryP); - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_add_method(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const host, - const char * const methodName, - xmlrpc_method const method, - void * const serverInfo); - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_add_method_w_doc(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const host, - const char * const methodName, - xmlrpc_method const method, - void * const serverInfo, - const char * const signatureString, - const char * const help); - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_add_method2(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const methodName, - xmlrpc_method2 method, - const char * const signatureString, - const char * const help, - void * const serverInfo); - -struct xmlrpc_method_info3 { - const char * methodName; - xmlrpc_method2 methodFunction; - void * serverInfo; - size_t stackSize; - const char * signatureString; - const char * help; -}; - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_add_method3( - xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const struct xmlrpc_method_info3 * const infoP); - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_set_default_method(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - xmlrpc_default_method const handler, - void * const userData); - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_set_preinvoke_method(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - xmlrpc_preinvoke_method const method, - void * const userData); - - -typedef void xmlrpc_server_shutdown_fn(xmlrpc_env * const envP, - void * const context, - const char * const comment, - void * const callInfo); - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_set_shutdown(xmlrpc_registry * const registryP, - xmlrpc_server_shutdown_fn * const shutdownFn, - void * const context); - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_set_dialect(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - xmlrpc_dialect const dialect); - -/*---------------------------------------------------------------------------- - Lower interface -- services to be used by an HTTP request handler ------------------------------------------------------------------------------*/ - -XMLRPC_SERVER_EXPORTED -void -xmlrpc_registry_process_call2(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const xmlData, - size_t const xmlLen, - void * const callInfo, - xmlrpc_mem_block ** const outputPP); - -XMLRPC_SERVER_EXPORTED -xmlrpc_mem_block * -xmlrpc_registry_process_call(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const host, - const char * const xmlData, - size_t const xmlLen); - -XMLRPC_SERVER_EXPORTED -size_t -xmlrpc_registry_max_stackSize(xmlrpc_registry * const registryP); - -#ifdef __cplusplus -} -#endif - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ -#endif diff --git a/trunk/include/xmlrpc-c/server_abyss.h b/trunk/include/xmlrpc-c/server_abyss.h deleted file mode 100644 index 49b1e5c02..000000000 --- a/trunk/include/xmlrpc-c/server_abyss.h +++ /dev/null @@ -1,382 +0,0 @@ -/*============================================================================ - server_abyss.h -============================================================================== - This declares the user interface to libxmlrpc_server_abyss, which - provides facilities for running an XML-RPC server based on the Xmlrpc-c - Abyss HTTP server. - - Nothing may include this header file that also includes , - because it conflicts with this file's use of . Furthermore, - nothing including this file may include without previously - defining WIN32_LEAN_AND_MEAN, because without that macro - includes automatically. -============================================================================*/ - -/* Copyright and license information is at the end of the file */ - -#ifndef XMLRPC_SERVER_ABYSS_H_INCLUDED -#define XMLRPC_SERVER_ABYSS_H_INCLUDED - -#ifdef _WIN32 -/* See restriction above concerning windows.h and winsock.h */ -# include /* For XMLRPC_SOCKET (= SOCKET) */ -# include -#endif - -#include /* For XMLRPC_SOCKET */ -#include /* For XMLRPC_DLLEXPORT */ -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - XMLRPC_SERVER_ABYSS_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_server_abyss. - - XMLRPC_BUILDING_SERVER_ABYSS says this compilation is part of - libxmlrpc_server_abyss, as opposed to something that _uses_ - libxmlrpc_server_abyss. -*/ -#ifdef XMLRPC_BUILDING_SERVER_ABYSS -#define XMLRPC_SERVER_ABYSS_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_SERVER_ABYSS_EXPORTED -#endif - -#define XMLRPC_SERVER_ABYSS_NO_FLAGS (0) - - -/*========================================================================= -** Global Initialization/Termination. -** -** These are not thread-safe. You call them at the beginning and end -** of your program, when it is only one thread. -**=======================================================================*/ - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_global_init(xmlrpc_env * const envP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_global_term(void); - -/*========================================================================= -** 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_bool socket_bound; - XMLRPC_SOCKET socket_handle; - const char * uri_path; - xmlrpc_bool chunk_response; - xmlrpc_bool enable_shutdown; - const char * allow_origin; - xmlrpc_bool access_ctl_expires; - unsigned int access_ctl_max_age; - const struct sockaddr * sockaddr_p; - socklen_t sockaddrlen; - unsigned int max_conn; - unsigned int max_conn_backlog; - size_t max_rpc_mem; -} 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 compatibility, 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. -*/ - -/*========================================================================= -** Simple server with Abyss under the covers -**=======================================================================*/ - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parms, - unsigned int const parmSize); - -/*========================================================================= -** Object-oriented XML-RPC server with Abyss under the covers -**=======================================================================*/ - -typedef struct xmlrpc_server_abyss xmlrpc_server_abyss_t; - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_create(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize, - xmlrpc_server_abyss_t ** const serverPP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_destroy(xmlrpc_server_abyss_t * const serverP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_run_server(xmlrpc_env * const envP, - xmlrpc_server_abyss_t * const serverP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_terminate(xmlrpc_env * const envP, - xmlrpc_server_abyss_t * const serverP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_reset_terminate(xmlrpc_env * const envP, - xmlrpc_server_abyss_t * const serverP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_use_sigchld(xmlrpc_server_abyss_t * const serverP); - - -typedef struct xmlrpc_server_abyss_sig xmlrpc_server_abyss_sig; - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_setup_sig( - xmlrpc_env * const envP, - xmlrpc_server_abyss_t * const serverP, - xmlrpc_server_abyss_sig ** const oldHandlersPP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_restore_sig( - const xmlrpc_server_abyss_sig * const oldHandlersP); - - - -/*========================================================================= -** Functions to make an XML-RPC server out of your own Abyss server -**=======================================================================*/ - -typedef void -xmlrpc_call_processor(xmlrpc_env * const envP, - void * const processorArg, - const char * const callXml, - size_t const callXmlLen, - TSession * const abyssSessionP, - xmlrpc_mem_block ** const responseXmlPP); - -typedef struct { - xmlrpc_call_processor * xml_processor; - void * xml_processor_arg; - size_t xml_processor_max_stack; - const char * uri_path; - xmlrpc_bool chunk_response; - const char * allow_origin; - /* NULL means don't answer HTTP access control query */ - xmlrpc_bool access_ctl_expires; - unsigned int access_ctl_max_age; -} xmlrpc_server_abyss_handler_parms; - -#define XMLRPC_AHPSIZE(MBRNAME) \ - XMLRPC_STRUCTSIZE(xmlrpc_server_abyss_handler_parms, MBRNAME) - -/* XMLRPC_AHPSIZE(xyz) is the minimum size a struct - xmlrpc_server_abyss_handler_parms must be to include the 'xyz' member. - This is essential to forward and backward compatibility, 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. -*/ - - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_set_handler3( - xmlrpc_env * const envP, - TServer * const srvP, - const xmlrpc_server_abyss_handler_parms * const parms, - unsigned int const parmSize); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_set_handler2( - TServer * const srvP, - const char * const uriPath, - xmlrpc_call_processor xmlProcessor, - void * const xmlProcessorArg, - size_t const xmlProcessorMaxStackSize, - xmlrpc_bool const chunkResponse); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_set_handlers2(TServer * const srvP, - const char * const filename, - xmlrpc_registry * const registryP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_set_handlers(TServer * const serverP, - xmlrpc_registry * const registryP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_set_handler(xmlrpc_env * const envP, - TServer * const serverP, - const char * const filename, - xmlrpc_registry * const registryP); - -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_set_default_handler(TServer * const serverP); - -/*========================================================================= -** 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. -*/ -XMLRPC_SERVER_ABYSS_EXPORTED -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. -**/ -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_run_first(runfirstFn const runfirst, - 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(). -**/ -XMLRPC_SERVER_ABYSS_EXPORTED -void -xmlrpc_server_abyss_init(int const flags, - const char * const config_file); - -/* This is called automatically by xmlrpc_server_abyss_init. */ -XMLRPC_SERVER_ABYSS_EXPORTED -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. -*/ -XMLRPC_SERVER_ABYSS_EXPORTED -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. */ -XMLRPC_SERVER_ABYSS_EXPORTED -void xmlrpc_server_abyss_add_method (char * const method_name, - xmlrpc_method const method, - void * const user_data); - -/* As above, but provide documentation (see xmlrpc_registry_add_method_w_doc -** for more information). You should really use this one. */ -XMLRPC_SERVER_ABYSS_EXPORTED -extern void -xmlrpc_server_abyss_add_method_w_doc (char * const method_name, - xmlrpc_method const method, - void * const user_data, - char * const signature, - char * const help); - -/*========================================================================= -** 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 diff --git a/trunk/include/xmlrpc-c/server_abyss.hpp b/trunk/include/xmlrpc-c/server_abyss.hpp deleted file mode 100644 index 6171f807f..000000000 --- a/trunk/include/xmlrpc-c/server_abyss.hpp +++ /dev/null @@ -1,196 +0,0 @@ -/*============================================================================ - server_abyss.hpp -============================================================================== - This declares the user interface to libxmlrpc_server_abyss++, which - provides facilities for running a C++ XML-RPC server based on the Xmlrpc-c - Abyss HTTP server. - - Nothing may include this header file that also includes , - because it conflicts with this file's use of . Furthermore, - nothing including this file may include without previously - defining WIN32_LEAN_AND_MEAN, because without that macro - includes automatically. -============================================================================*/ -#ifndef SERVER_ABYSS_HPP_INCLUDED -#define SERVER_ABYSS_HPP_INCLUDED - -#ifdef _WIN32 - /* See restrictions above on including and */ -# include // For XMLRPC_SOCKET (= SOCKET) -# include -#endif - -#include // For XMLRPC_SOCKET -#include -#include -#include -#include - -/* - XMLRPC_SERVER_ABYSSPP_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_server_abyss++. - - XMLRPC_BUILDING_SERVER_ABYSSPP says this compilation is part of - libxmlrpc_server_abyss++, as opposed to something that _uses_ - libxmlrpc_server_abyss++. -*/ -#ifdef XMLRPC_BUILDING_SERVER_ABYSSPP -#define XMLRPC_SERVER_ABYSSPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_SERVER_ABYSSPP_EXPORTED -#endif - -namespace xmlrpc_c { - -struct serverAbyss_impl; - -class XMLRPC_SERVER_ABYSSPP_EXPORTED serverAbyss { - -public: - struct constrOpt_impl; - - class XMLRPC_SERVER_ABYSSPP_EXPORTED constrOpt { - public: - constrOpt(); - ~constrOpt(); - - constrOpt & registryPtr (xmlrpc_c::registryPtr const& arg); - constrOpt & registryP (const xmlrpc_c::registry * const& arg); - constrOpt & socketFd (XMLRPC_SOCKET const& arg); - constrOpt & portNumber (unsigned int const& arg); - constrOpt & maxConn (unsigned int const& arg); - constrOpt & maxConnBacklog (unsigned int const& arg); - constrOpt & maxRpcMem (size_t const& arg); - constrOpt & keepaliveTimeout (unsigned int const& arg); - constrOpt & keepaliveMaxConn (unsigned int const& arg); - constrOpt & timeout (unsigned int const& arg); - constrOpt & dontAdvertise (bool const& arg); - constrOpt & uriPath (std::string const& arg); - constrOpt & chunkResponse (bool const& arg); - constrOpt & allowOrigin (std::string const& arg); - constrOpt & accessCtlMaxAge (unsigned int const& arg); - constrOpt & sockAddrP (const struct sockaddr * const& arg); - constrOpt & sockAddrLen (socklen_t const& arg); - constrOpt & logFileName (std::string const& arg); - constrOpt & serverOwnsSignals (bool const& arg); - constrOpt & expectSigchld (bool const& arg); - - private: - struct constrOpt_impl * implP; - friend class serverAbyss; - }; - - serverAbyss(constrOpt const& opt); - - 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, - bool const socketBound = false, - XMLRPC_SOCKET const socketFd = 0 - ); - ~serverAbyss(); - - void - getListenName(struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP); - - void - run(); - - void - runOnce(); - - void - runConn(int const socketFd); - -#ifndef _WIN32 - void - sigchld(pid_t pid); -#endif - - void - terminate(); - - class XMLRPC_SERVER_ABYSSPP_EXPORTED shutdown : - public xmlrpc_c::registry::shutdown { - public: - shutdown(xmlrpc_c::serverAbyss * const severAbyssP); - virtual ~shutdown(); - void doit(std::string const& comment, void * const callInfo) const; - private: - xmlrpc_c::serverAbyss * const serverAbyssP; - }; - -private: - - serverAbyss_impl * implP; - - void - initialize(constrOpt const& opt); -}; - -class XMLRPC_SERVER_ABYSSPP_EXPORTED callInfo_serverAbyss : - public xmlrpc_c::callInfo { -/*---------------------------------------------------------------------------- - This is information about how an XML-RPC call arrived via an Abyss server. - It is available to the user's XML-RPC method execute() method, so for - example an XML-RPC method might execute differently depending upon the - IP address of the client. - - This is for a user of a xmlrpc_c::serverAbyss server. ------------------------------------------------------------------------------*/ -public: - callInfo_serverAbyss(xmlrpc_c::serverAbyss * const abyssServerP, - TSession * const abyssSessionP); - - xmlrpc_c::serverAbyss * const serverAbyssP; - // The server that is processing the RPC. - TSession * const abyssSessionP; - // The HTTP transaction that embodies the RPC. You can ask this - // object things like what the IP address of the client is. -}; - -class XMLRPC_SERVER_ABYSSPP_EXPORTED callInfo_abyss : public xmlrpc_c::callInfo { -/*---------------------------------------------------------------------------- - This is information about how an XML-RPC call arrived via an Abyss server. - It is available to the user's XML-RPC method execute() method, so for - example an XML-RPC method might execute differently depending upon the - IP address of the client. - - This is for a user with his own Abyss server, using - the "set_handlers" routines to make it into an XML-RPC server. ------------------------------------------------------------------------------*/ -public: - callInfo_abyss(TSession * const abyssSessionP); - - TSession * abyssSessionP; - // The HTTP transaction that embodies the RPC. You can ask this - // object things like what the IP address of the client is. -}; - -XMLRPC_SERVER_ABYSSPP_EXPORTED -void -server_abyss_set_handlers(TServer * const srvP, - xmlrpc_c::registry const& registry, - std::string const& uriPath = "/RPC2"); - -XMLRPC_SERVER_ABYSSPP_EXPORTED -void -server_abyss_set_handlers(TServer * const srvP, - const xmlrpc_c::registry * const registryP, - std::string const& uriPath = "/RPC2"); - -XMLRPC_SERVER_ABYSSPP_EXPORTED -void -server_abyss_set_handlers(TServer * const srvP, - xmlrpc_c::registryPtr const registryPtr, - std::string const& uriPath = "/RPC2"); - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/server_cgi.h b/trunk/include/xmlrpc-c/server_cgi.h deleted file mode 100644 index bdf2965ee..000000000 --- a/trunk/include/xmlrpc-c/server_cgi.h +++ /dev/null @@ -1,70 +0,0 @@ -/* 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 /* For XMLRPC_DLLEXPORT */ -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - XMLRPC_SERVER_CGI_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_server_cgi. - - XMLRPC_BUILDING_SERVER_CGI says this compilation is part of - libxmlrpc_server_cgi, as opposed to something that _uses_ - libxmlrpc_server_cgi. -*/ -#ifdef XMLRPC_BUILDING_SERVER_CGI -#define XMLRPC_SERVER_CGI_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_SERVER_CGI_EXPORTED -#endif - -XMLRPC_SERVER_CGI_EXPORTED -void -xmlrpc_server_cgi_process_call(xmlrpc_registry * const registryP); - -#define XMLRPC_CGI_NO_FLAGS (0) - -XMLRPC_SERVER_CGI_EXPORTED -extern void -xmlrpc_cgi_init(int const flags); - -XMLRPC_SERVER_CGI_EXPORTED -extern xmlrpc_registry * -xmlrpc_cgi_registry (void); - -XMLRPC_SERVER_CGI_EXPORTED -void -xmlrpc_cgi_add_method(const char * const method_name, - xmlrpc_method const method, - void * const user_data); - -XMLRPC_SERVER_CGI_EXPORTED -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); -XMLRPC_SERVER_CGI_EXPORTED -extern void -xmlrpc_cgi_process_call (void); - -XMLRPC_SERVER_CGI_EXPORTED -extern void -xmlrpc_cgi_cleanup (void); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif diff --git a/trunk/include/xmlrpc-c/server_cgi.hpp b/trunk/include/xmlrpc-c/server_cgi.hpp deleted file mode 100644 index 04b5e6a24..000000000 --- a/trunk/include/xmlrpc-c/server_cgi.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef SERVER_CGI_HPP_INCLUDED -#define SERVER_CGI_HPP_INCLUDED - -#include -#include - -namespace xmlrpc_c { - -/* - XMLRPC_SERVER_CGIPP_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_server_cgi++. - - XMLRPC_BUILDING_SERVER_CGIPP says this compilation is part of - libxmlrpc_server_cgi++, as opposed to something that _uses_ - libxmlrpc_server_cgi++. -*/ -#ifdef XMLRPC_BUILDING_SERVER_CGIPP -#define XMLRPC_SERVER_CGIPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_SERVER_CGIPP_EXPORTED -#endif - -class XMLRPC_SERVER_CGIPP_EXPORTED serverCgi { - -public: - - class XMLRPC_SERVER_CGIPP_EXPORTED constrOpt { - public: - constrOpt(); - - constrOpt & registryPtr (xmlrpc_c::registryPtr const& arg); - constrOpt & registryP (const xmlrpc_c::registry * const& arg); - - struct value { - xmlrpc_c::registryPtr registryPtr; - const xmlrpc_c::registry * registryP; - } value; - struct { - bool registryPtr; - bool registryP; - } present; - }; - - serverCgi(constrOpt const& opt); - - ~serverCgi(); - - void - processCall(); - -private: - - struct serverCgi_impl * implP; -}; - - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/server_pstream.hpp b/trunk/include/xmlrpc-c/server_pstream.hpp deleted file mode 100644 index f675ca5d0..000000000 --- a/trunk/include/xmlrpc-c/server_pstream.hpp +++ /dev/null @@ -1,193 +0,0 @@ -/*============================================================================ - server_pstream.hpp -============================================================================== - This declares the user interface to libxmlrpc_server_pstream, which - provides facilities for running a pseudo-XML-RPC server based on - Xmlrpc-c packet stream sockets (i.e. no HTTP). - - Nothing may include this header file that also includes , - because it conflicts with this file's use of . Furthermore, - nothing including this file may include without previously - defining WIN32_LEAN_AND_MEAN, because without that macro - includes automatically. -============================================================================*/ -#ifndef SERVER_PSTREAM_HPP_INCLUDED -#define SERVER_PSTREAM_HPP_INCLUDED - -#ifdef _WIN32 - /* See restrictions above on including and */ -# include /* For XMLRPC_SOCKET (= SOCKET) */ -# include -#else -#include -#endif - -#include /* For XMLRPC_SOCKET */ -#include -#include -#include - -/* - XMLRPC_SERVER_PSTREAMPP_EXPORTED marks a symbol in this file that is - exported from libxmlrpc_server_pstream++. - - XMLRPC_BUILDING_SERVER_PSTREAMPP says this compilation is part of - libxmlrpc_server_pstream++, as opposed to something that _uses_ - libxmlrpc_server_pstream++. -*/ -#ifdef XMLRPC_BUILDING_SERVER_PSTREAMPP -#define XMLRPC_SERVER_PSTREAMPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_SERVER_PSTREAMPP_EXPORTED -#endif - -namespace xmlrpc_c { - -class XMLRPC_SERVER_PSTREAMPP_EXPORTED serverPstreamConn { - -public: - - struct constrOpt_impl; - - class XMLRPC_SERVER_PSTREAMPP_EXPORTED constrOpt { - public: - constrOpt(); - ~constrOpt(); - - constrOpt & registryPtr (xmlrpc_c::registryPtr const& arg); - constrOpt & registryP (const xmlrpc_c::registry * const& arg); - constrOpt & socketFd (XMLRPC_SOCKET const& arg); - - private: - struct constrOpt_impl * implP; - friend class serverPstreamConn; - }; - - serverPstreamConn(constrOpt const& opt); - - ~serverPstreamConn(); - - void - runOnce(xmlrpc_c::callInfo * const callInfoP, - volatile const int * const interruptP, - bool * const eofP); - - void - runOnce(volatile const int * const interruptP, - bool * const eofP); - - void - runOnce(bool * const eofP); - - void - runOnceNoWait(callInfo * const callInfoP, - bool * const eofP, - bool * const didOneP); - - void - runOnceNoWait(bool * const eofP, - bool * const didOneP); - - void - runOnceNoWait(bool * const eofP); - - void - run(xmlrpc_c::callInfo * const callInfoP, - volatile const int * const interruptP); - - void - run(volatile const int * const interruptP); - - void - run(); - -private: - struct serverPstreamConn_impl * implP; -}; - - -class XMLRPC_SERVER_PSTREAMPP_EXPORTED serverPstream { - -public: - - struct constrOpt_impl; - - class XMLRPC_SERVER_PSTREAMPP_EXPORTED constrOpt { - public: - constrOpt(); - ~constrOpt(); - - constrOpt & registryPtr (xmlrpc_c::registryPtr const& arg); - constrOpt & registryP (const xmlrpc_c::registry * const& arg); - constrOpt & socketFd (XMLRPC_SOCKET const& arg); - - private: - struct constrOpt_impl * implP; - friend class serverPstream; - }; - - serverPstream(constrOpt const& opt); - - virtual ~serverPstream(); // This makes it polymorphic - - void - runSerial(volatile const int * const interruptP); - - void - runSerial(); - - void - terminate(); - - class shutdown : public xmlrpc_c::registry::shutdown { - public: - shutdown(xmlrpc_c::serverPstream * const severAbyssP); - virtual ~shutdown(); - void doit(std::string const& comment, void * const callInfo) const; - private: - xmlrpc_c::serverPstream * const serverPstreamP; - }; - -private: - struct serverPstream_impl * implP; -}; - -// Note: there is no xmlrpc_c::callInfo_serverPstreamConn . That's -// because the serverPstreamConn server is so low-level that the user -// defines his own derived class of xmlrpc_c::callInfo. He creates an -// object of that class and passes it to the 'runOnce' method. The -// server then passes it on through to the user's XML-RPC method -// execute() method. - -class XMLRPC_SERVER_PSTREAMPP_EXPORTED callInfo_serverPstream : - public xmlrpc_c::callInfo { -/*---------------------------------------------------------------------------- - This is information about how an XML-RPC call arrived to the server. It is - available to the user's XML-RPC method execute() method, so for example an - XML-RPC method might execute differently depending upon the IP address of - the client. - - This is for a user of a xmlrpc_c::serverPstream server. ------------------------------------------------------------------------------*/ -public: - callInfo_serverPstream( - xmlrpc_c::serverPstream * const serverP, - struct sockaddr const clientAddr, - socklen_t const clientAddrSize); - - xmlrpc_c::serverPstream * const serverP; - // The server that is processing the RPC. - struct sockaddr const clientAddr; - // The address (typically, IP address and TCP port) of the XML-RPC - // client. This is a Unix OS type. - socklen_t const clientAddrSize; - // Size in bytes of the valid part of 'clientAddr'. (Usually implied - // by type of socket, as well as the address type member of - // 'clientAddr', but here because it's technically part of the POSIX - // socket interface). -}; - - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/server_w32httpsys.h b/trunk/include/xmlrpc-c/server_w32httpsys.h deleted file mode 100644 index 508b47097..000000000 --- a/trunk/include/xmlrpc-c/server_w32httpsys.h +++ /dev/null @@ -1,111 +0,0 @@ -/* 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 "xmlrpc-c/c_util.h" /* For XMLRPC_DLLEXPORT */ -#include "transport_config.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - XMLRPC_SERVER_HTTPSYS_EXPORTED marks a symbol in this file that is exported - from libxmlrpc_server_httpsys. - - XMLRPC_BUILDING_SERVER_HTTPSYS says this compilation is part of - libxmlrpc_server_httpsys, as opposed to something that _uses_ - libxmlrpc_server_httpsys. -*/ -#ifdef XMLRPC_BUILDING_SERVER_HTTPSYS -#define XMLRPC_SERVER_HTTPSYS_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_SERVER_HTTPSYS_EXPORTED -#endif - -/*========================================================================= -** 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. -*/ - -XMLRPC_SERVER_HTTPSYS_EXPORTED -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 diff --git a/trunk/include/xmlrpc-c/sleep_int.h b/trunk/include/xmlrpc-c/sleep_int.h deleted file mode 100644 index dd3376289..000000000 --- a/trunk/include/xmlrpc-c/sleep_int.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef SLEEP_INT_H_INCLUDED -#define SLEEP_INT_H_INCLUDED - -#include "xmlrpc-c/c_util.h" /* For XMLRPC_DLLEXPORT */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_millisecond_sleep(unsigned int const milliseconds); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/string_int.h b/trunk/include/xmlrpc-c/string_int.h deleted file mode 100644 index 8d27f663d..000000000 --- a/trunk/include/xmlrpc-c/string_int.h +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef XMLRPC_C_STRING_INT_H_INCLUDED -#define XMLRPC_C_STRING_INT_H_INCLUDED - - -#include -#include - -#include "xmlrpc_config.h" -#include "xmlrpc-c/c_util.h" -#include "bool.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -XMLRPC_UTIL_EXPORTED -bool -xmlrpc_strnomem(const char * const string); - -XMLRPC_UTIL_EXPORTED -const char * -xmlrpc_strnomemval(void); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_vasprintf(const char ** const retvalP, - const char * const fmt, - va_list varargs); - -XMLRPC_UTIL_EXPORTED -void XMLRPC_PRINTF_ATTR(2,3) -xmlrpc_asprintf(const char ** const retvalP, const char * const fmt, ...); - -XMLRPC_UTIL_EXPORTED -const char * -xmlrpc_strdupsol(const char * const string); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_strfree(const char * const string); - -XMLRPC_UTIL_EXPORTED -const char * -xmlrpc_strdupnull(const char * const string); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_strfreenull(const char * const string); - -static __inline__ bool -xmlrpc_streq(const char * const a, - const char * const b) { - return (strcmp(a, b) == 0); -} - -static __inline__ bool -xmlrpc_memeq(const void * const a, - const void * const b, - size_t const size) { - - return (memcmp(a, b, size) == 0); -} - -/* strcasecmp doesn't exist on some systems without _BSD_SOURCE, so - xmlrpc_strcaseeq() can't either. -*/ -#ifdef _BSD_SOURCE - -static __inline__ bool -xmlrpc_strcaseeq(const char * const a, - const char * const b) { -#if HAVE_STRCASECMP - return (strcasecmp(a, b) == 0); -#elif HAVE__STRICMP - return (_stricmp(a, b) == 0); -#elif HAVE_STRICMP - return (stricmp(a, b) == 0); -#else - #error "This platform has no known case-independent string compare fn" -#endif -} -#endif - -static __inline__ bool -xmlrpc_strneq(const char * const a, - const char * const b, - size_t const len) { - return (strncmp(a, b, len) == 0); -} - -XMLRPC_UTIL_EXPORTED -const char * -xmlrpc_makePrintable(const char * const input); - -XMLRPC_UTIL_EXPORTED -const char * -xmlrpc_makePrintable_lp(const char * const input, - size_t const inputLength); - -XMLRPC_UTIL_EXPORTED -const char * -xmlrpc_makePrintableChar(char const input); - -/*----------------------------------------------------------------*/ -/* Standard string functions with destination array size checking */ -/*----------------------------------------------------------------*/ -#define STRSCPY(A,B) \ - (strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0') -#define STRSCMP(A,B) \ - (strncmp((A), (B), sizeof(A))) -#define STRSCAT(A,B) \ - (strncat((A), (B), sizeof(A)-strlen(A)-1)) - -#define MEMSSET(a,b) (memset(a, b, sizeof(*a))) - -#define MEMSCPY(a,b) (memcpy(a, b, sizeof(*a))) - -#define MEMSZERO(a) (MEMSSET(a, 0)) - -/* We could do this, but it works only in GNU C -#define SSPRINTF(TARGET, REST...) \ - (snprintf(TARGET, sizeof(TARGET) , ## REST)) - -Or this, but it works only in C99 compilers, which leaves out MSVC -before 2005 and can't handle the zero variable argument case except -by an MSVC extension: - -#define SSPRINTF(TARGET, ...) \ - (snprintf(TARGET, sizeof(TARGET) , __VA_ARGS__)) - -*/ -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/string_number.h b/trunk/include/xmlrpc-c/string_number.h deleted file mode 100644 index 2e62809df..000000000 --- a/trunk/include/xmlrpc-c/string_number.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef STRING_NUMBER_H_INCLUDED -#define STRING_NUMBER_H_INCLUDED - -#include -#include /* For XMLRPC_DLLEXPORT */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_parse_int64(xmlrpc_env * const envP, - const char * const str, - xmlrpc_int64 * const i64P); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/time_int.h b/trunk/include/xmlrpc-c/time_int.h deleted file mode 100644 index 2e5e6f85d..000000000 --- a/trunk/include/xmlrpc-c/time_int.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef TIME_H_INCLUDED -#define TIME_H_INCLUDED - -#include - -#include "xmlrpc_config.h" -#include "xmlrpc-c/c_util.h" /* For XMLRPC_DLLEXPORT */ -#include "xmlrpc-c/util.h" -#include "int.h" - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -#if HAVE_TIMESPEC - # include /* for struct timespec */ - typedef struct timespec xmlrpc_timespec; -#else - typedef struct { - uint32_t tv_sec; - uint32_t tv_nsec; - } xmlrpc_timespec; -#endif - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_gettimeofday(xmlrpc_timespec * const todP); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_timegm(const struct tm * const brokenTime, - time_t * const timeValueP, - const char ** const errorP); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_localtime(time_t const datetime, - struct tm * const tmP); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_gmtime(time_t const datetime, - struct tm * const resultP); - -#endif diff --git a/trunk/include/xmlrpc-c/timeout.hpp b/trunk/include/xmlrpc-c/timeout.hpp deleted file mode 100644 index 2802bdb9f..000000000 --- a/trunk/include/xmlrpc-c/timeout.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef XMLRPC_TIMEOUT_H_INCLUDED -#define XMLRPC_TIMEOUT_H_INCLUDED - -#include - -/* - XMLRPC_LIBPP_EXPORTED marks a symbol in this file that is exported from - libxmlrpc++. - - XMLRPC_BUILDING_LIBPP says this compilation is part of libxmlrpc++, as - opposed to something that _uses_ libxmlrpc++. -*/ -#ifdef XMLRPC_BUILDING_LIBPP -#define XMLRPC_LIBPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_LIBPP_EXPORTED -#endif - -namespace xmlrpc_c { - -struct XMLRPC_LIBPP_EXPORTED timeout { - - timeout() : finite(false) {} - - timeout(unsigned int const duration) : - finite(true), duration(duration) {} - // 'duration' is the timeout time in milliseconds - - bool finite; - unsigned int duration; // in milliseconds -}; - - -} // namespace - -#endif diff --git a/trunk/include/xmlrpc-c/transport.h b/trunk/include/xmlrpc-c/transport.h deleted file mode 100644 index 0da23b55f..000000000 --- a/trunk/include/xmlrpc-c/transport.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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 -#include - -struct xmlrpc_call_info; - -struct xmlrpc_client_transport; - -/*========================================================================= -** Transport function type declarations. -**========================================================================= -*/ -typedef void (*xmlrpc_transport_setup)(xmlrpc_env * const envP); - -typedef void (*xmlrpc_transport_teardown)(void); - -typedef void (*xmlrpc_transport_create)( - xmlrpc_env * const envP, - int const flags, - const char * const appname, - const char * const appversion, - const void * 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_progress)( - struct xmlrpc_call_info * const callInfoP, - struct xmlrpc_progress_data const data); - -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, - xmlrpc_transport_progress progress, - 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); - -typedef void (*xmlrpc_transport_set_interrupt)( - struct xmlrpc_client_transport * const clientTransportP, - int * const interruptP); - -struct xmlrpc_client_transport_ops { - - xmlrpc_transport_setup setup_global_const; - xmlrpc_transport_teardown teardown_global_const; - xmlrpc_transport_create create; - xmlrpc_transport_destroy destroy; - xmlrpc_transport_send_request send_request; - xmlrpc_transport_call call; - xmlrpc_transport_finish_asynch finish_asynch; - xmlrpc_transport_set_interrupt set_interrupt; -}; - -extern int xmlrpc_trace_transport; - // This is nonzero to indicate that client XML transport logic should - // be traced. - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/util.h b/trunk/include/xmlrpc-c/util.h deleted file mode 100644 index cb04baa72..000000000 --- a/trunk/include/xmlrpc-c/util.h +++ /dev/null @@ -1,381 +0,0 @@ -/*============================================================================= - xmlrpc-c/util.h -=============================================================================== - - This is the interface to the libxmlrpc_util library, which contains - utility routines that have nothing to do with XML-RPC. The library - exists primarily because other Xmlrpc-c libraries use the utilities, - but the utilities are also documented for use by Xmlrpc-c users. - For use by Xmlrpc-c users, they are considered to be part of the - libxmlrpc library. libxmlrpc_util is a prerequisite of libxmlrpc. - - By Bryan Henderson, San Jose, CA 05.09.21. - - Contributed to the public domain by its author. -=============================================================================*/ - -#ifndef XMLRPC_C_UTIL_H_INCLUDED -#define XMLRPC_C_UTIL_H_INCLUDED - -#include -#include - -#include /* Defines XMLRPC_HAVE_WCHAR */ -#include /* for XMLRPC_PRINTF_ATTR, _DLLEXPORT */ - -#if XMLRPC_HAVE_WCHAR -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -/*========================================================================= -** 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) \ - ((size_t)(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) while (0) {} -#endif - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_assertion_failed(const char * const fileName, - int const lineNumber); - -/* Validate a pointer. */ -#define XMLRPC_ASSERT_PTR_OK(ptr) \ - XMLRPC_ASSERT((ptr) != NULL) - - -/*========================================================================= -** xmlrpc_env -**========================================================================= -** XML-RPC represents runtime errors as elements. These contain -** and elements. -** -** Since we need as much thread-safety as possible, we borrow an idea from -** CORBA--we store exception information in an "environment" object. -** You'll pass this to many different functions, and it will get filled -** out appropriately. -** -** For example: -** -** xmlrpc_env env; -** -** xmlrpc_env_init(&env); -** -** xmlrpc_do_something(&env); -** if (env.fault_occurred) -** report_error_appropriately(); -** -** xmlrpc_env_clean(&env); -*/ - -#define XMLRPC_INTERNAL_ERROR (-500) -#define XMLRPC_TYPE_ERROR (-501) -#define XMLRPC_INDEX_ERROR (-502) -#define XMLRPC_PARSE_ERROR (-503) -#define XMLRPC_NETWORK_ERROR (-504) -#define XMLRPC_TIMEOUT_ERROR (-505) -#define XMLRPC_NO_SUCH_METHOD_ERROR (-506) -#define XMLRPC_REQUEST_REFUSED_ERROR (-507) -#define XMLRPC_INTROSPECTION_DISABLED_ERROR (-508) -#define XMLRPC_LIMIT_EXCEEDED_ERROR (-509) -#define XMLRPC_INVALID_UTF8_ERROR (-510) - -typedef struct _xmlrpc_env { - int fault_occurred; - int fault_code; - char * fault_string; -} xmlrpc_env; - -/* Initialize and destroy the contents of the provided xmlrpc_env object. -** These functions will never fail. */ -XMLRPC_UTIL_EXPORTED -void xmlrpc_env_init (xmlrpc_env* env); -XMLRPC_UTIL_EXPORTED -void xmlrpc_env_clean (xmlrpc_env* const 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. */ -XMLRPC_UTIL_EXPORTED -void -xmlrpc_env_set_fault(xmlrpc_env * const env, - int const faultCode, - const char * const faultDescription); - -/* The same as the above, but using varargs */ -XMLRPC_UTIL_EXPORTED -void -xmlrpc_set_fault_formatted_v(xmlrpc_env * const envP, - int const code, - const char * const format, - va_list args); - -/* The same as the above, but using a printf-style format string. */ -XMLRPC_UTIL_EXPORTED -void -xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP, - int const code, - const char * const format, - ...) XMLRPC_PRINTF_ATTR(3,4); - -/* This one infers XMLRPC_INTERNAL_ERROR and has a shorter name. - So a call takes up less source code space. -*/ -XMLRPC_UTIL_EXPORTED -void -xmlrpc_faultf(xmlrpc_env * const envP, - const char * const format, - ...) XMLRPC_PRINTF_ATTR(2,3); - -/* A simple debugging assertion. */ -#define XMLRPC_ASSERT_ENV_OK(envP) \ - XMLRPC_ASSERT((envP) != NULL && \ - (envP->fault_string == NULL) && \ - !(envP)->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) - -#if !defined(__cplusplus) -#if defined(__GNUC__) -#define XMLRPC_FAILF( env, code, fmt, ... ) \ - do { \ - xmlrpc_env_set_fault_formatted((env), (code), (fmt), \ - ##__VA_ARGS__ ); \ - goto cleanup; \ - } while (0) -#endif -#endif - -#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) - - -/*========================================================================= - 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. -=========================================================================*/ - -typedef struct _xmlrpc_mem_block xmlrpc_mem_block; - -/* Allocate a new xmlrpc_mem_block. */ -XMLRPC_UTIL_EXPORTED -xmlrpc_mem_block* xmlrpc_mem_block_new (xmlrpc_env* const env, size_t const size); - -/* Destroy an existing xmlrpc_mem_block, and everything it contains. */ -XMLRPC_UTIL_EXPORTED -void xmlrpc_mem_block_free (xmlrpc_mem_block* const block); - -/* Initialize the contents of the provided xmlrpc_mem_block. */ -XMLRPC_UTIL_EXPORTED -void xmlrpc_mem_block_init - (xmlrpc_env* const env, xmlrpc_mem_block* const block, size_t const size); - -/* Deallocate the contents of the provided xmlrpc_mem_block, but not the -** block itself. */ -XMLRPC_UTIL_EXPORTED -void xmlrpc_mem_block_clean (xmlrpc_mem_block* const block); - -/* Get the size and contents of the xmlrpc_mem_block. */ -XMLRPC_UTIL_EXPORTED -size_t -xmlrpc_mem_block_size(const xmlrpc_mem_block * const block); - -XMLRPC_UTIL_EXPORTED -void * -xmlrpc_mem_block_contents(const xmlrpc_mem_block * const block); - -/* Resize an xmlrpc_mem_block, preserving as much of the contents as -** possible. */ -XMLRPC_UTIL_EXPORTED -void xmlrpc_mem_block_resize - (xmlrpc_env* const env, xmlrpc_mem_block* const block, size_t const size); - -/* Append data to an existing xmlrpc_mem_block. */ -XMLRPC_UTIL_EXPORTED -void xmlrpc_mem_block_append - (xmlrpc_env* const env, xmlrpc_mem_block* const block, const void * const data, size_t const len); - -#define XMLRPC_MEMBLOCK_NEW(type,env,size) \ - xmlrpc_mem_block_new((env), sizeof(type) * (size)) -#define XMLRPC_MEMBLOCK_FREE(type,block) \ - xmlrpc_mem_block_free(block) -#define XMLRPC_MEMBLOCK_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_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) - - -/*========================================================================= -** UTF-8 Encoding and Decoding -**=======================================================================*/ - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_validate_utf8(xmlrpc_env * const envP, - const char * const utf8Data, - size_t const utf8Len); - -/* Decode a UTF-8 string. */ -XMLRPC_UTIL_EXPORTED -xmlrpc_mem_block * -xmlrpc_utf8_to_wcs(xmlrpc_env * const envP, - const char * const utf8_data, - size_t const utf8_len); - -/* Encode a UTF-8 string. */ - -#if XMLRPC_HAVE_WCHAR -XMLRPC_UTIL_EXPORTED -xmlrpc_mem_block * -xmlrpc_wcs_to_utf8(xmlrpc_env * const envP, - const wchar_t * const wcsData, - size_t const wcsLen); -#endif - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_force_to_utf8(char * const buffer); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_force_to_xml_chars(char * const buffer); - -/*========================================================================= -** 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_UTIL_EXPORTED -xmlrpc_mem_block * -xmlrpc_base64_encode(xmlrpc_env * const envP, - const unsigned char * const binData, - size_t const binLen); - -/* This routine encodes everything in one line. This is needed for HTTP -** authentication and similar tasks. */ -XMLRPC_UTIL_EXPORTED -xmlrpc_mem_block * -xmlrpc_base64_encode_without_newlines(xmlrpc_env * const envP, - const unsigned char * const binData, - size_t const binLen); - -/* This decodes Base64 data with or without newlines. */ -XMLRPC_UTIL_EXPORTED -extern xmlrpc_mem_block * -xmlrpc_base64_decode(xmlrpc_env * const envP, - const char * const asciiData, - size_t const asciiLen); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/util_int.h b/trunk/include/xmlrpc-c/util_int.h deleted file mode 100644 index ce7d69da9..000000000 --- a/trunk/include/xmlrpc-c/util_int.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef XMLRPC_C_UTIL_INT_H_INCLUDED -#define XMLRPC_C_UTIL_INT_H_INCLUDED - -/* This file contains facilities for use by Xmlrpc-c code, but not intended - to be included in a user compilation. - - Names in here might conflict with other names in a user's compilation - if included in a user compilation. - - The facilities may change in future releases. -*/ - -#include "util.h" - -/* - XMLRPC_UTIL_EXPORTED marks a symbol in this file that is exported from - libxmlrpc_util. - - XMLRPC_BUILDING_UTIL says this compilation is part of libxmlrpc_util, as - opposed to something that _uses_ libxmlrpc_util. -*/ -#ifdef XMLRPC_BUILDING_UTIL -#define XMLRPC_UTIL_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_UTIL_EXPORTED -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -/* 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) - -/*============================================================================ - xmlrpc_mem_pool - - A memory pool from which you can allocate xmlrpc_mem_block's. - - This is a mechanism for limiting memory allocation. - - Since the xmlrpc_mem_block type is part of the API, we may want to make - xmlrpc_mem_pool external some day. For now, any xmlrpc_mem_block created - outside of Xmlrpc-c code goes in the default pool. -============================================================================*/ - -typedef struct _xmlrpc_mem_pool xmlrpc_mem_pool; - -XMLRPC_UTIL_EXPORTED -xmlrpc_mem_pool * -xmlrpc_mem_pool_new(xmlrpc_env * const envP, - size_t const size); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_mem_pool_free(xmlrpc_mem_pool * const poolP); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_mem_pool_alloc(xmlrpc_env * const envP, - xmlrpc_mem_pool * const poolP, - size_t const size); - -XMLRPC_UTIL_EXPORTED -void -xmlrpc_mem_pool_release(xmlrpc_mem_pool * const poolP, - size_t const size); - -XMLRPC_UTIL_EXPORTED -xmlrpc_mem_block * -xmlrpc_mem_block_new_pool(xmlrpc_env * const envP, - size_t const size, - xmlrpc_mem_pool * const poolP); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/include/xmlrpc-c/xml.hpp b/trunk/include/xmlrpc-c/xml.hpp deleted file mode 100644 index 9d88f3e32..000000000 --- a/trunk/include/xmlrpc-c/xml.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef XML_HPP_INCLUDED -#define XML_HPP_INCLUDED - -#include -#include -#include - -/* - XMLRPC_LIBPP_EXPORTED marks a symbol in this file that is exported from - libxmlrpc++. - - XMLRPC_BUILDING_LIBPP says this compilation is part of libxmlrpc++, as - opposed to something that _uses_ libxmlrpc++. -*/ -#ifdef XMLRPC_BUILDING_LIBPP -#define XMLRPC_LIBPP_EXPORTED XMLRPC_DLLEXPORT -#else -#define XMLRPC_LIBPP_EXPORTED -#endif - -namespace xmlrpc_c { -namespace xml { - -XMLRPC_LIBPP_EXPORTED -void -generateCall(std::string const& methodName, - xmlrpc_c::paramList const& paramList, - std::string * const callXmlP); - -XMLRPC_LIBPP_EXPORTED -void -generateCall(std::string const& methodName, - xmlrpc_c::paramList const& paramList, - xmlrpc_dialect const dialect, - std::string * const callXmlP); - -XMLRPC_LIBPP_EXPORTED -void -parseCall(std::string const& callXml, - std::string * const methodNameP, - xmlrpc_c::paramList * const paramListP); - -XMLRPC_LIBPP_EXPORTED -void -generateResponse(xmlrpc_c::rpcOutcome const& outcome, - xmlrpc_dialect const dialect, - std::string * const respXmlP); - -XMLRPC_LIBPP_EXPORTED -void -generateResponse(xmlrpc_c::rpcOutcome const& outcome, - std::string * const respXmlP); - -XMLRPC_LIBPP_EXPORTED -void -parseSuccessfulResponse(std::string const& responseXml, - xmlrpc_c::value * const resultP); - -XMLRPC_LIBPP_EXPORTED -void -parseResponse(std::string const& responseXml, - xmlrpc_c::rpcOutcome * const outcomeP); - -XMLRPC_LIBPP_EXPORTED -void -trace(std::string const& label, - std::string const& xml); - - -}} // namespace -#endif diff --git a/trunk/install-sh b/trunk/install-sh deleted file mode 100755 index e9de23842..000000000 --- a/trunk/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/trunk/irix-common.mk b/trunk/irix-common.mk deleted file mode 100644 index b0c936e8b..000000000 --- a/trunk/irix-common.mk +++ /dev/null @@ -1,31 +0,0 @@ -# -*-makefile-*- <-- an Emacs control - -# See unix-common.mk for an explanation of this file. This file is -# analogous to unix-common.mk, but is for an Irix system. - -SONAME = $(@:%.$(MAJ):%) - -SHLIB_CMD = $(CCLD) $(LADD) $(LDFLAGS_SHLIB) -o $@ $^ - -SHLIB_LE_TARGETS = $(call shliblefn, $(SHARED_LIBS_TO_BUILD)) - -$(SHLIB_LE_TARGETS):%:%.$(MAJ) - rm -f $@ - $(LN_S) $< $@ - - -.PHONY: $(SHLIB_INSTALL_TARGETS) -.PHONY: install-shared-libraries - -SHLIB_INSTALL_TARGETS = $(SHARED_LIBS_TO_INSTALL:%=%/install) - -#SHLIB_INSTALL_TARGETS is like "libfoo/install libbar/install" - -install-shared-libraries: $(SHLIB_INSTALL_TARGETS) - -$(SHLIB_INSTALL_TARGETS):%/install:%.$(SHLIB_SUFFIX).$(MAJ) -# $< is a library file name, e.g. libfoo.so.3.1 . - $(INSTALL_SHLIB) $< $(DESTDIR)$(LIBINST_DIR)/$< - cd $(DESTDIR)$(LIBINST_DIR); \ - rm -f $< $(<:%.$(MAJ)=%); \ - $(LN_S) $< $(<:%.$(MAJ)=%) diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile deleted file mode 100644 index c0e7889d6..000000000 --- a/trunk/lib/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - SRCDIR := $(call updir,$(CURDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib - -include $(BLDDIR)/config.mk - -# Build up SUBDIRS: -SUBDIRS = -SUBDIRS += util libutil -ifeq ($(ENABLE_CPLUSPLUS),yes) - SUBDIRS += libutil++ -endif -ifeq ($(ENABLE_ABYSS_SERVER),yes) - SUBDIRS += abyss - ifeq ($(ENABLE_CPLUSPLUS),yes) - SUBDIRS += abyss++ - endif -endif -ifeq ($(MUST_BUILD_WININET_CLIENT),yes) - SUBDIRS += wininet_transport -endif -ifeq ($(MUST_BUILD_CURL_CLIENT),yes) - SUBDIRS += curl_transport -endif -ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) - SUBDIRS += libwww_transport -endif -ifneq ($(ENABLE_LIBXML2_BACKEND),yes) - SUBDIRS += expat -endif - -ifeq ($(HAVE_OPENSSL),Y) - SUBDIRS += openssl -endif - -default: all - -.PHONY: all clean distclean tags distdir install check dep - -all: $(SUBDIRS:%=%/all) - -# Extra dependencies to make parallel make work in spite of all the submakes -# (See top level make file for details) -abyss/all curl_transport/all: $(BLDDIR)/version.h -abyss++/all: abyss/all -abyss/all expat/all libutil++/all: libutil/all - -clean: $(SUBDIRS:%=%/clean) clean-common - -distclean: $(SUBDIRS:%=%/distclean) distclean-common - -tags: $(SUBDIRS:%=%/tags) TAGS - -DISTFILES = - -distdir: distdir-common - -install: $(SUBDIRS:%=%/install) - -uninstall: $(SUBDIRS:%=%/uninstall) - -check: - -dep: $(SUBDIRS:%=%/dep) - -include $(SRCDIR)/common.mk - - - diff --git a/trunk/lib/abyss++/AbyssChanSwitch.cpp b/trunk/lib/abyss++/AbyssChanSwitch.cpp deleted file mode 100644 index e505a3a84..000000000 --- a/trunk/lib/abyss++/AbyssChanSwitch.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include - -using namespace std; - -#include "xmlrpc-c/abyss.h" - -#include "xmlrpc-c/AbyssChanSwitch.hpp" - - - -namespace xmlrpc_c { - - - -AbyssChanSwitch::AbyssChanSwitch() { - - this->_cChanSwitchP = NULL; -} - - - -AbyssChanSwitch::~AbyssChanSwitch() { - - if (this->_cChanSwitchP) - ChanSwitchDestroy(this->_cChanSwitchP); -} - - - -TChanSwitch * -AbyssChanSwitch::cChanSwitchP() const { - - return this->_cChanSwitchP; -} - - - -} // namespace diff --git a/trunk/lib/abyss++/AbyssChanSwitchOpenSsl.cpp b/trunk/lib/abyss++/AbyssChanSwitchOpenSsl.cpp deleted file mode 100644 index 7a5ef5900..000000000 --- a/trunk/lib/abyss++/AbyssChanSwitchOpenSsl.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include - -using namespace std; - -#ifdef _WIN32 - /* With _WIN32, does not declare - ChanSwitchOpenSslCreate */ - #error This module does not compile for a Windows target. -#endif - -#include -#include - -#include "xmlrpc-c/abyss.h" -#include "xmlrpc-c/abyss_openssl.h" - - -#include "xmlrpc-c/AbyssChanSwitchOpenSsl.hpp" - - - - -namespace xmlrpc_c { - - - -AbyssChanSwitchOpenSsl::AbyssChanSwitchOpenSsl( - int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - SSL_CTX * const sslCtxP) { - - const char * error; - - ChanSwitchOpenSslCreate(protocolFamily, sockAddrP, sockAddrLen, sslCtxP, - &this->_cChanSwitchP, &error); - - if (error) - throw runtime_error(error); -} - - - -AbyssChanSwitchOpenSsl::AbyssChanSwitchOpenSsl( - unsigned short const listenPortNum, - SSL_CTX * const sslCtxP) { - - const char * error; - - ChanSwitchOpenSslCreateIpV4Port(listenPortNum, sslCtxP, - &this->_cChanSwitchP, &error); - - if (error) - throw runtime_error(error); -} - - - -} // namespace diff --git a/trunk/lib/abyss++/AbyssChanSwitchUnix.cpp b/trunk/lib/abyss++/AbyssChanSwitchUnix.cpp deleted file mode 100644 index b16326106..000000000 --- a/trunk/lib/abyss++/AbyssChanSwitchUnix.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include - -using namespace std; - -#ifdef _WIN32 - /* With _WIN32, does not declare ChanSwitchUnixCreate */ - #error This module does not compile for a Windows target. -#endif - -#include "xmlrpc-c/abyss.h" - -#include "xmlrpc-c/AbyssChanSwitchUnix.hpp" - - - - -namespace xmlrpc_c { - - - -AbyssChanSwitchUnix::AbyssChanSwitchUnix(unsigned short const listenPortNum) { - - const char * error; - - ChanSwitchUnixCreate(listenPortNum, &this->_cChanSwitchP, &error); - - if (error) - throw runtime_error(error); -} - - - -} // namespace diff --git a/trunk/lib/abyss++/AbyssChanSwitchWin.cpp b/trunk/lib/abyss++/AbyssChanSwitchWin.cpp deleted file mode 100644 index eb5277fce..000000000 --- a/trunk/lib/abyss++/AbyssChanSwitchWin.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include - -using namespace std; - -#ifndef _WIN32 - /* Without _WIN32, does not declare ChanSwitchWinCreate */ - #error This module compiles only for a Windows target. -#endif - -#include "xmlrpc-c/abyss.h" - -#include "xmlrpc-c/AbyssChanSwitchWin.hpp" - - - - -namespace xmlrpc_c { - - - -AbyssChanSwitchWin::AbyssChanSwitchWin(unsigned short const listenPortNum) { - - const char * error; - - ChanSwitchWinCreate(listenPortNum, &this->_cChanSwitchP, &error); - - if (error) - throw runtime_error(error); -} - - - -} // namespace diff --git a/trunk/lib/abyss++/AbyssEnvironment.cpp b/trunk/lib/abyss++/AbyssEnvironment.cpp deleted file mode 100644 index e31a983ec..000000000 --- a/trunk/lib/abyss++/AbyssEnvironment.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include - -using namespace std; - -#include "xmlrpc-c/girerr.hpp" -using girerr::throwf; -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/abyss.h" - -#include "xmlrpc-c/AbyssEnvironment.hpp" - - - -namespace xmlrpc_c { - - - -AbyssEnvironment::AbyssEnvironment() { - - const char * error; - - AbyssInit(&error); - - if (error) { - string const errorStr(error); - - xmlrpc_strfree(error); - - throwf("AbyssInit() failed. %s", errorStr.c_str()); - } -} - - - -AbyssEnvironment::~AbyssEnvironment() { - - AbyssTerm(); -} - - - -} // namespace diff --git a/trunk/lib/abyss++/AbyssServer.cpp b/trunk/lib/abyss++/AbyssServer.cpp deleted file mode 100644 index d9383bb35..000000000 --- a/trunk/lib/abyss++/AbyssServer.cpp +++ /dev/null @@ -1,1035 +0,0 @@ -#include -#include -#include -#if defined(__GNUC__) && __GNUC__ < 3 -#include -#else -#include -#endif -#include -#include -#include - -using namespace std; - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/abyss.h" - -#include "xmlrpc-c/AbyssServer.hpp" - - - -namespace xmlrpc_c { - -AbyssServer::Exception::Exception(unsigned short const httpStatusCode, - string const& explanation) : - - runtime_error(explanation), - _httpStatusCode(httpStatusCode) -{} - - - -unsigned short -AbyssServer::Exception::httpStatusCode() const { - return this->_httpStatusCode; -} - - - -AbyssServer::ReqHandler::~ReqHandler() {} - - - -size_t -AbyssServer::ReqHandler::handleReqStackSize() const { - - return 0; // Means default -} - - - -void -AbyssServer::ReqHandler::terminate() {} - - - -} // namespace - -ostream& -operator<<(ostream & out, - xmlrpc_c::AbyssServer::Session::Method const& method) { - - string desc; - - typedef xmlrpc_c::AbyssServer::Session Session; - - switch (method) { - case Session::METHOD_UNKNOWN: desc = "UNKNOWN"; break; - case Session::METHOD_GET: desc = "GET"; break; - case Session::METHOD_PUT: desc = "PUT"; break; - case Session::METHOD_HEAD: desc = "HEAD"; break; - case Session::METHOD_POST: desc = "POST"; break; - case Session::METHOD_DELETE: desc = "DELETE"; break; - case Session::METHOD_TRACE: desc = "TRACE"; break; - case Session::METHOD_OPTIONS: desc = "OPTIONS"; break; - } - return out << desc; -} - - - -namespace xmlrpc_c { - - -class AbyssServer::Session::Impl { - -public: - - Impl(TSession * const cSessionP); - - size_t - contentLength() const; - - void - readSomeRequestBody(size_t const max, - unsigned char * const buffer, - bool * const eofP, - size_t * const byteCtP); - - void - readRequestBody(unsigned char * const buffer, - size_t const size); - - string const - body(); - - void - startWriteResponse(); - - // The external class has lots of trivial methods that are just frontends - // to the C object, so we make 'cSessionP' public to avoid all the work - // of writing Impl methods for all of those. - - TSession * const cSessionP; - -private: - - bool responseStarted; - // We've started (and possibly finished) a response in this session. - - bool requestBodyDelivered; - // We have delivered the request body to the object user. (or tried - // to and failed). - - size_t bodyReadCt; - // Number of bytes of the request body the object user has read. -}; - - - -AbyssServer::Session::Impl::Impl(TSession* const cSessionP) : - cSessionP(cSessionP) -{ - this->responseStarted = false; - this->requestBodyDelivered = false; - this->bodyReadCt = 0; -} - - - -size_t -AbyssServer::Session::Impl::contentLength() const { - - try { - const char * const contentLength = - RequestHeaderValue(this->cSessionP, "content-length"); - - if (contentLength == NULL) - throwf("Header is not present"); - else { - if (contentLength[0] == '\0') - throwf("The value is a null string"); - else { - unsigned long contentLengthValue; - char * tail; - - contentLengthValue = strtoul(contentLength, &tail, 10); - - if (*tail != '\0') - throwf("There's non-numeric crap in the value: '%s'", - tail); - else if ((unsigned long)(size_t)contentLengthValue - != contentLengthValue) - throwf("Value is too large; " - "we can't even do arithmetic on it: '%s'", - contentLength); - else - return (size_t)contentLengthValue; - } - } - } catch (exception const& e) { - throw AbyssServer::Exception( - 400, string("Invalid content-length header field. ") + e.what()); - } -} - - - -size_t -AbyssServer::Session::contentLength() const { - - return this->implP->contentLength(); -} - - - -void -AbyssServer::Session::Impl::readSomeRequestBody( - size_t const max, - unsigned char * const buffer, - bool * const eofP, - size_t * const byteCtP) { -/*----------------------------------------------------------------------------- - Read some of the request body. We read up to 'size' bytes, returning as - soon as we have at least one byte. If we know there is no more data - coming, we send an indication of that instead. - - We know there is no more data coming in one of two ways: With chunked - transfer encoding, we know when the client sends an end-of-data indication - in the data stream. Without chunked transfer encoding, we know when the - this object has already transferred the full length indicated by the - content-size header field, when there is one. If the client doesn't supply - content-size and does not use chunked transfer encoding, we never know the - client isn't going to send any more data, so never return *eofP == true. - - If the client closes the TCP connection before sending anything, we - throw an error. - - You can call this multiple times for one request, getting more of the - body each time. - - If you call this method and 'body' on the same session, results are - undefined. ------------------------------------------------------------------------------*/ - if (RequestHeaderValue(this->cSessionP, "content-length") - && this->contentLength() <= this->bodyReadCt) - *eofP = true; - else { - const char * piecePtr; - size_t pieceLen; - abyss_bool eof; - const char * error; - - SessionGetBody(this->cSessionP, max, - &eof, &piecePtr, &pieceLen, &error); - - if (error) { - string const errorMsg(error); - xmlrpc_strfree(error); - throw girerr::error(errorMsg); - } - - if (eof) - *eofP = true; - else { - this->bodyReadCt += pieceLen; - - *eofP = false; - *byteCtP = pieceLen; - - memcpy(buffer, piecePtr, pieceLen); - } - } -} - - - -void -AbyssServer::Session::readSomeRequestBody( - size_t const max, - unsigned char * const buffer, - bool * const eofP, - size_t * const byteCtP) { - - this->implP->readSomeRequestBody(max, buffer, eofP, byteCtP); -} - - - -void -AbyssServer::Session::Impl::readRequestBody(unsigned char * const buffer, - size_t const size) { -/*----------------------------------------------------------------------------- - Read some of the request body. We read 'size' bytes, waiting as long as - necessary for the client to send that much. If the client sends an - end-of-data indication (possible with chunked transfer encoding only) or - closes the TCP connection before sending that much, we throw an error. - - You can call this multiple times for one request, getting more of the - body each time. - - If you call this method and 'body' on the same session, results are - undefined. ------------------------------------------------------------------------------*/ - for (size_t bytesXferredCt = 0; bytesXferredCt < size; ) { - - size_t pieceLen; - - try { - bool eof; - - this->readSomeRequestBody(size - bytesXferredCt, - &buffer[bytesXferredCt], - &eof, - &pieceLen); - - if (eof) - throwf("Request body ended early (client sent the chunked " - "transfer end-of-data mark " - "or we exhausted content-length)"); - } catch (exception const& e) { - throwf("Failed to get a piece of the request body. %s", - e.what()); - } - bytesXferredCt += pieceLen; - assert(bytesXferredCt <= size); - } -} - - - -void -AbyssServer::Session::readRequestBody(unsigned char * const buffer, - size_t const size) { - - this->implP->readRequestBody(buffer, size); -} - - - -string const -AbyssServer::Session::Impl::body() { -/*----------------------------------------------------------------------------- - The body of the HTTP request (client may send a body with PUT or POST). - - We throw an error if there is no content-size header field. That means - we don't work with a chunked request. - - Some of the body may already be in Abyss's buffer. We retrieve that before - reading more, but then do the network I/O while we run, waiting as - necessary for the body to arrive. - - This works only once. If you call it a second time, it throws an error. - - If you call this method and 'readRequestBody' on the same session, - results are undefined. ------------------------------------------------------------------------------*/ - if (this->requestBodyDelivered) - throwf("The request body has already been delivered; you cannot " - "retrieve it twice"); - - this->requestBodyDelivered = true; - - size_t const contentLength(this->contentLength()); - - string body; - abyss_bool eof; - - body.reserve(contentLength); - - for (eof = false; body.size() < contentLength && !eof; ) { - const char * piecePtr; - size_t pieceLen; - const char * error; - - SessionGetBody(this->cSessionP, contentLength - body.size(), - &eof, &piecePtr, &pieceLen, &error); - - if (error) { - string const errorMsg(error); - xmlrpc_strfree(error); - throw girerr::error(errorMsg); - } - if (!eof) - body.append(piecePtr, pieceLen); - } - return body; -} - - - -string const -AbyssServer::Session::body() { - - return this->implP->body(); -} - - - -void -AbyssServer::Session::getHeaderField(string const& fieldName, - bool * const isPresentP, - string * const valueP) const { - - const char * const value = - RequestHeaderValue(this->implP->cSessionP, fieldName.c_str()); - - if (value == NULL) - *isPresentP = false; - else { - *isPresentP = true; - - *valueP = string(value); - } -} - - - -string const -AbyssServer::Session::headerFieldValue(string const& fieldName) const { - - bool isPresent; - string value; - - this->getHeaderField(fieldName, &isPresent, &value); - - if (isPresent) - return value; - else - throw AbyssServer::Exception( - 400, string("No '") + fieldName + "' field in header"); -} - - - -void -AbyssServer::Session::Impl::startWriteResponse() { - - // Note that ResponseWriteStart() assumes no response has been started; it - // asserts that fact. - - if (this->responseStarted) - throwf("Attempt to write multiple responses in same session"); - - ResponseWriteStart(this->cSessionP); - - this->responseStarted = true; -} - - - -void -AbyssServer::Session::startWriteResponse() { - - this->implP->startWriteResponse(); -} - - - -AbyssServer::Session::Session(TSession * const cSessionP) : - implP(new Impl(cSessionP)) -{} - - - -AbyssServer::Session::~Session() { - delete this->implP; -} - - - -AbyssServer::Session::Method -AbyssServer::Session::method() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - switch (requestInfoP->method) { - case m_unknown: return METHOD_UNKNOWN; - case m_get: return METHOD_GET; - case m_put: return METHOD_PUT; - case m_head: return METHOD_HEAD; - case m_post: return METHOD_POST; - case m_delete: return METHOD_DELETE; - case m_trace: return METHOD_TRACE; - case m_options: return METHOD_OPTIONS; - } - assert(false); // All values of TMethod are handled in switch. - return METHOD_UNKNOWN; /* Defeat bogus compiler warning */ -} - - - -string const -AbyssServer::Session::requestLine() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - assert(requestInfoP->requestline); - - return string(requestInfoP->requestline); -} - - - -string const -AbyssServer::Session::uriPathName() const { -/*----------------------------------------------------------------------------- - The path name from the URI for the HTTP request in this session. - - If the path name is empty (e.g. for URI http://example.com), this is a null - string (in contrast to the Abyss C interface, in which it is "*"). - - According to the URI RFC, RFC 3986, if the path name is - "http://example.com/example.html", the path name is "/example.html" (note - the leading slash), and that is what we return. ------------------------------------------------------------------------------*/ - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - string const requestInfoUri(requestInfoP->uri); - - // There seems to be a weird design in which if the URI has a null - // string path name, requestInfoP->uri is "*". According to the RFC, - // all URIs have a path name, and it may be a null string. - - return requestInfoUri == "*" ? "" : requestInfoUri; -} - - - -vector const -AbyssServer::Session::uriPathNameSegment() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - string const requestInfoUri(requestInfoP->uri); - - vector retval; - - retval.reserve(10); // A guess - - // There seems to be a weird design in which if the URI has an empty - // path name, requestInfoP->uri is "*". According to the RFC, - // all URIs have a path name, and it may be empty. - - if (requestInfoUri == "*") { - // empty path; no segments - } else { - string const pathName(requestInfoUri); - - if (pathName.length() < 1 || pathName[0] != '/') - throwf("INTERNAL ERROR: SessionGetRequestInfo returned " - "'uri' field that does not begin with a slash: '%s'", - pathName.c_str()); - - for (size_t p = 1; p < pathName.length(); ) { - size_t const slashPos(pathName.find('/', p)); - - size_t const segEnd(slashPos == string::npos ? - pathName.length() : slashPos); - - retval.push_back(pathName.substr(p, segEnd - p)); - - p = slashPos == string::npos ? segEnd : slashPos + 1; - } - } - return retval; -} - - - -bool -AbyssServer::Session::uriHasQuery() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - return requestInfoP->query != NULL; -} - - - -string const -AbyssServer::Session::uriQuery() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - if (requestInfoP->query) - return string(requestInfoP->query); - else - throwf("Request URI has no query part"); -} - - - -static map const -formInputFromQuery(string const& query) { -/*----------------------------------------------------------------------------- - 'query' interpreted as HTML form input. - - E.g. if 'query' is "employee=5&department=Q", we return a map with two - elements: - - "employee" => "5" - "department => "Q" - ------------------------------------------------------------------------------*/ - map retval; - - for (size_t pairBeg = 0; pairBeg < query.length(); ) { - size_t pairEnd; - - pairEnd = query.find('&', pairBeg); - if (pairEnd == string::npos) - pairEnd = query.length(); - - size_t keyEnd; - - keyEnd = query.find('=', pairBeg); - - if (keyEnd == string::npos || keyEnd >= pairEnd) - throwf("form input key/value pair '%s' " - "does not contain an equal sign", - query.substr(pairBeg, pairEnd - pairBeg).c_str()); - - size_t const keyBeg(pairBeg); - size_t const valueBeg(keyEnd + 1); - size_t const valueEnd(pairEnd); - - retval[query.substr(keyBeg, keyEnd - keyBeg)] = - query.substr(valueBeg, valueEnd - valueBeg); - - assert(pairEnd >= pairBeg); - - pairBeg = pairEnd + 1; - } - - return retval; -} - - - -map const -AbyssServer::Session::formInput() const { -/*----------------------------------------------------------------------------- - The query portion of the URI for this session, interpreted as HTML form - input. - - HTML form input takes the form of text key/value pairs. Our result is a - std::map that represents those key/value pairs in the obvious way. - - If the URI has no query part, throw an error. ------------------------------------------------------------------------------*/ - return formInputFromQuery(this->uriQuery()); -} - - - -bool -AbyssServer::Session::hasHost() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - return requestInfoP->host != NULL; -} - - - -string const -AbyssServer::Session::host() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - if (requestInfoP->host) - return string(requestInfoP->host); - else - throwf("Request does not specify a host"); -} - - - -bool -AbyssServer::Session::hasFrom() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - return requestInfoP->from != NULL; -} - - - -string const -AbyssServer::Session::from() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - if (requestInfoP->from) - return string(requestInfoP->from); - else - throwf("Request header does not have a 'from' field"); -} - - - -bool -AbyssServer::Session::hasUseragent() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - return requestInfoP->useragent != NULL; -} - - - -string const -AbyssServer::Session::useragent() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - if (requestInfoP->from) - return string(requestInfoP->useragent); - else - throwf("Request header does not have a 'useragent' field"); -} - - - -bool -AbyssServer::Session::hasReferer() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - return requestInfoP->referer != NULL; -} - - - -string const -AbyssServer::Session::referer() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - if (requestInfoP->referer) - return string(requestInfoP->from); - else - throwf("Request header does not have a 'referer' field"); -} - - - -bool -AbyssServer::Session::userIsAuthenticated() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - return requestInfoP->user != NULL; -} - - - -string const -AbyssServer::Session::user() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - if (requestInfoP->user) - return string(requestInfoP->user); - else - throwf("Request header does not identify a user or " - "server could not authenticate the identity"); -} - - - -unsigned short -AbyssServer::Session::port() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - return requestInfoP->port; -} - - - -bool -AbyssServer::Session::keepalive() const { - - const TRequestInfo * requestInfoP; - - SessionGetRequestInfo(this->implP->cSessionP, &requestInfoP); - - return requestInfoP->keepalive; -} - - - -bool -AbyssServer::Session::hasContentLength() const { - - return - RequestHeaderValue(this->implP->cSessionP, "content-length")!= NULL; -} - - - -void -AbyssServer::Session::setRespStatus(unsigned short const statusCode) { - - ResponseStatus(this->implP->cSessionP, statusCode); -} - - - -void -AbyssServer::Session::setRespContentType(string const& contentType) { - - ResponseContentType(this->implP->cSessionP, contentType.c_str()); -} - - - -void -AbyssServer::Session::setRespContentLength(uint64_t const contentLength) { - - ResponseContentLength(this->implP->cSessionP, contentLength); -} - - - -void -AbyssServer::Session::endWriteResponse() { - - ResponseWriteEnd(this->implP->cSessionP); -} - - - -void -AbyssServer::Session::writeResponseBody(const unsigned char * const data, - size_t const size) { -/*----------------------------------------------------------------------------- - Write some of the response body. If it's a chunked response, this - constitutes one chunk. If not, it's just part of the monolithic response. - Either way, you can call this multiple times for one response. ------------------------------------------------------------------------------*/ - ResponseWriteBody(this->implP->cSessionP, - reinterpret_cast(data), - size); -} - - - -void -AbyssServer::Session::writeResponse(string const& body) { - - this->startWriteResponse(); - - this->writeResponseBody( - reinterpret_cast(body.data()), - body.size()); - - this->endWriteResponse(); -} - - - -void -AbyssServer::Session::sendErrorResponse(string const& explanation) { -/*----------------------------------------------------------------------------- - Send a response indicating that the HTTP request failed, with text - explanation 'explanation'. The response is HTML and contains an appropriate - content-type header, regardless of any content type that may be set in the - object already. - - Assume the HTTP status code is already set in the object. ------------------------------------------------------------------------------*/ - ResponseError2(this->implP->cSessionP, explanation.c_str()); -} - - - -void -AbyssServer::Session::sendErrorResponse(Exception const& e) { -/*----------------------------------------------------------------------------- - Send a response indicating that the HTTP request failed, with HTTP status - code and text explanation 'e'. The response is HTML and contains an - appropriate content-type header, regardless of any content type that may be - set in the object already. ------------------------------------------------------------------------------*/ - this->setRespStatus(e.httpStatusCode()); - - this->sendErrorResponse(e.what()); -} - - - -AbyssServer::AbyssServer(AbyssChanSwitch * const chanSwitchP) { - - const char * error; - - ServerCreateSwitch(&this->cServer, - chanSwitchP->cChanSwitchP(), - &error); - - if (error) - throw runtime_error(error); -} - - - -void -AbyssServer::init() { - - const char * error; - - ServerInit2(&this->cServer, &error); - - if (error) - throw runtime_error(error); -} - - - -void -AbyssServer::run() { - - ServerRun(&this->cServer); -} - - - -void -AbyssServer::runOnce() { - - ServerRunOnce(&this->cServer); -} - - - -void -AbyssServer::terminate() { - - ServerTerminate(&this->cServer); -} - - - -void -AbyssServer::resetTerminate() { - - ServerResetTerminate(&this->cServer); -} - - - -AbyssServer::~AbyssServer() { - - ServerFree(&this->cServer); -} - - - -static void -cHandleRequest(void * const handlerPtr, - TSession * const cSessionP, - abyss_bool * const handledP) { -/*----------------------------------------------------------------------------- - This is an HTTP request handler function for the C abyss server. - I.e. it translates a call from the C Abyss server to a call to the - C++ HTTP request handler method. - - 'handlerPtr' is the handle of an Abyss::ReqHandler object; we call that - object's 'handleRequest' method. ------------------------------------------------------------------------------*/ - AbyssServer::ReqHandler * const reqHandlerP( - reinterpret_cast(handlerPtr)); - - try { - AbyssServer::Session session(cSessionP); - - bool handled; - - reqHandlerP->handleRequest(&session, &handled); - - *handledP = handled; - } catch (...) { - *handledP = false; - } -} - - - -static void -cTermHandler(void * const handlerPtr) { - - AbyssServer::ReqHandler * const reqHandlerP( - reinterpret_cast(handlerPtr)); - - // It's not supposed to throw an error, and there's nothing we could do - // but abort the program if it does, so we don't catch exceptions. - - reqHandlerP->terminate(); -} - - - -void -AbyssServer::addRequestHandler(ReqHandler * const handlerP) { - - ServerReqHandler3 cReqHandler; - - cReqHandler.handleReq = cHandleRequest; - - cReqHandler.userdata = handlerP; - - cReqHandler.handleReqStackSize = handlerP->handleReqStackSize(); - - cReqHandler.term = cTermHandler; - - abyss_bool success; - - ServerAddHandler3(&this->cServer, &cReqHandler, &success); - - if (!success) - throwf("ServerAddHandler3() failed"); -} - - - -} // namespace diff --git a/trunk/lib/abyss++/Makefile b/trunk/lib/abyss++/Makefile deleted file mode 100644 index f6538afc2..000000000 --- a/trunk/lib/abyss++/Makefile +++ /dev/null @@ -1,153 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - LIBDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/abyss++ - -include $(BLDDIR)/config.mk - -default: all - -TARGET_LIB_NAMES_PP = \ - libxmlrpc_abyss++ \ - -STATIC_LIBRARIES_TO_INSTALL = $(TARGET_STATIC_LIBRARIES) - -SHARED_LIBS_TO_BUILD = $(TARGET_LIB_NAMES_PP) -SHARED_LIBS_TO_INSTALL = $(TARGET_LIB_NAMES_PP) - -# INCLUDES and DEP_SOURCES are used by dep-common target -INCLUDES = $(BASIC_INCLUDES) -DEP_SOURCES = *.cpp - -LIBXMLRPC_ABYSSPP_MODS = AbyssServer AbyssChanSwitch AbyssEnvironment - -ifeq ($(findstring mingw,$(HOST_OS)),mingw) - LIBXMLRPC_ABYSSPP_MODS += AbyssChanSwitchWin -else - LIBXMLRPC_ABYSSPP_MODS += AbyssChanSwitchUnix - ifeq ($(MUST_BUILD_OPENSSL),yes) - LIBXMLRPC_ABYSSPP_MODS += AbyssChanSwitchOpenSsl - endif -endif - -TARGET_MODS_PP = \ - $(LIBXMLRPC_ABYSSPP_MODS) \ - -PKGCONFIG_FILES_TO_INSTALL := xmlrpc_abyss++.pc - -OMIT_ABYSSPP_LIB_RULE = Y -MAJ = 8 - # Major number of shared libraries in this directory - -include $(SRCDIR)/common.mk - - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -BASIC_INCLUDES = \ - -Iblddir/include \ - -Isrcdir/include \ - -Iblddir \ - -Isrcdir/lib/util/include - - -# TARGET_STATIC_LIBARIES, etc. are set by common.mk, based on -# TARGET_LIB_NAMES_PP. - -all: \ - $(TARGET_STATIC_LIBRARIES) \ - $(TARGET_SHARED_LIBS_PP) \ - $(TARGET_SHARED_LE_LIBS) \ - $(PKGCONFIG_FILES_TO_INSTALL) \ - - -#----------------------------------------------------------------------------- -# RULES TO LINK LIBRARIES -#----------------------------------------------------------------------------- - -# The actual rules for this are in common.mk, courtesy of TARGET_LIB_NAMES_PP - -# shlibfn generates e.g. libxmlrpc.so.3.1 -# shliblefn generates e.g. libxmlrpc.so - -# Sometimes -lpthread is necessary when link-editing a shared library that -# uses pthread services, and sometimes it is not. We've seen links on -# Windows and AIX fail without it. It seems to be a good idea in all cases, -# as it declares an actual dependency of the shared library. - -LIBXMLRPC_ABYSSPP_SH = $(call shlibfn, libxmlrpc_abyss++) - -$(LIBXMLRPC_ABYSSPP_SH): $(LIBXMLRPC_ABYSSPP_MODS:%=%.osh) \ - $(LIBXMLRPC_ABYSS) \ - $(LIBXMLRPC_UTILPP) \ - $(LIBXMLRPC_UTIL) \ - -$(LIBXMLRPC_ABYSSPP_SH): LIBOBJECTS = $(LIBXMLRPC_ABYSSPP_MODS:%=%.osh) -$(LIBXMLRPC_ABYSSPP_SH): LIBDEP = \ - -L. -Lblddir/src \ - -L$(LIBXMLRPC_ABYSS_DIR) -lxmlrpc_abyss \ - -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ - -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ - $(SOCKETLIBOPT) \ - $(THREADLIBS) \ - -libxmlrpc_abyss++.a: $(LIBXMLRPC_ABYSSPP_MODS:%=%.o) -libxmlrpc_abyss++.a: LIBOBJECTS=$(LIBXMLRPC_ABYSSPP_MODS:%=%.o) - -#----------------------------------------------------------------------------- -# RULE TO COMPILE OBJECT MODULES FOR LIBRARY -#----------------------------------------------------------------------------- - -# The actual rule for this is in common.mk, courtesy of TARGET_MODS_PP - -$(LIBXMLRPC_ABYSSPP_MODS:%=%.o) \ -$(LIBXMLRPC_ABYSSPP_MODS:%=%.osh): \ - INCLUDES = $(BASIC_INCLUDES) - -#----------------------------------------------------------------------------- -# RULES TO MAKE PKGCONFIG FILES -# -# (These are files used by the 'pkg-config' program to get information about -# using the libraries we build) -#----------------------------------------------------------------------------- - -xmlrpc_abyss++.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_abyss++" >>$@ - @echo "Description: Xmlrpc-c Abyss HTTP C++ library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc_abyss xmlrpc_util++" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_abyss++" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -#----------------------------------------------------------------------------- -# MISCELLANEOUS RULES -#----------------------------------------------------------------------------- - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean clean-local distclean distclean-local -clean: clean-common clean-local -clean-local: - -distclean: clean distclean-local distclean-common - -distclean-local: - -.PHONY: dep -dep: dep-common $(BLDDIR)/transport_config.h -dep-common: $(BLDDIR)/src/libxmlrpc_client.cflags - -include depend.mk diff --git a/trunk/lib/abyss/HISTORY b/trunk/lib/abyss/HISTORY deleted file mode 100644 index c7774dc9c..000000000 --- a/trunk/lib/abyss/HISTORY +++ /dev/null @@ -1,122 +0,0 @@ -Here is some stuff from the README file of the original Abyss source -package in 2000. Abyss used to be an independent package and was included -in Xmlrpc-c for convenience when Xmlrpc-c was created. Since then, the -code has been greatly modified and extended for Xmlrpc-c. - -The original Abyss project was a product of Moez Mahfoudh mmoez@bigfoot.com. - - - ABYSS Web Server - ------------------ - - -About: ------- - -ABYSS aims to be a fully HTTP/1.1 compliant web server. Its main design -goals are speed, low resource usage and portability. ABYSS works on most -UNIX based systems and on Win32 systems (Win95/98/2000/NT). - -Copyright: ----------- - -Copyright (C) 2000 Moez Mahfoudh. All rights reserved. - -Status: -------- - -ABYSS is still in development stage. Actual version is 0.3. Many features -are not implemented yet but the server core works well and seems to be -stable. It is fully reliable for serving static files on medium load sites. -In fact, primary benchmarks show that ABYSS is 70% as fast as Apache when -using the fork system. This rate jumps to 130% when using threads. -On UNIX platforms, some problems occurred because of the use of the Pthreads -library. This will be corrected in the future versions. That's why only the -fork system is usable under UNIX. This lowers performances but guarantees -stability. -CGI/1.1 support is still absent from the current version but will be -included in the near future. - -Change Log: ------------ - - * Version 0.3 (March 23,2000): - o Handles conditional GET requests (by date) - o Conforms to all the MUSTs of the RFC2616 (newer version of the - HTTP/1.1 protocol draft) - o New configuration options (such as pidfile for UNIX systems...) - o Handles HEAD and OPTIONS methods - o Many bug fixes - o Tested on Sun-OS 5.7 - o Second public release - - * Version 0.2 beta (February 7,2000): - o Handles GET on static files - o Handles correctly range requests - o Conforms to 80% of the MUSTs of the RFC2068 (HTTP/1.1 protocol - draft) - o Improved code portability (Win32 and UNIX platforms) - o Tested on Linux 2.2 and Win95/98 - o First public release - - * Version 0.1 (January 2000): - o Completely rewritten in C - o Speed improvement - o New memory allocation scheme (using pools) - o Never released - - * Version 0.0 (January 2000): - o Initial version - o Written in C++ - o Never released - -Downloading: ------------- - - * Version 0.3 (current version): - o UNIX package (source) abyss-0.3.tar.gz. - o Win32 package is not available but you can extract source files - from the UNIX package and compile them on Windows without any - modification. (Sorry for this inconvenience: I have no Windows - machine now to compile the program and to test it. If someone can - do that, please email me the zipped package and I'll add it here). - - * Version 0.2 beta: - o UNIX package (source) abyss-0.2b.tar.gz. - o Win32 package (source+binary) abyss-0.2b.zip. - -Installation: -------------- - - * For UNIX systems: - o Untar/Ungzip the distribution package with a command like tar xvfz - abyss-x.y.tar.gz - o Edit the Makefile src/Makefile to meet your system requirements. - o Go to directory src and execute make. - o The server binary is generated and stored in the bin directory. - o Edit the conf/abyss.conf to reflect your system configuration (At - least change the paths). - o Goto to the bin directory and start the server by typing ./abyss - -c ../conf/abyss.conf - - * For Win32 systems: - o Unzip the distribution package. - o An executable file is already present in the bin directory. - o If you wish to recompile the server, open the src/abyss.dsw file - with Microsoft Visual C++ 5.0 or higher and rebuild the project. - o Edit the conf/abyss.conf to reflect your system configuration (At - least change the paths). - o Goto to the bin directory and start the server by typing ./abyss - -c ../conf/abyss.conf - - -To do: ------- - - * CGI/1.1 support - * Web based configuration/administration - * Speed improvement - * File caching system - * Throttling - * PUT method handling - * ... diff --git a/trunk/lib/abyss/Makefile b/trunk/lib/abyss/Makefile deleted file mode 100644 index 20b69a1e8..000000000 --- a/trunk/lib/abyss/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - LIBDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/abyss - -include $(BLDDIR)/config.mk - -SUBDIRS = src - -default: all - -.PHONY: all -all: $(SUBDIRS:%=%/all) - -.PHONY: clean -clean: $(SUBDIRS:%=%/clean) clean-common - -.PHONY: distclean -distclean: $(SUBDIRS:%=%/distclean) distclean-common - -.PHONY: tags -tags: $(SUBDIRS:%=%/tags) TAGS - -DISTFILES = - -.PHONY: distdir -distdir: distdir-common - -.PHONY: install -install: $(SUBDIRS:%=%/install) - -.PHONY: uninstall -uninstall: $(SUBDIRS:%=%/uninstall) - -.PHONY: dep -dep: $(SUBDIRS:%=%/dep) - -include $(SRCDIR)/common.mk - - - diff --git a/trunk/lib/abyss/README b/trunk/lib/abyss/README deleted file mode 100644 index b1d6c8031..000000000 --- a/trunk/lib/abyss/README +++ /dev/null @@ -1,23 +0,0 @@ -This directory contains the Abyss HTTP server component of XML-RPC For C/C++ -(Xmlrpc-c). - -This was derived from the independently developed and distributed -Abyss web server package in 2001. Since that time, work has stopped -on package except for a non-free derivative of it that the original -author has done. He uses the Abyss name for that. - -So this is now strictly a piece of Xmlrpc-c. Some day, we should change -the name to avoid confusion with the old code on which it was based and -the current non-free version. - -But for Xmlrpc-c, we don't want to enhance this much. That would -duplicate the vast amount of work that has gone into other HTTP (web) -servers such as Apache. If someone needs fancy HTTP service for -XML-RPC, he should use Apache. One can use Apache with Xmlrpc-c -either by using an Apache request handler plugin or by using a CGI -script. Abyss is just for very simple servers, where the complexity -of using (or even acquiring) Apache would not be warranted. - - -Everything besides what's in the src/ directory is just historical -- -it comes from the original Abyss in 2001. diff --git a/trunk/lib/abyss/conf/abyss.conf b/trunk/lib/abyss/conf/abyss.conf deleted file mode 100644 index c74c758ca..000000000 --- a/trunk/lib/abyss/conf/abyss.conf +++ /dev/null @@ -1,56 +0,0 @@ -# ABYSS Web Server configuration file -# (C) Moez Mahfoudh - 2000 - -# Cases in option names are ignored, -# that means that PORT=port=PoRT=.. - -# When writing paths, do not worry about / or \ use. -# ABYSS will substitute / with \ on Win32 systems. - -# Options which are system specific (such as User) are -# ignored on systems which do not handle them. - -# The Port option tells the server on which TCP port to listen. -# default is 80 -Port 8000 - -# The name or #number of the user to run the server as if it is -# launched as root (UNIX specific) -User nobody - -# The Server Root (UNIX systems style) -ServerRoot /home/mahfoudh/abyss - -# The Server Root (Win32 systems style) -# ServerRoot c:\abyss - -# The Path option specifies the web files path. -Path htdocs - -# The Default option contains the name of the files the server should -# look for when only a path is given (e.g. http://myserver/info/). -Default index.html index.htm INDEX.HTM INDEX.HTML - -# The KeepAlive option is used to set the maximum number of requests -# served using the same persistent connection. -KeepAlive 10 - -# The TimeOut option tells the server how much seconds to wait for -# an idle connection before closing it. -TimeOut 10 - -# The MimeTypes option specifies the location of the file -# containing the mapping of MIME types and files extensions -MimeTypes conf/mime.types - -# The path of the log file -LogFile log/access.log - -# The file where the pid of the server is logged (UNIX specific) -PidFile log/abyss.pid - -# If AdvertiseServer if set to no, then no server field would be -# appended to the responses. This is the way to make the server -# identity unknown to some malicious people which can profit from -# well known security holes in the software to crash it. -AdvertiseServer yes diff --git a/trunk/lib/abyss/conf/mime.types b/trunk/lib/abyss/conf/mime.types deleted file mode 100644 index d53db0f4e..000000000 --- a/trunk/lib/abyss/conf/mime.types +++ /dev/null @@ -1,276 +0,0 @@ -# This is a comment. I love comments. - -# This file controls what Internet media types are sent to the client for -# given file extension(s). Sending the correct media type to the client -# is important so they know how to handle the content of the file. -# Extra types can either be added here or by using an AddType directive -# in your config files. For more information about Internet media types, -# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type -# registry is at . - -# MIME type Extension -application/EDI-Consent -application/EDI-X12 -application/EDIFACT -application/activemessage -application/andrew-inset ez -application/applefile -application/atomicmail -application/cals-1840 -application/commonground -application/cybercash -application/dca-rft -application/dec-dx -application/eshop -application/hyperstudio -application/iges -application/mac-binhex40 hqx -application/mac-compactpro cpt -application/macwriteii -application/marc -application/mathematica -application/msword doc -application/news-message-id -application/news-transmission -application/octet-stream bin dms lha lzh exe class -application/oda oda -application/pdf pdf -application/pgp-encrypted -application/pgp-keys -application/pgp-signature -application/pkcs10 -application/pkcs7-mime -application/pkcs7-signature -application/postscript ai eps ps -application/prs.alvestrand.titrax-sheet -application/prs.cww -application/prs.nprend -application/remote-printing -application/riscos -application/rtf rtf -application/set-payment -application/set-payment-initiation -application/set-registration -application/set-registration-initiation -application/sgml -application/sgml-open-catalog -application/slate -application/smil smi smil -application/vemmi -application/vnd.3M.Post-it-Notes -application/vnd.FloGraphIt -application/vnd.acucobol -application/vnd.anser-web-certificate-issue-initiation -application/vnd.anser-web-funds-transfer-initiation -application/vnd.audiograph -application/vnd.businessobjects -application/vnd.claymore -application/vnd.comsocaller -application/vnd.dna -application/vnd.dxr -application/vnd.ecdis-update -application/vnd.ecowin.chart -application/vnd.ecowin.filerequest -application/vnd.ecowin.fileupdate -application/vnd.ecowin.series -application/vnd.ecowin.seriesrequest -application/vnd.ecowin.seriesupdate -application/vnd.enliven -application/vnd.epson.salt -application/vnd.fdf -application/vnd.ffsns -application/vnd.framemaker -application/vnd.fujitsu.oasys -application/vnd.fujitsu.oasys2 -application/vnd.fujitsu.oasys3 -application/vnd.fujitsu.oasysgp -application/vnd.fujitsu.oasysprs -application/vnd.fujixerox.docuworks -application/vnd.hp-HPGL -application/vnd.hp-PCL -application/vnd.hp-PCLXL -application/vnd.hp-hps -application/vnd.ibm.MiniPay -application/vnd.ibm.modcap -application/vnd.intercon.formnet -application/vnd.intertrust.digibox -application/vnd.intertrust.nncp -application/vnd.is-xpr -application/vnd.japannet-directory-service -application/vnd.japannet-jpnstore-wakeup -application/vnd.japannet-payment-wakeup -application/vnd.japannet-registration -application/vnd.japannet-registration-wakeup -application/vnd.japannet-setstore-wakeup -application/vnd.japannet-verification -application/vnd.japannet-verification-wakeup -application/vnd.koan -application/vnd.lotus-1-2-3 -application/vnd.lotus-approach -application/vnd.lotus-freelance -application/vnd.lotus-organizer -application/vnd.lotus-screencam -application/vnd.lotus-wordpro -application/vnd.meridian-slingshot -application/vnd.mif mif -application/vnd.minisoft-hp3000-save -application/vnd.mitsubishi.misty-guard.trustweb -application/vnd.ms-artgalry -application/vnd.ms-asf -application/vnd.ms-excel xls -application/vnd.ms-powerpoint ppt -application/vnd.ms-project -application/vnd.ms-tnef -application/vnd.ms-works -application/vnd.music-niff -application/vnd.musician -application/vnd.netfpx -application/vnd.noblenet-directory -application/vnd.noblenet-sealer -application/vnd.noblenet-web -application/vnd.novadigm.EDM -application/vnd.novadigm.EDX -application/vnd.novadigm.EXT -application/vnd.osa.netdeploy -application/vnd.powerbuilder6 -application/vnd.powerbuilder6-s -application/vnd.rapid -application/vnd.seemail -application/vnd.shana.informed.formtemplate -application/vnd.shana.informed.interchange -application/vnd.shana.informed.package -application/vnd.street-stream -application/vnd.svd -application/vnd.swiftview-ics -application/vnd.truedoc -application/vnd.visio -application/vnd.webturbo -application/vnd.wrq-hp3000-labelled -application/vnd.wt.stf -application/vnd.xara -application/vnd.yellowriver-custom-menu -application/wita -application/wordperfect5.1 -application/x-bcpio bcpio -application/x-cdlink vcd -application/x-chess-pgn pgn -application/x-compress -application/x-cpio cpio -application/x-csh csh -application/x-director dcr dir dxr -application/x-dvi dvi -application/x-futuresplash spl -application/x-gtar gtar -application/x-gzip -application/x-hdf hdf -application/x-javascript js -application/x-koan skp skd skt skm -application/x-latex latex -application/x-netcdf nc cdf -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-stuffit sit -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-texinfo texinfo texi -application/x-troff t tr roff -application/x-troff-man man -application/x-troff-me me -application/x-troff-ms ms -application/x-ustar ustar -application/x-wais-source src -application/x400-bp -application/xml -application/zip zip -audio/32kadpcm -audio/basic au snd -audio/midi mid midi kar -audio/mpeg mpga mp2 mp3 -audio/vnd.qcelp -audio/x-aiff aif aiff aifc -audio/x-pn-realaudio ram rm -audio/x-pn-realaudio-plugin rpm -audio/x-realaudio ra -audio/x-wav wav -chemical/x-pdb pdb xyz -image/bmp bmp -image/cgm -image/g3fax -image/gif gif -image/ief ief -image/jpeg jpeg jpg jpe -image/naplps -image/png png -image/prs.btif -image/tiff tiff tif -image/vnd.dwg -image/vnd.dxf -image/vnd.fpx -image/vnd.net-fpx -image/vnd.svf -image/vnd.xiff -image/x-cmu-raster ras -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-rgb rgb -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -message/delivery-status -message/disposition-notification -message/external-body -message/http -message/news -message/partial -message/rfc822 -model/iges igs iges -model/mesh msh mesh silo -model/vnd.dwf -model/vrml wrl vrml -multipart/alternative -multipart/appledouble -multipart/byteranges -multipart/digest -multipart/encrypted -multipart/form-data -multipart/header-set -multipart/mixed -multipart/parallel -multipart/related -multipart/report -multipart/signed -multipart/voice-message -text/css css -text/directory -text/enriched -text/html html htm -text/plain asc txt -text/prs.lines.tag -text/rfc822-headers -text/richtext rtx -text/rtf rtf -text/sgml sgml sgm -text/tab-separated-values tsv -text/uri-list -text/vnd.abc -text/vnd.flatland.3dml -text/vnd.fmi.flexstor -text/vnd.in3d.3dml -text/vnd.in3d.spot -text/vnd.latex-z -text/x-setext etx -text/xml xml -video/mpeg mpeg mpg mpe -video/quicktime qt mov -video/vnd.motorola.video -video/vnd.motorola.videop -video/vnd.vivo -video/x-msvideo avi -video/x-sgi-movie movie -x-conference/x-cooltalk ice diff --git a/trunk/lib/abyss/example/conf/abyss.conf b/trunk/lib/abyss/example/conf/abyss.conf deleted file mode 100644 index f9c09f2a6..000000000 --- a/trunk/lib/abyss/example/conf/abyss.conf +++ /dev/null @@ -1,56 +0,0 @@ -# ABYSS Web Server configuration file -# (C) Moez Mahfoudh - 2000 - -# Cases in option names are ignored, -# that means that PORT=port=PoRT=.. - -# When writing paths, do not worry about / or \ use. -# ABYSS will substitute / with \ on Win32 systems. - -# Options which are system specific (such as User) are -# ignored on systems which do not handle them. - -# The Port option tells the server on which TCP port to listen. -# default is 80 -Port 8080 - -# The name or #number of the user to run the server as if it is -# launched as root (UNIX specific) -User nobody - -# The Server Root (UNIX systems style) -ServerRoot conf/abyss_root - -# The Server Root (Win32 systems style) -# ServerRoot G:\XML\xmlrpc-c-0.9.5\conf\abyss_root - -# The Path option specifies the web files path. -Path htdocs - -# The Default option contains the name of the files the server should -# look for when only a path is given (e.g. http://myserver/info/). -Default index.html index.htm INDEX.HTM INDEX.HTML - -# The KeepAlive option is used to set the maximum number of requests -# served using the same persistent connection. -KeepAlive 10 - -# The TimeOut option tells the server how much seconds to wait for -# an idle connection before closing it. -TimeOut 10 - -# The MimeTypes option specifies the location of the file -# containing the mapping of MIME types and files extensions -MimeTypes conf/mime.types - -# The path of the log file -LogFile log/access.log - -# The file where the pid of the server is logged (UNIX specific) -PidFile log/abyss.pid - -# If AdvertiseServer if set to no, then no server field would be -# appended to the responses. This is the way to make the server -# identity unknown to some malicious people which can profit from -# well known security holes in the software to crash it. -AdvertiseServer yes diff --git a/trunk/lib/abyss/example/conf/mime.types b/trunk/lib/abyss/example/conf/mime.types deleted file mode 100644 index d53db0f4e..000000000 --- a/trunk/lib/abyss/example/conf/mime.types +++ /dev/null @@ -1,276 +0,0 @@ -# This is a comment. I love comments. - -# This file controls what Internet media types are sent to the client for -# given file extension(s). Sending the correct media type to the client -# is important so they know how to handle the content of the file. -# Extra types can either be added here or by using an AddType directive -# in your config files. For more information about Internet media types, -# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type -# registry is at . - -# MIME type Extension -application/EDI-Consent -application/EDI-X12 -application/EDIFACT -application/activemessage -application/andrew-inset ez -application/applefile -application/atomicmail -application/cals-1840 -application/commonground -application/cybercash -application/dca-rft -application/dec-dx -application/eshop -application/hyperstudio -application/iges -application/mac-binhex40 hqx -application/mac-compactpro cpt -application/macwriteii -application/marc -application/mathematica -application/msword doc -application/news-message-id -application/news-transmission -application/octet-stream bin dms lha lzh exe class -application/oda oda -application/pdf pdf -application/pgp-encrypted -application/pgp-keys -application/pgp-signature -application/pkcs10 -application/pkcs7-mime -application/pkcs7-signature -application/postscript ai eps ps -application/prs.alvestrand.titrax-sheet -application/prs.cww -application/prs.nprend -application/remote-printing -application/riscos -application/rtf rtf -application/set-payment -application/set-payment-initiation -application/set-registration -application/set-registration-initiation -application/sgml -application/sgml-open-catalog -application/slate -application/smil smi smil -application/vemmi -application/vnd.3M.Post-it-Notes -application/vnd.FloGraphIt -application/vnd.acucobol -application/vnd.anser-web-certificate-issue-initiation -application/vnd.anser-web-funds-transfer-initiation -application/vnd.audiograph -application/vnd.businessobjects -application/vnd.claymore -application/vnd.comsocaller -application/vnd.dna -application/vnd.dxr -application/vnd.ecdis-update -application/vnd.ecowin.chart -application/vnd.ecowin.filerequest -application/vnd.ecowin.fileupdate -application/vnd.ecowin.series -application/vnd.ecowin.seriesrequest -application/vnd.ecowin.seriesupdate -application/vnd.enliven -application/vnd.epson.salt -application/vnd.fdf -application/vnd.ffsns -application/vnd.framemaker -application/vnd.fujitsu.oasys -application/vnd.fujitsu.oasys2 -application/vnd.fujitsu.oasys3 -application/vnd.fujitsu.oasysgp -application/vnd.fujitsu.oasysprs -application/vnd.fujixerox.docuworks -application/vnd.hp-HPGL -application/vnd.hp-PCL -application/vnd.hp-PCLXL -application/vnd.hp-hps -application/vnd.ibm.MiniPay -application/vnd.ibm.modcap -application/vnd.intercon.formnet -application/vnd.intertrust.digibox -application/vnd.intertrust.nncp -application/vnd.is-xpr -application/vnd.japannet-directory-service -application/vnd.japannet-jpnstore-wakeup -application/vnd.japannet-payment-wakeup -application/vnd.japannet-registration -application/vnd.japannet-registration-wakeup -application/vnd.japannet-setstore-wakeup -application/vnd.japannet-verification -application/vnd.japannet-verification-wakeup -application/vnd.koan -application/vnd.lotus-1-2-3 -application/vnd.lotus-approach -application/vnd.lotus-freelance -application/vnd.lotus-organizer -application/vnd.lotus-screencam -application/vnd.lotus-wordpro -application/vnd.meridian-slingshot -application/vnd.mif mif -application/vnd.minisoft-hp3000-save -application/vnd.mitsubishi.misty-guard.trustweb -application/vnd.ms-artgalry -application/vnd.ms-asf -application/vnd.ms-excel xls -application/vnd.ms-powerpoint ppt -application/vnd.ms-project -application/vnd.ms-tnef -application/vnd.ms-works -application/vnd.music-niff -application/vnd.musician -application/vnd.netfpx -application/vnd.noblenet-directory -application/vnd.noblenet-sealer -application/vnd.noblenet-web -application/vnd.novadigm.EDM -application/vnd.novadigm.EDX -application/vnd.novadigm.EXT -application/vnd.osa.netdeploy -application/vnd.powerbuilder6 -application/vnd.powerbuilder6-s -application/vnd.rapid -application/vnd.seemail -application/vnd.shana.informed.formtemplate -application/vnd.shana.informed.interchange -application/vnd.shana.informed.package -application/vnd.street-stream -application/vnd.svd -application/vnd.swiftview-ics -application/vnd.truedoc -application/vnd.visio -application/vnd.webturbo -application/vnd.wrq-hp3000-labelled -application/vnd.wt.stf -application/vnd.xara -application/vnd.yellowriver-custom-menu -application/wita -application/wordperfect5.1 -application/x-bcpio bcpio -application/x-cdlink vcd -application/x-chess-pgn pgn -application/x-compress -application/x-cpio cpio -application/x-csh csh -application/x-director dcr dir dxr -application/x-dvi dvi -application/x-futuresplash spl -application/x-gtar gtar -application/x-gzip -application/x-hdf hdf -application/x-javascript js -application/x-koan skp skd skt skm -application/x-latex latex -application/x-netcdf nc cdf -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-stuffit sit -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-texinfo texinfo texi -application/x-troff t tr roff -application/x-troff-man man -application/x-troff-me me -application/x-troff-ms ms -application/x-ustar ustar -application/x-wais-source src -application/x400-bp -application/xml -application/zip zip -audio/32kadpcm -audio/basic au snd -audio/midi mid midi kar -audio/mpeg mpga mp2 mp3 -audio/vnd.qcelp -audio/x-aiff aif aiff aifc -audio/x-pn-realaudio ram rm -audio/x-pn-realaudio-plugin rpm -audio/x-realaudio ra -audio/x-wav wav -chemical/x-pdb pdb xyz -image/bmp bmp -image/cgm -image/g3fax -image/gif gif -image/ief ief -image/jpeg jpeg jpg jpe -image/naplps -image/png png -image/prs.btif -image/tiff tiff tif -image/vnd.dwg -image/vnd.dxf -image/vnd.fpx -image/vnd.net-fpx -image/vnd.svf -image/vnd.xiff -image/x-cmu-raster ras -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-rgb rgb -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -message/delivery-status -message/disposition-notification -message/external-body -message/http -message/news -message/partial -message/rfc822 -model/iges igs iges -model/mesh msh mesh silo -model/vnd.dwf -model/vrml wrl vrml -multipart/alternative -multipart/appledouble -multipart/byteranges -multipart/digest -multipart/encrypted -multipart/form-data -multipart/header-set -multipart/mixed -multipart/parallel -multipart/related -multipart/report -multipart/signed -multipart/voice-message -text/css css -text/directory -text/enriched -text/html html htm -text/plain asc txt -text/prs.lines.tag -text/rfc822-headers -text/richtext rtx -text/rtf rtf -text/sgml sgml sgm -text/tab-separated-values tsv -text/uri-list -text/vnd.abc -text/vnd.flatland.3dml -text/vnd.fmi.flexstor -text/vnd.in3d.3dml -text/vnd.in3d.spot -text/vnd.latex-z -text/x-setext etx -text/xml xml -video/mpeg mpeg mpg mpe -video/quicktime qt mov -video/vnd.motorola.video -video/vnd.motorola.videop -video/vnd.vivo -video/x-msvideo avi -video/x-sgi-movie movie -x-conference/x-cooltalk ice diff --git a/trunk/lib/abyss/example/htdocs/index.htm b/trunk/lib/abyss/example/htdocs/index.htm deleted file mode 100644 index f0369a550..000000000 --- a/trunk/lib/abyss/example/htdocs/index.htm +++ /dev/null @@ -1,21 +0,0 @@ - - -ABYSS is working !!! - - -

Congratulations, ABYSS is working !!!

-
-

-ABYSS Web Server is working correctly on your system. You should now change this -page with yours. -
-Please include in your web pages (at least the first), the 'Powered by ABYSS' -banner to promote the use of ABYSS. -

-
-

-

-Copyright © 2000 Moez Mahfoudh. All rights reserved. - -

- diff --git a/trunk/lib/abyss/example/htdocs/pwrabyss.gif b/trunk/lib/abyss/example/htdocs/pwrabyss.gif deleted file mode 100644 index 9a4a3a3c1fa78ddc71f1251b7bf236931158e6d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2198 zcmeH}`&Sb70>Hn3DZUa#6P+d`m{?n~t{KeCG!cl*;cL03D853=oHk$8LBV{X;y{hW zMF~q&Or5l{xuK@16=^!so3U~hYE!&M<7TDz?%aRj{nMz+f|dk zLZMJ9fl{gL?FGHPy+cD_XlO{S25PlhqX8O?Mymx{tyZT4I-O3h2YS8UXaq*1abp8) z{LSA6{vQT*{#C$VEdcmBID7|1>5%qu;YhDz!yT6gN)YaQ{(%vc3|63avu9E}OYT;q zgUVf~U9u6OXZSTgCvH%11xOebjdXfc*Y3?)oEdp7Gq>KAci)9AWIb%62)&l#`;)9H zT}{TM5NXhOB?&(~7xs1YV=>HQX1<2iN4LXK!QNA>l43|)@40MC-(|XRKR4FiJ6si6 zNpc@{5pZQsZzBEF&6dmqBWAEz!?RPl^C331`nvRMkGENDA~;C@-9Sj;Uq)Nq+c}-E z5@NeMydvUN9}6lbL};tT4Jq2IGOn&0FpKU(i-XxwuE;sAxOe|2Cs#6wv{xh|>~3lk z6axJG*G+yY{bA^zuD2n>o68zMELQuVc1=A$qv9{>!*ASu`(+dCqACCJI87u^?#~=4 z>~=f%piriXaw`NJxW&ty#^PzB+!i!JIIvu3yC?|4oA#KEpIz^|NQ! zMh^ZS`XR}1iM|=0E2MQ~z8EhgV05uucjXr3Y0T3w4&74Z6JQ+@^=Ck~crY6m>zsTL zW&(wyA=duw*#Jc3^R#7=$r?`LHe08O6WcxOall5Fii-_6k@NW`##>4(&5VI~#MMRS z>YzIWvReB2a>Goc+u@72`bP8Mh*G={0FtamCuA|c&QL@*7l;Pv=0%1g`FibHdsth^ zzr-!kNmpcvNoK=S14UaQmTlCR@n0}HDOIw@YWOh@bTj$#WJ0oRo!xfD>(hEg=s?u* z)=RR&El8MahZIKkY)qb`bPP_Wbv&-S_VJOY2^IL8e%Z#aazE-j1&Je+5u2%~=IBS8 zuY|%gy1w}|T_5^p^bn&8wFHmlIF(rf6Sp(qr3(8LsCuwU%K)eWQoyFevK{o);Tsah zedEcg=OxY<0mMQVJNddA7k_@1;y#*Kq|Di(>l(03srzE0cHh3tOY09NS>#K_dt#2? z?ccXhY zH9jvjcBhl!COiA!j?<@eW<}9ejNcrm5l|CC@K#4Ag!jqXysZA@+CuZy_O->fAFD{= z8F6<2F!dHd<}f|&@0NcuF28$q;WcoEA`-&_#lLL7{(kk|z<0-gZpcx$yqJvM_Q%d*9v6oG4`*DdjXo2(l zP^e?vuNk;!w<$Asu&`xuqUrWl5s&er##H(+$&tkTW;vSBN*u$c^c=Cye}nZZYxDMn zH_*3v*In-z+h_WoVo|ahcwI7jRt@R1N?`=8-CBxT2ZBN?neW!xR29=h6<|{ugt41z zF?&cA46oWF@w0gBLJhS^3I{tFofT+;IzNWfOLrIE(~|`9ZJh!2>Tmm*&0`@>Z)I?5Gyb z!VuDOS3Ud8lRt)VhopnMJRH-bPxvK}Kg%1(UX*#D^6+*?@}89)OLsVj81B0;#VIX{ zDI2~q%}oeSDXGhR{*FWhhQ0}*ieo5sg>?8=&t&k diff --git a/trunk/lib/abyss/license.txt b/trunk/lib/abyss/license.txt deleted file mode 100644 index 1ee9c9fb4..000000000 --- a/trunk/lib/abyss/license.txt +++ /dev/null @@ -1,27 +0,0 @@ - ABYSS Web Server License - ------------------------ - -Copyright (C) 2000 by Moez Mahfoudh . All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. diff --git a/trunk/lib/abyss/src/Makefile b/trunk/lib/abyss/src/Makefile deleted file mode 100644 index 1078f4e9b..000000000 --- a/trunk/lib/abyss/src/Makefile +++ /dev/null @@ -1,167 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - ABYSSDIR := $(call updir,$(CURDIR)) - LIBDIR := $(call updir,$(ABYSSDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/abyss/src - -include $(BLDDIR)/config.mk - -default: all - -TARGET_LIBRARY_NAMES := libxmlrpc_abyss - -STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_abyss.a - -SHARED_LIBS_TO_BUILD := libxmlrpc_abyss -SHARED_LIBS_TO_INSTALL := libxmlrpc_abyss - -ifeq ($(findstring mingw,$(HOST_OS)),mingw) - THREAD_MODULE = thread_windows - SOCKET_MODS = socket_win -else - SOCKET_MODS = socket_unix - ifeq ($(MUST_BUILD_ABYSS_OPENSSL),yes) - SOCKET_MODS += socket_openssl - endif - - SOCKET_MODS += sockutil - - ifeq ($(ENABLE_ABYSS_THREADS),yes) - THREAD_MODULE = thread_pthread - else - THREAD_MODULE = thread_fork - endif -endif - -TARGET_MODS = \ - channel \ - chanswitch \ - conf \ - conn \ - data \ - date \ - file \ - handler \ - http \ - init \ - response \ - server \ - session \ - sessionReadRequest \ - socket \ - $(SOCKET_MODS) \ - token \ - $(THREAD_MODULE) \ - trace \ - - - -PKGCONFIG_FILES_TO_INSTALL := xmlrpc_abyss.pc - -OMIT_ABYSS_LIB_RULE = Y -MAJ=3 - # Major number of shared libraries in this directory - -include $(SRCDIR)/common.mk - -CFLAGS_LOCAL = -D_UNIX - -INCLUDES = \ - -Iblddir \ - -Iblddir/include \ - -Isrcdir \ - -Isrcdir/include \ - -Isrcdir/lib/util/include - -ABYSS_SHLIB = $(call shlibfn,libxmlrpc_abyss) -#ABYSS_SHLIB is e.g. libxmlrpc_abyss.so.3.1 -ABYSS_SHLIBLE = $(call shliblefn,libxmlrpc_abyss) -#ABYSS_SHLIBLE is e.g. libxmlrpc_abyss.so - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -.PHONY: all -all: libxmlrpc_abyss.a \ - $(TARGET_SHARED_LIBRARIES) \ - $(TARGET_SHARED_LE_LIBS) \ - $(PKGCONFIG_FILES_TO_INSTALL) \ - -# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES -$(ABYSS_SHLIB): $(TARGET_MODS:%=%.osh) \ - $(LIBXMLRPC_UTIL) -$(ABYSS_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) -$(ABYSS_SHLIB): LIBDEP = $(LIBXMLRPC_UTIL_LIBDEP) $(SOCKETLIBOPT) -ifeq ($(ENABLE_ABYSS_THREADS),yes) - $(ABYSS_SHLIB): LIBDEP += $(THREAD_LIBS) -endif -ifeq ($(MUST_BUILD_ABYSS_OPENSSL),yes) -$(ABYSS_SHLIB): LIBDEP += $(OPENSSL_LDADD) -endif - -# Rule for this is in common.mk, courtesy of TARGET_STATIC_LIBRARIES: - -libxmlrpc_abyss.a: $(TARGET_MODS:%=%.o) -libxmlrpc_abyss.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) - -#----------------------------------------------------------------------------- -# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES -#----------------------------------------------------------------------------- - -# Rules to compile object modules from which to build the static and shared -# Abyss library are in common.mk, courtesy of TARGET_MODS. - -socket_openssl.o socket_openssl.osh: CFLAGS_TARGET=$(OPENSSL_CFLAGS) - - -#----------------------------------------------------------------------------- -# RULES TO MAKE PKGCONFIG FILES -# -# (These are files used by the 'pkg-config' program to get information about -# using the libraries we build) -#----------------------------------------------------------------------------- - -SOCKLIB=$(SOCKETLIBOPT) - -xmlrpc_abyss.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_abyss" >>$@ - @echo "Description: Xmlrpc-c Abyss HTTP C library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_abyss $(SOCKLIB)" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -# Need this dependency for those who don't use depend.mk. -# Without it, version.h doesn't get created. -response.o response.osh handler.o handler.osh: version.h - -.PHONY: clean -clean: clean-common - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: tags -tags: TAGS - -.PHONY: distdir -distdir: - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: dep -dep: dep-common - -include depend.mk diff --git a/trunk/lib/abyss/src/abyss_info.h b/trunk/lib/abyss/src/abyss_info.h deleted file mode 100644 index 7d3131318..000000000 --- a/trunk/lib/abyss/src/abyss_info.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef ABYSS_INFO_H_INCLUDED -#define ABYSS_INFO_H_INCLUDED - -#include "version.h" /* defines XMLRPC_C_VERSION */ - -#define SERVER_HTML_INFO \ - "


" \ - "ABYSS Web Server for XML-RPC For C/C++ " \ - "version " XMLRPC_C_VERSION "
" \ - "

" - -#define SERVER_PLAIN_INFO \ - "\r\n" \ - "----------------------------------------" \ - "----------------------------------------\r\n" \ - "ABYSS Web Server for XML-RPC For C/C++ " \ - "version " XMLRPC_C_VERSION "\r\n" \ - "See xmlrpc-c.sourceforge.net" - -#endif diff --git a/trunk/lib/abyss/src/channel.c b/trunk/lib/abyss/src/channel.c deleted file mode 100644 index aee6be334..000000000 --- a/trunk/lib/abyss/src/channel.c +++ /dev/null @@ -1,198 +0,0 @@ -/*============================================================================ - socket.c -============================================================================== - Implementation of TChannel class: A generic channel over which one can - transport a bidirectional stream of bytes. - - A TChannel is a lot like a POSIX stream socket in "connected" state. -============================================================================*/ - -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "bool.h" -#include "int.h" -#include "mallocvar.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/abyss.h" -#if MSVCRT - #include "socket_win.h" -#else - #include "socket_unix.h" -#endif -#include "channel.h" - - - -static void -socketOsInit(const char ** const errorP) { - -#if MSVCRT - SocketWinInit(errorP); -#else - SocketUnixInit(errorP); -#endif -} - - - -static void -socketOsTerm(void) { - -#if MSVCRT - SocketWinTerm(); -#else - SocketUnixTerm(); -#endif -} - - - -bool ChannelTraceIsActive; - -void -ChannelInit(const char ** const errorP) { - - socketOsInit(errorP); - - if (!*errorP) { - ChannelTraceIsActive = (getenv("ABYSS_TRACE_CHANNEL") != NULL); - if (ChannelTraceIsActive) - fprintf(stderr, "Abyss channel layer will trace channel traffic " - "because of ABYSS_TRACE_CHANNEL environment variable\n"); - } -} - - - -void -ChannelTerm(void) { - - socketOsTerm(); -} - - - -/* ChannelCreate() is not exported to the Abyss user. It is meant to - be used by an implementation-specific TChannel generator which is - exported to the Abyss user, e.g. ChannelCreateUnix() in - socket_unix.c - - The TChannel generator functions are the _only_ user-accessible - functions that are particular to an implementation. -*/ - -static unsigned int const channelSignature = 0x06060B; - -void -ChannelCreate(const struct TChannelVtbl * const vtblP, - void * const implP, - TChannel ** const channelPP) { - - TChannel * channelP; - - MALLOCVAR(channelP); - - if (channelP) { - channelP->implP = implP; - channelP->vtbl = *vtblP; - channelP->signature = channelSignature; - *channelPP = channelP; - - if (ChannelTraceIsActive) - fprintf(stderr, "Created channel %p\n", channelP); - } -} - - - -void -ChannelDestroy(TChannel * const channelP) { - - if (ChannelTraceIsActive) - fprintf(stderr, "Destroying channel %p\n", channelP); - - assert(channelP->signature == channelSignature); - - channelP->vtbl.destroy(channelP); - - channelP->signature = 0; /* For debuggability */ - - free(channelP); -} - - - -void -ChannelWrite(TChannel * const channelP, - const unsigned char * const buffer, - uint32_t const len, - bool * const failedP) { - - if (ChannelTraceIsActive) - fprintf(stderr, "Writing %u bytes to channel %p\n", len, channelP); - - (*channelP->vtbl.write)(channelP, buffer, len, failedP); -} - - - -void -ChannelRead(TChannel * const channelP, - unsigned char * const buffer, - uint32_t const len, - uint32_t * const bytesReceivedP, - bool * const failedP) { - - if (ChannelTraceIsActive) - fprintf(stderr, "Reading %u bytes from channel %p\n", len, channelP); - - (*channelP->vtbl.read)(channelP, buffer, len, bytesReceivedP, failedP); -} - - - -void -ChannelWait(TChannel * const channelP, - bool const waitForRead, - bool const waitForWrite, - uint32_t const timems, - bool * const readyToReadP, - bool * const readyToWriteP, - bool * const failedP) { - - if (ChannelTraceIsActive) { - if (waitForRead) - fprintf(stderr, "Waiting %u milliseconds for data from " - "channel %p\n", timems, channelP); - if (waitForWrite) - fprintf(stderr, "Waiting %u milliseconds for channel %p " - "to be writable\n", timems, channelP); - } - (*channelP->vtbl.wait)(channelP, waitForRead, waitForWrite, timems, - readyToReadP, readyToWriteP, failedP); -} - - - -void -ChannelInterrupt(TChannel * const channelP) { - - if (ChannelTraceIsActive) - fprintf(stderr, "Interrupting channel waits\n"); - - (*channelP->vtbl.interrupt)(channelP); -} - - - -void -ChannelFormatPeerInfo(TChannel * const channelP, - const char ** const peerStringP) { - - (*channelP->vtbl.formatPeerInfo)(channelP, peerStringP); -} - diff --git a/trunk/lib/abyss/src/channel.h b/trunk/lib/abyss/src/channel.h deleted file mode 100644 index 6e5ae7e35..000000000 --- a/trunk/lib/abyss/src/channel.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef CHANNEL_H_INCLUDED -#define CHANNEL_H_INCLUDED - -/*============================================================================ - This is the generic channel interface for Abyss. It includes both - the generic interface to a channel from above and the interface - between generic channel code and a particular channel - implementation (e.g. POSIX socket) below. - - Abyss uses a channel to converse with an HTTP client. A channel is - oblivious to HTTP -- it just transports a byte stream in each direction. -============================================================================*/ - -#include "bool.h" -#include "int.h" -#include "xmlrpc-c/abyss.h" - -struct TChannelVtbl; - -void -ChannelCreate(const struct TChannelVtbl * const vtblP, - void * const implP, - TChannel ** const channelPP); - -typedef void ChannelDestroyImpl(TChannel * const channelP); - -typedef void ChannelWriteImpl(TChannel * const channelP, - const unsigned char * const buffer, - uint32_t const len, - bool * const failedP); - -typedef void ChannelReadImpl(TChannel * const channelP, - unsigned char * const buffer, - uint32_t const len, - uint32_t * const bytesReceivedP, - bool * const failedP); - -typedef uint32_t ChannelErrorImpl(TChannel * const channelP); - -typedef void ChannelWaitImpl(TChannel * const channelP, - bool const waitForRead, - bool const waitForWrite, - uint32_t const timems, - bool * const readyToReadP, - bool * const readyToWriteP, - bool * const failedP); - -typedef void ChannelInterruptImpl(TChannel * const channelP); - -typedef void ChannelFormatPeerInfoImpl(TChannel * const channelP, - const char ** const peerStringP); - -struct TChannelVtbl { - ChannelDestroyImpl * destroy; - ChannelWriteImpl * write; - ChannelReadImpl * read; - ChannelWaitImpl * wait; - ChannelInterruptImpl * interrupt; - ChannelFormatPeerInfoImpl * formatPeerInfo; -}; - -struct _TChannel { - unsigned int signature; - /* With both background and foreground use of sockets, and - background being both fork and pthread, it is very easy to - screw up socket lifetime and try to destroy twice. We use - this signature to help catch such bugs. - */ - void * implP; - struct TChannelVtbl vtbl; -}; - -#define TIME_INFINITE 0xffffffff - -extern bool ChannelTraceIsActive; - -void -ChannelInit(const char ** const errorP); - -void -ChannelTerm(void); - -void -ChannelWrite(TChannel * const channelP, - const unsigned char * const buffer, - uint32_t const len, - bool * const failedP); - -void -ChannelRead(TChannel * const channelP, - unsigned char * const buffer, - uint32_t const len, - uint32_t * const bytesReceivedP, - bool * const failedP); - -void -ChannelWait(TChannel * const channelP, - bool const waitForRead, - bool const waitForWrite, - uint32_t const timems, - bool * const readyToReadP, - bool * const readyToWriteP, - bool * const failedP); - -void -ChannelInterrupt(TChannel * const channelP); - -void -ChannelFormatPeerInfo(TChannel * const channelP, - const char ** const peerStringP); - -#endif diff --git a/trunk/lib/abyss/src/chanswitch.c b/trunk/lib/abyss/src/chanswitch.c deleted file mode 100644 index a686aafa4..000000000 --- a/trunk/lib/abyss/src/chanswitch.c +++ /dev/null @@ -1,252 +0,0 @@ -/*============================================================================ - socket.c -============================================================================== - Implementation of TChanSwitch class: A generic channel switch -- an object - that brokers a connection between an HTTP client and server. -============================================================================*/ - -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "bool.h" -#include "int.h" -#include "mallocvar.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/abyss.h" -#if MSVCRT - #include "socket_win.h" -#endif -#if !MSVCRT - #include "socket_unix.h" -#endif -#if HAVE_ABYSS_OPENSSL - #include "socket_openssl.h" -#endif -#include "chanswitch.h" - - - -static void -socketWinInit(const char ** const errorP) { -#if MSVCRT - SocketWinInit(errorP); -#else - *errorP = NULL; -#endif -} - - - -static void -socketWinTerm(void) { -#if MSVCRT - SocketWinTerm(); -#endif -} - - - -static void -socketUnixInit(const char ** const errorP) { -#if !MSVCRT - SocketUnixInit(errorP); -#else - *errorP = NULL; -#endif -} - - - -static void -socketUnixTerm(void) { -#if !MSVCRT - SocketUnixTerm(); -#endif -} - - - -static void -socketOpenSslTerm(void) { -#if HAVE_ABYSS_OPENSSL - SocketOpenSslTerm(); -#endif -} - - - -static void -socketOpenSslInit(const char ** const errorP) { -#if HAVE_ABYSS_OPENSSL - SocketOpenSslInit(errorP); -#else - *errorP = NULL; -#endif -} - - - -static void -socketOsInit(const char ** const errorP) { - - socketWinInit(errorP); - if (!*errorP) { - socketUnixInit(errorP); - if (!*errorP) { - socketOpenSslInit(errorP); - - if (*errorP) - socketUnixTerm(); - } - if (*errorP) - socketWinTerm(); - } -} - - - -static void -socketOsTerm(void) { - - socketOpenSslTerm(); - - socketUnixTerm(); - - socketWinTerm(); -} - - - -bool SwitchTraceIsActive; - -void -ChanSwitchInit(const char ** const errorP) { - - socketOsInit(errorP); - - if (!*errorP) { - SwitchTraceIsActive = (getenv("ABYSS_TRACE_SWITCH") != NULL); - if (SwitchTraceIsActive) - fprintf(stderr, "Abyss channel switch layer will trace " - "channel connection activity " - "because of ABYSS_TRACE_SWITCH environment variable\n"); - } -} - - - -void -ChanSwitchTerm(void) { - - socketOsTerm(); -} - - - -/* ChanSwitchCreate() is not exported to the Abyss user. It is meant to - be used by an implementation-specific TChanSwitch generator which is - exported to the Abyss user, e.g. SwitchCreateUnix() in - socket_unix.c - - The TChanSwitch generator functions are the _only_ user-accessible - functions that are particular to an implementation. -*/ - -static unsigned int const switchSignature = 0x06060A; - -void -ChanSwitchCreate(const struct TChanSwitchVtbl * const vtblP, - void * const implP, - TChanSwitch ** const chanSwitchPP) { - - TChanSwitch * chanSwitchP; - - MALLOCVAR(chanSwitchP); - - if (chanSwitchP) { - chanSwitchP->implP = implP; - chanSwitchP->vtbl = *vtblP; - chanSwitchP->signature = switchSignature; - - if (SwitchTraceIsActive) - fprintf(stderr, "Created channel switch %p\n", chanSwitchP); - - *chanSwitchPP = chanSwitchP; - } -} - - - -void -ChanSwitchDestroy(TChanSwitch * const chanSwitchP) { - - if (SwitchTraceIsActive) - fprintf(stderr, "Destroying channel switch %p\n", chanSwitchP); - - assert(chanSwitchP->signature == switchSignature); - - chanSwitchP->vtbl.destroy(chanSwitchP); - - chanSwitchP->signature = 0; /* For debuggability */ - - free(chanSwitchP); -} - - - -void -ChanSwitchListen(TChanSwitch * const chanSwitchP, - uint32_t const backlog, - const char ** const errorP) { - - if (SwitchTraceIsActive) - fprintf(stderr, "Channel switch %p listening.\n", chanSwitchP); - - (*chanSwitchP->vtbl.listen)(chanSwitchP, backlog, errorP); - - if (!*errorP) - chanSwitchP->isListening = true; -} - - - -void -ChanSwitchAccept(TChanSwitch * const chanSwitchP, - TChannel ** const channelPP, - void ** const channelInfoPP, - const char ** const errorP) { - - if (!chanSwitchP->isListening) - xmlrpc_asprintf(errorP, "Attempt to accept next connection from a " - "channel switch that is not listening " - "for connections"); - else { - if (SwitchTraceIsActive) - fprintf(stderr, "Getting a connection from Channel switch %p...\n", - chanSwitchP); - - (*chanSwitchP->vtbl.accept)(chanSwitchP, - channelPP, channelInfoPP, errorP); - - if (SwitchTraceIsActive && *errorP == NULL) - fprintf(stderr, "Got connection from channel switch. " - "Channel = %p\n", *channelPP); - } -} - - - -void -ChanSwitchInterrupt(TChanSwitch * const chanSwitchP) { - - if (SwitchTraceIsActive) - fprintf(stderr, "Interrupting wait for a connection " - "by Channel switch %p...\n", - chanSwitchP); - - (*chanSwitchP->vtbl.interrupt)(chanSwitchP); -} diff --git a/trunk/lib/abyss/src/chanswitch.h b/trunk/lib/abyss/src/chanswitch.h deleted file mode 100644 index 298360f9f..000000000 --- a/trunk/lib/abyss/src/chanswitch.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef CHANSWITCH_H_INCLUDED -#define CHANSWITCH_H_INCLUDED - -/*============================================================================ - This is the generic channel switch interface for Abyss. It - includes both the generic interface to a channel switch from above - and the interface between generic channel switch code and a - particular channel implementation (e.g. POSIX) below. - - A channel switch is what creates a channel -- it brokers a connection - between an HTTP client and server. -============================================================================*/ - -#include "bool.h" -#include "int.h" -#include "xmlrpc-c/abyss.h" - -typedef void SwitchDestroyImpl(TChanSwitch * const socketP); - -typedef void SwitchListenImpl(TChanSwitch * const chanSwitchP, - uint32_t const backlog, - const char ** const errorP); - -typedef void SwitchAcceptImpl(TChanSwitch * const chanSwitchP, - TChannel ** const channelPP, - void ** const channelInfoP, - const char ** const errorP); - -typedef void SwitchInterruptImpl(TChanSwitch * const chanSwitchP); - -struct TChanSwitchVtbl { - SwitchDestroyImpl * destroy; - SwitchListenImpl * listen; - SwitchAcceptImpl * accept; - SwitchInterruptImpl * interrupt; -}; - -struct _TChanSwitch { - unsigned int signature; - /* With both background and foreground use of switches, and - background being both fork and pthread, it is very easy to - screw up switch lifetime and try to destroy twice. We use - this signature to help catch such bugs. - */ - void * implP; - struct TChanSwitchVtbl vtbl; - bool isListening; - /* The switch is in listening state; i.e. user has done a successful - ChanSwitchListen(). - */ -}; - -extern bool SwitchTraceIsActive; - -void -ChanSwitchInit(const char ** const errorP); - -void -ChanSwitchTerm(void); - -void -ChanSwitchCreate(const struct TChanSwitchVtbl * const vtblP, - void * const implP, - TChanSwitch ** const chanSwitchPP); - -void -ChanSwitchListen(TChanSwitch * const chanSwitchP, - uint32_t const backlog, - const char ** const errorP); - -void -ChanSwitchAccept(TChanSwitch * const chanSwitchP, - TChannel ** const channelPP, - void ** const channelInfoPP, - const char ** const errorP); - -void -ChanSwitchInterrupt(TChanSwitch * const chanSwitchP); - -#endif - - diff --git a/trunk/lib/abyss/src/conf.c b/trunk/lib/abyss/src/conf.c deleted file mode 100644 index 4b00eb36a..000000000 --- a/trunk/lib/abyss/src/conf.c +++ /dev/null @@ -1,398 +0,0 @@ -/****************************************************************************** -** -** conf.c -** -** This file is part of the ABYSS Web server project. -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ - -#define _XOPEN_SOURCE 600 /* For strdup() */ -#define _BSD_SOURCE /* For xmlrpc_strcaseeq */ - -#include "xmlrpc_config.h" - -#include -#include -#include - -#if MSVCRT -#include -#endif - -#if !MSVCRT -#include -#endif - -#include "bool.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/abyss.h" -#include "trace.h" -#include "file.h" -#include "server.h" -#include "http.h" -#include "handler.h" - -/********************************************************************* -** Configuration Files Parsing Functions -*********************************************************************/ - - - -static bool -ConfReadLine(TFile * const fileP, - char * const buffer, - uint32_t const lenArg) { - - bool r; - char c; - char * p; - char * z; - uint32_t len; - - len = lenArg; /* initial value */ - r = true; /* initial value */ - z = buffer; /* initial value */ - - while (--len > 0) { - int32_t bytesRead; - - bytesRead = FileRead(fileP, z, 1); - if (bytesRead < 1) { - if (z == buffer) - r = false; - break; - }; - - if (*z == '\r' || *z == '\n') - break; - - ++z; - } - - if (len == 0) - while (FileRead(fileP, &c, 1) == 1) - if (c == '\r' || c == '\n') - break; - - *z = '\0'; - - /* Discard comments */ - p = strchr(buffer, '#'); - if (p) - *p = '\0'; - - return r; -} - - - -static bool -ConfNextToken(char ** const p) { - - while (1) - switch (**p) { - case '\t': - case ' ': - (*p)++; - break; - case '\0': - return false; - default: - return true; - }; -} - -static char * -ConfGetToken(char **p) { - char *p0=*p; - - while (1) - switch (**p) - { - case '\t': - case ' ': - case '\r': - case '\n': - case '\0': - if (p0==*p) - return NULL; - - if (**p) - { - **p='\0'; - (*p)++; - }; - return p0; - - default: - (*p)++; - }; -} - -static bool -ConfReadInt(const char * const p, - int32_t * const n, - int32_t const min, - int32_t const max) { -/*---------------------------------------------------------------------------- - Convert string 'p' to integer *n. - - If it isn't a valid integer or is not with the bounds [min, max], - return false. Otherwise, return true. ------------------------------------------------------------------------------*/ - char * e; - - *n = strtol(p, &e, 10); - - if (min != max) - return ((e != p) && (*n >= min) && (*n <= max)); - else - return (e != p); -} - - - -static bool -ConfReadBool(const char * const token, - bool * const bP) { - - bool succeeded; - - if (xmlrpc_strcaseeq(token, "yes")) { - *bP = true; - succeeded = true; - } else if (xmlrpc_strcaseeq(token, "no")) { - *bP = false; - succeeded = true; - } else - succeeded = false; - - return succeeded; -} - -/********************************************************************* -** MIME Types File -*********************************************************************/ - -static void -readMIMETypesFile(const char * const filename, - MIMEType ** const MIMETypePP) { - - bool success; - MIMEType * MIMETypeP; - - MIMETypeP = MIMETypeCreate(); - if (MIMETypeP) { - TFile * fileP; - bool fileOpened; - - fileOpened = FileOpen(&fileP, filename, O_RDONLY); - if (fileOpened) { - char z[512]; - while (ConfReadLine(fileP, z, 512)) { - char * p; - p = &z[0]; - - if (ConfNextToken(&p)) { - const char * mimetype = ConfGetToken(&p); - if (mimetype) { - while (ConfNextToken(&p)) { - const char * const ext = ConfGetToken(&p); - if (ext) - MIMETypeAdd2(MIMETypeP, mimetype, ext); - else - break; - } - } - } - } - FileClose(fileP); - success = true; - } else - success = false; - if (!success) - MIMETypeDestroy(MIMETypeP); - } else - success = false; - - if (success) - *MIMETypePP = MIMETypeP; - else - *MIMETypePP = NULL; -} - -/********************************************************************* -** Server Configuration File -*********************************************************************/ - -static void -chdirx(const char * const newdir, - bool * const successP) { - - *successP = XMLRPC_CHDIR(newdir) == 0; -} - - - -static void -parseUser(const char * const p, - struct _TServer * const srvP) { -#if MSVCRT - /* *srvP has no 'uid' or 'gid' member; system has no getpwnam() */ - TraceMsg("User option ignored"); -#else - if (p[0] == '#') { - int32_t n; - - if (!ConfReadInt(&p[1], &n, 0, 0)) - TraceExit("Bad user number '%s'", p); - else - srvP->uid = n; - } else { - struct passwd * pwd; - - if (!(pwd = getpwnam(p))) - TraceExit("Unknown user '%s'", p); - - srvP->uid = pwd->pw_uid; - if ((int)srvP->gid==(-1)) - srvP->gid = pwd->pw_gid; - }; -#endif -} - - - -static void -parsePidfile(const char * const p, - struct _TServer * const srvP) { - bool succeeded; - succeeded = FileOpenCreate(&srvP->pidfileP, p, O_TRUNC | O_WRONLY); - if (!succeeded) { - srvP->pidfileP = NULL; - TraceMsg("Bad PidFile value '%s'", p); - }; -} - - - -abyss_bool -ConfReadServerFile(const char * const filename, - TServer * const serverP) { - - struct _TServer * const srvP = serverP->srvP; - BIHandler * const handlerP = srvP->builtinHandlerP; - - TFile * fileP; - char z[512]; - char * p; - unsigned int lineNum; - TFileStat fs; - - if (!FileOpen(&fileP, filename, O_RDONLY)) - return false; - - lineNum = 0; - - while (ConfReadLine(fileP, z, 512)) { - ++lineNum; - p = z; - - if (ConfNextToken(&p)) { - const char * const option = ConfGetToken(&p); - if (option) { - ConfNextToken(&p); - - if (xmlrpc_strcaseeq(option, "port")) { - int32_t n; - if (ConfReadInt(p, &n, 1, 65535)) - srvP->port = n; - else - TraceExit("Invalid port '%s'", p); - } else if (xmlrpc_strcaseeq(option, "serverroot")) { - bool success; - chdirx(p, &success); - if (!success) - TraceExit("Invalid server root '%s'",p); - } else if (xmlrpc_strcaseeq(option, "path")) { - if (FileStat(p, &fs)) - if (fs.st_mode & S_IFDIR) { - HandlerSetFilesPath(handlerP, p); - continue; - } - TraceExit("Invalid path '%s'", p); - } else if (xmlrpc_strcaseeq(option, "default")) { - const char * filename; - - while ((filename = ConfGetToken(&p))) { - HandlerAddDefaultFN(handlerP, filename); - if (!ConfNextToken(&p)) - break; - } - } else if (xmlrpc_strcaseeq(option, "keepalive")) { - int32_t n; - if (ConfReadInt(p, &n, 1, 65535)) - srvP->keepalivemaxconn = n; - else - TraceExit("Invalid KeepAlive value '%s'", p); - } else if (xmlrpc_strcaseeq(option, "timeout")) { - int32_t n; - if (ConfReadInt(p, &n, 1, 3600)) { - srvP->keepalivetimeout = n; - /* Must see what to do with that */ - srvP->timeout = n; - } else - TraceExit("Invalid TimeOut value '%s'", p); - } else if (xmlrpc_strcaseeq(option, "mimetypes")) { - MIMEType * mimeTypeP; - readMIMETypesFile(p, &mimeTypeP); - if (!mimeTypeP) - TraceExit("Can't read MIME Types file '%s'", p); - else - HandlerSetMimeType(handlerP, mimeTypeP); - } else if (xmlrpc_strcaseeq(option,"logfile")) { - srvP->logfilename = strdup(p); - } else if (xmlrpc_strcaseeq(option,"user")) { - parseUser(p, srvP); - } else if (xmlrpc_strcaseeq(option, "pidfile")) { - parsePidfile(p, srvP); - } else if (xmlrpc_strcaseeq(option, "advertiseserver")) { - if (!ConfReadBool(p, &srvP->advertise)) - TraceExit("Invalid boolean value " - "for AdvertiseServer option"); - } else - TraceExit("Invalid option '%s' at line %u", - option, lineNum); - } - } - } - - FileClose(fileP); - return true; -} diff --git a/trunk/lib/abyss/src/conn.c b/trunk/lib/abyss/src/conn.c deleted file mode 100644 index 1c281654b..000000000 --- a/trunk/lib/abyss/src/conn.c +++ /dev/null @@ -1,665 +0,0 @@ -/* Copyright information is at the end of the file. */ - -#include -#include -#include -#include -#include -#include - -#include "bool.h" -#include "mallocvar.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/sleep_int.h" -#include "xmlrpc-c/abyss.h" -#include "channel.h" -#include "server.h" -#include "thread.h" -#include "file.h" - -#include "conn.h" - -/********************************************************************* -** Conn -*********************************************************************/ - -static TThreadProc connJob; - -static void -connJob(void * const userHandle) { -/*---------------------------------------------------------------------------- - This is the root function for a thread that processes a connection - (performs HTTP transactions). - - We never return. We ultimately exit the thread. ------------------------------------------------------------------------------*/ - TConn * const connectionP = userHandle; - - (connectionP->job)(connectionP); - - connectionP->finished = true; - /* Note that if we are running in a forked process, setting - connectionP->finished has no effect, because it's just our own - copy of *connectionP. In this case, Parent must update his own - copy based on a SIGCHLD signal that the OS will generate right - after we exit. - */ - - - /* Note that ThreadExit() runs a cleanup function, which in our - case is connDone(). - */ - ThreadExit(connectionP->threadP, 0); -} - - - -/* This is the maximum amount of stack that 'connJob' itself uses -- - does not count what user's connection job function uses. -*/ -#define CONNJOB_STACK 1024 - - - -static void -connDone(TConn * const connectionP) { - - /* In the forked case, this is designed to run in the parent - process after the child has terminated. - */ - connectionP->finished = true; - - if (connectionP->done) - connectionP->done(connectionP); -} - - - -static TThreadDoneFn threadDone; - -static void -threadDone(void * const userHandle) { - - TConn * const connectionP = userHandle; - - connDone(connectionP); -} - - - -static void -makeThread(TConn * const connectionP, - enum abyss_foreback const foregroundBackground, - bool const useSigchld, - size_t const jobStackSize, - const char ** const errorP) { - - switch (foregroundBackground) { - case ABYSS_FOREGROUND: - connectionP->hasOwnThread = false; - *errorP = NULL; - break; - case ABYSS_BACKGROUND: { - const char * error; - connectionP->hasOwnThread = true; - ThreadCreate(&connectionP->threadP, connectionP, - &connJob, &threadDone, useSigchld, - CONNJOB_STACK + jobStackSize, - &error); - if (error) { - xmlrpc_asprintf(errorP, "Unable to create thread to " - "process connection. %s", error); - xmlrpc_strfree(error); - } else - *errorP = NULL; - } break; - } /* switch */ -} - - - -void -ConnCreate(TConn ** const connectionPP, - TServer * const serverP, - TChannel * const channelP, - void * const channelInfoP, - TThreadProc * const job, - size_t const jobStackSize, - TThreadDoneFn * const done, - enum abyss_foreback const foregroundBackground, - bool const useSigchld, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Create an HTTP connection. - - A connection carries one or more HTTP transactions (request/response). - - *channelP transports the requests and responses. - - The connection handles those HTTP requests. - - The connection handles the requests primarily by running the - function 'job' once. Some connections can do that autonomously, as - soon as the connection is created. Others don't until Caller - subsequently calls ConnProcess. Some connections complete the - processing before ConnProcess returns, while others may run the - connection asynchronously to the creator, in the background, via a - TThread thread. 'foregroundBackground' determines which. - - 'job' calls methods of the connection to get requests and send - responses. - - Some time after the HTTP transactions are all done, 'done' gets - called in some context. - - 'channelInfoP' == NULL means no channel info supplied. ------------------------------------------------------------------------------*/ - TConn * connectionP; - - MALLOCVAR(connectionP); - - if (connectionP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for a connection " - "descriptor."); - else { - connectionP->server = serverP; - connectionP->channelP = channelP; - connectionP->channelInfoP = channelInfoP; - connectionP->buffer.b[0] = '\0'; - connectionP->buffersize = 0; - connectionP->bufferpos = 0; - connectionP->finished = false; - connectionP->job = job; - connectionP->done = done; - connectionP->inbytes = 0; - connectionP->outbytes = 0; - connectionP->trace = getenv("ABYSS_TRACE_CONN"); - - makeThread(connectionP, foregroundBackground, useSigchld, - jobStackSize, errorP); - } - *connectionPP = connectionP; -} - - - -uint32_t -ConnBufferSpace(TConn * const connectionP) { -/*----------------------------------------------------------------------------- - The amount of space left at the end of the connection buffer. - - Note that the space before the read pointer (connectionP->bufferpos) - is also unused, but we don't consider that. ------------------------------------------------------------------------------*/ - assert(connectionP->buffersize + 1 <= BUFFER_SIZE); - - return BUFFER_SIZE - connectionP->buffersize - 1; - /* - 1 is because we reserve the last byte of the buffer for a NUL. */ -} - - - -bool -ConnProcess(TConn * const connectionP) { -/*---------------------------------------------------------------------------- - Drive the main processing of a connection -- run the connection's - "job" function, which should read HTTP requests from the connection - and send HTTP responses. - - If we succeed, we guarantee the connection's "done" function will get - called some time after all processing is complete. It might be before - we return or some time after. If we fail, we guarantee the "done" - function will not be called. ------------------------------------------------------------------------------*/ - bool retval; - - if (connectionP->hasOwnThread) { - /* There's a background thread to handle this connection. Set - it running. - */ - assert(connectionP->threadP); - retval = ThreadRun(connectionP->threadP); - } else { - /* No background thread. We just handle it here while Caller waits. */ - (connectionP->job)(connectionP); - connDone(connectionP); - retval = true; - } - return retval; -} - - - -void -ConnWaitAndRelease(TConn * const connectionP) { - - if (connectionP->hasOwnThread) { - assert(connectionP->threadP); - ThreadWaitAndRelease(connectionP->threadP); - } - free(connectionP); -} - - - -bool -ConnKill(TConn * const connectionP) { - connectionP->finished = true; - return ThreadKill(connectionP->threadP); -} - - - -void -ConnReadInit(TConn * const connectionP) { -/*----------------------------------------------------------------------------- - Prepare to read data from the channel into the connection buffer. - - The connection buffer is not circular, so to make maximal room available - for this new data, we move everything now in the buffer (not yet - delivered to our client) down to the beginning of the buffer. Caller - can then read from the end of that data through the end of the buffer. ------------------------------------------------------------------------------*/ - if (connectionP->buffersize > connectionP->bufferpos) { - connectionP->buffersize -= connectionP->bufferpos; - memmove(connectionP->buffer.b, - connectionP->buffer.b + connectionP->bufferpos, - connectionP->buffersize); - connectionP->bufferpos = 0; - } else - connectionP->buffersize = connectionP->bufferpos = 0; - - connectionP->buffer.b[connectionP->buffersize] = '\0'; - - connectionP->inbytes = connectionP->outbytes = 0; -} - - - -static void -traceReadTimeout(TConn * const connectionP, - uint32_t const timeout) { - - if (connectionP->trace) - fprintf(stderr, "TIMED OUT waiting over %u seconds " - "for data from client.\n", timeout); -} - - - -static size_t -nextLineSize(const char * const string, - size_t const startPos, - size_t const stringSize) { -/*---------------------------------------------------------------------------- - Return the length of the line that starts at offset 'startPos' in the - string 'string', which is 'stringSize' characters long. - - 'string' in not NUL-terminated. - - A line begins at beginning of string or after a newline character and - runs through the next newline character or end of string. The line - includes the newline character at the end, if any. ------------------------------------------------------------------------------*/ - size_t i; - - for (i = startPos; i < stringSize && string[i] != '\n'; ++i); - - if (i < stringSize) - ++i; /* Include the newline */ - - return i - startPos; -} - - - -static void -traceBuffer(const char * const label, - const unsigned char * const buffer, - unsigned int const size) { - - const char * const buffer_t = (const char *)buffer; - - size_t cursor; /* Index into buffer[] */ - - fprintf(stderr, "%s:\n\n", label); - - for (cursor = 0; cursor < size; ) { - /* Print one line of buffer */ - - size_t const lineSize = nextLineSize(buffer_t, cursor, size); - const char * const printableLine = - xmlrpc_makePrintable_lp(&buffer_t[cursor], lineSize); - - fprintf(stderr, "%s\n", printableLine); - - cursor += lineSize; - - xmlrpc_strfree(printableLine); - } - fprintf(stderr, "\n"); -} - - - -static void -traceBufferText(const char * const label, - const char * const buffer, - unsigned int const size) { - - traceBuffer(label, (const unsigned char *)buffer, size); -} - - - -static void -traceChannelRead(TConn * const connectionP, - unsigned int const size) { - - if (connectionP->trace) - traceBuffer("READ FROM CHANNEL", - connectionP->buffer.b + connectionP->buffersize, size); -} - - - -static void -traceChannelWrite(TConn * const connectionP, - const char * const buffer, - unsigned int const size, - bool const failed) { - - if (connectionP->trace) { - const char * const label = - failed ? "FAILED TO WRITE TO CHANNEL" : "WROTE TO CHANNEL"; - traceBufferText(label, buffer, size); - } -} - - - -static void -readFromChannel(TConn * const connectionP, - bool * const eofP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Read some data from the channel of Connection *connectionP into the - connection buffer. - - Iff there are no more bytes forthcoming on the channel, return *eofP == - true. - - Wait if necessary for at least one byte to arrive, or to learn that there - are no more bytes coming (EOF). But don't wait for any more than that - - just read whatever is immediately available past that first byte. - - Fail if the buffer is full. ------------------------------------------------------------------------------*/ - uint32_t bytesRead; - bool readError; - - assert(connectionP->buffersize <= BUFFER_SIZE); - - if (BUFFER_SIZE - connectionP->buffersize < 2) - xmlrpc_asprintf(errorP, "Connection buffer full."); - else { - ChannelRead(connectionP->channelP, - connectionP->buffer.b + connectionP->buffersize, - BUFFER_SIZE - connectionP->buffersize - 1, - &bytesRead, &readError); - - if (readError) - xmlrpc_asprintf(errorP, "Error reading from channel"); - else { - *errorP = NULL; - if (bytesRead > 0) { - *eofP = false; - traceChannelRead(connectionP, bytesRead); - connectionP->inbytes += bytesRead; - connectionP->buffersize += bytesRead; - connectionP->buffer.t[connectionP->buffersize] = '\0'; - } else - *eofP = true; - } - } -} - - - -static void -dealWithReadTimeout(bool * const timedOutP, - bool const timedOut, - uint32_t const timeout, - const char ** const errorP) { - - if (timedOutP) - *timedOutP = timedOut; - else { - if (timedOut) - xmlrpc_asprintf(errorP, "Read from Abyss client " - "connection timed out after %u seconds " - "or was interrupted", - timeout); - } -} - - - -static void -dealWithReadEof(bool * const eofP, - bool const eof, - const char ** const errorP) { - - if (eofP) - *eofP = eof; - else { - if (eof) - xmlrpc_asprintf(errorP, "Read from Abyss client " - "connection failed because client closed the " - "connection"); - } -} - - - -void -ConnRead(TConn * const connectionP, - uint32_t const timeout, - bool * const eofP, - bool * const timedOutP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Read some stuff on connection *connectionP from the channel. Read it into - the connection's buffer. - - Don't wait more than 'timeout' seconds for data to arrive. If no data has - arrived by then and 'timedOutP' is null, fail. If 'timedOut' is non-null, - return as *timedOutP whether 'timeout' seconds passed without any data - arriving. - - Also, stop waiting upon any interruption and treat it the same as a - timeout. An interruption is either a signal received (and caught) at - an appropriate time or a ChannelInterrupt() call before or during the - wait. - - If 'eofP' is non-null, return *eofP == true, without reading anything, iff - there will no more data forthcoming on the connection because client has - closed the connection. If 'eofP' is null, fail in that case. - - Fail if the connection buffer is full. (Caller can use ConnBufferSpace() - to find out beforehand if this is going to be a problem). ------------------------------------------------------------------------------*/ - uint32_t const timeoutMs = timeout * 1000; - - if (timeoutMs < timeout) - /* Arithmetic overflow */ - xmlrpc_asprintf(errorP, "Timeout value is too large"); - else { - bool const waitForRead = true; - bool const waitForWrite = false; - - bool readyForRead; - bool failed; - - ChannelWait(connectionP->channelP, waitForRead, waitForWrite, - timeoutMs, &readyForRead, NULL, &failed); - - if (failed) - xmlrpc_asprintf(errorP, - "Wait for stuff to arrive from client failed."); - else { - bool eof; - if (readyForRead) { - readFromChannel(connectionP, &eof, errorP); - } else { - /* Wait was interrupted, either by our requested timeout, - a (caught) signal, or a ChannelInterrupt(). - */ - traceReadTimeout(connectionP, timeout); - *errorP = NULL; - eof = false; - } - if (!*errorP) - dealWithReadTimeout(timedOutP, !readyForRead, timeout, errorP); - if (!*errorP) - dealWithReadEof(eofP, eof, errorP); - } - } -} - - - -bool -ConnWrite(TConn * const connectionP, - const void * const buffer, - uint32_t const size) { - - bool failed; - - ChannelWrite(connectionP->channelP, buffer, size, &failed); - - traceChannelWrite(connectionP, buffer, size, failed); - - if (!failed) - connectionP->outbytes += size; - - return !failed; -} - - - -bool -ConnWriteFromFile(TConn * const connectionP, - const TFile * const fileP, - uint64_t const start, - uint64_t const last, - void * const buffer, - uint32_t const buffersize, - uint32_t const rate) { -/*---------------------------------------------------------------------------- - Write the contents of the file stream *fileP, from offset 'start' - up through 'last', to the HTTP connection *connectionP. - - Meter the reading so as not to read more than 'rate' bytes per second. - - Use the 'bufferSize' bytes at 'buffer' as an internal buffer for this. ------------------------------------------------------------------------------*/ - bool retval; - uint32_t waittime; - bool success; - uint32_t readChunkSize; - - if (rate > 0) { - readChunkSize = MIN(buffersize, rate); /* One second's worth */ - waittime = (1000 * buffersize) / rate; - } else { - readChunkSize = buffersize; - waittime = 0; - } - - success = FileSeek(fileP, start, SEEK_SET); - if (!success) - retval = false; - else { - uint64_t const totalBytesToRead = last - start + 1; - uint64_t bytesread; - - bytesread = 0; /* initial value */ - - while (bytesread < totalBytesToRead) { - uint64_t const bytesLeft = totalBytesToRead - bytesread; - uint64_t const bytesToRead64 = MIN(readChunkSize, bytesLeft); - uint32_t const bytesToRead = (uint32_t)bytesToRead64; - - uint32_t bytesReadThisTime; - - assert(bytesToRead == bytesToRead64); /* readChunkSize is uint32 */ - - bytesReadThisTime = FileRead(fileP, buffer, bytesToRead); - bytesread += bytesReadThisTime; - - if (bytesReadThisTime > 0) - ConnWrite(connectionP, buffer, bytesReadThisTime); - else - break; - - if (waittime > 0) - xmlrpc_millisecond_sleep(waittime); - } - retval = (bytesread >= totalBytesToRead); - } - return retval; -} - - - -TServer * -ConnServer(TConn * const connectionP) { - return connectionP->server; -} - - - -void -ConnFormatClientAddr(TConn * const connectionP, - const char ** const clientAddrPP) { - - ChannelFormatPeerInfo(connectionP->channelP, clientAddrPP); -} - - - -/******************************************************************************* -** -** conn.c -** -** This file is part of the ABYSS Web server project. -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ diff --git a/trunk/lib/abyss/src/conn.h b/trunk/lib/abyss/src/conn.h deleted file mode 100644 index e805d93e9..000000000 --- a/trunk/lib/abyss/src/conn.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef CONN_H_INCLUDED -#define CONN_H_INCLUDED - -#include "bool.h" -#include "xmlrpc-c/abyss.h" -#include "thread.h" - -struct TFile; - -#define BUFFER_SIZE 4097 - /* It's a typical page size plus a byte because we always make sure the - data in the buffer ends with an ASCII NUL, and this way in a large - transfer we actually transfer in 4096 byte chunks. - */ - -struct _TConn { - struct _TConn * nextOutstandingP; - /* Link to the next connection in the list of outstanding - connections - */ - TServer * server; - uint32_t buffersize; - /* Index into the connection buffer (buffer[], below) where - the next byte read on the connection will go. - */ - uint32_t bufferpos; - /* Index into the connection buffer (buffer[], below) where - the next byte to be delivered to the user is. - */ - uint32_t inbytes,outbytes; - TChannel * channelP; - void * channelInfoP; - /* Information about the channel, such as who is on the other end. - Format depends on the type of channel. The user of the connection - is expected to know that type, because he supplied the channel - when he created the channel. - - NULL means no channel info is available. - */ - bool hasOwnThread; - TThread * threadP; - bool finished; - /* We have done all the processing there is to do on this - connection, other than possibly notifying someone that we're - done. One thing this signifies is that any thread or process - that the connection spawned is dead or will be dead soon, so - one could reasonably wait for it to be dead, e.g. with - pthread_join(). Note that one can scan a bunch of processes - for 'finished' status, but sometimes can't scan a bunch of - threads for liveness. - */ - const char * trace; - TThreadProc * job; - /* The function to run, in a connection thread, to conduct business - on the connection. It reads stuff and writes stuff and, when it - is done with the connection, exits. - */ - TThreadDoneFn * done; - union { - unsigned char b[BUFFER_SIZE]; /* Just bytes */ - char t[BUFFER_SIZE]; /* Taken as text */ - } buffer; -}; - -typedef struct _TConn TConn; - -TConn * ConnAlloc(void); - -void ConnFree(TConn * const connectionP); - -void -ConnCreate(TConn ** const connectionPP, - TServer * const serverP, - TChannel * const channelP, - void * const channelInfoP, - TThreadProc * const job, - size_t const jobStackSize, - TThreadDoneFn * const done, - enum abyss_foreback const foregroundBackground, - bool const useSigchld, - const char ** const errorP); - -uint32_t -ConnBufferSpace(TConn * const connectionP); - -bool -ConnProcess(TConn * const connectionP); - -bool -ConnKill(TConn * const connectionP); - -void -ConnWaitAndRelease(TConn * const connectionP); - -bool -ConnWrite(TConn * const connectionP, - const void * const buffer, - uint32_t const size); - -void -ConnRead(TConn * const connectionP, - uint32_t const timeout, - bool * const eofP, - bool * const timedOutP, - const char ** const errorP); - -void -ConnReadInit(TConn * const connectionP); - -bool -ConnWriteFromFile(TConn * const connectionP, - const struct TFile * const fileP, - uint64_t const start, - uint64_t const last, - void * const buffer, - uint32_t const buffersize, - uint32_t const rate); - -TServer * -ConnServer(TConn * const connectionP); - -void -ConnFormatClientAddr(TConn * const connectionP, - const char ** const clientAddrPP); - -#endif diff --git a/trunk/lib/abyss/src/data.c b/trunk/lib/abyss/src/data.c deleted file mode 100644 index 77074341c..000000000 --- a/trunk/lib/abyss/src/data.c +++ /dev/null @@ -1,696 +0,0 @@ -/****************************************************************************** -** -** list.c -** -** This file is part of the ABYSS Web server project. -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -*******************************************************************************/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include - -#include "bool.h" -#include "mallocvar.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/lock.h" -#include "xmlrpc-c/lock_platform.h" - -#include "xmlrpc-c/abyss.h" - -#include "token.h" - -#include "data.h" - -/********************************************************************* -** List -*********************************************************************/ - -void -ListInit(TList * const listP) { - - listP->item = NULL; - listP->size = 0; - listP->maxsize = 0; - listP->autofree = false; -} - -void -ListInitAutoFree(TList * const listP) { - - listP->item = NULL; - listP->size = 0; - listP->maxsize = 0; - listP->autofree = true; -} - - - -void -ListFree(TList * const listP) { - - if (listP->item) { - if (listP->autofree) { - unsigned int i; - for (i = listP->size; i > 0; --i) - free(listP->item[i-1]); - - } - free(listP->item); - } - listP->item = NULL; - listP->size = 0; - listP->maxsize = 0; -} - - - -void -ListFreeItems(TList * const listP) { - - if (listP->item) { - unsigned int i; - for (i = listP->size; i > 0; --i) - free(listP->item[i-1]); - } -} - - - -bool -ListAdd(TList * const listP, - void * const str) { -/*---------------------------------------------------------------------------- - Add an item to the end of the list. ------------------------------------------------------------------------------*/ - bool success; - - if (listP->size >= listP->maxsize) { - uint16_t newSize = listP->maxsize + 16; - void **newitem; - - newitem = realloc(listP->item, newSize * sizeof(void *)); - if (newitem) { - listP->item = newitem; - listP->maxsize = newSize; - } - } - - if (listP->size >= listP->maxsize) - success = false; - else { - success = true; - listP->item[listP->size++] = str; - } - return success; -} - - - -void -ListRemove(TList * const listP) { -/*---------------------------------------------------------------------------- - Remove the last item from the list. ------------------------------------------------------------------------------*/ - - assert(listP->size > 0); - - --listP->size; -} - - - -bool -ListAddFromString(TList * const listP, - const char * const stringArg) { - - bool retval; - - if (!stringArg) - retval = true; - else { - char * buffer; - - buffer = strdup(stringArg); - if (!buffer) - retval = false; - else { - bool endOfString; - bool error; - char * c; - - for (c = &buffer[0], endOfString = false, error = false; - !endOfString && !error; - ) { - const char * t; - NextToken((const char **)&c); - - while (*c == ',') - ++c; - - t = GetToken(&c); - if (!t) - endOfString = true; - else { - char * p; - - for (p = c - 2; *p == ','; --p) - *p = '\0'; - - if (t[0] != '\0') { - bool added; - added = ListAdd(listP, (void*)t); - - if (!added) - error = true; - } - } - } - retval = !error; - xmlrpc_strfree(buffer); - } - } - return retval; -} - - - -bool -ListFindString(TList * const listP, - const char * const str, - uint16_t * const indexP) { - - if (listP->item && str) { - unsigned int i; - - for (i = 0; i < listP->size; ++i) { - if (xmlrpc_streq(str, (char *)(listP->item[i]))) { - *indexP = i; - return true; - } - } - } - return false; -} - -/********************************************************************* -** Buffer -*********************************************************************/ - -bool -BufferAlloc(TBuffer * const buf, - xmlrpc_uint32_t const memsize) { - - /* ************** Implement the static buffers ***/ - buf->staticid=0; - buf->data=(void *)malloc(memsize); - if (buf->data) - { - buf->size=memsize; - return true; - } - else - { - buf->size=0; - return false; - }; -} - - - -void -BufferFree(TBuffer * const buf) { - - if (buf->staticid) - { - /* ************** Implement the static buffers ***/ - } - else - free(buf->data); - - buf->size=0; - buf->staticid=0; -} - - - -bool -BufferRealloc(TBuffer * const buf, - xmlrpc_uint32_t const memsize) { - - if (buf->staticid) - { - TBuffer b; - - if (memsize<=buf->size) - return true; - - if (BufferAlloc(&b,memsize)) - { - memcpy(b.data,buf->data,buf->size); - BufferFree(buf); - *buf=b; - return true; - } - } - else - { - void *d; - - d=realloc(buf->data,memsize); - if (d) - { - buf->data=d; - buf->size=memsize; - return true; - } - } - - return false; -} - - -/********************************************************************* -** String -*********************************************************************/ - -bool -StringAlloc(TString * const stringP) { - - bool succeeded; - - stringP->size = 0; - - succeeded = BufferAlloc(&stringP->buffer, 256); - if (succeeded) { - *(char *)(stringP->buffer.data) = '\0'; - return true; - } else - return false; -} - - - -bool -StringConcat(TString * const stringP, - const char * const string2) { - - uint32_t const len = strlen(string2); - - if (len + stringP->size + 1 > stringP->buffer.size) { - bool succeeded; - succeeded = BufferRealloc( - &stringP->buffer, - ((len + stringP->size + 1 + 256) / 256) * 256); - if (!succeeded) - return false; - } - strcat((char *)(stringP->buffer.data), string2); - stringP->size += len; - return true; -} - - - -bool -StringBlockConcat(TString * const stringP, - const char * const string2, - char ** const ref) { - - uint32_t const len = strlen(string2) + 1; - - if (len + stringP->size > stringP->buffer.size) { - bool succeeded; - succeeded = BufferRealloc( - &stringP->buffer, - ((len + stringP->size + 1 + 256) / 256) * 256); - if (!succeeded) - return false; - } - *ref = (char *)(stringP->buffer.data) + stringP->size; - memcpy(*ref, string2, len); - stringP->size += len; - - return true; -} - - - -void -StringFree(TString * const stringP) { - stringP->size = 0; - BufferFree(&stringP->buffer); -} - - - -char * -StringData(TString * const stringP) { - return (char *)stringP->buffer.data; -} - - - -/********************************************************************* -** Hash -*********************************************************************/ - -static uint16_t -Hash16(const char * const start) { - - const char * s; - - uint16_t i; - - s = start; - i = 0; - - while(*s) - i = i * 37 + *s++; - - return i; -} - -/********************************************************************* -** Table -*********************************************************************/ - -void TableInit(TTable * const t) -{ - t->item=NULL; - t->size=t->maxsize=0; -} - -void TableFree(TTable * const t) -{ - uint16_t i; - - if (t->item) - { - if (t->size) - for (i=t->size;i>0;i--) - { - free(t->item[i-1].name); - free(t->item[i-1].value); - }; - - free(t->item); - } - - TableInit(t); -} - - - -static void -tableFindIndex(TTable * const tableP, - const char * const targetName, - bool * const foundP, - unsigned int * const indexP) { -/*---------------------------------------------------------------------------- - Find an entry in table *tableP that has key (name) 'name'. - - Return *foundP == true iff such an entry is in the table. - - Return the index of the found entry, if any, as *indexP. ------------------------------------------------------------------------------*/ - if (tableP->item) { - uint16_t const targetHash = Hash16(targetName); - - unsigned int i; - - for (i = 0; i < tableP->size; ++i) { - if (tableP->item[i].hash == targetHash) { - if (xmlrpc_streq(tableP->item[i].name, targetName)) { - *indexP = i; - *foundP = true; - return; - } - } - } - } - *foundP = false; -} - - - -bool -TableAddReplace(TTable * const tableP, - const char * const name, - const char * const value) { - - unsigned int tableIndex; - bool found; - - tableFindIndex(tableP, name, &found, &tableIndex); - - if (found) { - free(tableP->item[tableIndex].value); - if (value) - tableP->item[tableIndex].value = strdup(value); - else { - free(tableP->item[tableIndex].name); - if (--tableP->size > 0) - tableP->item[tableIndex] = tableP->item[tableP->size]; - } - return true; - } else - return TableAdd(tableP, name, value); -} - - - -bool -TableAdd(TTable * const t, - const char * const name, - const char * const value) { - - if (t->size>=t->maxsize) { - TTableItem *newitem; - - t->maxsize+=16; - - newitem=(TTableItem *)realloc(t->item,(t->maxsize)*sizeof(TTableItem)); - if (newitem) - t->item=newitem; - else { - t->maxsize-=16; - return false; - } - } - - t->item[t->size].name=strdup(name); - t->item[t->size].value=strdup(value); - t->item[t->size].hash=Hash16(name); - - ++t->size; - - return true; -} - - - -const char * -TableValue(TTable * const tableP, - const char * const name) { - - unsigned int tableIndex; - /* Index into the table of the entry with name 'name'. */ - bool found; - - tableFindIndex(tableP, name, &found, &tableIndex); - - if (found) - return tableP->item[tableIndex].value; - else - return NULL; -} - - - -/********************************************************************* -** Pool -*********************************************************************/ - -static TPoolZone * -PoolZoneAlloc(uint32_t const zonesize) { - - TPoolZone * poolZoneP; - - MALLOCARRAY(poolZoneP, zonesize); - if (poolZoneP) { - poolZoneP->pos = &poolZoneP->data[0]; - poolZoneP->maxpos = poolZoneP->pos + zonesize; - poolZoneP->next = NULL; - poolZoneP->prev = NULL; - } - return poolZoneP; -} - - - -static void -PoolZoneFree(TPoolZone * const poolZoneP) { - - free(poolZoneP); -} - - - -bool -PoolCreate(TPool * const poolP, - uint32_t const zonesize) { - - bool success; - - poolP->zonesize = zonesize; - - poolP->lockP = xmlrpc_lock_create(); - if (poolP->lockP) { - TPoolZone * const firstZoneP = PoolZoneAlloc(zonesize); - - if (firstZoneP != NULL) { - poolP->firstzone = firstZoneP; - poolP->currentzone = firstZoneP; - success = true; - } else - success = false; - if (!success) - poolP->lockP->destroy(poolP->lockP); - } else - success = false; - - return success; -} - - - -void * -PoolAlloc(TPool * const poolP, - uint32_t const size) { -/*---------------------------------------------------------------------------- - Allocate a block of size 'size' from pool 'poolP'. ------------------------------------------------------------------------------*/ - void * retval; - - if (size == 0) - retval = NULL; - else { - poolP->lockP->acquire(poolP->lockP); - { - TPoolZone * const curPoolZoneP = poolP->currentzone; - - - if (curPoolZoneP->pos + size < curPoolZoneP->maxpos) { - retval = curPoolZoneP->pos; - curPoolZoneP->pos += size; - } else { - uint32_t const zonesize = MAX(size, poolP->zonesize); - - TPoolZone * const newPoolZoneP = PoolZoneAlloc(zonesize); - if (newPoolZoneP) { - newPoolZoneP->prev = curPoolZoneP; - newPoolZoneP->next = curPoolZoneP->next; - curPoolZoneP->next = newPoolZoneP; - poolP->currentzone = newPoolZoneP; - retval= newPoolZoneP->data; - newPoolZoneP->pos = newPoolZoneP->data + size; - } else - retval = NULL; - } - } - poolP->lockP->release(poolP->lockP); - } - return retval; -} - - - -void -PoolReturn(TPool * const poolP, - void * const blockP) { -/*---------------------------------------------------------------------------- - Return the block at 'blockP' to the pool 'poolP'. WE ASSUME THAT IS - THE MOST RECENTLY ALLOCATED AND NOT RETURNED BLOCK IN THE POOL. ------------------------------------------------------------------------------*/ - TPoolZone * const curPoolZoneP = poolP->currentzone; - - assert((char*)curPoolZoneP->data < (char*)blockP && - (char*)blockP < (char*)curPoolZoneP->pos); - - curPoolZoneP->pos = blockP; - - if (curPoolZoneP->pos == curPoolZoneP->data) { - /* That emptied out the current zone. Free it and make the previous - zone current. - */ - - assert(curPoolZoneP->prev); /* entry condition */ - - curPoolZoneP->prev->next = NULL; - - PoolZoneFree(curPoolZoneP); - } -} - - - -void -PoolFree(TPool * const poolP) { - - TPoolZone * poolZoneP; - TPoolZone * nextPoolZoneP; - - for (poolZoneP = poolP->firstzone; poolZoneP; poolZoneP = nextPoolZoneP) { - nextPoolZoneP = poolZoneP->next; - free(poolZoneP); - } - poolP->lockP->destroy(poolP->lockP); -} - - - -const char * -PoolStrdup(TPool * const poolP, - const char * const origString) { - - char * newString; - - if (origString == NULL) - newString = NULL; - else { - newString = PoolAlloc(poolP, strlen(origString) + 1); - if (newString != NULL) - strcpy(newString, origString); - } - return newString; -} diff --git a/trunk/lib/abyss/src/data.h b/trunk/lib/abyss/src/data.h deleted file mode 100644 index 8e697ede3..000000000 --- a/trunk/lib/abyss/src/data.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef DATA_H_INCLUDED -#define DATA_H_INCLUDED - -#include "bool.h" -#include "int.h" - -struct lock; - -/********************************************************************* -** Buffer -*********************************************************************/ - -typedef struct -{ - void *data; - xmlrpc_uint32_t size; - xmlrpc_uint32_t staticid; -} TBuffer; - -bool -BufferAlloc(TBuffer * const buf, - xmlrpc_uint32_t const memsize); - -bool -BufferRealloc(TBuffer * const buf, - xmlrpc_uint32_t const memsize); - -void -BufferFree(TBuffer * const buf); - - -/********************************************************************* -** String -*********************************************************************/ - -typedef struct -{ - TBuffer buffer; - xmlrpc_uint32_t size; -} TString; - -bool -StringAlloc(TString * const stringP); - -bool -StringConcat(TString * const stringP, - const char * const string2); - -bool -StringBlockConcat(TString * const stringP, - const char * const string2, - char ** const ref); - -void -StringFree(TString * const stringP); - -char * -StringData(TString * const stringP); - - -/********************************************************************* -** List -*********************************************************************/ - -typedef struct { - void **item; - uint16_t size; - uint16_t maxsize; - bool autofree; -} TList; - -void -ListInit(TList * const listP); - -void -ListInitAutoFree(TList * const listP); - -void -ListFree(TList * const listP); - -void -ListFreeItems(TList * const listP); - -bool -ListAdd(TList * const listP, - void * const str); - -void -ListRemove(TList * const listP); - -bool -ListAddFromString(TList * const listP, - const char * const c); - -bool -ListFindString(TList * const listP, - const char * const str, - uint16_t * const indexP); - - -typedef struct -{ - char *name,*value; - uint16_t hash; -} TTableItem; - -typedef struct -{ - TTableItem *item; - uint16_t size,maxsize; -} TTable; - -void -TableInit(TTable * const t); - -void -TableFree(TTable * const t); - -bool -TableAdd(TTable * const t, - const char * const name, - const char * const value); - -bool -TableAddReplace(TTable * const t, - const char * const name, - const char * const value); - -const char * -TableValue(TTable * const tableP, - const char * const name); - - -/********************************************************************* -** Pool -*********************************************************************/ - -typedef struct _TPoolZone { - char * pos; - char * maxpos; - struct _TPoolZone * next; - struct _TPoolZone * prev; -/* char data[0]; Some compilers don't accept this */ - char data[1]; -} TPoolZone; - -typedef struct { - TPoolZone * firstzone; - TPoolZone * currentzone; - uint32_t zonesize; - struct lock * lockP; -} TPool; - -bool -PoolCreate(TPool * const poolP, - uint32_t const zonesize); - -void -PoolFree(TPool * const poolP); - -void * -PoolAlloc(TPool * const poolP, - uint32_t const size); - -void -PoolReturn(TPool * const poolP, - void * const blockP); - -const char * -PoolStrdup(TPool * const poolP, - const char * const origString); - - -#endif diff --git a/trunk/lib/abyss/src/date.c b/trunk/lib/abyss/src/date.c deleted file mode 100644 index 5e3555bce..000000000 --- a/trunk/lib/abyss/src/date.c +++ /dev/null @@ -1,206 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "bool.h" -#include "int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/time_int.h" -#include "xmlrpc-c/abyss.h" - -#include "date.h" - -/********************************************************************* -** Date -*********************************************************************/ - -static char *_DateDay[7]= -{ - "Sun","Mon","Tue","Wed","Thu","Fri","Sat" -}; - -static char *_DateMonth[12]= -{ - "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" -}; - - - -void -DateToString(time_t const datetime, - const char ** const dateStringP) { - - struct tm brokenTime; - - xmlrpc_gmtime(datetime, &brokenTime); - - if (mktime(&brokenTime) == (time_t)-1) - *dateStringP = NULL; - else - xmlrpc_asprintf(dateStringP, "%s, %02u %s %04u %02u:%02u:%02u UTC", - _DateDay[brokenTime.tm_wday], - brokenTime.tm_mday, - _DateMonth[brokenTime.tm_mon], - 1900 + brokenTime.tm_year, - brokenTime.tm_hour, - brokenTime.tm_min, - brokenTime.tm_sec); -} - - - -static const char * -tzOffsetStr(struct tm const tm, - time_t const datetime) { - - const char * retval; - time_t timeIfUtc; - const char * error; - - xmlrpc_timegm(&tm, &timeIfUtc, &error); - - if (error) { - xmlrpc_strfree(error); - xmlrpc_asprintf(&retval, "%s", "+????"); - } else { - int const tzOffset = (int)(datetime - timeIfUtc); - - assert(tzOffset == datetime - timeIfUtc); - - xmlrpc_asprintf(&retval, "%+03d%02d", - tzOffset/3600, abs(tzOffset % 3600)/60); - } - return retval; -} - - - -void -DateToLogString(time_t const datetime, - const char ** const dateStringP) { - - const char * tzo; - struct tm tm; - - xmlrpc_localtime(datetime, &tm); - - tzo = tzOffsetStr(tm, datetime); - - xmlrpc_asprintf(dateStringP, "%02d/%s/%04d:%02d:%02d:%02d %s", - tm.tm_mday, _DateMonth[tm.tm_mon], - 1900 + tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec, - tzo); - - xmlrpc_strfree(tzo); -} - - - -void -DateDecode(const char * const dateString, - bool * const validP, - time_t * const datetimeP) { -/*---------------------------------------------------------------------------- - Return the datetime represented by 'dateString', which is in the - format used in an HTTP header. - - We assume that format is always UTC-based; I don't know if HTTP - actually requires that -- maybe it could be some local time. ------------------------------------------------------------------------------*/ - int rc; - const char * s; - unsigned int monthOff; - struct tm tm; - bool error; - - s = &dateString[0]; - - /* Ignore spaces, day name and spaces */ - while ((*s==' ') || (*s=='\t')) - ++s; - - while ((*s!=' ') && (*s!='\t')) - ++s; - - while ((*s==' ') || (*s=='\t')) - ++s; - - error = false; /* initial value */ - - /* try to recognize the date format */ - rc = sscanf(s, "%*s %d %d:%d:%d %d%*s", - &tm.tm_mday, &tm.tm_hour, - &tm.tm_min, &tm.tm_sec, &tm.tm_year); - if (rc == 5) - monthOff = 0; - else { - int rc; - rc = sscanf(s, "%d %n%*s %d %d:%d:%d GMT%*s", - &tm.tm_mday, &monthOff, &tm.tm_year, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - if (rc != 5) { - int rc; - rc = sscanf(s, "%d-%n%*[A-Za-z]-%d %d:%d:%d GMT%*s", - &tm.tm_mday, &monthOff, &tm.tm_year, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - if (rc != 5) - error = true; - } - } - if (!error) { - const char * monthName = s + monthOff; - /* This is actually just the point in 'dateString' where - the month name begins -- it's not a nul-terminated string - */ - - unsigned int i; - bool gotMonth; - - for (i = 0, gotMonth = false; i < 12; ++i) { - const char * p; - - p =_DateMonth[i]; - - if (tolower(*p++) == tolower(monthName[0])) - if (*p++ == tolower(monthName[1])) - if (*p == tolower(monthName[2])) { - gotMonth = true; - tm.tm_mon = i; - } - } - - if (!gotMonth) - error = true; - else { - if (tm.tm_year > 1900) - tm.tm_year -= 1900; - else { - if (tm.tm_year < 70) - tm.tm_year += 100; - } - tm.tm_isdst = 0; - - { - const char * timeError; - xmlrpc_timegm(&tm, datetimeP, &timeError); - - if (timeError) { - error = true; - xmlrpc_strfree(timeError); - } - } - } - } - *validP = !error; -} - - - -abyss_bool -DateInit(void) { - - return true; -} diff --git a/trunk/lib/abyss/src/date.h b/trunk/lib/abyss/src/date.h deleted file mode 100644 index 7105e1de1..000000000 --- a/trunk/lib/abyss/src/date.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef DATE_H_INCLUDED -#define DATE_H_INCLUDED - -#include - -#include "bool.h" - -void -DateToString(time_t const datetime, - const char ** const dateStringP); - -void -DateToLogString(time_t const datetime, - const char ** const dateStringP); - -void -DateDecode(const char * const dateString, - bool * const validP, - time_t * const datetimeP); - -#endif diff --git a/trunk/lib/abyss/src/file.c b/trunk/lib/abyss/src/file.c deleted file mode 100644 index 45f506bab..000000000 --- a/trunk/lib/abyss/src/file.c +++ /dev/null @@ -1,384 +0,0 @@ -/****************************************************************************** -** -** file.c -** -** This file is part of the ABYSS Web server project. -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ - -/* There is a complex bug in AIX that is worked around by declaring this as - X/OPEN 6 source code even though we don't depend up on any specific stuff - from that standard. The AIX bug causes to define "lseek64" - twice. We tried _POSIX_SOURCE and that made the lseek problem go away but - caused not to define struct sockaddr! AIX 5.3 13.09.16. -*/ -#define _XOPEN_SOURCE 600 - -#include "xmlrpc_config.h" -#include "mallocvar.h" - -#define _CRT_SECURE_NO_WARNINGS - /* Tell msvcrt not to warn about functions that are often misused and - cause security exposures. - */ - -#define _FILE_OFFSET_BITS 64 - /* Tell GNU libc to make off_t 64 bits and all the POSIX file functions - the versions that handle 64 bit file offsets. - */ -#define _LARGE_FILES - /* Same as above, but for AIX */ - -#include - -#if MSVCRT - #include - typedef __int64 readwriterc_t; -#else - #include - #include - #include - #include - typedef ssize_t readwriterc_t; -#endif - -#include "bool.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/abyss.h" -#include "file.h" - -bool const win32 = -#if MSVCRT - true; -#else - false; -#endif - -struct TFileFind { -#if MSVCRT - intptr_t handle; -#else - char path[NAME_MAX+1]; - DIR * handle; -#endif -}; - - - -/********************************************************************* -** File -*********************************************************************/ - -static void -createFileImage(TFile ** const filePP, - const char * const name, - uint32_t const attrib, - bool const createFile, - bool * const succeededP) { - - TFile * fileP; - - MALLOCVAR(fileP); - if (fileP == NULL) - *succeededP = false; - else { - int rc; - - if (createFile) - rc = open(name, attrib | O_CREAT, XMLRPC_S_IWUSR | XMLRPC_S_IRUSR); - else - rc = open(name, attrib); - - if (rc < 0) - *succeededP = false; - else { - fileP->fd = rc; - *succeededP = true; - } - if (!*succeededP) - free(fileP); - } - *filePP = fileP; -} - - - -bool -FileOpen(TFile ** const filePP, - const char * const name, - uint32_t const attrib) { - - bool succeeded; - - createFileImage(filePP, name, attrib, false, &succeeded); - - return succeeded; -} - - - -bool -FileOpenCreate(TFile ** const filePP, - const char * const name, - uint32_t const attrib) { - - bool succeeded; - - createFileImage(filePP, name, attrib, true, &succeeded); - - return succeeded; -} - - - -bool -FileWrite(const TFile * const fileP, - const void * const buffer, - uint32_t const len) { - - readwriterc_t rc; - - rc = write(fileP->fd, buffer, len); - - return (rc > 0 && (uint32_t)rc == len); -} - - - -int32_t -FileRead(const TFile * const fileP, - void * const buffer, - uint32_t const len) { - - return read(fileP->fd, buffer, len); -} - - - -bool -FileSeek(const TFile * const fileP, - uint64_t const pos, - uint32_t const attrib) { - - int64_t rc; -#if MSVCRT - rc = _lseeki64(fileP->fd, pos, attrib); -#else - rc = lseek(fileP->fd, pos, attrib); -#endif - return (rc >= 0); -} - - - -uint64_t -FileSize(const TFile * const fileP) { - -#if MSVCRT - return (_filelength(fileP->fd)); -#else - struct stat fs; - - fstat(fileP->fd, &fs); - return (fs.st_size); -#endif -} - - - -bool -FileClose(TFile * const fileP) { - - int rc; - - rc = close(fileP->fd); - - if (rc >= 0) - free(fileP); - - return (rc >= 0); -} - - - -bool -FileStat(const char * const filename, - TFileStat * const filestat) { - - int rc; - -#if MSVCRT - rc = _stati64(filename,filestat); -#else - rc = stat(filename,filestat); -#endif - return (rc >= 0); -} - - - -static void -fileFindFirstWin(TFileFind * const filefindP ATTR_UNUSED, - const char * const path, - TFileInfo * const fileinfo ATTR_UNUSED, - bool * const retP ATTR_UNUSED) { - const char * search; - - xmlrpc_asprintf(&search, "%s\\*", path); - -#if MSVCRT - filefindP->handle = _findfirsti64(search, fileinfo); - *retP = filefindP->handle != -1; -#endif - xmlrpc_strfree(search); -} - - - -static void -fileFindFirstPosix(TFileFind * const filefindP, - const char * const path, - TFileInfo * const fileinfo, - bool * const retP) { - -#if !MSVCRT - strncpy(filefindP->path, path, NAME_MAX); - filefindP->path[NAME_MAX] = '\0'; - filefindP->handle = opendir(path); - if (filefindP->handle) - *retP = FileFindNext(filefindP, fileinfo); - else - *retP = false; -#endif -} - - - -bool -FileFindFirst(TFileFind ** const filefindPP, - const char * const path, - TFileInfo * const fileinfo) { - - bool succeeded; - - TFileFind * filefindP; - - MALLOCVAR(filefindP); - - if (filefindP == NULL) - succeeded = false; - else { - if (win32) - fileFindFirstWin(filefindP, path, fileinfo, &succeeded); - else - fileFindFirstPosix(filefindP, path, fileinfo, &succeeded); - if (!succeeded) - free(filefindP); - } - *filefindPP = filefindP; - - return succeeded; -} - - - -static void -fileFindNextWin(TFileFind * const filefindP ATTR_UNUSED, - TFileInfo * const fileinfo ATTR_UNUSED, - bool * const retvalP ATTR_UNUSED) { - -#if MSVCRT - *retvalP = _findnexti64(filefindP->handle, fileinfo) != -1; -#endif -} - - - -static void -fileFindNextPosix(TFileFind * const filefindP, - TFileInfo * const fileinfoP, - bool * const retvalP) { - -#if !MSVCRT - struct dirent * deP; - - deP = readdir(filefindP->handle); - if (deP) { - char z[NAME_MAX+1]; - struct stat fs; - - strcpy(fileinfoP->name, deP->d_name); - strcpy(z, filefindP->path); - strncat(z, "/",NAME_MAX); - strncat(z, fileinfoP->name, NAME_MAX); - z[NAME_MAX] = '\0'; - - stat(z, &fs); - - if (fs.st_mode & S_IFDIR) - fileinfoP->attrib = A_SUBDIR; - else - fileinfoP->attrib = 0; - - fileinfoP->size = fs.st_size; - fileinfoP->time_write = fs.st_mtime; - - *retvalP = true; - } else - *retvalP = false; -#endif -} - - - -bool -FileFindNext(TFileFind * const filefindP, - TFileInfo * const fileinfo) { - - bool retval; - - if (win32) - fileFindNextWin(filefindP, fileinfo, &retval); - else - fileFindNextPosix(filefindP, fileinfo, &retval); - - return retval; -} - - - -void -FileFindClose(TFileFind * const filefindP) { -#if MSVCRT - _findclose(filefindP->handle); -#else - closedir(filefindP->handle); -#endif - free(filefindP); -} diff --git a/trunk/lib/abyss/src/file.h b/trunk/lib/abyss/src/file.h deleted file mode 100644 index d3840395a..000000000 --- a/trunk/lib/abyss/src/file.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef FILE_H_INCLUDED -#define FILE_H_INCLUDED - -#include -#include -#include -#include - -#include "bool.h" -#include "int.h" -#include "xmlrpc-c/abyss.h" - -#ifndef NAME_MAX -#define NAME_MAX 1024 -#endif - -#if MSVCRT -#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 /* MSVCRT */ - -#if MSVCRT -typedef struct _stati64 TFileStat; -typedef struct _finddatai64_t TFileInfo; -#else /* MSVCRT */ - -#include -#include - -typedef struct stat TFileStat; - -typedef struct finddata_t { - char name[NAME_MAX+1]; - int attrib; - uint64_t size; - time_t time_write; -} TFileInfo; - -#endif /* MSVCRT */ - -typedef struct TFileFind TFileFind; - -typedef struct TFile { - int fd; -} TFile; - -bool -FileOpen(TFile ** const filePP, - const char * const name, - uint32_t const attrib); - -bool -FileOpenCreate(TFile ** const filePP, - const char * const name, - uint32_t const attrib); - -bool -FileClose(TFile * const fileP); - -bool -FileWrite(const TFile * const fileP, - const void * const buffer, - uint32_t const len); - -int32_t -FileRead(const TFile * const fileP, - void * const buffer, - uint32_t const len); - -bool -FileSeek(const TFile * const fileP, - uint64_t const pos, - uint32_t const attrib); - -uint64_t -FileSize(const TFile * const fileP); - -bool -FileStat(const char * const filename, - TFileStat * const filestat); - -bool -FileFindFirst(TFileFind ** const filefind, - const char * const path, - TFileInfo * const fileinfo); - -bool -FileFindNext(TFileFind * const filefind, - TFileInfo * const fileinfo); - -void -FileFindClose(TFileFind * const filefind); - -#endif diff --git a/trunk/lib/abyss/src/handler.c b/trunk/lib/abyss/src/handler.c deleted file mode 100644 index 80a2914e7..000000000 --- a/trunk/lib/abyss/src/handler.c +++ /dev/null @@ -1,838 +0,0 @@ -/*============================================================================= - handler.c -=============================================================================== - This file contains built-in HTTP request handlers. - - Copyright information is at end of file -=============================================================================*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include -#if MSVCRT - #include -#else - #include -#endif -#include - -#include "bool.h" -#include "int.h" -#include "girmath.h" -#include "mallocvar.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/time_int.h" - -#include "xmlrpc-c/abyss.h" -#include "trace.h" -#include "session.h" -#include "file.h" -#include "conn.h" -#include "http.h" -#include "date.h" -#include "abyss_info.h" - -#include "handler.h" - - - -struct BIHandler { - const char * filesPath; - TList defaultFileNames; - MIMEType * mimeTypeP; - /* NULL means to use the global MIMEType object */ -}; - - - -BIHandler * -HandlerCreate(void) { - - struct BIHandler * handlerP; - - MALLOCVAR(handlerP); - - if (handlerP) { - handlerP->filesPath = strdup(DEFAULT_DOCS); - ListInitAutoFree(&handlerP->defaultFileNames); - handlerP->mimeTypeP = NULL; - } - return handlerP; -} - - - -void -HandlerDestroy(BIHandler * const handlerP) { - - ListFree(&handlerP->defaultFileNames); - - xmlrpc_strfree(handlerP->filesPath); - - free(handlerP); -} - - - -void -HandlerSetMimeType(BIHandler * const handlerP, - MIMEType * const mimeTypeP) { - - handlerP->mimeTypeP = mimeTypeP; -} - - - -void -HandlerSetFilesPath(BIHandler * const handlerP, - const char * const filesPath) { - - xmlrpc_strfree(handlerP->filesPath); - handlerP->filesPath = strdup(filesPath); -} - - - -void -HandlerAddDefaultFN(BIHandler * const handlerP, - const char * const fileName) { - - ListAdd(&handlerP->defaultFileNames, strdup(fileName)); -} - - - -typedef int (*TQSortProc)(const void *, const void *); - -static int -cmpfilenames(const TFileInfo **f1,const TFileInfo **f2) { - if (((*f1)->attrib & A_SUBDIR) && !((*f2)->attrib & A_SUBDIR)) - return (-1); - if (!((*f1)->attrib & A_SUBDIR) && ((*f2)->attrib & A_SUBDIR)) - return 1; - - return strcmp((*f1)->name,(*f2)->name); -} - - - -static int -cmpfiledates(const TFileInfo ** const f1PP, - const TFileInfo ** const f2PP) { - - const TFileInfo * const f1P = *f1PP; - const TFileInfo * const f2P = *f2PP; - - int retval; - - if ((f1P->attrib & A_SUBDIR) && !(f2P->attrib & A_SUBDIR)) - retval = -1; - else if (!(f1P->attrib & A_SUBDIR) && (f2P->attrib & A_SUBDIR)) - retval = 1; - else { - assert((int)(f1P->time_write - f2P->time_write) == - (f1P->time_write - f2P->time_write)); - retval = (int)(f1P->time_write - f2P->time_write); - } - return retval; -} - - - -static void -determineSortType(const char * const query, - bool * const ascendingP, - uint16_t * const sortP, - bool * const textP, - const char ** const errorP) { - - *ascendingP = true; - *sortP = 1; - *textP = false; - *errorP = NULL; - - if (query) { - if (xmlrpc_streq(query, "plain")) - *textP = true; - else if (xmlrpc_streq(query, "name-up")) { - *sortP = 1; - *ascendingP = true; - } else if (xmlrpc_streq(query, "name-down")) { - *sortP = 1; - *ascendingP = false; - } else if (xmlrpc_streq(query, "date-up")) { - *sortP = 2; - *ascendingP = true; - } else if (xmlrpc_streq(query, "date-down")) { - *sortP = 2; - *ascendingP = false; - } else { - xmlrpc_asprintf(errorP, "invalid query value '%s'", query); - } - } -} - - - -static void -generateListing(TList * const listP, - const char * const dirName, - const char * const uri, - TPool * const poolP, - const char ** const errorP, - uint16_t * const responseStatusP) { - - TFileInfo fileinfo; - TFileFind * findhandleP; - - *errorP = NULL; - - if (!FileFindFirst(&findhandleP, dirName, &fileinfo)) { - *responseStatusP = ResponseStatusFromErrno(errno); - xmlrpc_asprintf(errorP, "Can't read first entry in directory"); - } else { - ListInit(listP); - - do { - TFileInfo * fi; - /* Files whose names start with a dot are ignored */ - /* This includes implicitly the ./ and ../ */ - if (*fileinfo.name == '.') { - if (xmlrpc_streq(fileinfo.name, "..")) { - if (xmlrpc_streq(uri, "/")) - continue; - } else - continue; - } - fi = (TFileInfo *)PoolAlloc(poolP, sizeof(fileinfo)); - if (fi) { - bool success; - memcpy(fi, &fileinfo, sizeof(fileinfo)); - success = ListAdd(listP, fi); - if (!success) - xmlrpc_asprintf(errorP, "ListAdd() failed"); - } else - xmlrpc_asprintf(errorP, "PoolAlloc() failed."); - } while (!*errorP && FileFindNext(findhandleP, &fileinfo)); - - if (*errorP) { - *responseStatusP = 500; - ListFree(listP); - } - FileFindClose(findhandleP); - } -} - - - -static const char * -plainTail(void) { -/*---------------------------------------------------------------------------- - The bottom part of the response body, in plain text format. ------------------------------------------------------------------------------*/ - const char * retval; - - xmlrpc_asprintf(&retval, SERVER_PLAIN_INFO); - - return retval; -} - - - -static const char * -htmlTail(void) { -/*---------------------------------------------------------------------------- - The bottom part of the response body, in HTML format. ------------------------------------------------------------------------------*/ - const char * retval; - - xmlrpc_asprintf( - &retval, - "" - SERVER_HTML_INFO - "\r\n\r\n"); - - return retval; -} - - - -static void -sendDirectoryDocumentHeading(TSession * const sessionP, - const char * const uri, - bool const text) { - - char z[4096]; - - if (text) { - size_t i; - char * p; - - sprintf(z, "Index of %s\r\n", uri); - i = strlen(z)-2; - p = z + i + 2; - - while (i > 0) { - *(p++) = '-'; - --i; - } - - *p = '\0'; - strcat(z, "\r\n\r\n" - "Name Size " - "Date-Time Type\r\n" - "------------------------------------" - "--------------------------------------------\r\n"); - } else { - sprintf(z, "Index of %s" - "

Index of %s

",
-                uri, uri);
-        strcat(z, "Name                      Size      "
-               "Date-Time             Type
\r\n"); - } - - HTTPWriteBodyChunk(sessionP, z, strlen(z)); -} - - - -static void -sendDirectoryDocument(TList * const listP, - bool const ascending, - uint16_t const sort, - bool const text, - const char * const uri, - MIMEType * const mimeTypeP, - TSession * const sessionP) { - - char z[4096]; - char *p,z1[26],z2[20],z3[9],u; - const char * z4; - int16_t i; - uint32_t k; - - sendDirectoryDocumentHeading(sessionP, uri, text); - - /* Sort the files */ - qsort(listP->item, listP->size, sizeof(void *), - (TQSortProc)(sort == 1 ? cmpfilenames : cmpfiledates)); - - /* Write the listing */ - if (ascending) - i = 0; - else - i = listP->size - 1; - - while ((i < listP->size) && (i >= 0)) { - TFileInfo * fi; - struct tm ftm; - - fi = listP->item[i]; - - if (ascending) - ++i; - else - --i; - - strcpy(z, fi->name); - - k = strlen(z); - - if (fi->attrib & A_SUBDIR) { - z[k++] = '/'; - z[k] = '\0'; - } - - if (k > 24) { - z[10] = '\0'; - strcpy(z1, z); - strcat(z1, "..."); - strcat(z1, z + k - 11); - k = 24; - p = z1 + 24; - } else { - strcpy(z1, z); - - ++k; - p = z1 + k; - while (k < 25) - z1[k++] = ' '; - - z1[25] = '\0'; - } - - xmlrpc_gmtime(fi->time_write, &ftm); - sprintf(z2, "%02u/%02u/%04u %02u:%02u:%02u",ftm.tm_mday,ftm.tm_mon+1, - ftm.tm_year+1900,ftm.tm_hour,ftm.tm_min,ftm.tm_sec); - - if (fi->attrib & A_SUBDIR) { - strcpy(z3, " -- "); - z4 = "Directory"; - } else { - if (fi->size < 9999) - u = 'b'; - else { - fi->size /= 1024; - if (fi->size < 9999) - u = 'K'; - else { - fi->size /= 1024; - if (fi->size < 9999) - u = 'M'; - else - u = 'G'; - } - } - - sprintf(z3, "%5" PRIu64 " %c", fi->size, u); - - if (xmlrpc_streq(fi->name, "..")) - z4 = ""; - else - z4 = MIMETypeFromFileName2(mimeTypeP, fi->name); - - if (!z4) - z4 = "Unknown"; - } - - if (text) - sprintf(z, "%s%s %s %s %s\r\n", z1, p, z3, z2, z4); - else - sprintf(z, "%s%s %s %s %s\r\n", - fi->name, fi->attrib & A_SUBDIR ? "/" : "", - z1, p, z3, z2, z4); - - HTTPWriteBodyChunk(sessionP, z, strlen(z)); - } - - { - const char * const tail = text ? plainTail() : htmlTail(); - - HTTPWriteBodyChunk(sessionP, tail, strlen(tail)); - - xmlrpc_strfree(tail); - } -} - - - -static bool -notRecentlyModified(TSession * const sessionP, - time_t const fileModTime) { - - bool retval; - const char * imsHdr; - - imsHdr = RequestHeaderValue(sessionP, "if-modified-since"); - if (imsHdr) { - bool valid; - time_t datetime; - DateDecode(imsHdr, &valid, &datetime); - if (valid) { - if (MIN(fileModTime, sessionP->date) <= datetime) - retval = true; - else - retval = false; - } else - retval = false; - } else - retval = false; - - return retval; -} - - - -static void -addLastModifiedHeader(TSession * const sessionP, - time_t const fileModTime) { - - const char * lastModifiedValue; - - DateToString(MIN(fileModTime, sessionP->date), &lastModifiedValue); - - if (lastModifiedValue) { - ResponseAddField(sessionP, "Last-Modified", lastModifiedValue); - xmlrpc_strfree(lastModifiedValue); - } -} - - - -static void -handleDirectory(TSession * const sessionP, - const char * const dirName, - time_t const fileModTime, - MIMEType * const mimeTypeP) { - - bool text; - bool ascending; - uint16_t sort; /* 1=by name, 2=by date */ - const char * error; - - determineSortType(sessionP->requestInfo.query, - &ascending, &sort, &text, &error); - - if (error) { - ResponseStatus(sessionP, 400); - xmlrpc_strfree(error); - } else if (notRecentlyModified(sessionP, fileModTime)) { - ResponseStatus(sessionP, 304); - ResponseWriteStart(sessionP); - } else { - TPool pool; - bool succeeded; - succeeded = PoolCreate(&pool, 1024); - if (!succeeded) - ResponseStatus(sessionP, 500); - else { - TList list; - uint16_t responseStatus; - const char * error; - generateListing(&list, dirName, sessionP->requestInfo.uri, - &pool, &error, &responseStatus); - if (error) { - ResponseStatus(sessionP, responseStatus); - xmlrpc_strfree(error); - } else { - ResponseStatus(sessionP, 200); - ResponseContentType(sessionP, - text ? "text/plain" : "text/html"); - - addLastModifiedHeader(sessionP, fileModTime); - - ResponseChunked(sessionP); - ResponseWriteStart(sessionP); - - if (sessionP->requestInfo.method!=m_head) - sendDirectoryDocument(&list, ascending, sort, text, - sessionP->requestInfo.uri, mimeTypeP, - sessionP); - - ResponseWriteEnd(sessionP); - - ListFree(&list); - } - PoolFree(&pool); - } - } -} - - - -static void -composeEntityHeader(const char ** const entityHeaderP, - const char * const mediatype, - uint64_t const start, - uint64_t const end, - uint64_t const filesize) { - - xmlrpc_asprintf(entityHeaderP, "Content-type: %s\r\n" - "Content-range: " - "bytes %" PRIu64 "-%" PRIu64 "/%" PRIu64 "\r\n" - "Content-length: %" PRIu64 "\r\n\r\n", - mediatype, start, end, filesize, end-start+1); -} - - - -#define BOUNDARY "##123456789###BOUNDARY" - -static void -sendBody(TSession * const sessionP, - const TFile * const fileP, - uint64_t const filesize, - const char * const mediatype, - uint64_t const start0, - uint64_t const end0) { -/*---------------------------------------------------------------------------- - 'start0' and 'end0' are meaningful only if the session has ranges. ------------------------------------------------------------------------------*/ - char buffer[4096]; - - if (sessionP->ranges.size == 0) - ConnWriteFromFile(sessionP->connP, fileP, 0, filesize - 1, - buffer, sizeof(buffer), 0); - else if (sessionP->ranges.size == 1) - ConnWriteFromFile(sessionP->connP, fileP, start0, end0, - buffer, sizeof(buffer), 0); - else { - uint64_t i; - for (i = 0; i <= sessionP->ranges.size; ++i) { - ConnWrite(sessionP->connP, "--", 2); - ConnWrite(sessionP->connP, BOUNDARY, strlen(BOUNDARY)); - ConnWrite(sessionP->connP, "\r\n", 2); - - if (i < sessionP->ranges.size) { - uint64_t start; - uint64_t end; - bool decoded; - - decoded = RangeDecode((char *)(sessionP->ranges.item[i]), - filesize, - &start, &end); - if (decoded) { - /* Entity header, not response header */ - const char * entityHeader; - - composeEntityHeader(&entityHeader, mediatype, - start, end, filesize); - - ConnWrite(sessionP->connP, - entityHeader, strlen(entityHeader)); - - xmlrpc_strfree(entityHeader); - - ConnWriteFromFile(sessionP->connP, fileP, start, end, - buffer, sizeof(buffer), 0); - } - } - } - } -} - - - -static void -sendFileAsResponse(TSession * const sessionP, - TFile * const fileP, - const char * const fileName, - time_t const fileModTime, - MIMEType * const mimeTypeP) { - - uint64_t const filesize = FileSize(fileP); - const char * const mediatype = MIMETypeGuessFromFile2(mimeTypeP, fileName); - - uint64_t start; /* Defined only if session has one range */ - uint64_t end; /* Defined only if session has one range */ - - switch (sessionP->ranges.size) { - case 0: - ResponseStatus(sessionP, 200); - break; - - case 1: { - bool decoded; - decoded = RangeDecode((char *)(sessionP->ranges.item[0]), filesize, - &start, &end); - if (!decoded) { - ListFree(&sessionP->ranges); - ResponseStatus(sessionP, 200); - } else { - const char * contentRange; - xmlrpc_asprintf(&contentRange, - "bytes %" PRIu64 "-%" PRIu64 "/%" PRIu64, - start, end, filesize); - ResponseAddField(sessionP, "Content-range", contentRange); - xmlrpc_strfree(contentRange); - - ResponseContentLength(sessionP, end - start + 1); - ResponseStatus(sessionP, 206); - } - } break; - - default: - ResponseContentType(sessionP, - "multipart/ranges; boundary=" BOUNDARY); - ResponseStatus(sessionP, 206); - break; - } - - if (sessionP->ranges.size == 0) { - ResponseContentLength(sessionP, filesize); - ResponseContentType(sessionP, mediatype); - } - - addLastModifiedHeader(sessionP, fileModTime); - - ResponseWriteStart(sessionP); - - if (sessionP->requestInfo.method != m_head) - sendBody(sessionP, fileP, filesize, mediatype, start, end); -} - - - -static void -handleFile(TSession * const sessionP, - const char * const fileName, - time_t const fileModTime, - MIMEType * const mimeTypeP) { -/*---------------------------------------------------------------------------- - This is an HTTP request handler for a GET. It does the classic - web server thing: send the file named in the URL to the client. ------------------------------------------------------------------------------*/ - TFile * fileP; - bool success; - - success = FileOpen(&fileP, fileName, O_BINARY | O_RDONLY); - if (!success) - ResponseStatusErrno(sessionP); - else { - if (notRecentlyModified(sessionP, fileModTime)) { - ResponseStatus(sessionP, 304); - ResponseWriteStart(sessionP); - } else - sendFileAsResponse(sessionP, fileP, - fileName, fileModTime, mimeTypeP); - - FileClose(fileP); - } -} - - - -static void -convertToNativeFileName(char * const fileName ATTR_UNUSED) { - -#if MSVCRT - char * p; - p = &fileName[0]; - while (*p) { - if ((*p) == '/') - *p= '\\'; - - ++p; - } -#endif -} - - - -abyss_bool -HandlerDefaultBuiltin(TSession * const sessionP) { - - BIHandler * const handlerP = SessionGetDefaultHandlerCtx(sessionP); - - char * p; - char z[4096]; - TFileStat fs; - bool endingslash; - - endingslash = false; /* initial value */ - - if (!HTTPRequestHasValidUriPath(sessionP)) { - ResponseStatus(sessionP, 400); - return true; - } - - /* Must check for * (asterisk uri) in the future */ - if (sessionP->requestInfo.method == m_options) { - ResponseAddField(sessionP, "Allow", "GET, HEAD"); - ResponseContentLength(sessionP, 0); - ResponseStatus(sessionP, 200); - return true; - } - - if ((sessionP->requestInfo.method != m_get) && - (sessionP->requestInfo.method != m_head)) { - ResponseAddField(sessionP, "Allow", "GET, HEAD"); - ResponseStatus(sessionP, 405); - return true; - } - - strcpy(z, handlerP->filesPath); - strcat(z, sessionP->requestInfo.uri); - - p = z + strlen(z) - 1; - if (*p == '/') { - endingslash = true; - *p = '\0'; - } - - convertToNativeFileName(z); - - if (!FileStat(z, &fs)) { - ResponseStatusErrno(sessionP); - return true; - } - - if (fs.st_mode & S_IFDIR) { - /* Redirect to the same directory but with the ending slash - ** to avoid problems with some browsers (IE for examples) when - ** they generate relative urls */ - if (!endingslash) { - strcpy(z, sessionP->requestInfo.uri); - p = z+strlen(z); - *p = '/'; - *(p+1) = '\0'; - ResponseAddField(sessionP, "Location", z); - ResponseStatus(sessionP, 302); - ResponseWriteStart(sessionP); - return true; - } - - *p = DIRECTORY_SEPARATOR[0]; - ++p; - { - unsigned int i; - i = handlerP->defaultFileNames.size; - while (i-- > 0) { - *p = '\0'; - strcat(z, (handlerP->defaultFileNames.item[i])); - if (FileStat(z, &fs)) { - if (!(fs.st_mode & S_IFDIR)) - handleFile(sessionP, z, fs.st_mtime, - handlerP->mimeTypeP); - } - } - } - - *(p-1) = '\0'; - - if (!FileStat(z, &fs)) { - ResponseStatusErrno(sessionP); - return true; - } - handleDirectory(sessionP, z, fs.st_mtime, handlerP->mimeTypeP); - } else - handleFile(sessionP, z, fs.st_mtime, handlerP->mimeTypeP); - - return true; -} - - - -size_t const HandlerDefaultBuiltinStack = 1024; - - -/****************************************************************************** -** -** server.c -** -** This file is part of the ABYSS Web server project. -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ diff --git a/trunk/lib/abyss/src/handler.h b/trunk/lib/abyss/src/handler.h deleted file mode 100644 index a8f2f3edc..000000000 --- a/trunk/lib/abyss/src/handler.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HANDLER_H_INCLUDED -#define HANDLER_H_INCLUDED - -#include "bool.h" -#include "xmlrpc-c/abyss.h" - -typedef struct BIHandler BIHandler; - -BIHandler * -HandlerCreate(void); - -void -HandlerDestroy(BIHandler * const handlerP); - - -void -HandlerSetMimeType(BIHandler * const handlerP, - MIMEType * const mimeTypeP); - -void -HandlerSetFilesPath(BIHandler * const handlerP, - const char * const filesPath); - -void -HandlerAddDefaultFN(BIHandler * const handlerP, - const char * const fileName); - -abyss_bool -HandlerDefaultBuiltin(TSession * const sessionP); - -extern size_t const HandlerDefaultBuiltinStack; - -#endif diff --git a/trunk/lib/abyss/src/http.c b/trunk/lib/abyss/src/http.c deleted file mode 100644 index f61c9928c..000000000 --- a/trunk/lib/abyss/src/http.c +++ /dev/null @@ -1,400 +0,0 @@ -/* Copyright information is at the end of the file */ - -#define _XOPEN_SOURCE 600 /* For strdup() */ -#define _BSD_SOURCE /* For xmlrpc_strcaseeq() */ - -#include -#include -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "bool.h" -#include "mallocvar.h" -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/base64_int.h" -#include "xmlrpc-c/abyss.h" - -#include "server.h" -#include "session.h" -#include "conn.h" -#include "token.h" -#include "date.h" -#include "data.h" - -#include "http.h" - - - -const char * -RequestHeaderValue(TSession * const sessionP, - const char * const name) { - - return TableValue(&sessionP->requestHeaderFields, name); -} - - - -const char * -HTTPMethodName(TMethod const method) { - - switch (method) { - case m_unknown: return "UNKNOWN"; - case m_get: return "GET"; - case m_put: return "PUT"; - case m_head: return "HEAD"; - case m_post: return "POST"; - case m_delete: return "DELETE"; - case m_trace: return "TRACE"; - case m_options: return "OPTIONS"; - } - assert(false); /* Compiler ought to know this, but doesn't */ - return 0; /* quiet compiler warning */ -} - - - -bool -HTTPRequestHasValidUri(TSession * const sessionP) { - - if (!sessionP->requestInfo.uri) - return false; - - if (xmlrpc_streq(sessionP->requestInfo.uri, "*")) - return (sessionP->requestInfo.method != m_options); - - if (strchr(sessionP->requestInfo.uri, '*')) - return false; - - return true; -} - - - -bool -HTTPRequestHasValidUriPath(TSession * const sessionP) { - - uint32_t i; - const char * p; - - p = sessionP->requestInfo.uri; - - i = 0; - - if (*p == '/') { - i = 1; - while (*p) - if (*(p++) == '/') { - if (*p == '/') - break; - else if ((xmlrpc_strneq(p,"./", 2)) || (xmlrpc_streq(p, "."))) - ++p; - else if ((xmlrpc_strneq(p, "../", 2)) || - (xmlrpc_streq(p, ".."))) { - p += 2; - --i; - if (i == 0) - break; - } - /* Prevent accessing hidden files (starting with .) */ - else if (*p == '.') - return false; - else - if (*p) - ++i; - } - } - return (*p == 0 && i > 0); -} - - - -abyss_bool -RequestAuth(TSession * const sessionP, - const char * const credential, - const char * const user, - const char * const pass) { -/*---------------------------------------------------------------------------- - Authenticate requester, in a very simplistic fashion. - - If the request executing on session *sessionP specifies basic - authentication (via Authorization header) with username 'user', password - 'pass', then return true. Else, return false and set up an authorization - failure response (HTTP response status 401) that says user must supply an - identity in the 'credential' domain. - - When we return true, we also set the username in the request info for the - session to 'user' so that a future SessionGetRequestInfo can get it. ------------------------------------------------------------------------------*/ - bool authorized; - const char * authValue; - - authValue = RequestHeaderValue(sessionP, "authorization"); - if (authValue) { - char * const valueBuffer = malloc(strlen(authValue)); - /* A buffer we can mangle as we parse the authorization: value */ - - if (!authValue) - /* Should return error, but we have no way to do that */ - authorized = false; - else { - const char * authType; - char * authHdrPtr; - - strcpy(valueBuffer, authValue); - authHdrPtr = &valueBuffer[0]; - - NextToken((const char **)&authHdrPtr); - GetTokenConst(&authHdrPtr, &authType); - if (authType) { - if (xmlrpc_strcaseeq(authType, "basic")) { - const char * userPass; - char userPassEncoded[80]; - - NextToken((const char **)&authHdrPtr); - - xmlrpc_asprintf(&userPass, "%s:%s", user, pass); - xmlrpc_base64Encode(userPass, userPassEncoded); - xmlrpc_strfree(userPass); - - if (xmlrpc_streq(authHdrPtr, userPassEncoded)) { - sessionP->requestInfo.user = xmlrpc_strdupsol(user); - authorized = true; - } else - authorized = false; - } else - authorized = false; - } else - authorized = false; - - free(valueBuffer); - } - } else - authorized = false; - - if (!authorized) { - const char * hdrValue; - xmlrpc_asprintf(&hdrValue, "Basic realm=\"%s\"", credential); - ResponseAddField(sessionP, "WWW-Authenticate", hdrValue); - - xmlrpc_strfree(hdrValue); - - ResponseStatus(sessionP, 401); - } - return authorized; -} - - - -/********************************************************************* -** Range -*********************************************************************/ - -abyss_bool -RangeDecode(char * const strArg, - xmlrpc_uint64_t const filesize, - xmlrpc_uint64_t * const start, - xmlrpc_uint64_t * const end) { - - char *str; - char *ss; - - str = strArg; /* initial value */ - - *start=0; - *end=filesize-1; - - if (*str=='-') - { - *start=filesize-strtol(str+1,&ss,10); - return ((ss!=str) && (!*ss)); - }; - - *start=strtol(str,&ss,10); - - if ((ss==str) || (*ss!='-')) - return false; - - str=ss+1; - - if (!*str) - return true; - - *end=strtol(str,&ss,10); - - if ((ss==str) || (*ss) || (*end<*start)) - return false; - - return true; -} - -/********************************************************************* -** HTTP -*********************************************************************/ - -const char * -HTTPReasonByStatus(uint16_t const code) { - - struct _HTTPReasons { - uint16_t status; - const char * reason; - }; - - static struct _HTTPReasons const reasons[] = { - { 100,"Continue" }, - { 101,"Switching Protocols" }, - { 200,"OK" }, - { 201,"Created" }, - { 202,"Accepted" }, - { 203,"Non-Authoritative Information" }, - { 204,"No Content" }, - { 205,"Reset Content" }, - { 206,"Partial Content" }, - { 300,"Multiple Choices" }, - { 301,"Moved Permanently" }, - { 302,"Moved Temporarily" }, - { 303,"See Other" }, - { 304,"Not Modified" }, - { 305,"Use Proxy" }, - { 400,"Bad Request" }, - { 401,"Unauthorized" }, - { 402,"Payment Required" }, - { 403,"Forbidden" }, - { 404,"Not Found" }, - { 405,"Method Not Allowed" }, - { 406,"Not Acceptable" }, - { 407,"Proxy Authentication Required" }, - { 408,"Request Timeout" }, - { 409,"Conflict" }, - { 410,"Gone" }, - { 411,"Length Required" }, - { 412,"Precondition Failed" }, - { 413,"Request Entity Too Large" }, - { 414,"Request-URI Too Long" }, - { 415,"Unsupported Media Type" }, - { 500,"Internal Server Error" }, - { 501,"Not Implemented" }, - { 502,"Bad Gateway" }, - { 503,"Service Unavailable" }, - { 504,"Gateway Timeout" }, - { 505,"HTTP Version Not Supported" }, - { 000, NULL } - }; - const struct _HTTPReasons * reasonP; - - reasonP = &reasons[0]; - - while (reasonP->status <= code) - if (reasonP->status == code) - return reasonP->reason; - else - ++reasonP; - - return "No Reason"; -} - - - -bool -HTTPWriteBodyChunk(TSession * const sessionP, - const char * const buffer, - uint32_t const len) { - - bool succeeded; - - if (sessionP->chunkedwrite && sessionP->chunkedwritemode) { - char chunkHeader[16]; - - sprintf(chunkHeader, "%x\r\n", len); - - succeeded = - ConnWrite(sessionP->connP, chunkHeader, strlen(chunkHeader)); - if (succeeded) { - succeeded = ConnWrite(sessionP->connP, buffer, len); - if (succeeded) - succeeded = ConnWrite(sessionP->connP, "\r\n", 2); - } - } else - succeeded = ConnWrite(sessionP->connP, buffer, len); - - return succeeded; -} - - - -bool -HTTPWriteEndChunk(TSession * const sessionP) { - - bool retval; - - if (sessionP->chunkedwrite && sessionP->chunkedwritemode) { - /* May be one day trailer dumping will be added */ - sessionP->chunkedwritemode = false; - retval = ConnWrite(sessionP->connP, "0\r\n\r\n", 5); - } else - retval = true; - - return retval; -} - - - -bool -HTTPKeepalive(TSession * const sessionP) { -/*---------------------------------------------------------------------------- - Return value: the connection should be kept alive after the session - *sessionP is over. ------------------------------------------------------------------------------*/ - return (sessionP->requestInfo.keepalive && - !sessionP->serverDeniesKeepalive && - sessionP->status < 400); -} - - - -bool -HTTPWriteContinue(TSession * const sessionP) { - - char const continueStatus[] = "HTTP/1.1 100 continue\r\n\r\n"; - /* This is a status line plus an end-of-header empty line */ - - return ConnWrite(sessionP->connP, continueStatus, strlen(continueStatus)); -} - - - -/****************************************************************************** -** -** http.c -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ diff --git a/trunk/lib/abyss/src/http.h b/trunk/lib/abyss/src/http.h deleted file mode 100644 index e7fac458f..000000000 --- a/trunk/lib/abyss/src/http.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HTTP_H_INCLUDED -#define HTTP_H_INCLUDED - -#include -#include "xmlrpc-c/abyss.h" - -const char * -HTTPMethodName(TMethod const method); - -bool -HTTPRequestHasValidUri(TSession * const sessionP); - -bool -HTTPRequestHasValidUriPath(TSession * const sessionP); - -const char * -HTTPReasonByStatus(uint16_t const code); - -bool -HTTPWriteBodyChunk(TSession * const sessionP, - const char * const buffer, - uint32_t const len); - -bool -HTTPWriteEndChunk(TSession * const sessionP); - -bool -HTTPKeepalive(TSession * const sessionP); - -bool -HTTPWriteContinue(TSession * const sessionP); - -#endif diff --git a/trunk/lib/abyss/src/init.c b/trunk/lib/abyss/src/init.c deleted file mode 100644 index b4e4a788e..000000000 --- a/trunk/lib/abyss/src/init.c +++ /dev/null @@ -1,101 +0,0 @@ -/*============================================================================= - The functions handle static stuff -- the functions do not operate on - any particular Abyss object, but rather on the global environment of - the program that uses the Abyss library. abyssInit() is essentially - and extension of the program loader. - - The intent is for any program that uses the Abyss library to call - AbyssInit() just as it starts up, and AbyssTerm() just as it exits. - It should do both when the program is only one thread, because they - are not thread-safe. - - These functions do the bare minimum they can get away with; we prefer - context to be local to invidual objects. -=============================================================================*/ - -#include - -#include "xmlrpc-c/string_int.h" - -#include "chanswitch.h" -#include "channel.h" - -#include "xmlrpc-c/abyss.h" - - -static unsigned int AbyssInitCount = 0; - -static void -initAbyss(const char ** const errorP) { - - const char * error; - - DateInit(); - MIMETypeInit(); - - ChanSwitchInit(&error); - - if (error) { - xmlrpc_asprintf(errorP, - "Could not initialize channel swtich class. %s", - error); - - xmlrpc_strfree(error); - } else { - const char * error; - ChannelInit(&error); - - if (error) { - xmlrpc_asprintf(errorP, "Could not initialize Channel class. %s", - error); - - xmlrpc_strfree(error); - } else { - AbyssInitCount = 1; - *errorP = NULL; - - if (*errorP) - ChannelTerm(); - } - if (*errorP) - ChanSwitchTerm(); - } -} - - - -void -AbyssInit(const char ** const errorP) { - - if (AbyssInitCount > 0) { - *errorP = NULL; - ++AbyssInitCount; - } else { - initAbyss(errorP); - if (!*errorP) - AbyssInitCount = 1; - } -} - - - -static void -termAbyss(void) { - - ChannelTerm(); - ChanSwitchTerm(); - MIMETypeTerm(); -} - - - -void -AbyssTerm(void) { - - assert(AbyssInitCount > 0); - - --AbyssInitCount; - - if (AbyssInitCount == 0) - termAbyss(); -} diff --git a/trunk/lib/abyss/src/main.c b/trunk/lib/abyss/src/main.c deleted file mode 100644 index 90f39f382..000000000 --- a/trunk/lib/abyss/src/main.c +++ /dev/null @@ -1,254 +0,0 @@ -/****************************************************************************** -** -** main.c -** -** This file is part of the ABYSS Web server project. -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#if MSVCRT -#include -#endif - -#ifdef _UNIX -#include -#include -#endif - -#include "xmlrpc-c/abyss.h" - -void Answer(TSession *r, uint16_t statuscode, char *buffer) -{ - ResponseChunked(r); - - ResponseStatus(r,statuscode); - - ResponseContentType(r,"text/html"); - - ResponseWriteStart(r); - - HTTPWrite(r,"",12); - - HTTPWrite(r,buffer,strlen(buffer)); - - HTTPWrite(r,"",14); - - HTTPWriteEnd(r); -} - -abyss_bool HandleTime(TSession *r) -{ - char z[50]; - time_t ltime; - TDate date; - const char * dateString; - const char * answer; - - if (!xmlrpc_streq(r->uri,"/time")) - return FALSE; - - if (!RequestAuth(r,"Mot de passe","moez","hello")) - return TRUE; - - time(<ime); - DateFromGMT(&date, ltime); - - DateToString(&date, &dateString); - - xmlrpc_asprintf(&answer, "The time is %s", dateString); - - Answer(r, 200, answer); - - xmlrpc_strfree(dateString); - xmlrpc_strfree(answer); - - return TRUE; -} - -abyss_bool HandleDump(TSession *r) -{ - char z[50]; - - if (!xmlrpc_streq(r->uri,"/name")) - return FALSE; - - sprintf(z,"Server name is %s", (r->server)->name ); - Answer(r,200,z); - - return TRUE; -} - -abyss_bool HandleStatus(TSession *r) -{ - uint32_t status; - - if (sscanf(r->uri,"/status/%d",&status)<=0) - return FALSE; - - ResponseStatus(r,(uint16_t)status); - - return TRUE; -} - -abyss_bool HandleMIMEType(TSession *r) -{ - char *m; - - if (!xmlrpc_strneq(r->uri, "/mime/", 6)) - return FALSE; - - m=MIMETypeFromExt(r->uri+6); - if (!m) - m="(none)"; - - Answer(r,200,m); - - return TRUE; -} - -#ifdef _UNIX -static void sigterm(int sig) -{ - TraceExit("Signal %d received. Exiting...\n",sig); -} - - - -static void -sigchld(int const signalClass) { - - bool childrenLeft; - bool error; - - childrenLeft = true; - error = false; - - /* Reap defunct children until there aren't any more. */ - while (childrenLeft && !error) { - int status; - pid_t rc; - rc = waitpid((pid_t) -1, &status, WNOHANG); - - if (rc == 0) - childrenLeft = false; - else if (rc < 0) { - /* because of ptrace */ - if (errno == EINTR) { - /* ptrace causes this */ - } else - error = true; - } else { - /* We reaped a child. */ - pid_t const pid = rc; - ThreadHandleSigchld(pid); - } - } -} -#endif _UNIX - - - -int main(int argc,char **argv) -{ - const char * const name = argv[0]; - TServer srv; - char * p; - const char * conffile; - bool err; - - conffile = DEFAULT_CONF_FILE; /* initial value */ - err = FALSE; /* initial value */ - - while (p=*(++argv)) - { - if ((*p=='-') && (*(p+1))) - if (*(p+2)=='\0') - switch (*(p+1)) - { - case 'c': - argv++; - if (*argv) - conffile=*argv; - else - err=TRUE; - break; - default: - err=TRUE; - } - else - err=TRUE; - else - err=TRUE; - }; - - if (err) - { - help(name); - exit(1); - }; - - DateInit(); - - MIMETypeInit(); - - ServerCreate(&srv,"HTTPServer",80,DEFAULT_DOCS,NULL); - - ConfReadServerFile(conffile,&srv); - - ServerAddHandler(&srv,HandleTime); - ServerAddHandler(&srv,HandleDump); - ServerAddHandler(&srv,HandleStatus); - ServerAddHandler(&srv,HandleMIMEType); - - ServerInit(&srv); - -#ifdef _UNIX - /* Catch various termination signals. */ - signal(SIGTERM,sigterm); - signal(SIGINT,sigterm); - signal(SIGHUP,sigterm); - signal(SIGUSR1,sigterm); - - /* Catch defunct children. */ - signal(SIGCHLD,sigchld); -#endif - - ServerDaemonize(srv); - - ServerRun(&srv); - - return 0; -} diff --git a/trunk/lib/abyss/src/response.c b/trunk/lib/abyss/src/response.c deleted file mode 100644 index cc0980a23..000000000 --- a/trunk/lib/abyss/src/response.c +++ /dev/null @@ -1,826 +0,0 @@ -/*============================================================================= - response -=============================================================================== - This module contains callbacks from and services for a request handler. - - Copyright information is at the end of the file -=============================================================================*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "bool.h" -#include "int.h" -#include "version.h" -#include "mallocvar.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/abyss.h" - -#include "trace.h" -#include "server.h" -#include "session.h" -#include "file.h" -#include "conn.h" -#include "token.h" -#include "date.h" -#include "data.h" -#include "abyss_info.h" -#include "http.h" - - - -void -ResponseError2(TSession * const sessionP, - const char * const explanation) { - - const char * errorDocument; - - ResponseAddField(sessionP, "Content-type", "text/html"); - - ResponseWriteStart(sessionP); - - xmlrpc_asprintf(&errorDocument, - "Error %d" - "" - "

Error %d

" - "

%s

" SERVER_HTML_INFO - "" - "", - sessionP->status, sessionP->status, explanation); - - ConnWrite(sessionP->connP, errorDocument, strlen(errorDocument)); - - xmlrpc_strfree(errorDocument); -} - - - -void -ResponseError(TSession * const sessionP) { - - ResponseError2(sessionP, HTTPReasonByStatus(sessionP->status)); -} - - - - -abyss_bool -ResponseChunked(TSession * const sessionP) { -/*---------------------------------------------------------------------------- - Make the response chunked. - - This is only a hope, things will be real only after a call of - ResponseWriteStart() ------------------------------------------------------------------------------*/ - assert(!sessionP->responseStarted); - - sessionP->chunkedwrite = - (sessionP->version.major > 1) || - (sessionP->version.major == 1 && (sessionP->version.minor >= 1)); - - sessionP->chunkedwritemode = true; - - return true; -} - - - -void -ResponseStatus(TSession * const sessionP, - unsigned short const code) { -/*---------------------------------------------------------------------------- - Set the status code for the response to 'code'. ------------------------------------------------------------------------------*/ - sessionP->status = code; -} - - - -xmlrpc_uint16_t -ResponseStatusFromErrno(int const errnoArg) { -/*---------------------------------------------------------------------------- - The appropriate HTTP status code for a POSIX errno of 'errnoArg'. ------------------------------------------------------------------------------*/ - uint16_t code; - - switch (errnoArg) { - case EACCES: - code=403; - break; - case ENOENT: - code=404; - break; - default: - code=500; - } - return code; -} - - - -void -ResponseStatusErrno(TSession * const sessionP) { -/*---------------------------------------------------------------------------- - Set the response state from the global 'errno' value (i.e. the result - of the last system call Caller made). ------------------------------------------------------------------------------*/ - ResponseStatus(sessionP, ResponseStatusFromErrno(errno)); -} - - - -static bool -isValidHttpToken(const char * const token) { - - char const separators[] = "()<>@,;:\\\"/[]?={} \t"; - const char * p; - bool valid; - - for (p = &token[0], valid = true; *p; ++p) { - if (!isprint(*p) || strchr(separators, *p)) - valid = false; - } - return valid; -} - - - - -static bool -isValidHttpText(const char * const text) { - - const char * p; - bool valid; - - for (p = &text[0], valid = true; *p; ++p) { - if (!isprint(*p)) - valid = false; - } - return valid; -} - - - -abyss_bool -ResponseAddField(TSession * const sessionP, - const char * const name, - const char * const value) { - - abyss_bool succeeded; - - if (!isValidHttpToken(name)) { - TraceMsg("Supplied HTTP header field name is not a valid HTTP token"); - succeeded = false; - } else if (!isValidHttpText(value)) { - TraceMsg("Supplied HTTP header field value is not valid HTTP text"); - succeeded = false; - } else { - succeeded = TableAdd(&sessionP->responseHeaderFields, name, value); - } - return succeeded; -} - - - -static void -addConnectionHeaderFld(TSession * const sessionP) { - - struct _TServer * const srvP = ConnServer(sessionP->connP)->srvP; - - if (HTTPKeepalive(sessionP)) { - const char * keepaliveValue; - - ResponseAddField(sessionP, "Connection", "Keep-Alive"); - - xmlrpc_asprintf(&keepaliveValue, "timeout=%u, max=%u", - srvP->keepalivetimeout, srvP->keepalivemaxconn); - - ResponseAddField(sessionP, "Keep-Alive", keepaliveValue); - - xmlrpc_strfree(keepaliveValue); - } else - ResponseAddField(sessionP, "Connection", "close"); -} - - - -static void -addDateHeaderFld(TSession * const sessionP) { - - if (sessionP->status >= 200) { - const char * dateValue; - - DateToString(sessionP->date, &dateValue); - - if (dateValue) { - ResponseAddField(sessionP, "Date", dateValue); - xmlrpc_strfree(dateValue); - } - } -} - - - -static void -addServerHeaderFld(TSession * const sessionP) { - - const char * serverValue; - - xmlrpc_asprintf(&serverValue, "Xmlrpc-c_Abyss/%s", XMLRPC_C_VERSION); - - ResponseAddField(sessionP, "Server", serverValue); - - xmlrpc_strfree(serverValue); -} - - - -static unsigned int -leadingWsCt(const char * const arg) { - - unsigned int i; - - for (i = 0; arg[i] && isspace(arg[i]); ++i); - - return i; -} - - - -static unsigned int -trailingWsPos(const char * const arg) { - - unsigned int i; - - for (i = strlen(arg); i > 0 && isspace(arg[i-1]); --i); - - return i; -} - - - -static const char * -formatFieldValue(const char * const unformatted) { -/*---------------------------------------------------------------------------- - Return the string of characters that goes after the colon on the - HTTP header field line, given that 'unformatted' is its basic value. ------------------------------------------------------------------------------*/ - const char * retval; - - /* An HTTP header field value may not have leading or trailing white - space. - */ - char * buffer; - - buffer = malloc(strlen(unformatted) + 1); - - if (buffer == NULL) - retval = xmlrpc_strnomemval(); - else { - unsigned int const lead = leadingWsCt(unformatted); - unsigned int const trail = trailingWsPos(unformatted); - assert(trail >= lead); - strncpy(buffer, &unformatted[lead], trail - lead); - buffer[trail - lead] = '\0'; - retval = buffer; - } - return retval; -} - - - -static void -sendHeader(TConn * const connP, - TTable const fields) { -/*---------------------------------------------------------------------------- - Send the HTTP response header whose fields are fields[]. - - Don't include the blank line that separates the header from the body. - - fields[] contains syntactically valid HTTP header field names and values. - But to the extent that int contains undefined field names or semantically - invalid values, the header we send is invalid. ------------------------------------------------------------------------------*/ - unsigned int i; - - for (i = 0; i < fields.size; ++i) { - TTableItem * const fieldP = &fields.item[i]; - const char * const fieldValue = formatFieldValue(fieldP->value); - - const char * line; - - xmlrpc_asprintf(&line, "%s: %s\r\n", fieldP->name, fieldValue); - ConnWrite(connP, line, strlen(line)); - xmlrpc_strfree(line); - xmlrpc_strfree(fieldValue); - } -} - - -void -ResponseWriteStart(TSession * const sessionP) { -/*---------------------------------------------------------------------------- - Begin the process of sending the response for an HTTP transaction - (i.e. Abyss session). - - As part of this, send the entire HTTP header for the response. ------------------------------------------------------------------------------*/ - struct _TServer * const srvP = ConnServer(sessionP->connP)->srvP; - - assert(!sessionP->responseStarted); - - if (sessionP->status == 0) { - /* Handler hasn't set status. That's an error */ - TraceMsg("Abyss client called ResponseWriteStart() on " - "a session for which he has not set the request status " - "('status' member of TSession). Using status 500\n"); - sessionP->status = 500; - } - - sessionP->responseStarted = true; - - { - const char * const reason = HTTPReasonByStatus(sessionP->status); - const char * line; - xmlrpc_asprintf(&line,"HTTP/1.1 %u %s\r\n", sessionP->status, reason); - ConnWrite(sessionP->connP, line, strlen(line)); - xmlrpc_strfree(line); - } - - addConnectionHeaderFld(sessionP); - - if (sessionP->chunkedwrite && sessionP->chunkedwritemode) - ResponseAddField(sessionP, "Transfer-Encoding", "chunked"); - - addDateHeaderFld(sessionP); - - if (srvP->advertise) - addServerHeaderFld(sessionP); - - /* Note that sessionP->responseHeaderFields is defined to contain - syntactically but not necessarily semantically valid header - field names and values. - */ - sendHeader(sessionP->connP, sessionP->responseHeaderFields); - - ConnWrite(sessionP->connP, "\r\n", 2); -} - - - -abyss_bool -ResponseWriteBody(TSession * const sessionP, - const char * const data, - xmlrpc_uint32_t const len) { - - return HTTPWriteBodyChunk(sessionP, data, len); -} - - - -abyss_bool -ResponseWriteEnd(TSession * const sessionP) { - - return HTTPWriteEndChunk(sessionP); -} - - - -abyss_bool -ResponseContentType(TSession * const serverP, - const char * const type) { - - return ResponseAddField(serverP, "Content-type", type); -} - - - -abyss_bool -ResponseContentLength(TSession * const sessionP, - xmlrpc_uint64_t const len) { - - char contentLengthValue[32]; - - sprintf(contentLengthValue, "%" PRIu64, len); - - return ResponseAddField(sessionP, "Content-length", contentLengthValue); -} - - - -void -ResponseAccessControl(TSession * const abyssSessionP, - ResponseAccessCtl const accessControl) { - - if (accessControl.allowOrigin) { - ResponseAddField(abyssSessionP, "Access-Control-Allow-Origin", - accessControl.allowOrigin); - ResponseAddField(abyssSessionP, "Access-Control-Allow-Methods", - "POST"); - ResponseAddField(abyssSessionP, "Access-Control-Allow-Headers", - "Content-Type"); - ResponseAddField(abyssSessionP, "Access-Control-Allow-Headers", - "Content-Length"); - if (accessControl.expires) { - char buffer[64]; - sprintf(buffer, "%u", accessControl.maxAge); - ResponseAddField(abyssSessionP, "Access-Control-Max-Age", buffer); - } - } -} - - - -/********************************************************************* -** MIMEType -*********************************************************************/ - -struct MIMEType { - TList typeList; - TList extList; - TPool pool; -}; - - -static MIMEType * globalMimeTypeP = NULL; - - - -MIMEType * -MIMETypeCreate(void) { - - MIMEType * MIMETypeP; - - MALLOCVAR(MIMETypeP); - - if (MIMETypeP) { - ListInit(&MIMETypeP->typeList); - ListInit(&MIMETypeP->extList); - PoolCreate(&MIMETypeP->pool, 1024); - } - return MIMETypeP; -} - - - -void -MIMETypeDestroy(MIMEType * const MIMETypeP) { - - PoolFree(&MIMETypeP->pool); - - free(MIMETypeP); -} - - - -void -MIMETypeInit(void) { - - if (globalMimeTypeP != NULL) - abort(); - - globalMimeTypeP = MIMETypeCreate(); -} - - - -void -MIMETypeTerm(void) { - - if (globalMimeTypeP == NULL) - abort(); - - MIMETypeDestroy(globalMimeTypeP); - - globalMimeTypeP = NULL; -} - - - -static void -mimeTypeAdd(MIMEType * const MIMETypeP, - const char * const type, - const char * const ext, - bool * const successP) { - - uint16_t index; - void * mimeTypesItem; - bool typeIsInList; - - assert(MIMETypeP != NULL); - - typeIsInList = ListFindString(&MIMETypeP->typeList, type, &index); - if (typeIsInList) - mimeTypesItem = MIMETypeP->typeList.item[index]; - else - mimeTypesItem = (void*)PoolStrdup(&MIMETypeP->pool, type); - - if (mimeTypesItem) { - bool extIsInList; - extIsInList = ListFindString(&MIMETypeP->extList, ext, &index); - if (extIsInList) { - MIMETypeP->typeList.item[index] = mimeTypesItem; - *successP = true; - } else { - void * extItem = (void*)PoolStrdup(&MIMETypeP->pool, ext); - if (extItem) { - bool addedToMimeTypes; - - addedToMimeTypes = - ListAdd(&MIMETypeP->typeList, mimeTypesItem); - if (addedToMimeTypes) { - bool addedToExt; - - addedToExt = ListAdd(&MIMETypeP->extList, extItem); - *successP = addedToExt; - if (!*successP) - ListRemove(&MIMETypeP->typeList); - } else - *successP = false; - if (!*successP) - PoolReturn(&MIMETypeP->pool, extItem); - } else - *successP = false; - } - } else - *successP = false; -} - - - - -abyss_bool -MIMETypeAdd2(MIMEType * const MIMETypeArg, - const char * const type, - const char * const ext) { - - MIMEType * MIMETypeP = MIMETypeArg ? MIMETypeArg : globalMimeTypeP; - - bool success; - - if (MIMETypeP == NULL) - success = false; - else - mimeTypeAdd(MIMETypeP, type, ext, &success); - - return success; -} - - - -abyss_bool -MIMETypeAdd(const char * const type, - const char * const ext) { - - return MIMETypeAdd2(globalMimeTypeP, type, ext); -} - - - -static const char * -mimeTypeFromExt(MIMEType * const MIMETypeP, - const char * const ext) { - - const char * retval; - uint16_t extindex; - bool extIsInList; - - assert(MIMETypeP != NULL); - - extIsInList = ListFindString(&MIMETypeP->extList, ext, &extindex); - if (!extIsInList) - retval = NULL; - else - retval = MIMETypeP->typeList.item[extindex]; - - return retval; -} - - - -const char * -MIMETypeFromExt2(MIMEType * const MIMETypeArg, - const char * const ext) { - - const char * retval; - - MIMEType * MIMETypeP = MIMETypeArg ? MIMETypeArg : globalMimeTypeP; - - if (MIMETypeP == NULL) - retval = NULL; - else - retval = mimeTypeFromExt(MIMETypeP, ext); - - return retval; -} - - - -const char * -MIMETypeFromExt(const char * const ext) { - - return MIMETypeFromExt2(globalMimeTypeP, ext); -} - - - -static void -findExtension(const char * const fileName, - const char ** const extP) { - - unsigned int extPos = 0; /* stifle unset variable warning */ - /* Running estimation of where in fileName[] the extension starts */ - bool extFound; - unsigned int i; - - /* We're looking for the last dot after the last slash */ - for (i = 0, extFound = false; fileName[i]; ++i) { - char const c = fileName[i]; - - if (c == '.') { - extFound = true; - extPos = i + 1; - } - if (c == '/') - extFound = false; - } - - if (extFound) - *extP = &fileName[extPos]; - else - *extP = NULL; -} - - - -static const char * -mimeTypeFromFileName(MIMEType * const MIMETypeP, - const char * const fileName) { - - const char * retval; - const char * ext; - - assert(MIMETypeP != NULL); - - findExtension(fileName, &ext); - - if (ext) - retval = MIMETypeFromExt2(MIMETypeP, ext); - else - retval = "application/octet-stream"; - - return retval; -} - - - -const char * -MIMETypeFromFileName2(MIMEType * const MIMETypeArg, - const char * const fileName) { - - const char * retval; - - MIMEType * MIMETypeP = MIMETypeArg ? MIMETypeArg : globalMimeTypeP; - - if (MIMETypeP == NULL) - retval = NULL; - else - retval = mimeTypeFromFileName(MIMETypeP, fileName); - - return retval; -} - - - -const char * -MIMETypeFromFileName(const char * const fileName) { - - return MIMETypeFromFileName2(globalMimeTypeP, fileName); -} - - - -static bool -fileContainsText(const char * const fileName) { -/*---------------------------------------------------------------------------- - Return true iff we can read the contents of the file named 'fileName' - and see that it appears to be composed of plain text characters. ------------------------------------------------------------------------------*/ - bool retval; - bool fileOpened; - TFile * fileP; - - fileOpened = FileOpen(&fileP, fileName, O_BINARY | O_RDONLY); - if (fileOpened) { - char const ctlZ = 26; - unsigned char buffer[80]; - int32_t readRc; - unsigned int i; - - readRc = FileRead(fileP, buffer, sizeof(buffer)); - - if (readRc >= 0) { - unsigned int bytesRead = readRc; - bool nonTextFound; - - nonTextFound = false; /* initial value */ - - for (i = 0; i < bytesRead; ++i) { - char const c = buffer[i]; - if (c < ' ' && !isspace(c) && c != ctlZ) - nonTextFound = true; - } - retval = !nonTextFound; - } else - retval = false; - FileClose(fileP); - } else - retval = false; - - return retval; -} - - - -static const char * -mimeTypeGuessFromFile(MIMEType * const MIMETypeP, - const char * const fileName) { - - const char * retval; - const char * ext; - - findExtension(fileName, &ext); - - retval = NULL; - - if (ext && MIMETypeP) - retval = MIMETypeFromExt2(MIMETypeP, ext); - - if (!retval) { - if (fileContainsText(fileName)) - retval = "text/plain"; - else - retval = "application/octet-stream"; - } - return retval; -} - - - -const char * -MIMETypeGuessFromFile2(MIMEType * const MIMETypeArg, - const char * const fileName) { - - return mimeTypeGuessFromFile(MIMETypeArg ? MIMETypeArg : globalMimeTypeP, - fileName); -} - - - -const char * -MIMETypeGuessFromFile(const char * const fileName) { - - return mimeTypeGuessFromFile(globalMimeTypeP, fileName); -} - - - -/****************************************************************************** -** -** http.c -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ diff --git a/trunk/lib/abyss/src/server.c b/trunk/lib/abyss/src/server.c deleted file mode 100644 index 5c7f83839..000000000 --- a/trunk/lib/abyss/src/server.c +++ /dev/null @@ -1,1828 +0,0 @@ -/* Copyright information is at end of file */ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ -#define _BSD_SOURCE /* Make sure setgroups()is in */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#if MSVCRT - #include -#else - #include -#endif -#include -#include -#include -#if !MSVCRT - #include -#endif - -#include "bool.h" -#include "girmath.h" -#include "mallocvar.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/sleep_int.h" -#include "xmlrpc-c/lock.h" -#include "xmlrpc-c/lock_platform.h" - -#include "xmlrpc-c/abyss.h" -#include "trace.h" -#include "thread.h" -#include "session.h" -#include "file.h" -#include "conn.h" -#include "chanswitch.h" -#include "channel.h" -#include "socket.h" -#if MSVCRT - #include "socket_win.h" -#else - #include "socket_unix.h" -#endif -#include "http.h" -#include "handler.h" -#include "sessionReadRequest.h" - -#include "server.h" - - -struct uriHandler { - initHandlerFn init; - termHandlerFn term; - handleReq3Fn handleReq3; - handleReq2Fn handleReq2; - URIHandler handleReq1; - void * userdata; -}; - - - -void -ServerTerminate(TServer * const serverP) { - - struct _TServer * const srvP = serverP->srvP; - - srvP->terminationRequested = true; - - if (srvP->chanSwitchP) - ChanSwitchInterrupt(srvP->chanSwitchP); -} - - - -void -ServerResetTerminate(TServer * const serverP) { - - struct _TServer * const srvP = serverP->srvP; - - srvP->terminationRequested = false; -} - - - -static void -initUnixStuff(struct _TServer * const srvP) { -#if !MSVCRT - srvP->pidfileP = NULL; - srvP->uid = srvP->gid = -1; -#endif -} - - - -static void -logOpen(struct _TServer * const srvP, - const char ** const errorP) { - - bool success; - - success = FileOpenCreate(&srvP->logfileP, srvP->logfilename, - O_WRONLY | O_APPEND); - if (success) { - srvP->logLockP = xmlrpc_lock_create(); - *errorP = NULL; - - srvP->logfileisopen = true; - - if (*errorP) - FileClose(srvP->logfileP); - } else - xmlrpc_asprintf(errorP, "Can't open log file '%s'", srvP->logfilename); -} - - - -static void -logClose(struct _TServer * const srvP) { - - if (srvP->logfileisopen) { - FileClose(srvP->logfileP); - srvP->logLockP->destroy(srvP->logLockP); - srvP->logfileisopen = false; - } -} - - - -static void -setupTrace(struct _TServer * const srvP) { - - srvP->tracer.traceIsActive = (getenv("ABYSS_TRACE_SERVER") != NULL); - - if (srvP->tracer.traceIsActive) - fprintf(stderr, "Abyss server will trace " - "basic server activity " - "because of ABYSS_TRACE_SERVER environment variable\n"); -} - - - -static void -tracev(const char * const fmt, - va_list argptr) { - - vfprintf(stderr, fmt, argptr); - - fprintf(stderr, "\n"); -} - - - -static void -trace(struct Tracer * const tracerP, - const char * const fmt, - ...) { - - if (tracerP->traceIsActive) { - va_list argptr; - - va_start(argptr, fmt); - tracev(fmt, argptr); - va_end(argptr); - } -} - - - -static void -initChanSwitchStuff(struct _TServer * const srvP, - bool const noAccept, - TChanSwitch * const chanSwitchP, - bool const userChanSwitch, - unsigned short const port, - const char ** const errorP) { - - - if (chanSwitchP) { - *errorP = NULL; - srvP->serverAcceptsConnections = true; - srvP->chanSwitchP = chanSwitchP; - srvP->weCreatedChanSwitch = !userChanSwitch; - } else if (noAccept) { - *errorP = NULL; - srvP->serverAcceptsConnections = false; - srvP->chanSwitchP = NULL; - srvP->weCreatedChanSwitch = false; - } else { - *errorP = NULL; - srvP->serverAcceptsConnections = true; - srvP->chanSwitchP = NULL; - srvP->weCreatedChanSwitch = false; - srvP->port = port; - } - srvP->readyToAccept = false; -} - - - -static void -createServer(struct _TServer ** const srvPP, - bool const noAccept, - TChanSwitch * const chanSwitchP, - bool const userChanSwitch, - unsigned short const portNumber, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Create a server object and return it as *srvPP. ------------------------------------------------------------------------------*/ - struct _TServer * srvP; - - MALLOCVAR(srvP); - - if (srvP == NULL) { - xmlrpc_asprintf(errorP, - "Unable to allocate space for server descriptor"); - } else { - setupTrace(srvP); - - srvP->terminationRequested = false; - - initChanSwitchStuff(srvP, noAccept, chanSwitchP, userChanSwitch, - portNumber, errorP); - - if (!*errorP) { - srvP->builtinHandlerP = HandlerCreate(); - if (!srvP->builtinHandlerP) - xmlrpc_asprintf(errorP, "Unable to allocate space for " - "builtin handler descriptor"); - else { - srvP->defaultHandler = HandlerDefaultBuiltin; - srvP->defaultHandlerContext = srvP->builtinHandlerP; - - srvP->name = strdup("unnamed"); - srvP->logfilename = NULL; - srvP->keepalivetimeout = 15; - srvP->keepalivemaxconn = 30; - srvP->timeout = 15; - srvP->advertise = true; - srvP->useSigchld = false; - srvP->uriHandlerStackSize = 0; - srvP->maxConn = 15; - srvP->maxConnBacklog = 15; - srvP->maxSessionMem = 0; - - initUnixStuff(srvP); - - ListInitAutoFree(&srvP->handlers); - - srvP->logfileisopen = false; - - *errorP = NULL; - - if (*errorP) - HandlerDestroy(srvP->builtinHandlerP); - } - } - if (*errorP) - free(srvP); - } - *srvPP = srvP; -} - - - -static void -setNamePathLog(TServer * const serverP, - const char * const name, - const char * const filesPath, - const char * const logFileName) { -/*---------------------------------------------------------------------------- - This odd function exists to help with backward compatibility. - Today, we have the expandable model where you create a server with - default parameters, then use ServerSet... functions to choose - non-default parameters. But before, you specified these three - parameters right in the arguments of various create functions. ------------------------------------------------------------------------------*/ - if (name) - ServerSetName(serverP, name); - if (filesPath) - ServerSetFilesPath(serverP, filesPath); - if (logFileName) - ServerSetLogFileName(serverP, logFileName); -} - - - -abyss_bool -ServerCreate(TServer * const serverP, - const char * const name, - xmlrpc_uint16_t const portNumber, - const char * const filesPath, - const char * const logFileName) { -/*---------------------------------------------------------------------------- - Create a server that will listen for and accept client connections on TCP - port 'portNumber'. Those connections will be raw TCP connections. - - Set *serverP to represent that server. ------------------------------------------------------------------------------*/ - - bool const noAcceptFalse = false; - bool const userChanSwitchFalse = false; - - bool success; - const char * error; - - createServer(&serverP->srvP, noAcceptFalse, - NULL, userChanSwitchFalse, - portNumber, &error); - - if (error) { - TraceMsg(error); - xmlrpc_strfree(error); - success = false; - } else { - success = true; - - setNamePathLog(serverP, name, filesPath, logFileName); - } - - return success; -} - - - -static void -createSwitchFromOsSocket(TOsSocket const osSocket, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - -#if MSVCRT - ChanSwitchWinCreateWinsock(osSocket, chanSwitchPP, errorP); -#else - ChanSwitchUnixCreateFd(osSocket, chanSwitchPP, errorP); -#endif -} - - - -static void -createChannelFromOsSocket(TOsSocket const osSocket, - TChannel ** const channelPP, - void ** const channelInfoPP, - const char ** const errorP) { - -#if MSVCRT - ChannelWinCreateWinsock(osSocket, channelPP, - (struct abyss_win_chaninfo**)channelInfoPP, - errorP); -#else - ChannelUnixCreateFd(osSocket, channelPP, - (struct abyss_unix_chaninfo**)channelInfoPP, - errorP); -#endif -} - - - -abyss_bool -ServerCreateSocket(TServer * const serverP, - const char * const name, - TOsSocket const socketFd, - const char * const filesPath, - const char * const logFileName) { -/*---------------------------------------------------------------------------- - Create a server that will listen for and accept client connections on - socket 'socketFd'. Those connections will be raw TCP connections. - - Set *serverP to represent that server. ------------------------------------------------------------------------------*/ - bool success; - TChanSwitch * chanSwitchP; - const char * error; - - createSwitchFromOsSocket(socketFd, &chanSwitchP, &error); - - if (error) { - TraceMsg(error); - success = false; - xmlrpc_strfree(error); - } else { - bool const noAcceptFalse = false; - bool const userChanSwitchFalse = false; - - const char * error; - - createServer(&serverP->srvP, noAcceptFalse, - chanSwitchP, userChanSwitchFalse, - 0, &error); - - if (error) { - TraceMsg(error); - success = false; - xmlrpc_strfree(error); - } else { - success = true; - - setNamePathLog(serverP, name, filesPath, logFileName); - } - if (!success) - ChanSwitchDestroy(chanSwitchP); - } - - return success; -} - - - -abyss_bool -ServerCreateNoAccept(TServer * const serverP, - const char * const name, - const char * const filesPath, - const char * const logFileName) { -/*---------------------------------------------------------------------------- - Create a server that will not get client connections; the user will have to - get the client connections and use server methods that take an existing - connection as an argument. - - Set *serverP to represent that server. ------------------------------------------------------------------------------*/ - bool const noAcceptTrue = true; - bool const userChanSwitchFalse = false; - - bool success; - const char * error; - - createServer(&serverP->srvP, noAcceptTrue, - NULL, userChanSwitchFalse, - 0, &error); - - if (error) { - TraceMsg(error); - success = false; - xmlrpc_strfree(error); - } else { - success = true; - - setNamePathLog(serverP, name, filesPath, logFileName); - } - return success; -} - - - -void -ServerCreateSwitch(TServer * const serverP, - TChanSwitch * const chanSwitchP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Create a server that will get client connections from channel switch - *chanSwitchP. Those connections would typically be raw TCP connections, - but could be anything that can be abstracted by a Channel object. For - example, an SSL encrypted TCP connection. - - Set *serverP to represent that server. ------------------------------------------------------------------------------*/ - bool const noAcceptFalse = false; - bool const userChanSwitchTrue = true; - - assert(serverP); - assert(chanSwitchP); - - createServer(&serverP->srvP, noAcceptFalse, - chanSwitchP, userChanSwitchTrue, - 0, errorP); -} - - - -void -ServerCreateSocket2(TServer * const serverP, - TSocket * const socketP, - const char ** const errorP) { - - TChanSwitch * const chanSwitchP = SocketGetChanSwitch(socketP); - - assert(socketP); - - if (!chanSwitchP) - xmlrpc_asprintf( - errorP, "Socket is not a listening socket. " - "You should use ServerCreateSwitch() instead, anyway."); - else - ServerCreateSwitch(serverP, chanSwitchP, errorP); -} - - - -static void -terminateHandlers(TList * const handlersP) { -/*---------------------------------------------------------------------------- - Terminate all handlers in the list '*handlersP'. - - I.e. call each handler's terminate function. ------------------------------------------------------------------------------*/ - if (handlersP->item) { - unsigned int i; - for (i = handlersP->size; i > 0; --i) { - struct uriHandler * const handlerP = handlersP->item[i-1]; - if (handlerP->term) - handlerP->term(handlerP->userdata); - } - } -} - - - -void -ServerFree(TServer * const serverP) { - - struct _TServer * const srvP = serverP->srvP; - - if (srvP->weCreatedChanSwitch) - ChanSwitchDestroy(srvP->chanSwitchP); - - xmlrpc_strfree(srvP->name); - - terminateHandlers(&srvP->handlers); - - ListFree(&srvP->handlers); - - HandlerDestroy(srvP->builtinHandlerP); - - logClose(srvP); - - if (srvP->logfilename) - xmlrpc_strfree(srvP->logfilename); - - free(srvP); -} - - - -void -ServerSetName(TServer * const serverP, - const char * const name) { - - xmlrpc_strfree(serverP->srvP->name); - - serverP->srvP->name = strdup(name); -} - - - -void -ServerSetFilesPath(TServer * const serverP, - const char * const filesPath) { - - HandlerSetFilesPath(serverP->srvP->builtinHandlerP, filesPath); -} - - - -void -ServerSetLogFileName(TServer * const serverP, - const char * const logFileName) { - - struct _TServer * const srvP = serverP->srvP; - - if (srvP->logfilename) - xmlrpc_strfree(srvP->logfilename); - - srvP->logfilename = strdup(logFileName); -} - - - -void -ServerSetKeepaliveTimeout(TServer * const serverP, - xmlrpc_uint32_t const keepaliveTimeout) { - - serverP->srvP->keepalivetimeout = MAX(keepaliveTimeout, 1); -} - - - -void -ServerSetKeepaliveMaxConn(TServer * const serverP, - xmlrpc_uint32_t const keepaliveMaxConn) { - - serverP->srvP->keepalivemaxconn = MAX(keepaliveMaxConn, 1); -} - - - -void -ServerSetTimeout(TServer * const serverP, - xmlrpc_uint32_t const timeout) { - - serverP->srvP->timeout = timeout; -} - - - -void -ServerSetAdvertise(TServer * const serverP, - abyss_bool const advertise) { - - serverP->srvP->advertise = advertise; -} - - - -void -ServerSetMimeType(TServer * const serverP, - MIMEType * const mimeTypeP) { - - HandlerSetMimeType(serverP->srvP->builtinHandlerP, mimeTypeP); -} - - - -void -ServerSetMaxConn(TServer * const serverP, - unsigned int const maxConn) { - - if (maxConn > 0) { - serverP->srvP->maxConn = maxConn; - } -} - - - -void -ServerSetMaxConnBacklog(TServer * const serverP, - unsigned int const maxConnBacklog) { - - if (maxConnBacklog > 0) { - serverP->srvP->maxConnBacklog = maxConnBacklog; - } -} - - - -void -ServerSetMaxSessionMem(TServer * const serverP, - size_t const size) { - - if (size > 0) - serverP->srvP->maxSessionMem = size; -} - - - -static URIHandler2 -makeUriHandler2(const struct uriHandler * const handlerP) { - - URIHandler2 retval; - - retval.init = handlerP->init; - retval.term = handlerP->term; - retval.handleReq2 = handlerP->handleReq2; - retval.handleReq1 = handlerP->handleReq1; - retval.userdata = handlerP->userdata; - - return retval; -} - - - -static void -runUserHandler(TSession * const sessionP, - struct _TServer * const srvP) { - - abyss_bool handled; - int i; - - for (i = srvP->handlers.size-1, handled = false; - i >= 0 && !handled; - --i) { - const struct uriHandler * const handlerP = srvP->handlers.item[i]; - - if (handlerP->handleReq3) - handlerP->handleReq3(handlerP->userdata, sessionP, &handled); - if (handlerP->handleReq2) { - URIHandler2 handler2 = makeUriHandler2(handlerP); - handlerP->handleReq2(&handler2, sessionP, &handled); - } else if (handlerP->handleReq1) - handled = handlerP->handleReq1(sessionP); - } - - assert(srvP->defaultHandler); - - if (!handled) - srvP->defaultHandler(sessionP); -} - - - -static void -handleReqTooNewHttpVersion(TSession * const sessionP) { - - const char * msg; - - ResponseStatus(sessionP, 505); - - xmlrpc_asprintf(&msg, "Request is in HTTP Version %u" - "We understand only HTTP 1", - sessionP->version.major); - - ResponseError2(sessionP, msg); - - xmlrpc_strfree(msg); -} - - - -static void -handleReqInvalidURI(TSession * const sessionP) { - - ResponseStatus(sessionP, 400); - - ResponseError2(sessionP, "Invalid URI"); -} - - - -static void -traceRequestStart(struct Tracer * const tracerP, - TSession * const sessionP) { - - if (sessionP->requestInfo.uri) { - trace(tracerP, "Processing request with URI '%s', method %s", - sessionP->requestInfo.uri, - HTTPMethodName(sessionP->requestInfo.method)); - } -} - - - -static void -processRequestFromClient(TConn * const connectionP, - bool const lastReqOnConn, - uint32_t const timeout, - struct Tracer * const tracerP, - bool * const keepAliveP) { -/*---------------------------------------------------------------------------- - Get and execute one HTTP request from client connection *connectionP, - through the connection buffer. I.e. Some of the request may already be in - the connection buffer, and we may leave some of later requests in the - connection buffer. - - In fact, because of timing considerations, we assume the client has begun - sending the request, which as a practical matter means Caller has already - deposited some of it in the connection buffer. - - If there isn't one full request in the buffer now, we wait for one full - request to come through the buffer, up to 'timeout'. - - We return as *keepAliveP whether Caller should keep the connection - alive for a while for possible future requests from the client, based - on 'lastReqOnConn' and the content of the HTTP request. - - Executing the request consists primarily of calling the URI handlers that - are associated with the connection (*connectionP), passing each the request - information we read. Each handler can respond according to the HTTP method - (GET, POST, etc) and URL etc, and that response may be either to - execute the request and send the response or refuse the request and let - us call the next one in the list. ------------------------------------------------------------------------------*/ - TSession session; - const char * error; - uint16_t httpErrorCode; - - SessionInit(&session, connectionP); - - session.serverDeniesKeepalive = lastReqOnConn; - - SessionReadRequest(&session, timeout, &error, &httpErrorCode); - - if (error) { - ResponseStatus(&session, httpErrorCode); - ResponseError2(&session, error); - xmlrpc_strfree(error); - } else { - traceRequestStart(tracerP, &session); - if (session.version.major >= 2) - handleReqTooNewHttpVersion(&session); - else if (!HTTPRequestHasValidUri(&session)) - handleReqInvalidURI(&session); - else - runUserHandler(&session, connectionP->server->srvP); - } - - assert(session.status != 0); - - if (session.responseStarted) - ResponseWriteEnd(&session); - else - ResponseError(&session); - - *keepAliveP = HTTPKeepalive(&session); - - SessionLog(&session); - - SessionTerm(&session); -} - - - -static TThreadProc serverFunc; - -static void -serverFunc(void * const userHandle) { -/*---------------------------------------------------------------------------- - Do server stuff on one connection. At its simplest, this means do - one HTTP request. But with keepalive, it can be many requests. ------------------------------------------------------------------------------*/ - TConn * const connectionP = userHandle; - struct _TServer * const srvP = connectionP->server->srvP; - - unsigned int requestCount; - /* Number of requests we've handled so far on this connection */ - bool connectionDone; - /* No more need for this HTTP connection */ - - trace(&srvP->tracer, - "Thread starting to handle requests on a new connection. " - "PID = %d", XMLRPC_GETPID()); - - requestCount = 0; - connectionDone = false; - - while (!connectionDone) { - bool timedOut, eof; - const char * readError; - - /* Wait for and get beginning (at least ) of next request. We do - this separately from getting the rest of the request because we - treat dead time between requests differently from dead time in - the middle of a request. - */ - ConnRead(connectionP, srvP->keepalivetimeout, - &timedOut, &eof, &readError); - - if (srvP->terminationRequested) { - connectionDone = true; - } else if (readError) { - TraceMsg("Failed to read from Abyss connection. %s", readError); - xmlrpc_strfree(readError); - connectionDone = true; - } else if (timedOut) { - connectionDone = true; - } else if (eof) { - connectionDone = true; - } else { - bool const lastReqOnConn = - requestCount + 1 >= srvP->keepalivemaxconn; - - bool keepalive; - - trace(&srvP->tracer, - "HTTP request %u at least partially received. " - "Receiving the rest and processing", requestCount); - - processRequestFromClient(connectionP, lastReqOnConn, srvP->timeout, - &srvP->tracer, &keepalive); - - trace(&srvP->tracer, - "Done processing the HTTP request. Keepalive = %s", - keepalive ? "YES" : "NO"); - - ++requestCount; - - if (!keepalive) - connectionDone = true; - - /**************** Must adjust the read buffer *****************/ - ConnReadInit(connectionP); - } - } - trace(&srvP->tracer, "PID %d done with connection", XMLRPC_GETPID()); -} - - - -/* This is the maximum amount of stack space, in bytes, serverFunc() - itself requires -- not counting what the user's request handler - (which serverFunc() calls) requires. -*/ -#define SERVER_FUNC_STACK 1024 - - - -static void -createSwitchFromPortNum(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - -#if MSVCRT - ChanSwitchWinCreate(portNumber, chanSwitchPP, errorP); -#else - ChanSwitchUnixCreate(portNumber, chanSwitchPP, errorP); -#endif -} - - - -static void -createChanSwitch(struct _TServer * const srvP, - const char ** const errorP) { - - TChanSwitch * chanSwitchP; - const char * error; - - /* Not valid to call this when channel switch already exists: */ - assert(srvP->chanSwitchP == NULL); - - createSwitchFromPortNum(srvP->port, &chanSwitchP, &error); - - if (error) { - xmlrpc_asprintf(errorP, - "Can't create channel switch. %s", error); - xmlrpc_strfree(error); - } else { - *errorP = NULL; - - srvP->weCreatedChanSwitch = true; - srvP->chanSwitchP = chanSwitchP; - } -} - - - -void -ServerInit2(TServer * const serverP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Initialize a server to accept connections. - - Do not confuse this with creating the server -- ServerCreate(). - - Not necessary or valid with a server that doesn't accept connections (i.e. - user supplies the channels (TCP connections)). ------------------------------------------------------------------------------*/ - struct _TServer * const srvP = serverP->srvP; - - if (!srvP->serverAcceptsConnections) - xmlrpc_asprintf(errorP, - "ServerInit() is not valid on a server that doesn't " - "accept connections " - "(i.e. created with ServerCreateNoAccept)"); - else { - *errorP = NULL; /* initial value */ - - if (!srvP->chanSwitchP) { - const char * error; - createChanSwitch(srvP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Unable to create a channel switch " - "for the server. %s", error); - xmlrpc_strfree(error); - } - } - - if (!*errorP) { - const char * error; - - assert(srvP->chanSwitchP); - - ChanSwitchListen(srvP->chanSwitchP, srvP->maxConnBacklog, &error); - - if (error) { - xmlrpc_asprintf(errorP, - "Failed to listen on bound socket. %s", - error); - xmlrpc_strfree(error); - } else { - srvP->readyToAccept = true; - } - } - } -} - - - -void -ServerInit(TServer * const serverP) { - - const char * error; - - ServerInit2(serverP, &error); - - if (error) { - TraceExit("ServerInit() failed. %s", error); - xmlrpc_strfree(error); - } -} - - - -/* We don't do any locking on the outstanding connections list, so - we must make sure that only the master thread (the one that listens - for connections) ever accesses it. - - That's why when a thread completes, it places the connection in - "finished" status, but doesn't destroy the connection. -*/ - -typedef struct { - - TConn * firstP; - unsigned int count; - /* Redundant with 'firstP', for quick access */ -} outstandingConnList; - - - -static void -createOutstandingConnList(outstandingConnList ** const listPP) { - - outstandingConnList * listP; - - MALLOCVAR_NOFAIL(listP); - - listP->firstP = NULL; /* empty list */ - listP->count = 0; - - *listPP = listP; -} - - - -static void -destroyOutstandingConnList(outstandingConnList * const listP) { - - assert(listP->firstP == NULL); - assert(listP->count == 0); - - free(listP); -} - - - -static void -addToOutstandingConnList(outstandingConnList * const listP, - TConn * const connectionP) { - - connectionP->nextOutstandingP = listP->firstP; - - listP->firstP = connectionP; - - ++listP->count; -} - - - -static void -freeFinishedConns(outstandingConnList * const listP) { -/*---------------------------------------------------------------------------- - Garbage-collect the resources associated with connections that are - finished with their jobs. Thread resources, connection pool - descriptor, etc. ------------------------------------------------------------------------------*/ - TConn ** pp; - - pp = &listP->firstP; - - while (*pp) { - TConn * const connectionP = (*pp); - - ThreadUpdateStatus(connectionP->threadP); - - if (connectionP->finished) { - /* Take it out of the list */ - *pp = connectionP->nextOutstandingP; - --listP->count; - - ConnWaitAndRelease(connectionP); - } else { - /* Move to next connection in list */ - pp = &connectionP->nextOutstandingP; - } - } -} - - - -static void -waitForConnectionFreed(outstandingConnList * const outstandingConnListP - ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - Wait for a connection descriptor in 'connectionPool' to be probably - freed. ------------------------------------------------------------------------------*/ - - /* TODO: We should do something more sophisticated here. For pthreads, - we can have a thread signal us by semaphore when it terminates. - For fork, we might be able to use the "done" handler argument - to ConnCreate() to get interrupted when the death of a child - signal happens. - */ - - xmlrpc_millisecond_sleep(2000); -} - - - -static void -waitForNoConnections(outstandingConnList * const outstandingConnListP) { - - while (outstandingConnListP->firstP) { - freeFinishedConns(outstandingConnListP); - - if (outstandingConnListP->firstP) - waitForConnectionFreed(outstandingConnListP); - } -} - - - -static void -waitForConnectionCapacity(outstandingConnList * const outstandingConnListP, - unsigned int const maxConn) { -/*---------------------------------------------------------------------------- - Wait until there are fewer than 'maxConn' connections in progress. ------------------------------------------------------------------------------*/ - while (outstandingConnListP->count >= maxConn) { - freeFinishedConns(outstandingConnListP); - if (outstandingConnListP->firstP) - waitForConnectionFreed(outstandingConnListP); - } -} - - - -static void -interruptChannels(outstandingConnList * const outstandingConnListP) { -/*---------------------------------------------------------------------------- - Get every thread that is waiting to read a request or write a response - for a connection to stop waiting. ------------------------------------------------------------------------------*/ - TConn * connP; - - for (connP = outstandingConnListP->firstP; - connP; connP = connP->nextOutstandingP) { - - if (connP->finished) { - /* The connection couldn't be waiting on the channel, and the - channel probably doesn't even exit anymore. - */ - } else - ChannelInterrupt(connP->channelP); - } -} - - - -#if !MSVCRT -void -ServerHandleSigchld(pid_t const pid) { - - ThreadHandleSigchld(pid); -} -#endif - - - -void -ServerUseSigchld(TServer * const serverP) { - - struct _TServer * const srvP = serverP->srvP; - - srvP->useSigchld = true; -} - - - -static TThreadDoneFn destroyChannel; - -static void -destroyChannel(void * const userHandle) { -/*---------------------------------------------------------------------------- - This is a "connection done" function for the connection the server - serves. It gets called some time after the connection has done its - thing. Its job is to clean up stuff the server created for use by - the connection, but the server can't clean up because the - connection might be processed asynchronously in a background - thread. - - To wit, we destroy the connection's channel and release the memory - for the information about that channel. ------------------------------------------------------------------------------*/ - TConn * const connectionP = userHandle; - - ChannelDestroy(connectionP->channelP); - free(connectionP->channelInfoP); -} - - - -static void -processNewChannel(TServer * const serverP, - TChannel * const channelP, - void * const channelInfoP, - outstandingConnList * const outstandingConnListP, - const char ** const errorP) { - - struct _TServer * const srvP = serverP->srvP; - - TConn * connectionP; - const char * error; - - freeFinishedConns(outstandingConnListP); - - trace(&srvP->tracer, "Waiting for there to be fewer than the maximum " - "%u sessions in progress", - srvP->maxConn); - - waitForConnectionCapacity(outstandingConnListP, srvP->maxConn); - - ConnCreate(&connectionP, serverP, channelP, channelInfoP, - &serverFunc, - SERVER_FUNC_STACK + srvP->uriHandlerStackSize, - &destroyChannel, ABYSS_BACKGROUND, - srvP->useSigchld, - &error); - if (!error) { - addToOutstandingConnList(outstandingConnListP, connectionP); - ConnProcess(connectionP); - /* When connection is done (which could be later, courtesy of a - background thread), destroyChannel() will destroy *channelP. - */ - *errorP = NULL; - } else { - xmlrpc_asprintf( - errorP, "Failed to create an Abyss connection. %s", error); - xmlrpc_strfree(error); - } -} - - - -static void -acceptAndProcessNextConnection( - TServer * const serverP, - outstandingConnList * const outstandingConnListP, - const char ** const errorP) { - - struct _TServer * const srvP = serverP->srvP; - - const char * error; - TChannel * channelP; - void * channelInfoP; - - trace(&srvP->tracer, "Waiting for a new channel from channel switch"); - - assert(srvP->readyToAccept); - assert(srvP->chanSwitchP); - - ChanSwitchAccept(srvP->chanSwitchP, &channelP, &channelInfoP, &error); - - if (error) { - xmlrpc_asprintf(errorP, - "Failed to accept the next connection from a client " - "at the channel level. %s", error); - xmlrpc_strfree(error); - } else { - if (channelP) { - const char * error; - - trace(&srvP->tracer, "Got a new channel from channel switch"); - - processNewChannel(serverP, channelP, channelInfoP, - outstandingConnListP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Failed to use new channel %lx", - (unsigned long) channelP); - ChannelDestroy(channelP); - free(channelInfoP); - } else { - trace(&srvP->tracer, - "successfully processed newly accepted channel"); - /* Connection created above will destroy *channelP - and *channelInfoP as it terminates. - */ - } - } else { - /* Accept function was interrupted before it got a connection */ - trace(&srvP->tracer, - "Wait for new channel from switch was interrupted"); - *errorP = NULL; - } - } -} - - - -static void -serverRun2(TServer * const serverP, - const char ** const errorP) { - - struct _TServer * const srvP = serverP->srvP; - outstandingConnList * outstandingConnListP; - - createOutstandingConnList(&outstandingConnListP); - - *errorP = NULL; /* initial value */ - - trace(&srvP->tracer, "Starting main connection accepting loop"); - - while (!srvP->terminationRequested && !*errorP) - acceptAndProcessNextConnection(serverP, outstandingConnListP, errorP); - - trace(&srvP->tracer, "Main connection accepting loop is done"); - - if (!*errorP) { - trace(&srvP->tracer, - "Interrupting and waiting for %u existing connections " - "to finish", - outstandingConnListP->count); - - interruptChannels(outstandingConnListP); - - waitForNoConnections(outstandingConnListP); - - trace(&srvP->tracer, "No connections left"); - - destroyOutstandingConnList(outstandingConnListP); - } -} - - - -void -ServerRun(TServer * const serverP) { - - struct _TServer * const srvP = serverP->srvP; - - trace(&srvP->tracer, "%s entered", __FUNCTION__); - - if (!srvP->serverAcceptsConnections) - TraceMsg("This server is not set up to accept connections " - "on its own, so you can't use ServerRun(). " - "Try ServerRunConn()"); - else if (!srvP->readyToAccept) - TraceMsg("You cannot run this server until you initialize it to " - "accept connections, with ServerInit()"); - else { - const char * error; - - serverRun2(serverP, &error); - - if (error) { - TraceMsg("Server failed. %s", error); - - xmlrpc_strfree(error); - } - } - trace(&srvP->tracer, "%s exiting", __FUNCTION__); -} - - - -static void -serverRunChannel(TServer * const serverP, - TChannel * const channelP, - void * const channelInfoP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Do the HTTP transaction on the channel 'channelP'. - (channel must be at the beginning of the HTTP request -- nothing having - been read or written yet). - - channelInfoP == NULL means no channel info supplied. ------------------------------------------------------------------------------*/ - struct _TServer * const srvP = serverP->srvP; - - TConn * connectionP; - const char * error; - - trace(&srvP->tracer, "%s entered", __FUNCTION__); - - srvP->keepalivemaxconn = 1; - - ConnCreate(&connectionP, - serverP, channelP, channelInfoP, - &serverFunc, SERVER_FUNC_STACK + srvP->uriHandlerStackSize, - NULL, ABYSS_FOREGROUND, srvP->useSigchld, - &error); - if (error) { - xmlrpc_asprintf(errorP, "Couldn't create HTTP connection out of " - "channel (connected socket). %s", error); - xmlrpc_strfree(error); - } else { - *errorP = NULL; - - ConnProcess(connectionP); - - ConnWaitAndRelease(connectionP); - } - trace(&srvP->tracer, "%s exiting", __FUNCTION__); -} - - - -void -ServerRunChannel(TServer * const serverP, - TChannel * const channelP, - void * const channelInfoP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Do the HTTP transaction on the channel 'channelP'. - - (channel must be at the beginning of the HTTP request -- nothing having - been read or written yet). ------------------------------------------------------------------------------*/ - struct _TServer * const srvP = serverP->srvP; - - trace(&srvP->tracer, "%s entered", __FUNCTION__); - - if (srvP->serverAcceptsConnections) - xmlrpc_asprintf(errorP, - "This server is configured to accept connections on " - "its own socket. " - "Try ServerRun() or ServerCreateNoAccept()."); - else - serverRunChannel(serverP, channelP, channelInfoP, errorP); - - trace(&srvP->tracer, "%s exiting", __FUNCTION__); -} - - - -void -ServerRunConn2(TServer * const serverP, - TSocket * const connectedSocketP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Do the HTTP transaction on the TCP connection on the socket - *connectedSocketP. - (socket must be connected state, with nothing having been read or - written on the connection yet). ------------------------------------------------------------------------------*/ - TChannel * const channelP = SocketGetChannel(connectedSocketP); - - if (!channelP) - xmlrpc_asprintf(errorP, "The socket supplied is not a connected " - "socket. You should use ServerRunChannel() instead, " - "anyway."); - else - ServerRunChannel(serverP, - channelP, SocketGetChannelInfo(connectedSocketP), - errorP); -} - - - -void -ServerRunConn(TServer * const serverP, - TOsSocket const connectedOsSocket) { - - TChannel * channelP; - void * channelInfoP; - const char * error; - - createChannelFromOsSocket(connectedOsSocket, - &channelP, &channelInfoP, &error); - if (error) { - TraceExit("Unable to use supplied socket"); - xmlrpc_strfree(error); - } else { - const char * error; - - ServerRunChannel(serverP, channelP, channelInfoP, &error); - - if (error) { - TraceExit("Failed to run server on connection on file " - "descriptor %d. %s", connectedOsSocket, error); - xmlrpc_strfree(error); - } - ChannelDestroy(channelP); - free(channelInfoP); - } -} - - - -void -ServerRunOnce(TServer * const serverP) { -/*---------------------------------------------------------------------------- - Accept a connection from the channel switch and do the HTTP transaction - that comes over it. - - If no connection is presently waiting at the switch, wait for one. But - return immediately if we receive a signal during the wait. ------------------------------------------------------------------------------*/ - struct _TServer * const srvP = serverP->srvP; - - trace(&srvP->tracer, "%s entered", __FUNCTION__); - - if (!srvP->serverAcceptsConnections) - TraceMsg("This server is not set up to accept connections " - "on its own, so you can't use ServerRun(). " - "Try ServerRunConn()"); - else if (!srvP->readyToAccept) - TraceMsg("You cannot run this server until you initialize it to " - "accept connections, with ServerInit()"); - else { - const char * error; - TChannel * channelP; - void * channelInfoP; - - srvP->keepalivemaxconn = 1; - - assert(srvP->chanSwitchP); - - ChanSwitchAccept(srvP->chanSwitchP, &channelP, &channelInfoP, &error); - if (error) { - TraceMsg("Failed to accept the next connection from a client " - "at the channel level. %s", error); - xmlrpc_strfree(error); - } else { - if (channelP) { - const char * error; - - serverRunChannel(serverP, channelP, channelInfoP, &error); - - if (error) { - const char * peerDesc; - ChannelFormatPeerInfo(channelP, &peerDesc); - TraceExit("Got a connection from '%s', but failed to " - "run server on it. %s", peerDesc, error); - xmlrpc_strfree(peerDesc); - xmlrpc_strfree(error); - } - ChannelDestroy(channelP); - free(channelInfoP); - } - } - } - trace(&srvP->tracer, "%s exiting", __FUNCTION__); -} - - - -void -ServerRunOnce2(TServer * const serverP, - enum abyss_foreback const foregroundBackground ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - This is a backward compatibility interface to ServerRunOnce(). - - 'foregroundBackground' is meaningless. We always process the - connection in the foreground. The parameter exists because we once - thought we could do them in the background, but we really can't do - that in any clean way. If Caller wants background execution, he can - spin his own thread or process to call us. It makes much more sense - in Caller's context. ------------------------------------------------------------------------------*/ - ServerRunOnce(serverP); -} - - - -static void -setGroups(const char ** const errorP) { - -#if HAVE_SETGROUPS - if (setgroups(0, NULL) == -1) - xmlrpc_asprintf(errorP, "setgroups() errno = %d (%s)", - errno, strerror(errno)); -#else - *errorP = NULL; -#endif -} - - - -void -ServerDaemonize(TServer * const serverP) { -/*---------------------------------------------------------------------------- - Turn Caller into a daemon (i.e. fork a child, then exit; the child - returns to Caller). - - NOTE: It's ridiculous, but conventional, for us to do this. It's - ridiculous because the task of daemonizing is not something - particular to Abyss. It ought to be done by a higher level. In - fact, it should be done before the Abyss server program is even - execed. The user should run a "daemonize" program that creates a - daemon which execs the Abyss server program. ------------------------------------------------------------------------------*/ - struct _TServer * const srvP = serverP->srvP; - -#if !MSVCRT - /* Become a daemon */ - switch (fork()) { - case 0: - break; - case -1: - TraceExit("Unable to become a daemon"); - default: - /* We are the parent */ - exit(0); - } - - setsid(); - - /* Change the current user if we are root */ - if (getuid()==0) { - const char * error; - if (srvP->uid == (uid_t)-1) - TraceExit("Can't run under root privileges. " - "Please add a User option in your " - "Abyss configuration file."); - - setGroups(&error); - - if (error) { - TraceExit("Failed to set groups. %s", error); - xmlrpc_strfree(error); - } - - if (srvP->gid != (gid_t)-1) - if (setgid(srvP->gid)==(-1)) - TraceExit("Failed to change the group."); - - if (setuid(srvP->uid) == -1) - TraceExit("Failed to change the user."); - } - - if (srvP->pidfileP) { - char z[16]; - - sprintf(z, "%d", XMLRPC_GETPID()); - FileWrite(srvP->pidfileP, z, strlen(z)); - FileClose(srvP->pidfileP); - } -#endif /* MSVCRT */ -} - - - -static void -serverAddHandler(TServer * const serverP, - initHandlerFn init, - termHandlerFn term, - URIHandler handleReq1, - handleReq2Fn handleReq2, - handleReq3Fn handleReq3, - void * const userdata, - size_t const handleReqStackSizeReq, - abyss_bool * const successP) { - - struct _TServer * const srvP = serverP->srvP; - size_t handleReqStackSize = - handleReqStackSizeReq ? handleReqStackSizeReq : 128*1024; - - struct uriHandler * handlerP; - - MALLOCVAR(handlerP); - if (handlerP == NULL) - *successP = false; - else { - handlerP->init = init; - handlerP->term = term; - handlerP->handleReq1 = handleReq1; - handlerP->handleReq2 = handleReq2; - handlerP->handleReq3 = handleReq3; - handlerP->userdata = userdata; - - srvP->uriHandlerStackSize = - MAX(srvP->uriHandlerStackSize, handleReqStackSize); - - if (handlerP->init == NULL) - *successP = true; - else { - URIHandler2 handler2 = makeUriHandler2(handlerP); - handlerP->init(&handler2, successP); - } - if (*successP) - *successP = ListAdd(&serverP->srvP->handlers, handlerP); - - if (!*successP) - free(handlerP); - } -} - - - -void -ServerAddHandler3(TServer * const serverP, - const struct ServerReqHandler3 * const handlerP, - abyss_bool * const successP) { - - serverAddHandler(serverP, NULL, handlerP->term, NULL, NULL, - handlerP->handleReq, handlerP->userdata, - handlerP->handleReqStackSize, successP); -} - - - -void -ServerAddHandler2(TServer * const serverP, - URIHandler2 * const handlerArgP, - abyss_bool * const successP) { - - /* This generation of the URI handler interface is strange because - it went through an unfortunate evolution. So it halfway looks like - the use supplies a handler object and Abyss calls its methods, and - halfway looks like the user simply describes his handler. - - Abyss calls handleReq2 with a pointer to a URIHandler2 like the - one which is our argument, but it isn't the same one. User can - discard *handlerArgP as soon as we return. - */ - - serverAddHandler(serverP, - handlerArgP->init, - handlerArgP->term, - NULL, - handlerArgP->handleReq2, - NULL, - handlerArgP->userdata, - 0, - successP); -} - - - -abyss_bool -ServerAddHandler(TServer * const serverP, - URIHandler const function) { - - URIHandler2 handler; - abyss_bool success; - - handler.init = NULL; - handler.term = NULL; - handler.userdata = NULL; - handler.handleReq2 = NULL; - handler.handleReq1 = function; - - ServerAddHandler2(serverP, &handler, &success); - - return success; -} - - - -/* This is the maximum amount of stack we allow a user's default URI - handler to use. (If he exceeds this, results are undefined). - - We really ought to provide user a way to set this, as he can for - his non-default URI handlers. -*/ -#define USER_DEFAULT_HANDLER_STACK 128*1024 - -void -ServerDefaultHandler(TServer * const serverP, - URIHandler const handler) { - - struct _TServer * const srvP = serverP->srvP; - - if (handler) { - srvP->defaultHandler = handler; - srvP->uriHandlerStackSize = - MAX(srvP->uriHandlerStackSize, USER_DEFAULT_HANDLER_STACK); - } else { - srvP->defaultHandler = HandlerDefaultBuiltin; - srvP->defaultHandlerContext = srvP->builtinHandlerP; - srvP->uriHandlerStackSize = - MAX(srvP->uriHandlerStackSize, HandlerDefaultBuiltinStack); - } -} - - - -void -LogWrite(TServer * const serverP, - const char * const msg) { - - struct _TServer * const srvP = serverP->srvP; - - if (!srvP->logfileisopen && srvP->logfilename) { - const char * error; - logOpen(srvP, &error); - - if (error) { - TraceMsg("Failed to open log file. %s", error); - - xmlrpc_strfree(error); - } - } - if (srvP->logfileisopen) { - const char * const lbr = "\n"; - srvP->logLockP->acquire(srvP->logLockP); - FileWrite(srvP->logfileP, msg, strlen(msg)); - FileWrite(srvP->logfileP, lbr, strlen(lbr)); - - srvP->logLockP->release(srvP->logLockP); - } -} -/******************************************************************************* -** -** server.c -** -** This file is part of the ABYSS Web server project. -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ diff --git a/trunk/lib/abyss/src/server.h b/trunk/lib/abyss/src/server.h deleted file mode 100644 index 0462e74c9..000000000 --- a/trunk/lib/abyss/src/server.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef SERVER_H_INCLUDED -#define SERVER_H_INCLUDED - -#include - -#include "xmlrpc_config.h" -#include "bool.h" -#include "xmlrpc-c/lock.h" -#include "xmlrpc-c/abyss.h" - -#include "data.h" - -struct TFile; - -struct Tracer { - bool traceIsActive; - /* We should report to Standard Error our internal activities */ -}; - -struct _TServer { - struct Tracer tracer; - - bool terminationRequested; - /* User wants this server to terminate as soon as possible, - in particular before accepting any more connections and without - waiting for any. - */ - bool chanSwitchBound; - /* The channel switch exists and is bound to a local address - (may already be listening as well) - */ - TChanSwitch * chanSwitchP; - /* Meaningful only when 'chanSwitchBound' is true: the channel - switch which directs connections from clients to this server. - */ - bool weCreatedChanSwitch; - /* We created the channel switch 'chanSwitchP', as - opposed to 1) User supplied it; or 2) there isn't one. - */ - const char * logfilename; - bool logfileisopen; - struct TFile * logfileP; - struct lock * logLockP; - const char * name; - bool serverAcceptsConnections; - /* We listen for and accept TCP connections for HTTP transactions. - (The alternative is the user supplies a TCP-connected socket - for each transaction) - */ - bool readyToAccept; - /* We are the kind of server that listens for TCP connections and the - user has initialized us to do so (called ServerInit()). - */ - uint16_t port; - /* Meaningful only when 'chanSwitchBound' is false: TCP port - number to which we should bind the switch. - */ - uint32_t keepalivetimeout; - uint32_t keepalivemaxconn; - uint32_t timeout; - /* Maximum time in seconds the server will wait to read a header - or a data chunk from the channel. - */ - uint32_t maxConn; - /* Maximum number of connections the server allows to exist (i.e. - HTTP transactions in progress) at once. Server will not accept - a connection if it already has this many. - */ - uint32_t maxConnBacklog; - /* Maximum number of connections the server allows the OS to queue - waiting for the server to accept it. The OS accepts this many TCP - connections on the server's behalf and holds them waiting for the - server to accept them from the OS. - */ - size_t maxSessionMem; - /* The maximum memory the server can use for certain purposes for a - single session. These purposes consist of things where the size - of the memory is unpredictable, especially under the control of the - client. This limit stops clients from using too much memory and - consequently denying service to other clients. - - Zero means no limit. - */ - TList handlers; - /* Ordered list of HTTP request handlers. For each HTTP request, - Server calls each one in order until one reports that it handled - it. - - Each item in the list of of type 'uriHandler'. - */ - URIHandler defaultHandler; - /* The handler for HTTP requests that aren't claimed by any handler - in the list 'handlers'. This can't be null; if user doesn't - supply anything better, it is a built-in basic web server - handler. */ - void * defaultHandlerContext; - /* This is opaque data to be given to the default handler when it - requests it. - */ - void * builtinHandlerP; - bool advertise; - bool useSigchld; - /* Meaningless if not using forking for threads. - TRUE means user will call ServerHandleSigchld to indicate that - a SIGCHLD signal was received, and server shall use that as its - indication that a child has died. FALSE means server will not - be aware of SIGCHLD and will instead poll for existence of PIDs - to determine if a child has died. - */ - size_t uriHandlerStackSize; - /* The maximum amount of stack any URI handler request handler - function will use. Note that this is just the requirement - of the function itself, not the stack size for the thread - that runs it. - */ -#if !MSVCRT - uid_t uid; - gid_t gid; -#endif - struct TFile * pidfileP; -}; - -#endif diff --git a/trunk/lib/abyss/src/session.c b/trunk/lib/abyss/src/session.c deleted file mode 100644 index 2fac2d970..000000000 --- a/trunk/lib/abyss/src/session.c +++ /dev/null @@ -1,726 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "bool.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/abyss.h" -#include "server.h" -#include "http.h" -#include "conn.h" - -#include "session.h" - - - -static void -refillBuffer(TSession * const sessionP, - const char ** const errorP) { - - struct _TServer * const srvP = sessionP->connP->server->srvP; - - /* Reset our read buffer and flush data from previous reads. */ - ConnReadInit(sessionP->connP); - - *errorP = NULL; /* initial assumption */ - - if (sessionP->continueRequired) { - bool succeeded; - succeeded = HTTPWriteContinue(sessionP); - if (!succeeded) - xmlrpc_asprintf(errorP, "Failed to send a Continue header " - "to the client to tell it to go ahead with " - "sending the body"); - } - if (!*errorP) { - const char * error; - - sessionP->continueRequired = false; - - /* Read more network data into our buffer. Fail if we time out - before client sends any data or client closes the connection or - there's some network error. We're very forgiving about the - timeout here. We allow a full timeout per network read, which - would allow somebody to keep a connection alive nearly - indefinitely. But it's hard to do anything intelligent here - without very complicated code. - */ - ConnRead(sessionP->connP, srvP->timeout, NULL, NULL, &error); - if (error) { - xmlrpc_asprintf(errorP, "Failed to get more data from " - "the client. %s", error); - xmlrpc_strfree(error); - } - } -} - - - -abyss_bool -SessionRefillBuffer(TSession * const sessionP) { -/*---------------------------------------------------------------------------- - Get the next piece of HTTP request body from the connection into the - buffer. Add at least a byte to the buffer; wait for the data (subject to - the server's timeout parameters) as necessary. - - I.e. read data from the socket. - - "piece" is not any formal part of the body - its just some arbitrary - amount of data - at least one byte - that we choose to read. - - We fail if the session is in a failed state. Because the methods that - extract data from the buffer were designed without the ability to fail, - this is often the only way we have to communicate to the Abyss user that - things have gone pear-shape. And even with this, we are unable to tell - the user why - we just have a binary "failed" return value. ------------------------------------------------------------------------------*/ - bool succeeded; - - if (sessionP->failureReason) - succeeded = false; - else { - const char * error; - - refillBuffer(sessionP, &error); - - if (error) { - sessionP->failureReason = error; - succeeded = false; - } else - succeeded = true; - } - return succeeded; -} - - - -size_t -SessionReadDataAvail(TSession * const sessionP) { - - return sessionP->connP->buffersize - sessionP->connP->bufferpos; - -} - - - -static const char * -firstLfPos(TConn * const connectionP) { -/*---------------------------------------------------------------------------- - Return a pointer in the connection's receive buffer to the first - LF (linefeed aka newline) character in the buffer. - - If there is no LF in the buffer, return NULL. ------------------------------------------------------------------------------*/ - const char * const bufferStart = - connectionP->buffer.t + connectionP->bufferpos; - const char * const bufferEnd = - connectionP->buffer.t + connectionP->buffersize; - - const char * p; - - for (p = bufferStart; p < bufferEnd && *p != '\n'; ++p); - - if (p < bufferEnd) - return p; - else - return NULL; -} - - - -static void -getLine(TConn * const connectionP, - const char ** const lineP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Extract one line from the connection buffer. - - If there is a full line in the buffer now, including line end delimiter, at - the current position, return it as *lineP in newly malloced storage and - advance the current buffer position past the line. - - Do not include the line end delimiter in the returned line. - - If there is no full line, return NULL as *lineP. - - But if there is no full line and the connection buffer is full (so that - there won't ever be a full line), fail. ------------------------------------------------------------------------------*/ - const char * lfPos; - - lfPos = firstLfPos(connectionP); - - if (lfPos) { - unsigned int const lfIdx = lfPos - connectionP->buffer.t; - - char * line; - assert(lfIdx > connectionP->bufferpos); - line = malloc(lfIdx - connectionP->bufferpos + 1); - if (!line) - xmlrpc_asprintf(errorP, "Memory allocation failed for small " - "buffer to read a line from the client"); - else { - unsigned int i, j; - for (i = connectionP->bufferpos, j = 0; i < lfIdx; ++i, ++j) - line[j] = connectionP->buffer.t[i]; - line[j] = '\0'; - - /* Chop off the CR */ - if (j > 1 && line[j-1] == '\r') - line[j-1] = '\0'; - - connectionP->bufferpos = lfIdx + 1; - - *errorP = NULL; - *lineP = line; - } - } else { - unsigned int const usedByteCt = - connectionP->buffersize - connectionP->bufferpos; - - if (usedByteCt + 1 >= BUFFER_SIZE) { - /* + 1 for a NUL. - - We don't have a full line yet, and a buffer refill won't - help because the buffer is full. - */ - xmlrpc_asprintf(errorP, "Line received from client does not " - "fit in the server's connection buffer."); - } else { - *errorP = NULL; - *lineP = NULL; - } - } -} - - - -static void -parseHexDigit(char const digit, - unsigned int * const valueP, - const char ** const errorP) { - - *errorP = NULL; /* initial assumption */ - - switch (toupper(digit)) { - case '0': *valueP = 0x0; break; - case '1': *valueP = 0x1; break; - case '2': *valueP = 0x2; break; - case '3': *valueP = 0x3; break; - case '4': *valueP = 0x4; break; - case '5': *valueP = 0x5; break; - case '6': *valueP = 0x6; break; - case '7': *valueP = 0x7; break; - case '8': *valueP = 0x8; break; - case '9': *valueP = 0x9; break; - case 'A': *valueP = 0xA; break; - case 'B': *valueP = 0xB; break; - case 'C': *valueP = 0xC; break; - case 'D': *valueP = 0xD; break; - case 'E': *valueP = 0xE; break; - case 'F': *valueP = 0xF; break; - default: - xmlrpc_asprintf(errorP, "Invalid hex digit: 0x%02x", (unsigned)digit); - } -} - - - -static void -parseChunkHeader(const char * const line, - uint32_t * const chunkSizeP, - const char ** const errorP) { - - /* The chunk header is normally just a hexadecimal coding of the chunk - size, but that can theoretically be followed by a semicolon, and then a - "chunk extension." The standard says a server must ignore a chunk - extension it does not understand, which for us is all chunk extensions. - */ - - char * const semPos = strchr(line, ';'); - - const char * const end = semPos ? semPos : line + strlen(line); - /* Points just past the end of the chunk size */ - - unsigned int accum; - const char * p; - - for (accum = 0, p = &line[0], *errorP = NULL; - p < end && !*errorP; ++p) { - - unsigned int digitValue; - - parseHexDigit(*p, &digitValue, errorP); - - if (!*errorP) { - accum <<= 4; - accum += digitValue; - } - } - *chunkSizeP = accum; -} - - - -static void -getChunkHeader(TSession * const sessionP, - bool * const gotHeaderP, - uint32_t * const chunkSizeP, - const char ** const errorP) { -/*----------------------------------------------------------------------------- - Assuming the stream from the client is positioned to the beginning of a - chunk header (the line that contains the chunk size and chunk - extension), read off the line and return as *chunkSizeP the chunk size - it indicates. - - Iff a whole line is not in the buffer, leave the stream alone and return - *gotHeaderP == false. ------------------------------------------------------------------------------*/ - const char * line; - const char * error; - - getLine(sessionP->connP, &line, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Failed trying to process a chunk header. %s", - error); - xmlrpc_strfree(error); - } else { - if (line) { - parseChunkHeader(line, chunkSizeP, errorP); - - if (!*errorP) { - *gotHeaderP = true; - } - xmlrpc_strfree(line); - } else { - *errorP = NULL; - *gotHeaderP = false; - } - } -} - - - -static void -processChunkDelimIfThere(TSession * const sessionP, - const char ** const errorP) { -/*----------------------------------------------------------------------------- - Read off a chunk delimiter (CRLF) from the connection buffer, if there - is one there. - - Fail if there is something inconsistent with CRLF there. - - Do nothing if there is nothing or just part of CRLF there; Caller can - try again later when there is more data. ------------------------------------------------------------------------------*/ - uint32_t const byteCt = - sessionP->connP->buffersize - sessionP->connP->bufferpos; - - if (byteCt < 1) { - *errorP = NULL; - } else { - const char * const next = - &sessionP->connP->buffer.t[sessionP->connP->bufferpos]; - - if (next[0] != '\r') - xmlrpc_asprintf(errorP, "Garbage where chunk delimiter should be"); - if (byteCt < 2) - *errorP = NULL; - else { - if (next[1] != '\n') - xmlrpc_asprintf(errorP, - "Garbage where chunk delimiter should be"); - else { - *errorP = NULL; - sessionP->chunkState.position = CHUNK_ATHEADER; - sessionP->connP->bufferpos += 2; - } - } - } -} - - - -static void -processChunkHeaderIfThere(TSession * const sessionP, - const char ** const errorP) { - - bool gotHeader; - uint32_t chunkSize; - - getChunkHeader(sessionP, &gotHeader, &chunkSize, errorP); - - if (!*errorP) { - if (gotHeader) { - if (chunkSize == 0) - sessionP->chunkState.position = CHUNK_EOF; - else { - sessionP->chunkState.position = CHUNK_INCHUNK; - sessionP->chunkState.bytesLeftCt = chunkSize; - } - } - } -} - - - -static void -getChunkData(TSession * const sessionP, - size_t const max, - const char ** const outStartP, - size_t * const outLenP) { - - uint32_t const bufferPos = sessionP->connP->bufferpos; - - uint32_t const bytesInBufferCt = - sessionP->connP->buffersize - sessionP->connP->bufferpos; - - uint32_t const outLen = - MIN(MIN(sessionP->chunkState.bytesLeftCt, - bytesInBufferCt), - max); - - *outStartP = &sessionP->connP->buffer.t[bufferPos]; - - sessionP->connP->bufferpos += outLen; - - sessionP->chunkState.bytesLeftCt -= outLen; - - if (sessionP->chunkState.bytesLeftCt == 0) - sessionP->chunkState.position = CHUNK_AFTERCHUNK; - - *outLenP = outLen; -} - - - -static void -getSomeChunkedRequestBody(TSession * const sessionP, - size_t const max, - abyss_bool * const eofP, - const char ** const outStartP, - size_t * const outLenP, - const char ** const errorP) { -/*----------------------------------------------------------------------------- - Same as SessionGetReadData, but assuming the client is sending the body - in chunked form. - - Iff we encounter the end of body indication (a zero-size chunk), - return *eofP true and nothing as *outStartP or *outLenP. ------------------------------------------------------------------------------*/ - /* In chunked form, the client sends a sequence of chunks. Each chunk is - introduced by a one-line header. That header tells the size of the - chunk. The end of the body is delimited by a zero-length chunk. - */ - if (sessionP->chunkState.position == CHUNK_EOF) { - xmlrpc_asprintf(errorP, "The client has previously sent an " - "end-of-data indication (zero-length chunk)"); - } else { - if (sessionP->chunkState.position == CHUNK_AFTERCHUNK) { - processChunkDelimIfThere(sessionP, errorP); - } - if (!*errorP) { - if (sessionP->chunkState.position == CHUNK_ATHEADER) { - processChunkHeaderIfThere(sessionP, errorP); - } - } - if (!*errorP) { - if (sessionP->chunkState.position == CHUNK_INCHUNK) { - *eofP = false; - getChunkData(sessionP, max, outStartP, outLenP); - } else if (sessionP->chunkState.position == CHUNK_EOF) { - *eofP = true; - } else { - *eofP = false; - *outLenP = 0; - *outStartP = NULL; - } - } - } -} - - - -static void -getSomeUnchunkedRequestBody(TSession * const sessionP, - size_t const max, - const char ** const outStartP, - size_t * const outLenP) { -/*----------------------------------------------------------------------------- - Same as SessionGetReadData, but assuming the client is just sending a - plain stream of bytes for the body; not chunked. ------------------------------------------------------------------------------*/ - uint32_t const bufferPos = sessionP->connP->bufferpos; - - *outStartP = &sessionP->connP->buffer.t[bufferPos]; - - assert(bufferPos <= sessionP->connP->buffersize); - - *outLenP = MIN(max, sessionP->connP->buffersize - bufferPos); - - /* move pointer past the bytes we are returning */ - sessionP->connP->bufferpos += *outLenP; - - assert(sessionP->connP->bufferpos <= sessionP->connP->buffersize); -} - - - -void -SessionGetReadData(TSession * const sessionP, - size_t const max, - const char ** const outStartP, - size_t * const outLenP) { -/*---------------------------------------------------------------------------- - Extract some HTTP request body which the server has read and buffered for - the session. Don't get or wait for any data that has not yet arrived. Do - not return more than 'max'. - - We return a pointer to the first byte as *outStartP, and the length in - bytes as *outLenP. The memory pointed to belongs to the session. - - Iff the request body is chunked, we can be unable to do this (e.g. the - chunk header is invalid). But for historical reasons, we can't fail, so we - just put the session in a failed state and tell Caller there is no data, - and when Caller next calls SessionRefillBuffer, he will find out. ------------------------------------------------------------------------------*/ - if (sessionP->requestIsChunked) { - abyss_bool eof; - getSomeChunkedRequestBody(sessionP, max, &eof, outStartP, outLenP, - &sessionP->failureReason); - if (eof) - xmlrpc_asprintf(&sessionP->failureReason, - "End of request body encountered"); - } else { - getSomeUnchunkedRequestBody(sessionP, max, outStartP, outLenP); - } -} - - - -void -SessionGetBody(TSession * const sessionP, - size_t const max, - abyss_bool * const eofP, - const char ** const outStartP, - size_t * const outLenP, - const char ** const errorP) { -/*----------------------------------------------------------------------------- - Get some of the HTTP request body. - - If there is some request body in the connection buffer already, return that - immediately. If not, wait for some to arrive and return that. Don't wait - for more than one byte (but return more if possible without waiting), and - don't return more than 'max' bytes. - - We return a pointer to the first byte as *outStartP, and the length in - bytes as *outLenP. The memory pointed to belongs to the session. - - Iff the data indicates end-of-body (possible only when the body is chunked), - return *eofP == true and nothing as *outStartP and *outLenP. - - Assume the session has already received and processed the HTTP header. ------------------------------------------------------------------------------*/ - if (sessionP->failureReason) - xmlrpc_asprintf(errorP, "The session has previously failed: %s", - sessionP->failureReason); - else { - size_t outLen; - abyss_bool eof; - const char * error; - - for (outLen = 0, eof = false, error = NULL; - outLen == 0 && !eof && !error; ) { - if (sessionP->requestIsChunked) - getSomeChunkedRequestBody(sessionP, max, &eof, - outStartP, &outLen, - &error); - else { - getSomeUnchunkedRequestBody(sessionP, max, outStartP, &outLen); - error = NULL; - eof = false; - } - if (outLen == 0 && !eof && !error) - refillBuffer(sessionP, &error); - } - if (error) - sessionP->failureReason = xmlrpc_strdupsol(error); - - *errorP = error; - *eofP = eof; - *outLenP = outLen; - } -} - - - -void -SessionGetRequestInfo(TSession * const sessionP, - const TRequestInfo ** const requestInfoPP) { - - *requestInfoPP = &sessionP->requestInfo; -} - - - -void -SessionGetChannelInfo(TSession * const sessionP, - void ** const channelInfoPP) { - - *channelInfoPP = sessionP->connP->channelInfoP; -} - - - -abyss_bool -SessionLog(TSession * const sessionP) { - - const char * logline; - const char * user; - const char * date; - const char * peerInfo; - - if (sessionP->validRequest) { - if (sessionP->requestInfo.user) - user = sessionP->requestInfo.user; - else - user = "no_user"; - } else - user = "???"; - - DateToLogString(sessionP->date, &date); - - ConnFormatClientAddr(sessionP->connP, &peerInfo); - - xmlrpc_asprintf(&logline, "%s - %s - [%s] \"%s\" %d %u", - peerInfo, - user, - date, - sessionP->validRequest ? - sessionP->requestInfo.requestline : "???", - sessionP->status, - sessionP->connP->outbytes - ); - xmlrpc_strfree(peerInfo); - xmlrpc_strfree(date); - - LogWrite(sessionP->connP->server, logline); - - xmlrpc_strfree(logline); - - return true; -} - - - -void * -SessionGetDefaultHandlerCtx(TSession * const sessionP) { - - struct _TServer * const srvP = sessionP->connP->server->srvP; - - return srvP->defaultHandlerContext; -} - - - -void -SessionInit(TSession * const sessionP, - TConn * const connectionP) { - - sessionP->validRequest = false; /* Don't have valid request yet */ - - sessionP->failureReason = NULL; - - time(&sessionP->date); - - sessionP->connP = connectionP; - - sessionP->responseStarted = false; - - sessionP->chunkedwrite = false; - sessionP->chunkedwritemode = false; - - sessionP->continueRequired = false; - - sessionP->requestIsChunked = false; - - sessionP->chunkState.position = CHUNK_ATHEADER; - - sessionP->memPoolP = NULL; - - ListInit(&sessionP->cookies); - ListInit(&sessionP->ranges); - TableInit(&sessionP->requestHeaderFields); - TableInit(&sessionP->responseHeaderFields); - - sessionP->status = 0; /* No status from handler yet */ - - StringAlloc(&(sessionP->header)); -} - - - -static void -freeRequestInfo(TRequestInfo * const requestInfoP) { - - xmlrpc_strfreenull(requestInfoP->host); - - xmlrpc_strfreenull(requestInfoP->user); - - xmlrpc_strfree(requestInfoP->uri); - - xmlrpc_strfree(requestInfoP->requestline); -} - - - -void -SessionTerm(TSession * const sessionP) { - - if (sessionP->validRequest) - freeRequestInfo(&sessionP->requestInfo); - - ListFree(&sessionP->cookies); - ListFree(&sessionP->ranges); - TableFree(&sessionP->requestHeaderFields); - TableFree(&sessionP->responseHeaderFields); - StringFree(&(sessionP->header)); - - if (sessionP->memPoolP) - xmlrpc_mem_pool_free(sessionP->memPoolP); -} - - - -void -SessionMakeMemPool(TSession * const sessionP, - size_t const size, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Set up a memory pool for this session. All future allocations of memory - for certain purposes will come from this pool. - - The point of this is that the pool has limited size, so this puts a limit - on how much memory the session can use. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - - xmlrpc_env_init(&env); - - sessionP->memPoolP = xmlrpc_mem_pool_new(&env, size); - - if (env.fault_occurred) - *errorP = xmlrpc_strdupsol(env.fault_string); - else - *errorP = NULL; - - xmlrpc_env_clean(&env); -} - - - diff --git a/trunk/lib/abyss/src/session.h b/trunk/lib/abyss/src/session.h deleted file mode 100644 index bfbaaf645..000000000 --- a/trunk/lib/abyss/src/session.h +++ /dev/null @@ -1,146 +0,0 @@ -#ifndef SESSION_H_INCLUDED -#define SESSION_H_INCLUDED - -#include "xmlrpc-c/abyss.h" -#include "xmlrpc-c/util_int.h" -#include "bool.h" -#include "date.h" -#include "data.h" -#include "conn.h" - -typedef struct { - uint8_t major; - uint8_t minor; -} httpVersion; - -typedef enum { - /* This tells what is supposed to be at the current read position - in the connection buffer. - */ - CHUNK_ATHEADER, /* A chunk header (including EOF marker) */ - CHUNK_INCHUNK, /* Somewhere in chunk data */ - CHUNK_AFTERCHUNK, /* The delimiter after a chunk */ - CHUNK_EOF /* Past EOF marker */ -} ChunkPosition; - -struct _TSession { - bool validRequest; - /* Client has sent, and server has recognized, a valid HTTP request. - This is false when the session is new. If and when the server - reads the request from the client and finds it to be valid HTTP, - it becomes true. - */ - xmlrpc_mem_pool * memPoolP; - /* The memory pool from which various memory needed for our processing - comes. We don't allocate all memory from here; just parts that - have unpredictable size that might allow a client to get more than - its share of system meomry if we didn't limit it. This pool has a - limited size. - - NULL means all memory comes from the general system pool and there - is therefore no protection of clients from each other. - */ - const char * failureReason; - /* This is non-null to indicate that we have encountered a protocol - error or other problem in the session and the session cannot - continue. The value is a text explanation of the problem. - */ - TRequestInfo requestInfo; - /* Some of the strings this references are in individually malloc'ed - memory, but some are pointers into arbitrary other data structures - that happen to live as long as the session. Some day, we will - fix that. - - 'requestInfo' is valid only if 'validRequest' is true. - */ - uint32_t nbfileds; - TList cookies; - TList ranges; - - uint16_t status; - /* Response status from handler. Zero means session is not ready - for a response yet. This can mean that we ran a handler and it - did not call ResponseStatus() to declare this fact. - */ - TString header; - - bool serverDeniesKeepalive; - /* Server doesn't want keepalive for this session, regardless of - what happens in the session. E.g. because the connection has - already been kept alive long enough. - */ - bool responseStarted; - /* Handler has at least started the response (i.e. called - ResponseWriteStart()) - */ - - struct _TConn * connP; - - httpVersion version; - - TTable requestHeaderFields; - /* All the fields of the header of the HTTP request. The key is the - field name in lower case. The value is the verbatim value from - the field. - */ - - TTable responseHeaderFields; - /* All the fields of the header of the HTTP response. - This gets successively computed; at any moment, it is the list of - fields the user has requested so far. It also includes fields - Abyss itself has decided to include. (Blechh. This needs to be - cleaned up). - - Each table item is an HTTP header field. The Name component of the - table item is the header field name (it is syntactically valid but - not necessarily a defined field name) and the Value component is the - header field value (it is syntactically valid but not necessarily - semantically valid). - */ - - time_t date; - - bool chunkedwrite; - bool chunkedwritemode; - - bool continueRequired; - /* This client must receive 100 (continue) status before it will - send more of the body of the request. - */ - - bool requestIsChunked; - /* The request body (PUT/POST data) is chunked. */ - - struct { - /* Meaningful only when 'requestIsChunked' is true */ - - ChunkPosition position; - - uint32_t bytesLeftCt; - /* Number of bytes left to read in the current chunk. Always - greater than zero except locally. - - Meaningful only when 'position' is INCHUNK. - */ - } chunkState; -}; - -/*---------------------------------------------------------------------------- - Following are methods of a TSession object private to Abyss. Other - methods are for use by user Uri handlers and are declared in the - external abyss.h header file. ------------------------------------------------------------------------------*/ - -void -SessionInit(TSession * const sessionP, - TConn * const c); - -void -SessionTerm(TSession * const sessionP); - -void -SessionMakeMemPool(TSession * const sessionP, - size_t const size, - const char ** const errorP); - -#endif diff --git a/trunk/lib/abyss/src/sessionReadRequest.c b/trunk/lib/abyss/src/sessionReadRequest.c deleted file mode 100644 index bad3f06f8..000000000 --- a/trunk/lib/abyss/src/sessionReadRequest.c +++ /dev/null @@ -1,1210 +0,0 @@ -#define _XOPEN_SOURCE 600 /* For strdup() */ -#define _BSD_SOURCE /* For xmlrpc_strcaseeq() */ - -#include -#include -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "bool.h" -#include "mallocvar.h" -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/base64_int.h" -#include "xmlrpc-c/abyss.h" - -#include "server.h" -#include "session.h" -#include "conn.h" -#include "token.h" -#include "date.h" -#include "data.h" - -#include "sessionReadRequest.h" - - - -static void -initRequestInfo(TRequestInfo * const requestInfoP, - httpVersion const httpVersion, - const char * const requestLine, - TMethod const httpMethod, - const char * const host, - unsigned int const port, - const char * const path, - const char * const query) { -/*---------------------------------------------------------------------------- - Set up the request info structure. For information that is - controlled by the header, use the defaults -- I.e. the value that - applies if the request contains no applicable header field. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_PTR_OK(requestLine); - XMLRPC_ASSERT_PTR_OK(path); - - requestInfoP->requestline = xmlrpc_strdupsol(requestLine); - requestInfoP->method = httpMethod; - requestInfoP->host = xmlrpc_strdupnull(host); - requestInfoP->port = port; - requestInfoP->uri = strdup(path); - requestInfoP->query = xmlrpc_strdupnull(query); - requestInfoP->from = NULL; - requestInfoP->useragent = NULL; - requestInfoP->referer = NULL; - requestInfoP->user = NULL; - - if (httpVersion.major > 1 || - (httpVersion.major == 1 && httpVersion.minor >= 1)) - requestInfoP->keepalive = true; - else - requestInfoP->keepalive = false; -} - - - -static char * -firstLfPos(TConn * const connectionP, - char * const lineStart) { -/*---------------------------------------------------------------------------- - Return a pointer in the connection's receive buffer to the first - LF (linefeed aka newline) character in the buffer at or after 'lineStart'. - - If there is no LF in the buffer at or after 'lineStart', return NULL. ------------------------------------------------------------------------------*/ - const char * const bufferEnd = - connectionP->buffer.t + connectionP->buffersize; - - char * p; - - for (p = lineStart; p < bufferEnd && *p != '\n'; ++p); - - if (p < bufferEnd) - return p; - else - return NULL; -} - - - -static void -getLineInBuffer(TConn * const connectionP, - char * const lineStart, - time_t const deadline, - char ** const lineEndP, - bool * const timedOutP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Get a line into the connection's read buffer, starting at position - 'lineStart', if there isn't one already there. 'lineStart' is either - within the buffer or just after it. - - Read the channel until we get a full line, except fail if we don't get - one by 'deadline'. ------------------------------------------------------------------------------*/ - char * lfPos; - bool timedOut; - - assert(lineStart <= connectionP->buffer.t + connectionP->buffersize); - - for (*errorP = NULL, lfPos = NULL, timedOut = false; - !*errorP && !lfPos && !timedOut; - ) { - int const timeLeft = (int)(deadline - time(NULL)); - if (timeLeft <= 0) - timedOut = true; - else { - lfPos = firstLfPos(connectionP, lineStart); - if (!lfPos) { - if (ConnBufferSpace(connectionP) < 1) - xmlrpc_asprintf(errorP, "HTTP request header does not " - "fit in the server's connection buffer."); - else { - const char * readError; - ConnRead(connectionP, timeLeft, NULL, - &timedOut, &readError); - if (readError) { - xmlrpc_asprintf(errorP, "Failed to read from the " - "connection. %s", readError); - xmlrpc_strfree(readError); - } - } - } - } - } - *lineEndP = lfPos + 1; - *timedOutP = timedOut; -} - - - -static bool -isContinuationLine(const char * const line) { - - return (line[0] == ' ' || line[0] == '\t'); -} - - - -static bool -isEmptyLine(const char * const line) { - - return (line[0] == '\n' || (line[0] == '\r' && line[1] == '\n')); -} - - - -static void -convertLineEnd(char * const lineStart, - char * const prevLineStart, - char const newVal) { -/*---------------------------------------------------------------------------- - Assuming a line begins at 'lineStart' and the line before it (the - "previous line") begins at 'prevLineStart', replace the line - delimiter at the end of the previous line with the character 'newVal'. - - The line delimiter is either CRLF or LF. In the CRLF case, we replace - both CR and LF with 'newVal'. ------------------------------------------------------------------------------*/ - assert(lineStart >= prevLineStart + 1); - *(lineStart-1) = newVal; - if (prevLineStart + 1 < lineStart && - *(lineStart-2) == '\r') - *(lineStart-2) = newVal; -} - - - -static void -getRestOfField(TConn * const connectionP, - char * const lineEnd, - time_t const deadline, - const char ** const fieldEndP, - bool * const timedOutP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Given that the read buffer for connection *connectionP contains (at - its current read position) the first line of an HTTP header field, which - ends at position 'lineEnd', find or get the rest of it. - - Some or all of the rest of the field may be in the buffer already; - we read more from the connection as necessary, but not if it takes past - 'deadline'. In the latter case, we fail. - - We return the location of the end of the whole field as *headerEndP. - We do not remove the field from the buffer, but we do modify the - buffer so as to join the multiple lines of the field into a single - line, and to NUL-terminate the field. ------------------------------------------------------------------------------*/ - char * const fieldStart = connectionP->buffer.t + connectionP->bufferpos; - - char * fieldEnd; - /* End of the field lines we've seen at so far */ - bool gotWholeField; - bool timedOut; - - fieldEnd = lineEnd; /* initial value - end of 1st line */ - - for (gotWholeField = false, timedOut = false, *errorP = NULL; - !gotWholeField && !timedOut && !*errorP;) { - - char * nextLineEnd; - - /* Note that we are guaranteed, assuming the HTTP stream is - valid, that there is at least one more line in it. Worst - case, it's the empty line that marks the end of the header. - */ - getLineInBuffer(connectionP, fieldEnd, deadline, - &nextLineEnd, &timedOut, errorP); - if (!*errorP) { - if (isContinuationLine(fieldEnd)) { - /* Join previous line to this one */ - convertLineEnd(fieldEnd, fieldStart, ' '); - /* Add this line to the header */ - fieldEnd = nextLineEnd; - } else { - gotWholeField = true; - - /* NUL-terminate the whole field */ - convertLineEnd(fieldEnd, fieldStart, '\0'); - } - } - } - *fieldEndP = fieldEnd; - *timedOutP = timedOut; -} - - - -static void -readField(TConn * const connectionP, - time_t const deadline, - bool * const endOfHeaderP, - char ** const fieldP, - bool * const timedOutP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Read an HTTP header field, or the end of header empty line, on connection - *connectionP. - - An HTTP header field is basically a line, except that if a line starts - with white space, it's a continuation of the previous line. A line - is delimited by either LF or CRLF. - - The first line of an HTTP header field is never empty; an empty line - signals the end of the HTTP header and beginning of the HTTP body. We - call that empty line the EOH mark. - - We assume the connection is positioned to a header or EOH mark. - - In the course of reading, we read at least one character past the - line delimiter at the end of the field or EOH mark; we may read - much more. But we leave everything after the field or EOH (and - its line delimiter) in the internal buffer, with the buffer pointer - pointing to it. - - We use stuff already in the internal buffer (perhaps left by a - previous call to this subroutine) before reading any more from from - the channel. - - We return as *fieldP the next field as an ASCIIZ string, with no - line delimiter. That string is stored in the "unused" portion of - the connection's internal buffer. Iff there is no next field, we - return *endOfHeaderP == true and nothing meaningful as *fieldP. ------------------------------------------------------------------------------*/ - char * const bufferStart = connectionP->buffer.t + connectionP->bufferpos; - - char * lineEnd; - const char * getLineError; - - getLineInBuffer(connectionP, bufferStart, deadline, &lineEnd, - timedOutP, &getLineError); - - if (getLineError) { - xmlrpc_asprintf(errorP, "Failed to get a line of HTTP header " - "from client. %s", getLineError); - xmlrpc_strfree(getLineError); - } else if (!*timedOutP) { - if (isContinuationLine(bufferStart)) - xmlrpc_asprintf(errorP, "Client sent continuation line when " - "we were expecting a new header"); - else if (isEmptyLine(bufferStart)) { - /* Consume the EOH mark from the buffer */ - connectionP->bufferpos = lineEnd - connectionP->buffer.t; - *endOfHeaderP = true; - *errorP = NULL; - } else { - /* We have the first line of a field; there may be more. */ - - const char * fieldEnd; - const char * error; - - *endOfHeaderP = false; - - getRestOfField(connectionP, lineEnd, deadline, - &fieldEnd, timedOutP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "After receiving the beginning of " - "an HTTP header field, failed to read " - "the rest of it. %s", error); - xmlrpc_strfree(error); - } else { - *errorP = NULL; - - if (!*timedOutP) { - *fieldP = bufferStart; - - /* Consume the header from the buffer (but be careful -- - you can't reuse that part of the buffer because the - string we will return is in it! - */ - connectionP->bufferpos = fieldEnd - connectionP->buffer.t; - } - } - } - } -} - - - -static void -skipToNonemptyLine(TConn * const connectionP, - time_t const deadline, - bool * const timedOutP, - const char ** const errorP) { - - char * const bufferStart = connectionP->buffer.t + connectionP->bufferpos; - - bool gotNonEmptyLine; - char * lineStart; - - for (lineStart = bufferStart, gotNonEmptyLine = false, *timedOutP = false, - *errorP = NULL; - !gotNonEmptyLine && !*timedOutP && !*errorP; ) { - - char * lineEnd; - - getLineInBuffer(connectionP, lineStart, deadline, &lineEnd, - timedOutP, errorP); - - if (!*errorP && !*timedOutP) { - if (!isEmptyLine(lineStart)) - gotNonEmptyLine = true; - else - lineStart = lineEnd; - } - } - if (!*errorP && !*timedOutP) { - /* Consume all the empty lines; advance buffer pointer to first - non-empty line. - */ - connectionP->bufferpos = lineStart - connectionP->buffer.t; - } -} - - - -static void -readRequestField(TSession * const sessionP, - time_t const deadline, - char ** const requestLineP, - bool * const timedOutP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Read the HTTP request field (POST, etc.) from session 'sessionP'. We read - through the session's internal buffer; i.e. we may get data that was - previously read from the network, or we may read more from the network. - - We assume the connection is presently positioned to the beginning of - the HTTP document. We leave it positioned after the request field. - - We ignore any empty lines at the beginning of the stream, per - RFC2616 Section 4.1. - - If we can't get the field before 'deadline', return *timedOutP = true. - - Return as *requestLineP the request field read. This ASCIIZ string is - in the session's internal buffer. ------------------------------------------------------------------------------*/ - char * line; - bool endOfHeader; - const char * skipError; - - skipToNonemptyLine(sessionP->connP, deadline, timedOutP, &skipError); - - if (skipError) { - xmlrpc_asprintf(errorP, "Failed to find the request field, " - "i.e. a non-empty line. %s", skipError); - xmlrpc_strfree(skipError); - } else if (!*timedOutP) { - const char * error; - - readField(sessionP->connP, deadline, &endOfHeader, &line, - timedOutP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Got beginning of the request field, " - "but failed to get the rest. %s", error); - xmlrpc_strfree(error); - } else { - *errorP = NULL; - - if (!*timedOutP) { - /* End of header is delimited by an empty line, and we skipped - all the empty lines above, so readField() could not have - encountered EOH: - */ - assert(!endOfHeader); - - *requestLineP = line; - } - } - } -} - - - -static void -hexDigitValue(char const digit, - unsigned int * const valueP, - const char ** const errorP) { - - if (digit == '\0') - xmlrpc_asprintf(errorP, "string ends in the middle of a " - "%% escape sequence"); - else { - char const digitLc = tolower(digit); - - if ((digitLc >= '0') && (digitLc <= '9')) { - *valueP = digitLc - '0'; - *errorP = NULL; - } else if ((digitLc >= 'a') && (digitLc <= 'f')) { - *valueP = 10 + digitLc - 'a'; - *errorP = NULL; - } else - xmlrpc_asprintf(errorP, "Non-hexadecimal digit '%c' in " - "%%HH escape sequence", digit); - } -} - - - -static void -parsePerCentEscape(const char ** const srcP, - char * const unescapedP, - const char ** const errorP) { -/*----------------------------------------------------------------------------- - With *srcP pointing to a supposed %HH escape sequence in a buffer, set - *unescapedP to the character that the sequence represents and advance *srcP - past it. ------------------------------------------------------------------------------*/ - unsigned int digit0; - - const char * src; - - src = *srcP; /* initial value */ - - ++src; /* Move past per cent sign */ - - if (!*src) - xmlrpc_asprintf(errorP, "URI ends after the %%"); - else { - *errorP = NULL; /* initial assumption */ - - hexDigitValue(*src++, &digit0, errorP); - - if (!*errorP) { - unsigned int digit1; - - if (!*src) - xmlrpc_asprintf(errorP, "URI ends after the first digit"); - else { - hexDigitValue(*src++, &digit1, errorP); - - if (!*errorP) - *unescapedP = ((digit0 << 4) | digit1); - } - } - } - *srcP = src; -} - - - -static void -unescapeUri(const char * const uriComponent, - const char ** const unescapedP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Unescape a component of a URI, e.g. the host name. That component may - have %HH encoding, especially of characters that are delimiters within - a URI like slash and colon. - - Return the unescaped version as *unescapedP in newly malloced storage. ------------------------------------------------------------------------------*/ - char * buffer; - - buffer = strdup(uriComponent); - - if (!buffer) - xmlrpc_asprintf(errorP, "Couldn't get memory for URI unescape buffer"); - else { - const char * src; - char * dst; - - src = dst = buffer; - - *errorP = NULL; /* initial value */ - - while (*src && !*errorP) { - switch (*src) { - case '%': { - char unescaped; - const char * error; - - parsePerCentEscape(&src, &unescaped, &error); - - if (error) { - xmlrpc_asprintf(errorP, - "Invalid %%HH escape sequence. %s", - error); - xmlrpc_strfree(error); - } else - *dst++ = unescaped; - } break; - - default: - *dst++ = *src++; - break; - } - } - *dst = '\0'; - - if (*errorP) - xmlrpc_strfree(buffer); - else - *unescapedP = buffer; - } -} - - - -static void -parseHostPort(const char * const hostport, - const char ** const hostP, - unsigned short * const portP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Parse a 'hostport', a string in the form www.acme.com:8080 . - - Return the host name part (www.acme.com) as *hostP (in newly - malloced storage), and the port part (8080) as *portP. - - Default the port to 80 if 'hostport' doesn't have the port part. ------------------------------------------------------------------------------*/ - char * buffer; - - buffer = strdup(hostport); - - if (!buffer) - xmlrpc_asprintf(errorP, "Couldn't get memory for host/port buffer"); - else { - /* Note that the host portion may contain colons. The old RFC says - it can't, but a newer one says the host may be an IPv6 address - in the form [x:x:x...]. But the port portion may contain only - digits, so we use the _last_ colon as the delimiter. - */ - char * const colonPos = strrchr(buffer, ':'); - - if (colonPos) { - const char * p; - uint32_t port; - - *colonPos = '\0'; /* Split hostport at the colon */ - - for (p = colonPos + 1, port = 0; - isdigit(*p) && port < 65535; - (port = port * 10 + (*p - '0')), ++p); - - if (*p || port == 0) { - xmlrpc_asprintf(errorP, "There is nothing, or something " - "non-numeric for the port number after the " - "colon in '%s'", hostport); - } else { - *hostP = xmlrpc_strdupsol(buffer); - *portP = port; - *errorP = NULL; - } - } else { - *hostP = xmlrpc_strdupsol(buffer); - *portP = 80; - *errorP = NULL; - } - free(buffer); - } -} - - - -static void -splitUriQuery(const char * const requestUri, - const char ** const queryP, - const char ** const noQueryP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Split 'requestUri' at the question mark, returning the stuff after - as *queryP and the stuff before as *noQueryP. ------------------------------------------------------------------------------*/ - char * buffer; - - buffer = strdup(requestUri); - - if (!buffer) - xmlrpc_asprintf(errorP, "Couldn't get memory for URI buffer"); - else { - char * const qmark = strchr(buffer, '?'); - - if (qmark) { - *qmark = '\0'; - *queryP = xmlrpc_strdupsol(qmark + 1); - } else - *queryP = NULL; - - *errorP = NULL; - *noQueryP = buffer; - } -} - - - -static void -parseHttpHostPortPath(const char * const hostportpath, - const char ** const hostP, - unsigned short* const portP, - const char ** const pathP, - const char ** const errorP) { - - const char * path; - - char * buffer; - - buffer = strdup(hostportpath); - - if (!buffer) - xmlrpc_asprintf(errorP, - "Couldn't get memory for host/port/path buffer"); - else { - char * const slashPos = strchr(buffer, '/'); - - char * hostport; - - if (slashPos) { - path = xmlrpc_strdupsol(slashPos); /* Includes the initial slash */ - - *slashPos = '\0'; /* NUL termination for hostport */ - } else - path = strdup("*"); - - hostport = buffer; - - /* The following interprets the port field without taking into account - any %HH encoding, as the RFC says may be there. We ignore that - remote possibility out of laziness. - */ - parseHostPort(hostport, hostP, portP, errorP); - - if (*errorP) - xmlrpc_strfree(path); - else - *pathP = path; - - free(buffer); - } -} - - - -static void -unescapeHostPathQuery(const char * const host, - const char * const path, - const char * const query, - const char ** const hostP, - const char ** const pathP, - const char ** const queryP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Unescape each of the four components of a URI. - - Each may be NULL, in which case we return NULL. ------------------------------------------------------------------------------*/ - if (host) - unescapeUri(host, hostP, errorP); - else - *hostP = NULL; - if (!*errorP) { - if (path) - unescapeUri(path, pathP, errorP); - else - *pathP = NULL; - if (!*errorP) { - if (query) - unescapeUri(query, queryP, errorP); - else - *queryP = NULL; - if (*errorP) - xmlrpc_strfree(*pathP); - } else { - if (*hostP) - xmlrpc_strfree(*hostP); - } - } -} - - - -static void -parseRequestUri(char * const requestUri, - const char ** const hostP, - unsigned short * const portP, - const char ** const pathP, - const char ** const queryP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Parse the request URI (in the request line - "GET http://www.myserver.com:8080/myfile.cgi?parm HTTP/1.1", - "http://www.myserver.com:8080/myfile.cgi?parm" is the request URI). - - Return as *hostP the "www.myserver.com" in the above example. If - that part of the URI doesn't exist, return *hostP == NULL. - - Return as *portP the 8080 in the above example. If it doesn't exist, - return 80. - - Return as *pathP the "/myfile.cgi" in the above example. If it - doesn't exist, return "*". - - Return as *queryP the "parm" in the above example. If it doesn't - exist, return *queryP == NULL. - - Return strings in newly malloc'ed storage. - - We can return syntactically invalid entities, e.g. a host name that - contains "<", if 'requestUri' is similarly invalid. We should fix that - some day. RFC 2396 lists a lot of characters as reserved for certain - use in the URI, such as colon, and totally disallowed, such as space. ------------------------------------------------------------------------------*/ - const char * requestUriNoQuery; - /* The request URI with any query (the stuff marked by a question - mark at the end of a request URI) chopped off. - */ - const char * query; - const char * path; - const char * host; - unsigned short port; - - splitUriQuery(requestUri, &query, &requestUriNoQuery, errorP); - if (!*errorP) { - if (requestUriNoQuery[0] == '/') { - host = NULL; - path = xmlrpc_strdupsol(requestUriNoQuery); - port = 80; - *errorP = NULL; - } else { - if (!xmlrpc_strneq(requestUriNoQuery, "http://", 7)) - xmlrpc_asprintf(errorP, "Scheme is not http://"); - else - parseHttpHostPortPath(&requestUriNoQuery[7], - &host, &port, &path, errorP); - } - - if (!*errorP) { - *portP = port; - unescapeHostPathQuery(host, path, query, - hostP, pathP, queryP, errorP); - - if (host) - xmlrpc_strfree(host); - if (path) - xmlrpc_strfree(path); - } - - if (query) - xmlrpc_strfree(query); - xmlrpc_strfree(requestUriNoQuery); - } -} - - - -static TMethod -methodFromMethodName(const char * const httpMethodName) { - - if (xmlrpc_streq(httpMethodName, "GET")) - return m_get; - else if (xmlrpc_streq(httpMethodName, "PUT")) - return m_put; - else if (xmlrpc_streq(httpMethodName, "OPTIONS")) - return m_options; - else if (xmlrpc_streq(httpMethodName, "DELETE")) - return m_delete; - else if (xmlrpc_streq(httpMethodName, "POST")) - return m_post; - else if (xmlrpc_streq(httpMethodName, "TRACE")) - return m_trace; - else if (xmlrpc_streq(httpMethodName, "HEAD")) - return m_head; - else - return m_unknown; -} - - - -static void -parseHttpVersion(const char * const textFromReqLine, - httpVersion * const httpVersionP, - const char ** const errorP) { - - uint32_t vmin, vmaj; - - if (sscanf(textFromReqLine, "HTTP/%d.%d", &vmaj, &vmin) != 2) - xmlrpc_asprintf(errorP, "Does not have the form HTTP/n.n"); - else { - *errorP = NULL; - httpVersionP->major = vmaj; - httpVersionP->minor = vmin; - } -} - - - -static void -parseRequestLine(char * const requestLine, - TMethod * const httpMethodP, - httpVersion * const httpVersionP, - const char ** const hostP, - unsigned short * const portP, - const char ** const pathP, - const char ** const queryP, - bool * const moreLinesP, - const char ** const errorP) { - - char * const requestBuffer = strdup(requestLine); - - const char * httpMethodName; - char * p; - - if (requestBuffer == NULL) - xmlrpc_asprintf(errorP, "Couldn't get memory for working buffer"); - else { - p = requestBuffer; - - /* Jump over spaces */ - NextToken((const char **)&p); - - httpMethodName = GetToken(&p); - if (!httpMethodName) - xmlrpc_asprintf(errorP, "No method name (e.g. \"GET\")"); - else { - char * requestUri; - - *httpMethodP = methodFromMethodName(httpMethodName); - - /* URI and Query Decoding */ - NextToken((const char **)&p); - - requestUri = GetToken(&p); - if (!requestUri) - xmlrpc_asprintf(errorP, "No URI after the method name ('%s')", - httpMethodName); - else { - const char * host; - unsigned short port; - const char * path; - const char * query; - const char * error; - - parseRequestUri(requestUri, - &host, &port, &path, &query, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Invalid URI ('%s'). %s", - requestUri, error); - xmlrpc_strfree(error); - } else { - const char * httpVersion; - - NextToken((const char **)&p); - - /* HTTP Version Decoding */ - - httpVersion = GetToken(&p); - if (httpVersion) { - const char * error; - parseHttpVersion(httpVersion, httpVersionP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Invalid HTTP version " - "token ('%s'). %s", - httpVersion, error); - xmlrpc_strfree(error); - } else { - *errorP = NULL; - *moreLinesP = true; - } - } else { - /* There is no HTTP version, so this is a single - line request. - */ - *errorP = NULL; - *moreLinesP = false; - } - if (*errorP) { - xmlrpc_strfree(host); - xmlrpc_strfree(path); - xmlrpc_strfree(query); - } - *hostP = host; - *portP = port; - *pathP = path; - *queryP = query; - } - } - } - xmlrpc_strfree(requestBuffer); - } -} - - - -static void -strtolower(char * const s) { - - char * t; - - t = &s[0]; - while (*t) { - *t = tolower(*t); - ++t; - } -} - - - -static void -getFieldNameToken(char ** const pP, - char ** const fieldNameP, - const char ** const errorP, - uint16_t * const httpErrorCodeP) { -/*---------------------------------------------------------------------------- - Assuming that *pP points to the place in an HTTP header where the field - name belongs, return the field name and advance *pP past that token. - - The field name is the lower case representation of the value of the - field name token. - - If the field name is invalid, return a text explanation as *errorP - and a suitable HTTP status code as *httpErrorCodeP. If not, return - *errorP == NULL and nothing as *httpErrorCodeP. ------------------------------------------------------------------------------*/ - char * fieldName; - - NextToken((const char **)pP); - - fieldName = GetToken(pP); - if (!fieldName) { - xmlrpc_asprintf(errorP, "The header has no field name token"); - *httpErrorCodeP = 400; /* Bad Request */ - } else { - if (fieldName[strlen(fieldName)-1] != ':') { - /* Not a valid field name */ - xmlrpc_asprintf(errorP, "The field name token '%s' " - "does not end with a colon (:)", fieldName); - *httpErrorCodeP = 400; /* Bad Request */ - } else { - fieldName[strlen(fieldName)-1] = '\0'; /* remove trailing colon */ - - strtolower(fieldName); - - *errorP = NULL; - } - } - *fieldNameP = fieldName; -} - - - -static void -processField(const char * const fieldName, - char * const fieldValue, - TSession * const sessionP, - const char ** const errorP, - uint16_t * const httpErrorCodeP) { -/*---------------------------------------------------------------------------- - We may modify *fieldValue, and we put pointers to *fieldValue and - *fieldName into *sessionP. - - We must fix this some day. *sessionP should point to individual - malloc'ed strings. ------------------------------------------------------------------------------*/ - *errorP = NULL; /* initial assumption */ - - if (xmlrpc_streq(fieldName, "connection")) { - if (xmlrpc_strcaseeq(fieldValue, "keep-alive")) - sessionP->requestInfo.keepalive = true; - else - sessionP->requestInfo.keepalive = false; - } else if (xmlrpc_streq(fieldName, "host")) { - if (sessionP->requestInfo.host) { - xmlrpc_strfree(sessionP->requestInfo.host); - sessionP->requestInfo.host = NULL; - } - parseHostPort(fieldValue, &sessionP->requestInfo.host, - &sessionP->requestInfo.port, errorP); - } else if (xmlrpc_streq(fieldName, "from")) - sessionP->requestInfo.from = fieldValue; - else if (xmlrpc_streq(fieldName, "user-agent")) - sessionP->requestInfo.useragent = fieldValue; - else if (xmlrpc_streq(fieldName, "referer")) - sessionP->requestInfo.referer = fieldValue; - else if (xmlrpc_streq(fieldName, "range")) { - if (xmlrpc_strneq(fieldValue, "bytes=", 6)) { - bool succeeded; - succeeded = ListAddFromString(&sessionP->ranges, &fieldValue[6]); - if (!succeeded) { - xmlrpc_asprintf(errorP, "ListAddFromString() failed for " - "\"range: bytes=...\" header value '%s'", - &fieldValue[6]); - *httpErrorCodeP = 400; - } - } - } else if (xmlrpc_streq(fieldName, "cookies")) { - bool succeeded; - succeeded = ListAddFromString(&sessionP->cookies, fieldValue); - if (!succeeded) { - xmlrpc_asprintf(errorP, "ListAddFromString() failed for " - "cookies: header value '%s'", fieldValue); - *httpErrorCodeP = 400; - } - } else if (xmlrpc_streq(fieldName, "expect")) { - if (xmlrpc_strcaseeq(fieldValue, "100-continue")) - sessionP->continueRequired = true; - } else if (xmlrpc_streq(fieldName, "transfer-encoding")) { - if (xmlrpc_strcaseeq(fieldValue, "chunked")) - sessionP->requestIsChunked = true; - else if (xmlrpc_strcaseeq(fieldValue, "identity")) { - // Same as no transfer-encoding specified - } else { - xmlrpc_asprintf(errorP, "Server does not know '%s' transfer " - "encoding. It knows only 'chunked' and " - "'identity'", fieldValue); - *httpErrorCodeP = 501; - } - } -} - - - -static void -readAndProcessHeaderFields(TSession * const sessionP, - time_t const deadline, - const char ** const errorP, - uint16_t * const httpErrorCodeP) { -/*---------------------------------------------------------------------------- - Read all the HTTP header fields from the session *sessionP, which has at - least one field coming. Update *sessionP to reflect the information in the - fields. - - If we find an error in the fields or while trying to read them, we return - a text explanation of the problem as *errorP and an appropriate HTTP error - code as *httpErrorCodeP. Otherwise, we return *errorP = NULL and nothing - as *httpErrorCodeP. ------------------------------------------------------------------------------*/ - bool endOfHeader; - bool timedOut; - - assert(!sessionP->validRequest); - /* Calling us doesn't make sense if there is already a valid request */ - - for (endOfHeader = false, *errorP = NULL, timedOut = false; - !endOfHeader && !*errorP && !timedOut; ) { - char * field; - const char * error; - readField(sessionP->connP, deadline, &endOfHeader, &field, - &timedOut, &error); - if (error) { - xmlrpc_asprintf(errorP, "Failed to read header from " - "client connection. %s", error); - *httpErrorCodeP = 500; /* Internal server error */ - xmlrpc_strfree(error); - } else if (timedOut) { - xmlrpc_asprintf(errorP, "Timed out wating for client to send " - "something"); - *httpErrorCodeP = 408; /* Request timed out */ - } else { - if (!endOfHeader) { - char * p; - char * fieldName; - - p = &field[0]; - getFieldNameToken(&p, &fieldName, errorP, httpErrorCodeP); - if (!*errorP) { - char * fieldValue; - - NextToken((const char **)&p); - - fieldValue = p; - - TableAdd(&sessionP->requestHeaderFields, - fieldName, fieldValue); - - processField(fieldName, fieldValue, sessionP, errorP, - httpErrorCodeP); - } - } - } - } -} - - - -void -SessionReadRequest(TSession * const sessionP, - uint32_t const timeout, - const char ** const errorP, - uint16_t * const httpErrorCodeP) { -/*---------------------------------------------------------------------------- - Read the header of a new HTTP request (assuming nothing has yet been - read on the session). - - Update *sessionP with the information from the header. - - Leave the connection positioned to the body of the request, ready - to be read by an HTTP request handler (via SessionRefillBuffer() and - SessionGetReadData()). - - If we are unable to read the header, we return a text description as - *errorP and a suitable HTTP status code as *httpErrorCodeP. - - If we successfully read the header, we return *errorP == NULL and - nothing as *httpErrorCodeP. ------------------------------------------------------------------------------*/ - time_t const deadline = time(NULL) + timeout; - - bool timedOut; - const char * error; - char * requestLine; /* In connection's internal buffer */ - - readRequestField(sessionP, deadline, &requestLine, &timedOut, &error); - if (error) { - xmlrpc_asprintf(errorP, "Problem getting the request header. %s", - error); - *httpErrorCodeP = 500; /* Internal error */ - xmlrpc_strfree(error); - } else if (timedOut) { - xmlrpc_asprintf(errorP, "Timed out waiting for client to send " - "the request field"); - *httpErrorCodeP = 408; /* Request timed out */ - } else { - TMethod httpMethod; - const char * host; - const char * path; - const char * query; - unsigned short port; - bool moreFields; - const char * error; - - parseRequestLine(requestLine, &httpMethod, &sessionP->version, - &host, &port, &path, &query, - &moreFields, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Unable to parse the request header " - "'%s'. %s", requestLine, error); - *httpErrorCodeP = 400; /* Bad request */ - xmlrpc_strfree(error); - } else { - initRequestInfo(&sessionP->requestInfo, sessionP->version, - requestLine, - httpMethod, host, port, path, query); - - if (moreFields) { - readAndProcessHeaderFields(sessionP, deadline, - errorP, httpErrorCodeP); - } else - *errorP = NULL; - - if (!*errorP) - sessionP->validRequest = true; - - xmlrpc_strfreenull(host); - xmlrpc_strfree(path); - xmlrpc_strfreenull(query); - } - } -} - - - diff --git a/trunk/lib/abyss/src/sessionReadRequest.h b/trunk/lib/abyss/src/sessionReadRequest.h deleted file mode 100644 index 6b3107ef6..000000000 --- a/trunk/lib/abyss/src/sessionReadRequest.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef SESSION_READ_REQUEST_H_INCLUDED -#define SESSION_READ_REQUEST_H_INCLUDED - -#include "session.h" - -void -SessionReadRequest(TSession * const sessionP, - uint32_t const timeout, - const char ** const errorP, - uint16_t * const httpErrorCodeP); - -#endif diff --git a/trunk/lib/abyss/src/socket.c b/trunk/lib/abyss/src/socket.c deleted file mode 100644 index 4724e6dfc..000000000 --- a/trunk/lib/abyss/src/socket.c +++ /dev/null @@ -1,127 +0,0 @@ -/*============================================================================ - socket.c -============================================================================== - Implementation of obsolete TSocket class. - - Use TChannel and TChanSwitch instead for new work. -============================================================================*/ - -#include -#include - -#include "int.h" -#include "mallocvar.h" -#include "xmlrpc-c/abyss.h" -#include "channel.h" -#include "chanswitch.h" - -#include "socket.h" - - -/* SocketCreate...() is not exported to the Abyss user. It is meant to - be used by an implementation-specific TSocket generator which is - exported to the Abyss user, e.g. SocketCreateUnix() in - socket_unix.c - - The TSocket generator functions are the _only_ user-accessible - functions that are particular to an implementation. -*/ - -static unsigned int const socketSignature = 0x060609; - - -static void -socketCreate(TSocket ** const socketPP) { - - TSocket * socketP; - - MALLOCVAR(socketP); - - if (socketP) { - socketP->signature = socketSignature; - *socketPP = socketP; - } else - *socketPP = NULL; -} - - - -void -SocketCreateChannel(TChannel * const channelP, - void * const channelInfoP, - TSocket ** const socketPP) { - - TSocket * socketP; - - socketCreate(&socketP); - - if (socketP) { - socketP->channelP = channelP; - socketP->chanSwitchP = NULL; - socketP->channelInfoP = channelInfoP; - *socketPP = socketP; - } else - *socketPP = NULL; -} - - - -void -SocketCreateChanSwitch(TChanSwitch * const chanSwitchP, - TSocket ** const socketPP) { - - TSocket * socketP; - - socketCreate(&socketP); - - if (socketP) { - socketP->channelP = NULL; - socketP->chanSwitchP = chanSwitchP; - *socketPP = socketP; - } else - *socketPP = NULL; -} - - - -void -SocketDestroy(TSocket * const socketP) { - - assert(socketP->signature == socketSignature); - - if (socketP->channelP) { - ChannelDestroy(socketP->channelP); - free(socketP->channelInfoP); - } - - if (socketP->chanSwitchP) - ChanSwitchDestroy(socketP->chanSwitchP); - - socketP->signature = 0; /* For debuggability */ - - free(socketP); -} - - - -TChanSwitch * -SocketGetChanSwitch(TSocket * const socketP) { - - return socketP->chanSwitchP; -} - - - -TChannel * -SocketGetChannel(TSocket * const socketP) { - - return socketP->channelP; -} - - - -void * -SocketGetChannelInfo(TSocket * const socketP) { - - return socketP->channelInfoP; -} diff --git a/trunk/lib/abyss/src/socket.h b/trunk/lib/abyss/src/socket.h deleted file mode 100644 index 50e67ba6b..000000000 --- a/trunk/lib/abyss/src/socket.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef SOCKET_H_INCLUDED -#define SOCKET_H_INCLUDED - -/*============================================================================ - This is for backward compatibility. Abyss used to have a socket - concept modelled after POSIX sockets, in which a single class (TSocket) - contained two very different kinds of objects: some analogous to - a TChanSwitch and analogout to a TChannel. - - Now that we have TChanSwitch and TChannel, users should use those, - but there may be old programs that use TSocket, and we want them to - continue working. - - Actually, this may not be necessary. There was only one release - (1.06) that had the TSocket interface, and that release didn't - provide any incentive to upgrade an older program to use TSocket, - so there may be few or no users of TSocket. -============================================================================*/ - -#include "int.h" - -#include "xmlrpc-c/abyss.h" - -struct _TSocket { - unsigned int signature; - /* With both background and foreground use of sockets, and - background being both fork and pthread, it is very easy to - screw up socket lifetime and try to destroy twice. We use - this signature to help catch such bugs. - */ - - /* Exactly one of 'chanSwitchP' and 'channelP' is non-null. - That's how you know which of the two varieties of socket this is. - */ - TChanSwitch * chanSwitchP; - TChannel * channelP; - - void * channelInfoP; /* Defined only for a channel socket */ -}; - -void -SocketCreateChannel(TChannel * const channelP, - void * const channelInfoP, - TSocket ** const socketPP); - -void -SocketCreateChanSwitch(TChanSwitch * const chanSwitchP, - TSocket ** const socketPP); - -TChanSwitch * -SocketGetChanSwitch(TSocket * const socketP); - -TChannel * -SocketGetChannel(TSocket * const socketP); - -void * -SocketGetChannelInfo(TSocket * const socketP); - -#endif - diff --git a/trunk/lib/abyss/src/socket_openssl.c b/trunk/lib/abyss/src/socket_openssl.c deleted file mode 100644 index 1f35ec317..000000000 --- a/trunk/lib/abyss/src/socket_openssl.c +++ /dev/null @@ -1,973 +0,0 @@ -/*============================================================================= - socket_openssl.c -=============================================================================== - This is the implementation of TChanSwitch and TChannel - for an SSL (Secure Sockets Layer) connection based on an OpenSSL - connection object -- what you create with SSL_new(). -=============================================================================*/ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "bool.h" -#include "mallocvar.h" -#include "trace.h" -#include "chanswitch.h" -#include "channel.h" -#include "socket.h" -#include "xmlrpc-c/abyss.h" -#include "xmlrpc-c/abyss_openssl.h" - -#include "sockutil.h" -#include "socket_openssl.h" - - - -/* We've seen Openssl from the year 2002 not have SSL_ERROR_WANT_ACCEPT. - In 2016, it is defined as a macro. -*/ -#ifdef SSL_ERROR_WANT_ACCEPT -#define HAVE_SSL_ERROR_WANT_ACCEPT 1 -#else -#define HAVE_SSL_ERROR_WANT_ACCEPT 0 -#endif - - - -static const char * -sslErrorMsg(void) { -/*---------------------------------------------------------------------------- - The information on the OpenSSL error stack, in human-readable (barely) - form. ------------------------------------------------------------------------------*/ - const char * retval; - bool eof; - - retval = xmlrpc_strdupsol(""); - - for (eof = false; !eof; ) { - const char * sourceFileName; - int lineNum; - - int const errCode = ERR_get_error_line(&sourceFileName, &lineNum); - - if (errCode == 0) - eof = true; - else { - const char * newRetval; - - xmlrpc_asprintf(&newRetval, "%s %s (%s:%d); ", - retval, ERR_error_string(errCode, NULL), - sourceFileName, lineNum); - - xmlrpc_strfree(retval); - - retval = newRetval; - } - } - return retval; -} - - - -static const char * -sslResultMsg(int const resultCode) { -/*---------------------------------------------------------------------------- - English description of a result code such as OpenSSL's SSL_get_error - returns. ------------------------------------------------------------------------------*/ - switch (resultCode) { - case SSL_ERROR_NONE: return "None"; - case SSL_ERROR_SSL: return "SSL"; - case SSL_ERROR_WANT_READ: return "Want Read"; - case SSL_ERROR_WANT_WRITE: return "Want Write"; - case SSL_ERROR_WANT_X509_LOOKUP: return "Want X509_LOOKUP"; - case SSL_ERROR_SYSCALL: return "Syscall"; - case SSL_ERROR_ZERO_RETURN: return "Zero Return"; - case SSL_ERROR_WANT_CONNECT: return "Want Connect"; -#if HAVE_SSL_ERROR_WANT_ACCEPT - case SSL_ERROR_WANT_ACCEPT: return "Want Accept"; -#endif - default: return "???"; - } -} - - - -static void -sslCreate(SSL_CTX * const sslCtxP, - SSL ** const sslPP, - const char ** const errorP) { - - *sslPP = SSL_new(sslCtxP); - - if (!*sslPP) { - const char * const sslMsg = sslErrorMsg(); - - xmlrpc_asprintf(errorP, "Failed to create SSL connection " - "object. SSL_new() failed. %s", sslMsg); - xmlrpc_strfree(sslMsg); - } else - *errorP = NULL; -} - - - -static void -sslSetFd(SSL * const sslP, - int const acceptedFd, - const char ** const errorP) { - - int succeeded; - - succeeded = SSL_set_fd(sslP, acceptedFd); - - if (!succeeded) { - const char * sslMsg; - - sslMsg = sslErrorMsg(); - - xmlrpc_asprintf(errorP, "SSL_set_fd(%d) failed. %s", - acceptedFd, sslMsg); - - xmlrpc_strfree(sslMsg); - } else - *errorP = NULL; -} - - - -static void -traceCipherList(SSL * const sslP) { - - int priority; - bool eof; - - fprintf(stderr, "SSL object will consider using the following " - "ciphers in priority order, if conditions are right to use " - "them and the client agrees: "); - - for (priority = 0, eof = false; !eof; ++priority) { - const char * const cipherName = SSL_get_cipher_list(sslP, priority); - - if (cipherName) - fprintf(stderr, "%s ", cipherName); - else - eof = true; - } - fprintf(stderr, "\n"); -} - - - -static void -sslAccept(SSL * const sslP, - const char ** const errorP) { - - int rc; - - if (SwitchTraceIsActive) - traceCipherList(sslP); - - rc = SSL_accept(sslP); - - if (rc == 1) - *errorP = NULL; - else { - int const resultCode = SSL_get_error(sslP, rc); - - const char * const errorStack = sslErrorMsg(); - - xmlrpc_asprintf(errorP, "SSL_accept() failed. rc=%d/%d: %s. " - "OpenSSL error stack: %s\n", - rc, resultCode, sslResultMsg(resultCode), errorStack); - - xmlrpc_strfree(errorStack); - } -} - - - -struct ChannelOpenSsl { -/*---------------------------------------------------------------------------- - The properties/state of a TChannel unique to the OpenSSL variety. ------------------------------------------------------------------------------*/ - int fd; - /* File descriptor of the TCP connection underlying the SSL connection - */ - SSL * sslP; - /* SSL connection handle */ - bool userSuppliedSsl; - /* The SSL connection belongs to the user; we did not create it. */ -}; - - - -void -SocketOpenSslInit(const char ** const errorP) { - - SSL_load_error_strings(); - /* readable error messages, don't call this if memory is tight */ - SSL_library_init(); /* initialize library */ - - *errorP = NULL; -} - - - -void -SocketOpenSslTerm(void) { - - ERR_free_strings(); - -} - - - -/*============================================================================= - TChannel -=============================================================================*/ - -static ChannelDestroyImpl channelDestroy; - -static void -channelDestroy(TChannel * const channelP) { - - struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; - - if (!channelOpenSslP->userSuppliedSsl) - SSL_shutdown(channelOpenSslP->sslP); - - free(channelOpenSslP); -} - - - -static ChannelWriteImpl channelWrite; - -static void -channelWrite(TChannel * const channelP, - const unsigned char * const buffer, - uint32_t const len, - bool * const failedP) { - - struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; - - unsigned int bytesLeft; - bool error; - - assert(sizeof(int) >= sizeof(len)); - - for (bytesLeft = len, error = false; bytesLeft > 0 && !error; ) { - uint32_t const maxSend = (uint32_t)(-1) >> 1; - - int rc; - - rc = SSL_write(channelOpenSslP->sslP, &buffer[len-bytesLeft], - MIN(maxSend, bytesLeft)); - - if (ChannelTraceIsActive) { - if (rc <= 0) - fprintf(stderr, - "Abyss socket: SSL_write() failed. rc=%d/%d", - rc, SSL_get_error(channelOpenSslP->sslP, rc)); - else - fprintf(stderr, "Abyss socket: sent %u bytes: '%.*s'\n", - rc, rc, &buffer[len-bytesLeft]); - } - if (rc <= 0) - /* 0 means connection closed; < 0 means severe error */ - error = true; - else - bytesLeft -= rc; - } - *failedP = error; -} - - - -static ChannelReadImpl channelRead; - -static void -channelRead(TChannel * const channelP, - unsigned char * const buffer, - uint32_t const bufferSize, - uint32_t * const bytesReceivedP, - bool * const failedP) { - - struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; - - int rc; - rc = SSL_read(channelOpenSslP->sslP, buffer, bufferSize); - - if (rc < 0) { - *failedP = true; - if (ChannelTraceIsActive) - fprintf(stderr, "Failed to receive data from OpenSSL connection. " - "SSL_read() failed with rc %d/%d\n", - rc, SSL_get_error(channelOpenSslP->sslP, rc)); - } else { - *failedP = false; - *bytesReceivedP = rc; - - if (ChannelTraceIsActive) - fprintf(stderr, "Abyss channel: read %u bytes: '%.*s'\n", - *bytesReceivedP, (int)(*bytesReceivedP), buffer); - } -} - - - -static ChannelWaitImpl channelWait; - -static void -channelWait(TChannel * const channelP ATTR_UNUSED, - bool const waitForRead ATTR_UNUSED, - bool const waitForWrite ATTR_UNUSED, - uint32_t const timeoutMs ATTR_UNUSED, - bool * const readyToReadP, - bool * const readyToWriteP, - bool * const failedP) { -/*---------------------------------------------------------------------------- - See socket_unix.c for an explanation of the purpose of this - subroutine. - - We don't actually fulfill that purpose, though, because we don't know - how yet. Instead, we return immediately and hope that if Caller - subsequently does a read or write, it blocks until it can do its thing. ------------------------------------------------------------------------------*/ - if (readyToReadP) - *readyToReadP = true; - if (readyToWriteP) - *readyToWriteP = true; - if (failedP) - *failedP = false; -} - - - -static ChannelInterruptImpl channelInterrupt; - -static void -channelInterrupt(TChannel * const channelP ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - Interrupt any waiting that a thread might be doing in channelWait() - now or in the future. ------------------------------------------------------------------------------*/ - - /* This is trivial, since channelWait() doesn't actually wait */ -} - - - -static ChannelFormatPeerInfoImpl channelFormatPeerInfo; - -static void -channelFormatPeerInfo(TChannel * const channelP, - const char ** const peerStringP) { - - struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; - - sockutil_formatPeerInfo(channelOpenSslP->fd, peerStringP); -} - - - -static struct TChannelVtbl const channelVtbl = { - &channelDestroy, - &channelWrite, - &channelRead, - &channelWait, - &channelInterrupt, - &channelFormatPeerInfo, -}; - - - -static void -getPeerAddrFromSsl(SSL * const sslP, - struct sockaddr * const peerAddrRetP, - size_t * const peerAddrLenRetP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - From the SSL connection with handle 'sslP', get the address (IP address, - normally) of the peer (the Abyss client). ------------------------------------------------------------------------------*/ - int const sockFd = SSL_get_fd(sslP); - - struct sockaddr * peerAddrP; - size_t peerAddrLen; - const char * error; - - sockutil_getPeerName(sockFd, &peerAddrP, &peerAddrLen, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Could not get identity of client. %s", - error); - xmlrpc_strfree(error); - } else { - *errorP = NULL; - *peerAddrLenRetP = peerAddrLen; - *peerAddrRetP = *peerAddrP; - - free(peerAddrP); - } -} - - - -static void -makeChannelInfo(struct abyss_openSsl_chaninfo ** const channelInfoPP, - SSL * const sslP, - const char ** const errorP) { - - struct abyss_openSsl_chaninfo * channelInfoP; - - MALLOCVAR(channelInfoP); - - if (channelInfoP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory"); - else { - channelInfoP->sslP = sslP; - - getPeerAddrFromSsl(sslP, - &channelInfoP->peerAddr, - &channelInfoP->peerAddrLen, - errorP); - - if (*errorP) - free(channelInfoP); - else - *channelInfoPP = channelInfoP; - } -} - - - -static void -makeChannelFromSsl(SSL * const sslP, - bool const userSuppliedSsl, - TChannel ** const channelPP, - const char ** const errorP) { - - struct ChannelOpenSsl * channelOpenSslP; - - MALLOCVAR(channelOpenSslP); - - if (channelOpenSslP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for OpenSSL " - "socket descriptor"); - else { - TChannel * channelP; - - channelOpenSslP->sslP = sslP; - channelOpenSslP->userSuppliedSsl = userSuppliedSsl; - - /* This should be ok as far as I can tell */ - ChannelCreate(&channelVtbl, channelOpenSslP, &channelP); - - if (channelP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for " - "channel descriptor."); - else { - *channelPP = channelP; - *errorP = NULL; - } - if (*errorP) - free(channelOpenSslP); - } -} - - - -void -ChannelOpenSslCreateSsl(SSL * const sslP, - TChannel ** const channelPP, - struct abyss_openSsl_chaninfo ** const channelInfoPP, - const char ** const errorP) { - - assert(sslP); - - makeChannelInfo(channelInfoPP, sslP, errorP); - if (!*errorP) { - bool const userSuppliedTrue = true; - - makeChannelFromSsl(sslP, userSuppliedTrue, channelPP, errorP); - - if (*errorP) { - free(*channelInfoPP); - } - } -} - - - -/*============================================================================= - TChanSwitch -=============================================================================*/ - -struct ChanSwitchOpenSsl { -/*---------------------------------------------------------------------------- - The properties/state of a TChanSwitch uniqe to the OpenSSL variety. - - Note that OpenSSL deals only in connected sockets, so this switch - doesn't really have anything to do with OpenSSL except that it - creates OpenSSL TChannels. The switch is just a POSIX listening - socket, and is almost identical to the Abyss Unix channel switch. ------------------------------------------------------------------------------*/ - int listenFd; - /* File descriptor of the POSIX socket (such as is created by - socket() in the C library) for the listening socket. - */ - bool userSuppliedFd; - /* The file descriptor and associated POSIX socket belong to the - user; we did not create it. - */ - SSL_CTX * sslCtxP; - /* The context in which we create all our OpenSSL connections */ - - sockutil_InterruptPipe interruptPipe; - /* We use this to interrupt a wait for the next client to arrive */ -}; - - - -static SwitchDestroyImpl chanSwitchDestroy; - -static void -chanSwitchDestroy(TChanSwitch * const chanSwitchP) { - - struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; - - sockutil_interruptPipeTerm(chanSwitchOpenSslP->interruptPipe); - - if (!chanSwitchOpenSslP->userSuppliedFd) - close(chanSwitchOpenSslP->listenFd); - - free(chanSwitchOpenSslP); -} - - - -static SwitchListenImpl chanSwitchListen; - -static void -chanSwitchListen(TChanSwitch * const chanSwitchP, - uint32_t const backlog, - const char ** const errorP) { - - struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; - - sockutil_listen(chanSwitchOpenSslP->listenFd, backlog, errorP); -} - - - -static void -createSslFromAcceptedConn(int const acceptedFd, - SSL_CTX * const sslCtxP, - SSL ** const sslPP, - const char ** const errorP) { - - SSL * sslP; - const char * error; - - sslCreate(sslCtxP, &sslP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Failed to create SSL connection " - "object. %s", error); - xmlrpc_strfree(error); - } else { - const char * error; - - sslSetFd(sslP, acceptedFd, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Failed to set file descriptor for SSL " - "connection. %s", error); - xmlrpc_strfree(error); - } else { - const char * error; - - sslAccept(sslP, &error); - - if (error) { - xmlrpc_asprintf(errorP, - "Failed to set up SSL communication on " - "working TCP connection. %s", error); - xmlrpc_strfree(error); - } else - *errorP = NULL; - } - if (*errorP) - SSL_free(sslP); - else { - *sslPP = sslP; - } - } -} - - - -static void -createChannelFromAcceptedConn(int const acceptedFd, - SSL_CTX * const sslCtxP, - TChannel ** const channelPP, - void ** const channelInfoPP, - const char ** const errorP) { - - struct ChannelOpenSsl * channelOpenSslP; - - MALLOCVAR(channelOpenSslP); - - if (!channelOpenSslP) - xmlrpc_asprintf(errorP, "Unable to allocate memory"); - else { - SSL * sslP; - const char * error; - - createSslFromAcceptedConn(acceptedFd, sslCtxP, &sslP, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Failed to create an OpenSSL connection " - "from the accepted TCP connection. %s", error); - xmlrpc_strfree(error); - } else { - struct abyss_openSsl_chaninfo * channelInfoP; - - makeChannelInfo(&channelInfoP, sslP, errorP); - if (!*errorP) { - bool const userSuppliedFalse = false; - - makeChannelFromSsl(sslP, userSuppliedFalse, - channelPP, errorP); - - if (*errorP) - free(channelInfoP); - else - *channelInfoPP = channelInfoP; - } - if (*errorP) - SSL_free(sslP); - else - channelOpenSslP->sslP = sslP; - } - if (*errorP) - free(channelOpenSslP); - } -} - - - -static SwitchAcceptImpl chanSwitchAccept; - -static void -chanSwitchAccept(TChanSwitch * const chanSwitchP, - TChannel ** const channelPP, - void ** const channelInfoPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Accept a connection via the channel switch *chanSwitchP. Return as - *channelPP the channel for the accepted connection. - - If no connection is waiting at *chanSwitchP, wait until one is. - - If we receive a signal while waiting, return immediately with - *channelPP == NULL. ------------------------------------------------------------------------------*/ - struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; - - bool interrupted; - TChannel * channelP; - - interrupted = false; /* Haven't been interrupted yet */ - channelP = NULL; /* No connection yet */ - *errorP = NULL; /* No error yet */ - - while (!channelP && !*errorP && !interrupted) { - struct sockaddr peerAddr; - socklen_t peerAddrLen; - int rc; - - peerAddrLen = sizeof(peerAddr); /* initial value */ - - rc = accept(chanSwitchOpenSslP->listenFd, &peerAddr, &peerAddrLen); - - if (rc >= 0) { - int const acceptedFd = rc; - - const char * error; - - createChannelFromAcceptedConn( - acceptedFd, chanSwitchOpenSslP->sslCtxP, - &channelP, channelInfoPP, &error); - - if (error) { - close(acceptedFd); - - if (SwitchTraceIsActive) - fprintf(stderr, - "Failed to create a channel from the " - "TCP connection we accepted. %s. " - "Closing TCP connection, waiting for the " - "next one\n", error); - xmlrpc_strfree(error); - } - } else if (errno == EINTR) - interrupted = true; - else - xmlrpc_asprintf(errorP, "accept() failed, errno = %d (%s)", - errno, strerror(errno)); - } - *channelPP = channelP; -} - - - -static SwitchInterruptImpl chanSwitchInterrupt; - -static void -chanSwitchInterrupt(TChanSwitch * const chanSwitchP) { -/*---------------------------------------------------------------------------- - Interrupt any waiting that a thread might be doing in chanSwitchAccept() - now or in the future. - - TODO: Make a way to reset this so that future chanSwitchAccept()s can once - again wait. ------------------------------------------------------------------------------*/ - struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; - - unsigned char const zero[1] = {0u}; - - write(chanSwitchOpenSslP->interruptPipe.interruptorFd, - &zero, sizeof(zero)); -} - - - -static struct TChanSwitchVtbl const chanSwitchVtbl = { - &chanSwitchDestroy, - &chanSwitchListen, - &chanSwitchAccept, - &chanSwitchInterrupt, -}; - - - -static void -createChanSwitch(int const fd, - bool const userSuppliedFd, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - struct ChanSwitchOpenSsl * chanSwitchOpenSslP; - - assert(!sockutil_connected(fd)); - - if (SwitchTraceIsActive) - fprintf(stderr, "Creating OpenSSL-based channel switch\n"); - - MALLOCVAR(chanSwitchOpenSslP); - - if (chanSwitchOpenSslP == NULL) - xmlrpc_asprintf(errorP, "unable to allocate memory for OpenSSL " - "channel switch descriptor."); - else { - TChanSwitch * chanSwitchP; - - chanSwitchOpenSslP->sslCtxP = sslCtxP; - - chanSwitchOpenSslP->listenFd = fd; - chanSwitchOpenSslP->userSuppliedFd = userSuppliedFd; - - sockutil_interruptPipeInit(&chanSwitchOpenSslP->interruptPipe, errorP); - - if (!*errorP) { - ChanSwitchCreate(&chanSwitchVtbl, chanSwitchOpenSslP, - &chanSwitchP); - if (*errorP) - sockutil_interruptPipeTerm(chanSwitchOpenSslP->interruptPipe); - - if (chanSwitchP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for " - "channel switch descriptor"); - else { - *chanSwitchPP = chanSwitchP; - *errorP = NULL; - } - } - if (*errorP) - free(chanSwitchOpenSslP); - } -} - - - -static void -switchCreateIpV4Port(unsigned short const portNumber, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Create a POSIX-socket-based channel switch for an IPv4 endpoint. - - Set the socket's local address so that a subsequent "listen" will listen on - all interfaces, port number 'portNumber'. ------------------------------------------------------------------------------*/ - int rc; - rc = socket(PF_INET, SOCK_STREAM, 0); - if (rc < 0) - xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - else { - int const socketFd = rc; - - sockutil_setSocketOptions(socketFd, errorP); - if (!*errorP) { - sockutil_bindSocketToPortInet(socketFd, portNumber, errorP); - - if (!*errorP) { - bool const userSupplied = false; - createChanSwitch(socketFd, userSupplied, sslCtxP, - chanSwitchPP, errorP); - } - } - if (*errorP) - close(socketFd); - } -} - - - -static void -switchCreateIpV6Port(unsigned short const portNumber, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Same as switchCreateIpV4Port(), except for IPv6. ------------------------------------------------------------------------------*/ - int rc; - rc = socket(PF_INET6, SOCK_STREAM, 0); - if (rc < 0) - xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - else { - int const socketFd = rc; - - sockutil_setSocketOptions(socketFd, errorP); - if (!*errorP) { - sockutil_bindSocketToPortInet6(socketFd, portNumber, errorP); - - if (!*errorP) { - bool const userSupplied = false; - createChanSwitch(socketFd, userSupplied, sslCtxP, - chanSwitchPP, errorP); - } - } - if (*errorP) - close(socketFd); - } -} - - - -void -ChanSwitchOpenSslCreate(int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - int rc; - rc = socket(protocolFamily, SOCK_STREAM, 0); - if (rc < 0) - xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - else { - int const socketFd = rc; - - if (SwitchTraceIsActive) - fprintf(stderr, "Created socket for protocol family %d\n", - protocolFamily); - - sockutil_setSocketOptions(socketFd, errorP); - if (!*errorP) { - sockutil_bindSocketToPort(socketFd, sockAddrP, sockAddrLen, - errorP); - - if (!*errorP) { - bool const userSupplied = false; - createChanSwitch(socketFd, userSupplied, sslCtxP, - chanSwitchPP, errorP); - } - } - if (*errorP) - close(socketFd); - } - -} - - - -void -ChanSwitchOpenSslCreateIpV4Port(unsigned short const portNumber, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - switchCreateIpV4Port(portNumber, sslCtxP, chanSwitchPP, errorP); -} - - - -void -ChanSwitchOpenSslCreateIpV6Port(unsigned short const portNumber, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - switchCreateIpV6Port(portNumber, sslCtxP, chanSwitchPP, errorP); -} - - - -void -ChanSwitchOpenSslCreateFd(int const fd, - SSL_CTX * const sslCtxP, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - if (sockutil_connected(fd)) - xmlrpc_asprintf(errorP, - "Socket (file descriptor %d) is in connected " - "state.", fd); - else { - bool const userSupplied = true; - createChanSwitch(fd, userSupplied, sslCtxP, chanSwitchPP, errorP); - } -} - - diff --git a/trunk/lib/abyss/src/socket_openssl.h b/trunk/lib/abyss/src/socket_openssl.h deleted file mode 100644 index a9662df65..000000000 --- a/trunk/lib/abyss/src/socket_openssl.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SOCKET_OPENSSL_H_INCLUDED -#define SOCKET_OPENSSL_H_INCLUDED - -#include - -#include - -void -SocketOpenSslInit(const char ** const errorP); - -void -SocketOpenSslTerm(void); - -#endif diff --git a/trunk/lib/abyss/src/socket_unix.c b/trunk/lib/abyss/src/socket_unix.c deleted file mode 100644 index 1848f6ac3..000000000 --- a/trunk/lib/abyss/src/socket_unix.c +++ /dev/null @@ -1,873 +0,0 @@ -/*============================================================================= - socket_unix.c -=============================================================================== - This is the implementation of TChanSwitch and TChannel (and - obsolete TSocket) for a standard Unix (POSIX) - stream socket -- what you create with a socket() C library call. -=============================================================================*/ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if HAVE_SYS_FILIO_H - #include -#endif - -#include "c_util.h" -#include "int.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "mallocvar.h" -#include "trace.h" -#include "chanswitch.h" -#include "channel.h" -#include "socket.h" -#include "netinet/in.h" -#include "xmlrpc-c/abyss.h" - -#include "sockutil.h" - -#include "socket_unix.h" - - - -struct socketUnix { -/*---------------------------------------------------------------------------- - The properties/state of a TChanSwitch or TChannel unique to the - Unix variety. ------------------------------------------------------------------------------*/ - int fd; - /* File descriptor of the POSIX socket (such as is created by - socket() in the C library) for the socket. - */ - bool userSuppliedFd; - /* The file descriptor and associated POSIX socket belong to the - user; we did not create it. - */ - sockutil_InterruptPipe interruptPipe; - - bool isListening; - /* We've done a 'listen' on the socket */ -}; - - - -void -SocketUnixInit(const char ** const errorP) { - - *errorP = NULL; -} - - - -void -SocketUnixTerm(void) { - -} - - - -/*============================================================================= - TChannel -=============================================================================*/ - -static void -channelDestroy(TChannel * const channelP) { - - struct socketUnix * const socketUnixP = channelP->implP; - - sockutil_interruptPipeTerm(socketUnixP->interruptPipe); - - if (!socketUnixP->userSuppliedFd) - close(socketUnixP->fd); - - free(socketUnixP); -} - - - -static ChannelWriteImpl channelWrite; - -static void -channelWrite(TChannel * const channelP, - const unsigned char * const buffer, - uint32_t const len, - bool * const failedP) { - - struct socketUnix * const socketUnixP = channelP->implP; - - size_t bytesLeft; - bool error; - - assert(sizeof(size_t) >= sizeof(len)); - - for (bytesLeft = len, error = false; - bytesLeft > 0 && !error; - ) { - size_t const maxSend = (size_t)(-1) >> 1; - - ssize_t rc; - - // We'd like to use MSG_NOSIGNAL here, to prevent this send() from - // causing a SIGPIPE if the other end of the socket is closed, but - // MSG_NOSIGNAL is not standard enough. An SO_NOSIGPIPE socket - // option is another way, but even less standard. So instead, the - // thread simply must be set to ignore SIGPIPE. - - rc = send(socketUnixP->fd, &buffer[len-bytesLeft], - MIN(maxSend, bytesLeft), 0); - - if (ChannelTraceIsActive) { - if (rc < 0) - fprintf(stderr, "Abyss channel: send() failed. errno=%d (%s)", - errno, strerror(errno)); - else if (rc == 0) - fprintf(stderr, "Abyss channel: send() failed. " - "Socket closed.\n"); - else { - size_t const bytesTransferred = rc; - fprintf(stderr, "Abyss channel: sent %u bytes: '%.*s'\n", - (unsigned)bytesTransferred, - (int)(MIN(bytesTransferred, 4096)), - &buffer[len-bytesLeft]); - } - } - if (rc <= 0) - /* 0 means connection closed; < 0 means severe error */ - error = true; - else - bytesLeft -= rc; - } - *failedP = error; -} - - - -static ChannelReadImpl channelRead; - -static void -channelRead(TChannel * const channelP, - unsigned char * const buffer, - uint32_t const bufferSize, - uint32_t * const bytesReceivedP, - bool * const failedP) { - - struct socketUnix * const socketUnixP = channelP->implP; - - int rc; - rc = recv(socketUnixP->fd, buffer, bufferSize, 0); - - if (rc < 0) { - *failedP = true; - if (ChannelTraceIsActive) - fprintf(stderr, "Abyss channel: " - "Failed to receive data from socket. " - "recv() failed with errno %d (%s)\n", - errno, strerror(errno)); - } else { - *failedP = false; - *bytesReceivedP = rc; - - if (ChannelTraceIsActive) - fprintf(stderr, "Abyss channel: read %u bytes: '%.*s'\n", - *bytesReceivedP, (int)(*bytesReceivedP), buffer); - } -} - - - -static ChannelWaitImpl channelWait; - -static void -channelWait(TChannel * const channelP, - bool const waitForRead, - bool const waitForWrite, - uint32_t const timeoutMs, - bool * const readyToReadP, - bool * const readyToWriteP, - bool * const failedP) { -/*---------------------------------------------------------------------------- - Wait for the channel to be immediately readable or writable. - - Readable means there is at least one byte of data to read or the - partner has disconnected. Writable means the channel will take at - least one byte of data to send or the partner has disconnected. - - 'waitForRead' and 'waitForWrite' determine which of these - conditions for which to wait; if both are true, we wait for either - one. - - We return before the requested condition holds if 'timeoutMs' - milliseconds pass. timeoutMs == TIME_INFINITE means infinity. - - We return before the requested condition holds if the process receives - (and catches) a signal, but only if it receives that signal a certain - time after we start running. (That means this function isn't useful - for most purposes). - - Return *readyToReadP == true if the reason for returning is that - the channel is immediately readable. But only if 'readyToReadP' is - non-null. *readyToWriteP is analogous - for writable. Both may be true. - - Return *failedP true iff we fail to wait for the requested condition - because of some unusual problem and 'failedP' is non-null. Being - interrupted by a signal is not a failure. - - If one of these return value pointers is NULL, don't return that - value. ------------------------------------------------------------------------------*/ - struct socketUnix * const socketUnixP = channelP->implP; - - /* Design note: some old systems may not have poll(). We're assuming - that we don't have to run on any such system. select() is more - universal, but can't handle a file descriptor with a high number. - - pselect() and ppoll() would allow us to be properly - interruptible by a signal -- we would add a signal mask to our - arguments. But ppoll() is fairly rare. pselect() is more - common, but in older Linux systems it doesn't actually work. - */ - bool readyToRead, readyToWrite, failed; - struct pollfd pollfds[2]; - int rc; - - pollfds[0].fd = socketUnixP->fd; - pollfds[0].events = - (waitForRead ? POLLIN : 0) | - (waitForWrite ? POLLOUT : 0); - - pollfds[1].fd = socketUnixP->interruptPipe.interrupteeFd; - pollfds[1].events = POLLIN; - - rc = poll(pollfds, ARRAY_SIZE(pollfds), - timeoutMs == TIME_INFINITE ? -1 : (int)timeoutMs); - - if (rc < 0) { - if (errno == EINTR) { - failed = false; - readyToRead = false; - readyToWrite = false; - } else { - failed = true; - readyToRead = false; /* quiet compiler warning */ - readyToWrite = false; /* quiet compiler warning */ - } - } else { - failed = false; - readyToRead = !!(pollfds[0].revents & POLLIN); - readyToWrite = !!(pollfds[0].revents & POLLOUT); - } - - if (failedP) - *failedP = failed; - if (readyToReadP) - *readyToReadP = readyToRead; - if (readyToWriteP) - *readyToWriteP = readyToWrite; -} - - - -static ChannelInterruptImpl channelInterrupt; - -static void -channelInterrupt(TChannel * const channelP) { -/*---------------------------------------------------------------------------- - Interrupt any waiting that a thread might be doing in channelWait() - now or in the future. - - TODO: Make a way to reset this so that future channelWait()s can once - again wait. ------------------------------------------------------------------------------*/ - struct socketUnix * const socketUnixP = channelP->implP; - - sockutil_interruptPipeInterrupt(socketUnixP->interruptPipe); -} - - - -void -ChannelUnixGetPeerName(TChannel * const channelP, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP) { - - struct socketUnix * const socketUnixP = channelP->implP; - - sockutil_getPeerName(socketUnixP->fd, sockaddrPP, sockaddrLenP, errorP); -} - - - -static ChannelFormatPeerInfoImpl channelFormatPeerInfo; - -static void -channelFormatPeerInfo(TChannel * const channelP, - const char ** const peerStringP) { - - struct socketUnix * const socketUnixP = channelP->implP; - - sockutil_formatPeerInfo(socketUnixP->fd, peerStringP); -} - - - -static struct TChannelVtbl const channelVtbl = { - &channelDestroy, - &channelWrite, - &channelRead, - &channelWait, - &channelInterrupt, - &channelFormatPeerInfo, -}; - - - -static void -makeChannelInfo(struct abyss_unix_chaninfo ** const channelInfoPP, - struct sockaddr const peerAddr, - socklen_t const peerAddrLen, - const char ** const errorP) { - - struct abyss_unix_chaninfo * channelInfoP; - - MALLOCVAR(channelInfoP); - - if (channelInfoP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory"); - else { - channelInfoP->peerAddrLen = peerAddrLen; - channelInfoP->peerAddr = peerAddr; - - *errorP = NULL; - } - *channelInfoPP = channelInfoP; -} - - - -static void -makeChannelFromFd(int const fd, - TChannel ** const channelPP, - const char ** const errorP) { - - struct socketUnix * socketUnixP; - - MALLOCVAR(socketUnixP); - - if (socketUnixP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for Unix " - "channel descriptor"); - else { - TChannel * channelP; - - socketUnixP->fd = fd; - socketUnixP->userSuppliedFd = true; - - sockutil_interruptPipeInit(&socketUnixP->interruptPipe, errorP); - - if (!*errorP) { - ChannelCreate(&channelVtbl, socketUnixP, &channelP); - - if (channelP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for " - "channel descriptor."); - else { - *channelPP = channelP; - *errorP = NULL; - } - if (*errorP) - sockutil_interruptPipeTerm(socketUnixP->interruptPipe); - } - if (*errorP) - free(socketUnixP); - } -} - - - -void -ChannelUnixCreateFd(int const fd, - TChannel ** const channelPP, - struct abyss_unix_chaninfo ** const channelInfoPP, - const char ** const errorP) { - - if (!sockutil_connected(fd)) - xmlrpc_asprintf(errorP, "Socket on file descriptor %d is not in " - "connected state.", fd); - else { - struct sockaddr * peerAddrP; - size_t peerAddrLen; - const char * error; - - sockutil_getPeerName(fd, &peerAddrP, &peerAddrLen, &error); - - if (error) { - xmlrpc_asprintf(errorP, "Failed to get identity of client. %s", - error); - xmlrpc_strfree(error); - } else { - makeChannelInfo(channelInfoPP, *peerAddrP, peerAddrLen, errorP); - if (!*errorP) { - makeChannelFromFd(fd, channelPP, errorP); - - if (*errorP) - free(*channelInfoPP); - } - free(peerAddrP); - } - } -} - - - -/*============================================================================= - TChanSwitch -=============================================================================*/ - -static SwitchDestroyImpl chanSwitchDestroy; - -static void -chanSwitchDestroy(TChanSwitch * const chanSwitchP) { - - struct socketUnix * const socketUnixP = chanSwitchP->implP; - - sockutil_interruptPipeTerm(socketUnixP->interruptPipe); - - if (!socketUnixP->userSuppliedFd) - close(socketUnixP->fd); - - free(socketUnixP); -} - - - -static SwitchListenImpl chanSwitchListen; - -static void -chanSwitchListen(TChanSwitch * const chanSwitchP, - uint32_t const backlog, - const char ** const errorP) { - - struct socketUnix * const socketUnixP = chanSwitchP->implP; - - if (socketUnixP->isListening) - xmlrpc_asprintf(errorP, "Channel switch is already listening"); - else { - sockutil_listen(socketUnixP->fd, backlog, errorP); - - if (!*errorP) - socketUnixP->isListening = true; - } -} - - - -static void -createChannelForAccept(int const acceptedFd, - struct sockaddr const peerAddr, - TChannel ** const channelPP, - void ** const channelInfoPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Make a channel object (TChannel) out of a socket just created by - accept() on a listening socket -- i.e. a socket for a client connection. - - 'acceptedFd' is the file descriptor of the socket. - - 'peerAddr' is the address of the client, from accept(). ------------------------------------------------------------------------------*/ - struct abyss_unix_chaninfo * channelInfoP; - - makeChannelInfo(&channelInfoP, peerAddr, sizeof(peerAddr), errorP); - if (!*errorP) { - struct socketUnix * acceptedSocketP; - - MALLOCVAR(acceptedSocketP); - - if (!acceptedSocketP) - xmlrpc_asprintf(errorP, "Unable to allocate memory"); - else { - acceptedSocketP->fd = acceptedFd; - acceptedSocketP->userSuppliedFd = false; - - sockutil_interruptPipeInit( - &acceptedSocketP->interruptPipe, errorP); - - if (!*errorP) { - TChannel * channelP; - - ChannelCreate(&channelVtbl, acceptedSocketP, &channelP); - if (!channelP) - xmlrpc_asprintf(errorP, - "Failed to create TChannel object."); - else { - *errorP = NULL; - *channelPP = channelP; - *channelInfoPP = channelInfoP; - } - if (*errorP) - sockutil_interruptPipeTerm(acceptedSocketP->interruptPipe); - } - if (*errorP) - free(acceptedSocketP); - } - if (*errorP) - free(channelInfoP); - } -} - - - -static SwitchAcceptImpl chanSwitchAccept; - -static void -chanSwitchAccept(TChanSwitch * const chanSwitchP, - TChannel ** const channelPP, - void ** const channelInfoPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Accept a connection via the channel switch *chanSwitchP. Return as - *channelPP the channel for the accepted connection. - - If no connection is waiting at *chanSwitchP, wait until one is. - - If we receive a signal while waiting, return immediately with - *channelPP == NULL. ------------------------------------------------------------------------------*/ - struct socketUnix * const listenSocketP = chanSwitchP->implP; - - bool interrupted; - TChannel * channelP; - - interrupted = false; /* Haven't been interrupted yet */ - channelP = NULL; /* No connection yet */ - *errorP = NULL; /* No error yet */ - - while (!channelP && !*errorP && !interrupted) { - - sockutil_waitForConnection(listenSocketP->fd, - listenSocketP->interruptPipe, - &interrupted, errorP); - - if (!*errorP && !interrupted) { - struct sockaddr peerAddr; - socklen_t peerAddrLen; - int rc; - - peerAddrLen = sizeof(peerAddr); /* initial value */ - - rc = accept(listenSocketP->fd, &peerAddr, &peerAddrLen); - - if (rc >= 0) { - int const acceptedFd = rc; - - createChannelForAccept(acceptedFd, peerAddr, - &channelP, channelInfoPP, errorP); - - if (*errorP) - close(acceptedFd); - } else if (errno == EINTR) - interrupted = true; - else - xmlrpc_asprintf(errorP, "accept() failed, errno = %d (%s)", - errno, strerror(errno)); - } - } - *channelPP = channelP; -} - - - -static SwitchInterruptImpl chanSwitchInterrupt; - -static void -chanSwitchInterrupt(TChanSwitch * const chanSwitchP) { -/*---------------------------------------------------------------------------- - Interrupt any waiting that a thread might be doing in chanSwitchAccept() - now or in the future. - - TODO: Make a way to reset this so that future chanSwitchAccept()s can once - again wait. ------------------------------------------------------------------------------*/ - struct socketUnix * const listenSocketP = chanSwitchP->implP; - - unsigned char const zero[1] = {0u}; - - write(listenSocketP->interruptPipe.interruptorFd, &zero, sizeof(zero)); -} - - - -static struct TChanSwitchVtbl const chanSwitchVtbl = { - &chanSwitchDestroy, - &chanSwitchListen, - &chanSwitchAccept, - &chanSwitchInterrupt, -}; - - - -static void -createChanSwitch(int const fd, - bool const userSuppliedFd, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Create a channel switch from the bound, but not yet listening, socket - with file descriptor 'fd'. - - Return the handle of the new channel switch as *chanSwitchPP. - - 'userSuppliedFd' means the file descriptor (socket) shall _not_ belong to - the channel switch, so destroying the channel switch does not close it. ------------------------------------------------------------------------------*/ - struct socketUnix * socketUnixP; - - assert(!sockutil_connected(fd)); - - if (SwitchTraceIsActive) - fprintf(stderr, "Creating Unix listen-socket based channel switch\n"); - - MALLOCVAR(socketUnixP); - - if (socketUnixP == NULL) - xmlrpc_asprintf(errorP, "unable to allocate memory for Unix " - "channel switch descriptor."); - else { - TChanSwitch * chanSwitchP; - - socketUnixP->fd = fd; - socketUnixP->userSuppliedFd = userSuppliedFd; - socketUnixP->isListening = false; - - sockutil_interruptPipeInit(&socketUnixP->interruptPipe, errorP); - - if (!*errorP) { - ChanSwitchCreate(&chanSwitchVtbl, socketUnixP, &chanSwitchP); - if (*errorP) - sockutil_interruptPipeTerm(socketUnixP->interruptPipe); - - if (chanSwitchP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for " - "channel switch descriptor"); - else { - *chanSwitchPP = chanSwitchP; - *errorP = NULL; - } - } - if (*errorP) - free(socketUnixP); - } -} - - - -static void -switchCreateIpV4Port(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Create a POSIX-socket-based channel switch for an IPv4 endpoint. - - Set the socket's local address so that a subsequent "listen" will listen on - all interfaces, port number 'portNumber'. ------------------------------------------------------------------------------*/ - int rc; - rc = socket(PF_INET, SOCK_STREAM, 0); - if (rc < 0) - xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - else { - int const socketFd = rc; - - sockutil_setSocketOptions(socketFd, errorP); - if (!*errorP) { - sockutil_bindSocketToPortInet(socketFd, portNumber, errorP); - - if (!*errorP) { - bool const userSupplied = false; - createChanSwitch(socketFd, userSupplied, chanSwitchPP, errorP); - } - } - if (*errorP) - close(socketFd); - } -} - - - -static void -switchCreateIpV6Port(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Same as switchCreateIpV4Port(), except for IPv6. ------------------------------------------------------------------------------*/ - int rc; - rc = socket(PF_INET6, SOCK_STREAM, 0); - if (rc < 0) - xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - else { - int const socketFd = rc; - - sockutil_setSocketOptions(socketFd, errorP); - if (!*errorP) { - sockutil_bindSocketToPortInet6(socketFd, portNumber, errorP); - - if (!*errorP) { - bool const userSupplied = false; - createChanSwitch(socketFd, userSupplied, chanSwitchPP, errorP); - } - } - if (*errorP) - close(socketFd); - } -} - - - -void -ChanSwitchUnixCreate(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - switchCreateIpV4Port(portNumber, chanSwitchPP, errorP); -} - - - -void -ChanSwitchUnixCreate2(int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - int rc; - rc = socket(protocolFamily, SOCK_STREAM, 0); - if (rc < 0) - xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - else { - int const socketFd = rc; - - if (SwitchTraceIsActive) - fprintf(stderr, "Created socket for protocol family %d\n", - protocolFamily); - - sockutil_setSocketOptions(socketFd, errorP); - if (!*errorP) { - sockutil_bindSocketToPort(socketFd, sockAddrP, sockAddrLen, - errorP); - - if (!*errorP) { - bool const userSupplied = false; - createChanSwitch(socketFd, userSupplied, chanSwitchPP, errorP); - } - } - if (*errorP) - close(socketFd); - } - -} - - - -void -ChanSwitchUnixCreateIpV6Port(unsigned short const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - switchCreateIpV6Port(portNumber, chanSwitchPP, errorP); -} - - - -void -ChanSwitchUnixCreateFd(int const fd, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - if (sockutil_connected(fd)) - xmlrpc_asprintf(errorP, - "Socket (file descriptor %d) is in connected " - "state.", fd); - else { - bool const userSupplied = true; - createChanSwitch(fd, userSupplied, chanSwitchPP, errorP); - } -} - - - -void -ChanSwitchUnixGetListenName(TChanSwitch * const chanSwitchP, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - The primary case where this is useful is where the user created the channel - switch with a parameters telling the OS to pick the TCP port. In that - case, this is the only way the user can find out what port the OS picked. ------------------------------------------------------------------------------*/ - struct socketUnix * const socketUnixP = chanSwitchP->implP; - - if (!socketUnixP->isListening) - xmlrpc_asprintf(errorP, "Channel Switch is not listening"); - else - sockutil_getSockName(socketUnixP->fd, - sockaddrPP, sockaddrLenP, errorP); -} - - - -/*============================================================================= - obsolete TSocket interface -=============================================================================*/ - - -void -SocketUnixCreateFd(int const fd, - TSocket ** const socketPP) { - - TSocket * socketP; - const char * error; - - if (sockutil_connected(fd)) { - TChannel * channelP; - struct abyss_unix_chaninfo * channelInfoP; - ChannelUnixCreateFd(fd, &channelP, &channelInfoP, &error); - if (!error) - SocketCreateChannel(channelP, channelInfoP, &socketP); - } else { - TChanSwitch * chanSwitchP; - ChanSwitchUnixCreateFd(fd, &chanSwitchP, &error); - if (!error) - SocketCreateChanSwitch(chanSwitchP, &socketP); - } - if (error) { - *socketPP = NULL; - xmlrpc_strfree(error); - } else - *socketPP = socketP; -} - - - diff --git a/trunk/lib/abyss/src/socket_unix.h b/trunk/lib/abyss/src/socket_unix.h deleted file mode 100644 index 40094e306..000000000 --- a/trunk/lib/abyss/src/socket_unix.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SOCKET_UNIX_H_INCLUDED -#define SOCKET_UNIX_H_INCLUDED - -#include - -#include - -void -SocketUnixInit(const char ** const errorP); - -void -SocketUnixTerm(void); - -#endif diff --git a/trunk/lib/abyss/src/socket_win.c b/trunk/lib/abyss/src/socket_win.c deleted file mode 100644 index 3204a60c1..000000000 --- a/trunk/lib/abyss/src/socket_win.c +++ /dev/null @@ -1,1083 +0,0 @@ -/*============================================================================= - socket_win.c -=============================================================================== - This is the implementation of TChanSwitch and TChannel - for a Winsock socket. -=============================================================================*/ - -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "mallocvar.h" -#include "trace.h" -#include "chanswitch.h" -#include "channel.h" -#include "socket.h" -#include "xmlrpc-c/abyss.h" - -#include "socket_win.h" - -#ifndef socklen_t -typedef int socklen_t; -#endif - -/* ============================================================= - Provided nice error strings, NOT available in system errors. - ============================================================= */ - -typedef struct tagSOCKERRS { - int err; // WSAGetLastError() value - char * desc; // description of error -} SOCKERR; - -/* could/should perhaps be by the actual call, - but for now, just one big list, with some repeats -*/ - -SOCKERR sSockErr[] = { - { WSANOTINITIALISED, - "WSANOTINITIALISED - " - "WSAStartup must be called before using this function." }, - { WSAENETDOWN, - "WSAENETDOWN - " - "The network subsystem has failed." }, - { WSAEACCES, - "WSAEACCES - " - "Attempt to connect datagram socket to broadcast address failed " - "because setsockopt option SO_BROADCAST is not enabled." }, - { WSAEADDRINUSE, - "WSAEADDRINUSE - " - "A process on the computer is already bound to the same fully-qualified " - "address and the socket has not been marked to allow address reuse with " - "SO_REUSEADDR. For example, the IP address and port are bound in the " - "af_inet case). (See the SO_REUSEADDR socket option under setsockopt.)" }, - { WSAEADDRNOTAVAIL, - "WSAEADDRNOTAVAIL - " - "The specified address is not a valid address for this computer." }, - { WSAEFAULT, - "WSAEFAULT - " - "The name or namelen parameter is not a valid part of the user " - "address space, the namelen parameter is too small, the name parameter " - "contains an incorrect address format for the associated " - "address family, or the first two bytes of the memory block " - "specified by name does not match the address family associated with " - "the socket descriptor s." }, - { WSAEINPROGRESS, - "WSAEINPROGRESS - " - "A blocking Windows Sockets 1.1 call is in progress, or the " - "service provider is still processing a callback function." }, - { WSAEINVAL, - "WSAEINVAL - " - "The socket is already bound to an address." }, - { WSAENOBUFS, - "WSAENOBUFS - " - "Not enough buffers available, too many connections." }, - { WSAENOTSOCK, - "WSAENOTSOCK - " - "The descriptor is not a socket." }, - - // setsocketopt - { WSAENETRESET, - "WSAENETRESET - " - "Connection has timed out when SO_KEEPALIVE is set." }, - { WSAENOPROTOOPT, - "WSAENOPROTOOPT - " - "The option is unknown or the specified provider " - "or socket is not capable of implementing it " - "(see SO_GROUP_PRIORITY limitations)." }, - { WSAENOTCONN, - "WSAENOTCONN - " - "Connection has been reset when SO_KEEPALIVE is set." }, - - // WSAStartup - { WSASYSNOTREADY, - "WSASYSNOTREADY - " - "The underlying network subsystem is not ready for " - "network communication." }, - { WSAVERNOTSUPPORTED, - "WSAVERNOTSUPPORTED - " - "The version of Windows Sockets function requested is not provided " - "by this particular Windows Sockets implementation." }, - { WSAEINPROGRESS, - "WSAEINPROGRESS - " - "A blocking Windows Sockets 1.1 operation is in progress." }, - { WSAEPROCLIM, - "WSAEPROCLIM - " - "Limit on the number of tasks allowed by the Windows Sockets " - "implementation has been reached." }, - { WSAEFAULT, - "WSAEFAULT - " - "The lpWSAData is not a valid pointer." }, - // listen - { WSANOTINITIALISED, - "WSANOTINITIALISED - " - "A successful WSAStartup call must occur before using this function." }, - { WSAENETDOWN, - "WSAENETDOWN - " - "The network subsystem has failed." }, - { WSAEADDRINUSE, - "WSAEADDRINUSE - " - "The socket's local address is already in use and the socket " - "was not marked to allow address reuse with SO_REUSEADDR. " - "This error usually occurs during execution of the bind function, " - "but could be delayed until this function if the bind was to " - "a partially wildcard address (involving ADDR_ANY) " - "and if a specific address needs to be committed at the time " - "of this function call." }, - { WSAEINPROGRESS, - "WSAEINPROGRESS - " - "A blocking Windows Sockets 1.1 call is in progress, " - "or the service provider is still processing a callback function." }, - { WSAEINVAL, - "WSAEINVAL - " - "The socket has not been bound with bind." }, - { WSAEISCONN, - "WSAEISCONN - " - "The socket is already connected." }, - { WSAEMFILE, - "WSAEMFILE - " - "No more socket descriptors are available." }, - { WSAENOBUFS, - "WSAENOBUFS - " - "No buffer space is available." }, - { WSAENOTSOCK, - "WSAENOTSOCK - " - "The descriptor is not a socket." }, - { WSAEOPNOTSUPP, - "WSAEOPNOTSUPP - " - "The referenced socket is not of a type that has a listen operation." }, - - // getpeername - { WSANOTINITIALISED, - "WSANOTINITIALISED - " - "A successful WSAStartup call must occur before using this function." }, - { WSAENETDOWN, - "WSAENETDOWN - " - "The network subsystem has failed." }, - { WSAEFAULT, - "WSAEFAULT - " - "The name or the namelen parameter is not a valid part of the " - "user address space, or the namelen parameter is too small." }, - { WSAEINPROGRESS, - "WSAEINPROGRESS - " - "A blocking Windows Sockets 1.1 call is in progress, " - "or the service provider is still processing a callback function." }, - { WSAENOTCONN, - "WSAENOTCONN - " - "The socket is not connected." }, - { WSAENOTSOCK, - "WSAENOTSOCK - " - "The descriptor is not a socket." }, - - // accept - { WSANOTINITIALISED, - "WSANOTINITIALISED - " - "A successful WSAStartup call must occur before using this function." }, - { WSAENETDOWN, - "WSAENETDOWN - " - "The network subsystem has failed." }, - { WSAEFAULT, - "WSAEFAULT - " - "The addrlen parameter is too small or addr is not a valid part " - "of the user address space." }, - { WSAEINTR, - "WSAEINTR - " - "A blocking Windows Sockets 1.1 call was canceled through " - "WSACancelBlockingCall." }, - { WSAEINPROGRESS, - "WSAEINPROGRESS - " - "A blocking Windows Sockets 1.1 call is in progress, " - "or the service provider is still processing a callback function." }, - { WSAEINVAL, - "WSAEINVAL - " - "The listen function was not invoked prior to accept." }, - { WSAEMFILE, - "WSAEMFILE - " - "The queue is nonempty upon entry to accept and " - "there are no descriptors available." }, - { WSAENOBUFS, - "WSAENOBUFS - " - "No buffer space is available." }, - { WSAENOTSOCK, - "WSAENOTSOCK - " - "The descriptor is not a socket." }, - { WSAEOPNOTSUPP, - "WSAEOPNOTSUPP - " - "The referenced socket is not a type that offers connection-oriented " - "service." }, - { WSAEWOULDBLOCK, - "WSAEWOULDBLOCK - " - "The socket is marked as nonblocking and no connections are present " - "to be accepted." }, - - /* must be last entry */ - { 0, 0 } -}; - - - -static const char * -getWSAError(int const wsaErrno) { - - SOCKERR * pseP; - - pseP = &sSockErr[0]; // initial value - - while (pseP->desc) { - if (pseP->err == wsaErrno) - return pseP->desc; - - ++pseP; - } - - return "(no description available)"; -} - - - -struct socketWin { -/*---------------------------------------------------------------------------- - The properties/state of a TSocket unique to a Unix TSocket. ------------------------------------------------------------------------------*/ - SOCKET winsock; - bool userSuppliedWinsock; - /* 'socket' was supplied by the user; it belongs to him */ - HANDLE interruptEvent; -}; - -static -bool -connected(SOCKET const fd) { -/*---------------------------------------------------------------------------- - Return TRUE iff the socket on file descriptor 'fd' is in the connected - state. - If 'fd' does not identify a stream socket or we are unable to determine - the state of the stream socket, the answer is "false". ------------------------------------------------------------------------------*/ - bool connected; - struct sockaddr sockaddr; - socklen_t nameLen; - int rc; - - nameLen = sizeof(sockaddr); - - rc = getpeername(fd, &sockaddr, &nameLen); - - if (rc == 0) - connected = TRUE; - else - connected = FALSE; - - return connected; -} - - - -void -SocketWinInit(const char ** const errorP) { - - WORD wVersionRequested; - WSADATA wsaData; - int err; - - wVersionRequested = MAKEWORD(1, 0); - - err = WSAStartup(wVersionRequested, &wsaData); - - if (err != 0) { - int const lastError = WSAGetLastError(); - xmlrpc_asprintf(errorP, "WSAStartup() faild with error %d (%s)", - lastError, getWSAError(lastError)); - } else - *errorP = NULL; -} - - - -void -SocketWinTerm(void) { - - WSACleanup(); -} - - - -/*============================================================================= - TChannel -=============================================================================*/ - -static ChannelDestroyImpl channelDestroy; - -static void -channelDestroy(TChannel * const channelP) { - - struct socketWin * const socketWinP = channelP->implP; - - if (!socketWinP->userSuppliedWinsock) - closesocket(socketWinP->winsock); - - CloseHandle(socketWinP->interruptEvent); - - free(socketWinP); -} - - - -static ChannelWriteImpl channelWrite; - -static void -channelWrite(TChannel * const channelP, - const unsigned char * const buffer, - uint32_t const len, - bool * const failedP) { - - struct socketWin * const socketWinP = channelP->implP; - - size_t bytesLeft; - bool error; - - assert(sizeof(size_t) >= sizeof(len)); - - for (bytesLeft = len, error = FALSE; - bytesLeft > 0 && !error; - ) { - size_t const maxSend = (size_t)(-1) >> 1; - - int rc; - - rc = send(socketWinP->winsock, &buffer[len-bytesLeft], - MIN(maxSend, bytesLeft), 0); - - if (rc <= 0) - /* 0 means connection closed; < 0 means severe error */ - error = TRUE; - else - bytesLeft -= rc; - } - *failedP = error; -} - - - -static ChannelReadImpl channelRead; - -static void -channelRead(TChannel * const channelP, - unsigned char * const buffer, - uint32_t const bufferSize, - uint32_t * const bytesReceivedP, - bool * const failedP) { - - struct socketWin * const socketWinP = channelP->implP; - - int rc; - rc = recv(socketWinP->winsock, buffer, bufferSize, 0); - - if (rc < 0) { - *failedP = TRUE; - } else { - *failedP = FALSE; - *bytesReceivedP = rc; - } -} - - - -static ChannelWaitImpl channelWait; - -static void -channelWait(TChannel * const channelP, - bool const waitForRead, - bool const waitForWrite, - uint32_t const timems, - bool * const readyToReadP, - bool * const readyToWriteP, - bool * const failedP) { - - struct socketWin * const socketWinP = channelP->implP; - - fd_set rfds, wfds; - TIMEVAL tv; - bool failed, readRdy, writeRdy, timedOut; - - FD_ZERO(&rfds); - FD_ZERO(&wfds); - - if (waitForRead) - FD_SET(socketWinP->winsock, &rfds); - - if (waitForWrite) - FD_SET(socketWinP->winsock, &wfds); - - tv.tv_sec = timems / 1000; - tv.tv_usec = timems % 1000; - - for (failed = FALSE, readRdy = FALSE, writeRdy = FALSE, timedOut = FALSE; - !failed && !readRdy && !writeRdy && !timedOut; - ) { - - int rc; - - rc = select(socketWinP->winsock + 1, &rfds, &wfds, NULL, - (timems == TIME_INFINITE ? NULL : &tv)); - - switch(rc) { - case 0: - timedOut = TRUE; - break; - case -1: /* socket error */ - if (WSAGetLastError() != WSAEINTR) - failed = TRUE; - break; - default: - if (FD_ISSET(socketWinP->winsock, &rfds)) - readRdy = TRUE; - if (FD_ISSET(socketWinP->winsock, &wfds)) - writeRdy = TRUE; - } - } - - if (failedP) - *failedP = failed; - if (readyToReadP) - *readyToReadP = readRdy; - if (readyToWriteP) - *readyToWriteP = writeRdy; -} - - - -static ChannelInterruptImpl channelInterrupt; - -static void -channelInterrupt(TChannel * const channelP) { -/*---------------------------------------------------------------------------- - Interrupt any waiting that a thread might be doing in channelWait() - now or in the future. - - Actually, this is just a no-op because we don't yet know how to - accomplish that. (But we could probably do it the same way - chanSwitchInterrupt() works -- no one has needed it enough yet to do that - work). ------------------------------------------------------------------------------*/ - -} - - - -void -ChannelWinGetPeerName(TChannel * const channelP, - struct sockaddr_in * const inAddrP, - const char ** const errorP) { - - struct socketWin * const socketWinP = channelP->implP; - - socklen_t addrlen; - int rc; - struct sockaddr sockAddr; - - addrlen = sizeof(sockAddr); - - rc = getpeername(socketWinP->winsock, &sockAddr, &addrlen); - - if (rc != 0) { - int const lastError = WSAGetLastError(); - xmlrpc_asprintf(errorP, "getpeername() failed. WSA error = %d (%s)", - lastError, getWSAError(lastError)); - } else { - if (addrlen != sizeof(sockAddr)) - xmlrpc_asprintf(errorP, "getpeername() returned a socket address " - "of the wrong size: %u. Expected %u", - addrlen, sizeof(sockAddr)); - else { - if (sockAddr.sa_family != AF_INET) - xmlrpc_asprintf(errorP, - "Socket does not use the Inet (IP) address " - "family. Instead it uses family %d", - sockAddr.sa_family); - else { - *inAddrP = *(struct sockaddr_in *)&sockAddr; - - *errorP = NULL; - } - } - } -} - - - -static ChannelFormatPeerInfoImpl channelFormatPeerInfo; - -static void -channelFormatPeerInfo(TChannel * const channelP, - const char ** const peerStringP) { - - struct socketWin * const socketWinP = channelP->implP; - - struct sockaddr sockaddr; - socklen_t sockaddrLen; - int rc; - - sockaddrLen = sizeof(sockaddr); - - rc = getpeername(socketWinP->winsock, &sockaddr, &sockaddrLen); - - if (rc != 0) { - int const lastError = WSAGetLastError(); - xmlrpc_asprintf(peerStringP, "?? getpeername() failed. " - "WSAERROR %d (%s)", - lastError, getWSAError(lastError)); - } else { - switch (sockaddr.sa_family) { - case AF_INET: { - struct sockaddr_in * const sockaddrInP = - (struct sockaddr_in *) &sockaddr; - if (sockaddrLen < sizeof(*sockaddrInP)) - xmlrpc_asprintf(peerStringP, "??? getpeername() returned " - "the wrong size"); - else { - unsigned char * const ipaddr = (unsigned char *) - &sockaddrInP->sin_addr.s_addr; - xmlrpc_asprintf(peerStringP, "%u.%u.%u.%u:%hu", - ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], - sockaddrInP->sin_port); - } - } break; - default: - xmlrpc_asprintf(peerStringP, "??? AF=%u", sockaddr.sa_family); - } - } -} - - - -static struct TChannelVtbl const channelVtbl = { - &channelDestroy, - &channelWrite, - &channelRead, - &channelWait, - &channelInterrupt, - &channelFormatPeerInfo, -}; - - - -static void -makeChannelFromWinsock(SOCKET const winsock, - TChannel ** const channelPP, - const char ** const errorP) { - - struct socketWin * socketWinP; - - MALLOCVAR(socketWinP); - - if (socketWinP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for Windows " - "socket descriptor"); - else { - TChannel * channelP; - - socketWinP->winsock = winsock; - socketWinP->userSuppliedWinsock = TRUE; - socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - - ChannelCreate(&channelVtbl, socketWinP, &channelP); - - if (channelP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for " - "channel descriptor."); - else { - *channelPP = channelP; - *errorP = NULL; - } - if (*errorP) { - CloseHandle(socketWinP->interruptEvent); - free(socketWinP); - } - } -} - - - -static void -makeChannelInfo(struct abyss_win_chaninfo ** const channelInfoPP, - struct sockaddr const peerAddr, - socklen_t const peerAddrLen, - const char ** const errorP) { - - struct abyss_win_chaninfo * channelInfoP; - - MALLOCVAR(channelInfoP); - - if (channelInfoP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory"); - else { - channelInfoP->peerAddrLen = peerAddrLen; - channelInfoP->peerAddr = peerAddr; - - *channelInfoPP = channelInfoP; - - *errorP = NULL; - } -} - - - -void -ChannelWinCreateWinsock(SOCKET const fd, - TChannel ** const channelPP, - struct abyss_win_chaninfo ** const channelInfoPP, - const char ** const errorP) { - - struct sockaddr peerAddr; - socklen_t peerAddrLen; - int rc; - - peerAddrLen = sizeof(peerAddr); - - rc = getpeername(fd, &peerAddr, &peerAddrLen); - - if (rc != 0) { - int const lastError = WSAGetLastError(); - if (lastError == WSAENOTCONN) { - /* NOTE: This specific string 'not in connected' is - required by one of the rpctest suite items, in abyss.c - (line 186), hence the separation of the error messages - in this case ... - */ - xmlrpc_asprintf(errorP, "Socket on file descriptor %d " - "is not in connected state. WSAERROR = %d (%s)", - fd, lastError, getWSAError(lastError)); - } else - xmlrpc_asprintf(errorP, "getpeername() failed. WSAERROR = %d (%s)", - lastError, getWSAError(lastError)); - } else { - makeChannelInfo(channelInfoPP, peerAddr, peerAddrLen, errorP); - if (!*errorP) { - makeChannelFromWinsock(fd, channelPP, errorP); - - if (*errorP) - free(*channelInfoPP); - } - } -} - - -/*============================================================================= - TChanSwitch -=============================================================================*/ - -static SwitchDestroyImpl chanSwitchDestroy; - -void -chanSwitchDestroy(TChanSwitch * const chanSwitchP) { - - struct socketWin * const socketWinP = chanSwitchP->implP; - - if (!socketWinP->userSuppliedWinsock) - closesocket(socketWinP->winsock); - - CloseHandle(socketWinP->interruptEvent); - - free(socketWinP); -} - - - -static SwitchListenImpl chanSwitchListen; - -static void -chanSwitchListen(TChanSwitch * const chanSwitchP, - uint32_t const backlog, - const char ** const errorP) { - - struct socketWin * const socketWinP = chanSwitchP->implP; - - int32_t const minus1 = -1; - - int rc; - - /* Disable the Nagle algorithm to make persistant connections faster */ - - setsockopt(socketWinP->winsock, IPPROTO_TCP, TCP_NODELAY, - (const char *)&minus1, sizeof(minus1)); - - rc = listen(socketWinP->winsock, backlog); - - if (rc != 0) { - int const lastError = WSAGetLastError(); - xmlrpc_asprintf(errorP, "setsockopt() failed with WSAERROR %d (%s)", - lastError, getWSAError(lastError)); - } else - *errorP = NULL; -} - - - -static void -createChannelForAccept(int const acceptedWinsock, - struct sockaddr const peerAddr, - TChannel ** const channelPP, - void ** const channelInfoPP, - const char ** const errorP) { - - struct abyss_win_chaninfo * channelInfoP; - makeChannelInfo(&channelInfoP, peerAddr, sizeof(peerAddr), errorP); - if (!*errorP) { - struct socketWin * acceptedSocketP; - - MALLOCVAR(acceptedSocketP); - - if (!acceptedSocketP) - xmlrpc_asprintf(errorP, "Unable to allocate memory"); - else { - TChannel * channelP; - - acceptedSocketP->winsock = acceptedWinsock; - acceptedSocketP->userSuppliedWinsock = FALSE; - acceptedSocketP->interruptEvent = - CreateEvent(NULL, FALSE, FALSE, NULL); - - ChannelCreate(&channelVtbl, acceptedSocketP, &channelP); - if (!channelP) - xmlrpc_asprintf(errorP, - "Failed to create TChannel object."); - else { - *errorP = NULL; - *channelPP = channelP; - *channelInfoPP = channelInfoP; - } - if (*errorP) { - CloseHandle(acceptedSocketP->interruptEvent); - free(acceptedSocketP); - } - } - } -} - - - -static SwitchAcceptImpl chanSwitchAccept; - -static void -chanSwitchAccept(TChanSwitch * const chanSwitchP, - TChannel ** const channelPP, - void ** const channelInfoPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Accept a connection via the channel switch *chanSwitchP. Return as - *channelPP the channel for the accepted connection. - - If no connection is waiting at *chanSwitchP, wait until one is. - - If we receive a signal while waiting, return immediately with - *channelPP == NULL. ------------------------------------------------------------------------------*/ - struct socketWin * const listenSocketP = chanSwitchP->implP; - HANDLE acceptEvent = WSACreateEvent(); - bool interrupted; - TChannel * channelP; - - interrupted = FALSE; /* Haven't been interrupted yet */ - channelP = NULL; /* No connection yet */ - *errorP = NULL; /* No error yet */ - - WSAEventSelect(listenSocketP->winsock, acceptEvent, - FD_ACCEPT | FD_CLOSE | FD_READ); - - while (!channelP && !*errorP && !interrupted) { - HANDLE interrupts[2] = {acceptEvent, listenSocketP->interruptEvent}; - int rc; - struct sockaddr peerAddr; - socklen_t size = sizeof(peerAddr); - - rc = WaitForMultipleObjects(2, interrupts, FALSE, INFINITE); - if (WAIT_OBJECT_0 + 1 == rc) { - interrupted = TRUE; - continue; - }; - - rc = accept(listenSocketP->winsock, &peerAddr, &size); - - if (rc >= 0) { - int const acceptedWinsock = rc; - - createChannelForAccept(acceptedWinsock, peerAddr, - &channelP, channelInfoPP, errorP); - - if (*errorP) - closesocket(acceptedWinsock); - } else { - int const lastError = WSAGetLastError(); - - if (lastError == WSAEINTR) - interrupted = TRUE; - else - xmlrpc_asprintf(errorP, - "accept() failed, WSA error = %d (%s)", - lastError, getWSAError(lastError)); - } - } - *channelPP = channelP; - CloseHandle(acceptEvent); -} - - - -static SwitchInterruptImpl chanSwitchInterrupt; - -static void -chanSwitchInterrupt(TChanSwitch * const chanSwitchP) { -/*---------------------------------------------------------------------------- - Interrupt any waiting that a thread might be doing in chanSwitchAccept() - now or in the future. ------------------------------------------------------------------------------*/ - struct socketWin * const listenSocketP = chanSwitchP->implP; - - SetEvent(listenSocketP->interruptEvent); -} - - - -static struct TChanSwitchVtbl const chanSwitchVtbl = { - &chanSwitchDestroy, - &chanSwitchListen, - &chanSwitchAccept, - &chanSwitchInterrupt, -}; - - - -static void -setSocketOptions(SOCKET const fd, - const char ** const errorP) { - - int32_t const n = 1; - - int rc; - - rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof(n)); - - if (rc != 0) { - int const lastError = WSAGetLastError(); - xmlrpc_asprintf(errorP, "Failed to set socket options. " - "setsockopt() failed with WSAERROR %d (%s)", - lastError, getWSAError(lastError)); - } else - *errorP = NULL; -} - - - -void -bindSocketToPort(SOCKET const winsock, - struct in_addr * const addrP, - uint16_t const portNumber, - const char ** const errorP) { - - struct sockaddr_in name; - int rc; - - ZeroMemory(&name, sizeof(name)); - name.sin_family = AF_INET; - name.sin_port = htons(portNumber); - if (addrP) - name.sin_addr = *addrP; - - rc = bind(winsock, (struct sockaddr *)&name, sizeof(name)); - - if (rc != 0) { - int const lastError = WSAGetLastError(); - xmlrpc_asprintf(errorP, "Unable to bind socket to port number %u. " - "bind() failed with WSAERROR %i (%s)", - portNumber, lastError, getWSAError(lastError)); - } else - *errorP = NULL; -} - - - -void -ChanSwitchWinCreate(uint16_t const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Create a Winsock-based channel switch. - - Set the socket's local address so that a subsequent "listen" will listen - on all IP addresses, port number 'portNumber'. ------------------------------------------------------------------------------*/ - struct socketWin * socketWinP; - - MALLOCVAR(socketWinP); - - if (!socketWinP) - xmlrpc_asprintf(errorP, "Unable to allocate memory for Windows socket " - "descriptor structure."); - else { - SOCKET winsock; - - winsock = socket(AF_INET, SOCK_STREAM, 0); - - if (winsock == 0 || winsock == INVALID_SOCKET) { - int const lastError = WSAGetLastError(); - xmlrpc_asprintf(errorP, "socket() failed with WSAERROR %d (%s)", - lastError, getWSAError(lastError)); - } else { - socketWinP->winsock = winsock; - socketWinP->userSuppliedWinsock = FALSE; - socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - - setSocketOptions(socketWinP->winsock, errorP); - if (!*errorP) { - bindSocketToPort(socketWinP->winsock, NULL, portNumber, - errorP); - if (!*errorP) - ChanSwitchCreate(&chanSwitchVtbl, socketWinP, - chanSwitchPP); - } - - if (*errorP) { - CloseHandle(socketWinP->interruptEvent); - closesocket(winsock); - } - } - if (*errorP) - free(socketWinP); - } -} - - - -void -ChanSwitchWinCreateWinsock(SOCKET const winsock, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - struct socketWin * socketWinP; - - if (connected(winsock)) - xmlrpc_asprintf(errorP, "Socket is in connected state."); - else { - MALLOCVAR(socketWinP); - - if (socketWinP == NULL) - xmlrpc_asprintf(errorP, "unable to allocate memory for Windows " - "socket descriptor."); - else { - TChanSwitch * chanSwitchP; - - socketWinP->winsock = winsock; - socketWinP->userSuppliedWinsock = TRUE; - socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - - ChanSwitchCreate(&chanSwitchVtbl, socketWinP, &chanSwitchP); - - if (chanSwitchP == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate memory for " - "channel switch descriptor"); - else { - *chanSwitchPP = chanSwitchP; - *errorP = NULL; - } - if (*errorP) { - CloseHandle(socketWinP->interruptEvent); - free(socketWinP); - } - } - } -} - -static void -bindSocketToAddr(SOCKET const winsock, - const struct sockaddr * const addrP, - socklen_t const sockAddrLen, - const char ** const errorP) { - - int rc; - - rc = bind(winsock, (struct sockaddr *)addrP, sockAddrLen); - - if (rc != 0) { - int const lastError = WSAGetLastError(); - xmlrpc_asprintf(errorP, "Unable to bind socket to the socket address. " - "bind() failed with WSAERROR %i (%s)", - lastError, getWSAError(lastError)); - } else - *errorP = NULL; -} - -void -ChanSwitchWinCreate2(int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - - struct socketWin * socketWinP; - - MALLOCVAR(socketWinP); - - if (!socketWinP) - xmlrpc_asprintf(errorP, "Unable to allocate memory for Windows socket " - "descriptor structure."); - else { - SOCKET winsock; - - winsock = socket(protocolFamily, SOCK_STREAM, 0); - - if (winsock == 0 || winsock == INVALID_SOCKET) { - int const lastError = WSAGetLastError(); - xmlrpc_asprintf(errorP, "socket() failed with WSAERROR %d (%s)", - lastError, getWSAError(lastError)); - } else { - socketWinP->winsock = winsock; - socketWinP->userSuppliedWinsock = FALSE; - socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - - setSocketOptions(socketWinP->winsock, errorP); - if (!*errorP) { - bindSocketToAddr(socketWinP->winsock, sockAddrP, sockAddrLen, - errorP); - if (!*errorP) - ChanSwitchCreate(&chanSwitchVtbl, socketWinP, - chanSwitchPP); - } - - if (*errorP) { - CloseHandle(socketWinP->interruptEvent); - closesocket(winsock); - } - } - if (*errorP) - free(socketWinP); - } -} - - - -void -ChanSwitchWinGetListenName(TChanSwitch * const chanSwitchP, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP) { - - struct socketWin * const socketWinP = chanSwitchP->implP; - - // Anyone who knows how to do this with Winsock, please submit a patch. - - xmlrpc_asprintf(errorP, "Code has not been written " - "(ChanSwitchWinGetListenName in " - "lib/abyss/src/socket_win.c) to determine the name of the " - "socket on which the channel switch is listening for " - "connections"); -} - - - diff --git a/trunk/lib/abyss/src/socket_win.h b/trunk/lib/abyss/src/socket_win.h deleted file mode 100644 index b52305fea..000000000 --- a/trunk/lib/abyss/src/socket_win.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef SOCKET_WIN_H_INCLUDED -#define SOCKET_WIN_H_INCLUDED - -void -SocketWinInit(const char ** const errorP); - -void -SocketWinTerm(void); - -#endif diff --git a/trunk/lib/abyss/src/sockutil.c b/trunk/lib/abyss/src/sockutil.c deleted file mode 100644 index bd991998b..000000000 --- a/trunk/lib/abyss/src/sockutil.c +++ /dev/null @@ -1,490 +0,0 @@ -/*============================================================================= - sockutil.c -=============================================================================== - This is utility functions for use in channel and channel switches - that use Unix sockets. -=============================================================================*/ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if HAVE_SYS_FILIO_H - #include -#endif - -#include "c_util.h" -#include "int.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "mallocvar.h" -#include "trace.h" -#include "chanswitch.h" -#include "channel.h" -#include "socket.h" -#include "netinet/in.h" -#include "xmlrpc-c/abyss.h" - -#include "sockutil.h" - - -void -sockutil_interruptPipeInit(sockutil_InterruptPipe * const pipeP, - const char ** const errorP) { - - int pipeFd[2]; - int rc; - - rc = pipe(pipeFd); - - if (rc != 0) - xmlrpc_asprintf(errorP, "Unable to create a pipe to use to interrupt " - "waits. pipe() failed with errno %d (%s)", - errno, strerror(errno)); - else { - *errorP = NULL; - pipeP->interruptorFd = pipeFd[1]; - pipeP->interrupteeFd = pipeFd[0]; - } -} - - - -void -sockutil_interruptPipeTerm(sockutil_InterruptPipe const pipe) { - - close(pipe.interruptorFd); - close(pipe.interrupteeFd); -} - - - -void -sockutil_interruptPipeInterrupt(sockutil_InterruptPipe const interruptPipe) { - - unsigned char const zero[1] = {0u}; - - write(interruptPipe.interruptorFd, &zero, sizeof(zero)); -} - - - -bool -sockutil_connected(int const fd) { -/*---------------------------------------------------------------------------- - Return TRUE iff the socket on file descriptor 'fd' is in the connected - state. - - If 'fd' does not identify a stream socket or we are unable to determine - the state of the stream socket, the answer is "false". ------------------------------------------------------------------------------*/ - bool connected; - struct sockaddr sockaddr; - socklen_t nameLen; - int rc; - - nameLen = sizeof(sockaddr); - - rc = getpeername(fd, &sockaddr, &nameLen); - - if (rc == 0) - connected = true; - else - connected = false; - - return connected; -} - - - -void -sockutil_getSockName(int const sockFd, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP) { - - unsigned char * sockName; - socklen_t nameSize; - - nameSize = sizeof(struct sockaddr) + 1; - - sockName = malloc(nameSize); - - if (sockName == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate space for socket name"); - else { - int rc; - socklen_t nameLen; - nameLen = nameSize; /* initial value */ - rc = getsockname(sockFd, (struct sockaddr *)sockName, &nameLen); - - if (rc < 0) - xmlrpc_asprintf(errorP, "getsockname() failed. errno=%d (%s)", - errno, strerror(errno)); - else { - if (nameLen > nameSize-1) - xmlrpc_asprintf(errorP, - "getsockname() says the socket name is " - "larger than %u bytes, which means it is " - "not in the expected format.", - nameSize-1); - else { - *sockaddrPP = (struct sockaddr *)sockName; - *sockaddrLenP = nameLen; - *errorP = NULL; - } - } - if (*errorP) - free(sockName); - } -} - - - -void -sockutil_getPeerName(int const sockFd, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP) { - - unsigned char * peerName; - socklen_t nameSize; - - nameSize = sizeof(struct sockaddr) + 1; - - peerName = malloc(nameSize); - - if (peerName == NULL) - xmlrpc_asprintf(errorP, "Unable to allocate space for peer name"); - else { - int rc; - socklen_t nameLen; - nameLen = nameSize; /* initial value */ - rc = getpeername(sockFd, (struct sockaddr *)peerName, &nameLen); - - if (rc < 0) - xmlrpc_asprintf(errorP, "getpeername() failed. errno=%d (%s)", - errno, strerror(errno)); - else { - if (nameLen > nameSize-1) - xmlrpc_asprintf(errorP, - "getpeername() says the socket name is " - "larger than %u bytes, which means it is " - "not in the expected format.", - nameSize-1); - else { - *sockaddrPP = (struct sockaddr *)peerName; - *sockaddrLenP = nameLen; - *errorP = NULL; - } - } - if (*errorP) - free(peerName); - } -} - - - -static void -formatPeerInfoInet(const struct sockaddr_in * const sockaddrInP, - socklen_t const sockaddrLen, - const char ** const peerStringP) { - - if (sockaddrLen < sizeof(*sockaddrInP)) - xmlrpc_asprintf(peerStringP, "??? getpeername() returned " - "the wrong size"); - else { - unsigned char * const ipaddr = (unsigned char *) - &sockaddrInP->sin_addr.s_addr; - xmlrpc_asprintf(peerStringP, "%u.%u.%u.%u:%hu", - ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], - ntohs(sockaddrInP->sin_port)); - } -} - - - -static void -formatPeerInfoInet6(const struct sockaddr_in6 * const sockaddrIn6P, - socklen_t const sockaddrLen, - const char ** const peerStringP) { - - if (sockaddrLen < sizeof(*sockaddrIn6P)) - xmlrpc_asprintf(peerStringP, "??? getpeername() returned " - "the wrong size"); - else { - /* Gcc on Debian 6 gives a bewildering error message about aliasing - if we try to dereference sockaddrIn6P in various ways, regardless - of casts to void * or anything else. So we copy the data structure - as raw memory contents and then access the copy. 12.02.05. - */ - struct sockaddr_in6 sockaddr; - - MEMSCPY(&sockaddr, sockaddrIn6P); - - { - char buffer[256]; - const char * rc; - - rc = inet_ntop(AF_INET6, &sockaddr.sin6_addr, - buffer, sizeof(buffer)); - - /* Punt the supposedly impossible error */ - if (rc == NULL) - STRSCPY(buffer, "???"); - - xmlrpc_asprintf(peerStringP, "[%s]:%hu", - buffer, sockaddr.sin6_port); - } - } -} - - - -void -sockutil_formatPeerInfo(int const sockFd, - const char ** const peerStringP) { - - struct sockaddr sockaddr; - socklen_t sockaddrLen; - int rc; - - sockaddrLen = sizeof(sockaddr); - - rc = getpeername(sockFd, &sockaddr, &sockaddrLen); - - if (rc < 0) - xmlrpc_asprintf(peerStringP, "?? getpeername() failed. errno=%d (%s)", - errno, strerror(errno)); - else { - switch (sockaddr.sa_family) { - case AF_INET: - formatPeerInfoInet((const struct sockaddr_in *) &sockaddr, - sockaddrLen, - peerStringP); - break; - case AF_INET6: - formatPeerInfoInet6((const struct sockaddr_in6 *) &sockaddr, - sockaddrLen, - peerStringP); - break; - default: - xmlrpc_asprintf(peerStringP, "??? AF=%u", sockaddr.sa_family); - } - } -} - - - -void -sockutil_listen(int const sockFd, - uint32_t const backlog, - const char ** const errorP) { - - int32_t const minus1 = -1; - - int rc; - - /* Disable the Nagle algorithm to make persistant connections faster */ - - setsockopt(sockFd, IPPROTO_TCP, TCP_NODELAY, &minus1, sizeof(minus1)); - - rc = listen(sockFd, backlog); - - if (rc == -1) - xmlrpc_asprintf(errorP, "listen() failed with errno %d (%s)", - errno, strerror(errno)); - else - *errorP = NULL; -} - - - -void -sockutil_waitForConnection(int const listenSockFd, - sockutil_InterruptPipe const interruptPipe, - bool * const interruptedP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Wait for the listening socket to have a connection ready to accept. - - We return before the requested condition holds if the process receives - (and catches) a signal, but only if it receives that signal a certain - time after we start running. (That means this behavior isn't useful - for most purposes). - - We furthermore return before the requested condition holds if someone sends - a byte through the listening socket's interrupt pipe (or has sent one - previously since the most recent time the pipe was drained). - - Return *interruptedP == true if we return before there is a connection - ready to accept. ------------------------------------------------------------------------------*/ - struct pollfd pollfds[2]; - int rc; - - pollfds[0].fd = listenSockFd; - pollfds[0].events = POLLIN; - - pollfds[1].fd = interruptPipe.interrupteeFd; - pollfds[1].events = POLLIN; - - rc = poll(pollfds, ARRAY_SIZE(pollfds), -1); - - if (rc < 0) { - if (errno == EINTR) { - *errorP = NULL; - *interruptedP = true; - } else { - xmlrpc_asprintf(errorP, "poll() failed, errno = %d (%s)", - errno, strerror(errno)); - *interruptedP = false; /* quiet compiler warning */ - } - } else if (pollfds[0].revents & POLLHUP) { - xmlrpc_asprintf(errorP, "INTERNAL ERROR: listening socket " - "is not listening"); - } else if (pollfds[1].revents & POLLHUP) { - xmlrpc_asprintf(errorP, "INTERNAL ERROR: interrupt socket hung up"); - } else if (pollfds[0].revents & POLLERR) { - xmlrpc_asprintf(errorP, "listening socket is in POLLERR status"); - } else if (pollfds[1].revents & POLLHUP) { - xmlrpc_asprintf(errorP, "interrupt socket is in POLLERR status"); - } else { - *errorP = NULL; - *interruptedP = !(pollfds[0].revents & POLLIN); - } -} - - - -void -sockutil_setSocketOptions(int const fd, - const char ** const errorP) { - - int32_t n = 1; - int rc; - - rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof(n)); - - if (rc < 0) - xmlrpc_asprintf(errorP, "Failed to set socket options. " - "setsockopt() failed with errno %d (%s)", - errno, strerror(errno)); - else - *errorP = NULL; -} - - - -static void -traceSocketBound(const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen) { - - if (sockAddrP->sa_family == AF_INET && - sockAddrLen >= sizeof(struct sockaddr_in)) { - const struct sockaddr_in * const sockAddrInP = - (const struct sockaddr_in *)sockAddrP; - - unsigned char * const ipaddr = (unsigned char *) - &sockAddrInP->sin_addr.s_addr; - - fprintf(stderr, "Bound socket for channel switch to " - "AF_INET port %u.%u.%u.%u:%hu\n", - ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], - ntohs(sockAddrInP->sin_port)); - } else { - fprintf(stderr, "Bound socket for channel switch to address of " - "family %d\n", sockAddrP->sa_family); - } -} - - - -void -sockutil_bindSocketToPort(int const fd, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - const char ** const errorP) { - - int rc; - - rc = bind(fd, sockAddrP, sockAddrLen); - - if (rc == -1) - xmlrpc_asprintf(errorP, "Unable to bind socket " - "to the socket address. " - "bind() failed with errno %d (%s)", - errno, strerror(errno)); - else { - *errorP = NULL; - - if (SwitchTraceIsActive) - traceSocketBound(sockAddrP, sockAddrLen); - } -} - - - -void -sockutil_bindSocketToPortInet(int const fd, - uint16_t const portNumber, - const char ** const errorP) { - - struct sockaddr_in name; - int rc; - - name.sin_family = AF_INET; - name.sin_port = htons(portNumber); - name.sin_addr.s_addr = INADDR_ANY; - - rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); - - if (rc == -1) - xmlrpc_asprintf(errorP, "Unable to bind IPv4 socket " - "to port number %hu. " - "bind() failed with errno %d (%s)", - portNumber, errno, strerror(errno)); - else - *errorP = NULL; -} - - - -void -sockutil_bindSocketToPortInet6(int const fd, - uint16_t const portNumber, - const char ** const errorP) { - - struct sockaddr_in6 name; - int rc; - - name.sin6_family = AF_INET6; - name.sin6_port = htons(portNumber); - name.sin6_addr = in6addr_any; - - rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); - - if (rc == -1) - xmlrpc_asprintf(errorP, "Unable to bind IPv6 socket " - "to port number %hu. " - "bind() failed with errno %d (%s)", - portNumber, errno, strerror(errno)); - else - *errorP = NULL; -} - - - diff --git a/trunk/lib/abyss/src/sockutil.h b/trunk/lib/abyss/src/sockutil.h deleted file mode 100644 index 8d2b94e13..000000000 --- a/trunk/lib/abyss/src/sockutil.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef SOCKUTIL_H_INCLUDED -#define SOCKUTIL_H_INCLUDED - -#include -#include - -typedef struct { - int interruptorFd; - int interrupteeFd; -} sockutil_InterruptPipe; - -void -sockutil_interruptPipeInit(sockutil_InterruptPipe * const pipeP, - const char ** const errorP); - -void -sockutil_interruptPipeTerm(sockutil_InterruptPipe const pipe); - -void -sockutil_interruptPipeInterrupt(sockutil_InterruptPipe const interruptPipe); - -bool -sockutil_connected(int const fd); - -void -sockutil_getSockName(int const sockFd, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP); - -void -sockutil_getPeerName(int const sockFd, - struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP, - const char ** const errorP); - -void -sockutil_formatPeerInfo(int const sockFd, - const char ** const peerStringP); - -void -sockutil_listen(int const sockFd, - uint32_t const backlog, - const char ** const errorP); - -void -sockutil_waitForConnection(int const listenSockFd, - sockutil_InterruptPipe const interruptPipe, - bool * const interruptedP, - const char ** const errorP); - -void -sockutil_setSocketOptions(int const fd, - const char ** const errorP); - -void -sockutil_bindSocketToPort(int const fd, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - const char ** const errorP); - -void -sockutil_bindSocketToPortInet(int const fd, - uint16_t const portNumber, - const char ** const errorP); - -void -sockutil_bindSocketToPortInet6(int const fd, - uint16_t const portNumber, - const char ** const errorP); - -#endif diff --git a/trunk/lib/abyss/src/thread.h b/trunk/lib/abyss/src/thread.h deleted file mode 100644 index 980200d4b..000000000 --- a/trunk/lib/abyss/src/thread.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef THREAD_H_INCLUDED -#define THREAD_H_INCLUDED - -/********************************************************************* -** Thread -*********************************************************************/ - -#include "bool.h" - -typedef struct abyss_thread TThread; - -void -ThreadPoolInit(void); - -typedef void TThreadProc(void * const userHandleP); -typedef void TThreadDoneFn(void * const userHandleP); - -void -ThreadCreate(TThread ** const threadPP, - void * const userHandle, - TThreadProc * const func, - TThreadDoneFn * const threadDone, - bool const useSigchld, - size_t const stackSize, - const char ** const errorP); - -bool -ThreadRun(TThread * const threadP); - -bool -ThreadStop(TThread * const threadP); - -bool -ThreadKill(TThread * const threadP); - -void -ThreadWaitAndRelease(TThread * const threadP); - -void -ThreadExit(TThread * const threadP, - int const retValue); - -void -ThreadRelease(TThread * const threadP); - -bool -ThreadForks(void); - -void -ThreadUpdateStatus(TThread * const threadP); - -#if !MSVCRT -void -ThreadHandleSigchld(pid_t const pid); -#endif - -#endif diff --git a/trunk/lib/abyss/src/thread_fork.c b/trunk/lib/abyss/src/thread_fork.c deleted file mode 100644 index 26d28341a..000000000 --- a/trunk/lib/abyss/src/thread_fork.c +++ /dev/null @@ -1,293 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/abyss.h" - -#include "mallocvar.h" -#include "thread.h" - - -static void -blockSignalClass(int const signalClass, - sigset_t * const oldBlockedSetP) { - - sigset_t newBlockedSet; - - sigemptyset(&newBlockedSet); - sigaddset(&newBlockedSet, signalClass); - - sigprocmask(SIG_BLOCK, &newBlockedSet, oldBlockedSetP); -} - - - -struct abyss_thread { - struct abyss_thread * nextInPoolP; - TThreadDoneFn * threadDone; - void * userHandle; - pid_t pid; - bool useSigchld; - /* This means that user is going to call ThreadHandleSigchld() - when it gets a death of a child signal for this process. If - false, he's going to leave us in the dark, so we'll have to - poll to know if the process is dead or not. - */ -}; - - -/* Because signals are global, we need this global variable in order for - the signal handler to figure out to what thread the signal belongs. -*/ - -/* We use a singly linked list. Every time we access it, we have to run - the whole chain. To make this scale up, we should replace it with - a doubly linked list and some kind of index by PID. - - But large scale systems probably aren't using fork threads anyway. -*/ - -static struct { - struct abyss_thread * firstP; -} ThreadPool; - - - -void -ThreadPoolInit(void) { - - ThreadPool.firstP = NULL; -} - - - -static struct abyss_thread * -findThread(pid_t const pid) { - - struct abyss_thread * p; - - for (p = ThreadPool.firstP; p && p->pid != pid; p = p->nextInPoolP); - - return p; -} - - - -static void -addToPool(struct abyss_thread * const threadP) { - - if (ThreadPool.firstP == NULL) - ThreadPool.firstP = threadP; - else { - struct abyss_thread * p; - - for (p = ThreadPool.firstP; p->nextInPoolP; p = p->nextInPoolP); - - /* p points to the last thread in the list */ - - p->nextInPoolP = threadP; - } -} - - - -static void -removeFromPool(struct abyss_thread * const threadP) { - - if (threadP == ThreadPool.firstP) - ThreadPool.firstP = threadP->nextInPoolP; - else { - struct abyss_thread * p; - - for (p = ThreadPool.firstP; - p && p->nextInPoolP != threadP; - p = p->nextInPoolP); - - if (p) - /* p points to thread right before the one we want to remove */ - p->nextInPoolP = threadP->nextInPoolP; - } -} - - - -void -ThreadHandleSigchld(pid_t const pid) { -/*---------------------------------------------------------------------------- - Handle a death of a child signal for process 'pid', which may be one - of our threads. ------------------------------------------------------------------------------*/ - struct abyss_thread * const threadP = findThread(pid); - - if (threadP) { - if (threadP->threadDone) - threadP->threadDone(threadP->userHandle); - threadP->pid = 0; - } - /* Note that threadDone might free *threadP */ -} - - - -void -ThreadUpdateStatus(TThread * const threadP) { - - if (!threadP->useSigchld) { - if (threadP->pid) { - if (kill(threadP->pid, 0) != 0) { - if (threadP->threadDone) - threadP->threadDone(threadP->userHandle); - threadP->pid = 0; - } - } - } -} - - - -void -ThreadCreate(TThread ** const threadPP, - void * const userHandle, - TThreadProc * const func, - TThreadDoneFn * const threadDone, - bool const useSigchld, - size_t const stackSize ATTR_UNUSED, - const char ** const errorP) { - - TThread * threadP; - - MALLOCVAR(threadP); - if (threadP == NULL) - xmlrpc_asprintf(errorP, - "Can't allocate memory for thread descriptor."); - else { - sigset_t oldBlockedSet; - pid_t rc; - - threadP->nextInPoolP = NULL; - threadP->threadDone = threadDone; - threadP->userHandle = userHandle; - threadP->useSigchld = useSigchld; - threadP->pid = 0; - - /* We have to be sure we don't get the SIGCHLD for this child's - death until the child is properly registered in the thread pool - so that the handler will know who he is. - */ - blockSignalClass(SIGCHLD, &oldBlockedSet); - - rc = fork(); - - if (rc < 0) - xmlrpc_asprintf(errorP, "fork() failed, errno=%d (%s)", - errno, strerror(errno)); - else if (rc == 0) { - /* This is the child */ - free(threadP); - (*func)(userHandle); - /* Note that thread cleanup (threadDone) is done by the _parent_, - upon seeing our exit. - */ - exit(0); - } else { - /* This is the parent */ - threadP->pid = rc; - - addToPool(threadP); - - sigprocmask(SIG_SETMASK, &oldBlockedSet, NULL); /* restore */ - - *errorP = NULL; - *threadPP = threadP; - } - if (*errorP) { - removeFromPool(threadP); - free(threadP); - } - } -} - - - -bool -ThreadRun(TThread * const threadP ATTR_UNUSED) { - return true; -} - - - -bool -ThreadStop(TThread * const threadP ATTR_UNUSED) { - return true; -} - - - -bool -ThreadKill(TThread * const threadP ATTR_UNUSED) { - return true; -} - - - -void -ThreadWaitAndRelease(TThread * const threadP) { - - if (threadP->pid) { - int exitStatus; - - waitpid(threadP->pid, &exitStatus, 0); - - threadP->threadDone(threadP->userHandle); - - threadP->pid = 0; - } - ThreadRelease(threadP); -} - - - -void -ThreadExit(TThread * const threadP ATTR_UNUSED, - int const retValue) { - - /* Note that the OS will automatically send a SIGCHLD signal to - the parent process after we exit. The handler for that signal - will run threadDone in parent's context. Alternatively, if - the parent isn't set up for signals, the parent will eventually - poll for the existence of our PID and call threadDone when he - sees we've gone. - */ - - /* Note that thread cleanup (threadDone) is done by the _parent_, - upon seeing our exit. - */ - - exit(retValue); -} - - - -void -ThreadRelease(TThread * const threadP) { - - removeFromPool(threadP); - free(threadP); -} - - - -bool -ThreadForks(void) { - - return true; -} - - - diff --git a/trunk/lib/abyss/src/thread_pthread.c b/trunk/lib/abyss/src/thread_pthread.c deleted file mode 100644 index dd0df72cb..000000000 --- a/trunk/lib/abyss/src/thread_pthread.c +++ /dev/null @@ -1,202 +0,0 @@ -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" - -#include "bool.h" -#include "mallocvar.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" - -#include "xmlrpc-c/abyss.h" - -#include "thread.h" - - - -struct abyss_thread { - pthread_t thread; - void * userHandle; - TThreadProc * func; - TThreadDoneFn * threadDone; -}; - -/* We used to have MIN_STACK_SIZE = 16K, which was said to be the - minimum stack size on Win32. Scott Kolodzeski found in November - 2005 that this was insufficient for 64 bit Solaris -- we fail - when creating the first thread. So we changed to 128K. -*/ -#define MIN_STACK_SIZE (128*1024L) - - -typedef void * (pthreadStartRoutine)(void *); - - - -static pthreadStartRoutine execute; - -static void * -execute(void * const arg) { - - /* We make sure the user's "thread done" function runs as the thread - exits, whether it exits by directly calling ThreadExit() or by - returning to caller. - - In the direct exit case, the OS calls the "thread done" function by - virtual of a cleanup that we set up. In the return to caller case, we - get control back and our call to pthread_cleanup_pop() calls the - "thread done" function. - */ - - struct abyss_thread * const threadP = arg; - bool const executeTrue = true; - - pthread_cleanup_push(threadP->threadDone, threadP->userHandle); - - threadP->func(threadP->userHandle); - - pthread_cleanup_pop(executeTrue); - - return NULL; -} - - - - -void -ThreadCreate(TThread ** const threadPP, - void * const userHandle, - TThreadProc * const func, - TThreadDoneFn * const threadDone, - bool const useSigchld ATTR_UNUSED, - size_t const stackSize, - const char ** const errorP) { - - if ((size_t)(int)stackSize != stackSize) - xmlrpc_asprintf(errorP, "Stack size %lu is too big", - (unsigned long)stackSize); - else { - TThread * threadP; - - MALLOCVAR(threadP); - if (threadP == NULL) - xmlrpc_asprintf(errorP, - "Can't allocate memory for thread descriptor."); - else { - pthread_attr_t attr; - int rc; - - pthread_attr_init(&attr); - - pthread_attr_setstacksize(&attr, MAX(MIN_STACK_SIZE, stackSize)); - - threadP->userHandle = userHandle; - threadP->func = func; - threadP->threadDone = threadDone; - - rc = pthread_create(&threadP->thread, &attr, - execute, threadP); - if (rc == 0) { - *errorP = NULL; - *threadPP = threadP; - } else - xmlrpc_asprintf( - errorP, "pthread_create() failed, errno = %d (%s)", - errno, strerror(errno)); - - pthread_attr_destroy(&attr); - - if (*errorP) - free(threadP); - } - } -} - - - -bool -ThreadRun(TThread * const threadP ATTR_UNUSED) { - return true; -} - - - -bool -ThreadStop(TThread * const threadP ATTR_UNUSED) { - return true; -} - - - -bool -ThreadKill(TThread * const threadP ATTR_UNUSED) { - - return (pthread_kill(threadP->thread, SIGTERM) == 0); -} - - - -void -ThreadWaitAndRelease(TThread * const threadP) { - - void * threadReturn; - - pthread_join(threadP->thread, &threadReturn); - - free(threadP); -} - - - -void -ThreadExit(TThread * const threadP ATTR_UNUSED, - int const retValue) { - - pthread_exit((void*)&retValue); - - /* Note that the above runs our cleanup routine (which we registered - with pthread_cleanup_push() before exiting. - */ -} - - - -void -ThreadRelease(TThread * const threadP) { - - pthread_detach(threadP->thread); - - free(threadP); -} - - - -bool -ThreadForks(void) { - - return false; -} - - - -void -ThreadUpdateStatus(TThread * const threadP ATTR_UNUSED) { - - /* Threads keep their own statuses up to date, so there's nothing - to do here. - */ -} - - - -void -ThreadHandleSigchld(pid_t const pid ATTR_UNUSED) { - - /* Death of a child signals have nothing to do with pthreads */ -} - - - diff --git a/trunk/lib/abyss/src/thread_windows.c b/trunk/lib/abyss/src/thread_windows.c deleted file mode 100644 index a0b240a07..000000000 --- a/trunk/lib/abyss/src/thread_windows.c +++ /dev/null @@ -1,171 +0,0 @@ -/* This code is just a first draft by someone who doesn't know anything - about Windows. It has never been compiled. It is just a framework - for someone who knows Windows to pick up and finish. - - Bryan Henderson redesigned the threading structure for Abyss in - April 2006 and wrote this file then. He used the former - threading code, which did work on Windows, as a basis. -*/ - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - -#include "xmlrpc_config.h" - -#include "bool.h" -#include "int.h" -#include "xmlrpc-c/util_int.h" -#include "mallocvar.h" -#include "xmlrpc-c/string_int.h" - -#include "xmlrpc-c/abyss.h" -#include "trace.h" - -#include "thread.h" - - -struct abyss_thread { - HANDLE handle; - void * userHandle; - TThreadProc * func; - TThreadDoneFn * threadDone; -}; - -#define MIN_THREAD_STACK_SIZE (16*1024L) - - -typedef uint32_t (WINAPI WinThreadProc)(void *); - - -static WinThreadProc threadRun; - -static uint32_t WINAPI -threadRun(void * const arg) { - - struct abyss_thread * const threadP = arg; - - threadP->func(threadP->userHandle); - - threadP->threadDone(threadP->userHandle); - - return 0; -} - - - -void -ThreadCreate(TThread ** const threadPP, - void * const userHandle, - TThreadProc * const func, - TThreadDoneFn * const threadDone, - bool const useSigchld, - size_t const stackSize, - const char ** const errorP) { - - TThread * threadP; - - MALLOCVAR(threadP); - - if (threadP == NULL) - xmlrpc_asprintf(errorP, - "Can't allocate memory for thread descriptor."); - else { - DWORD z; - - threadP->userHandle = userHandle; - threadP->func = func; - threadP->threadDone = threadDone; - - threadP->handle = (HANDLE) - _beginthreadex(NULL, - MAX(stackSize, MIN_THREAD_STACK_SIZE), - threadRun, - threadP, - CREATE_SUSPENDED, - &z); - - if (threadP->handle == NULL) - xmlrpc_asprintf(errorP, "_beginthreadex() failed."); - else { - *errorP = NULL; - *threadPP = threadP; - } - if (*errorP) - free(threadP); - } -} - - - -bool -ThreadRun(TThread * const threadP) { - return (ResumeThread(threadP->handle) != 0xFFFFFFFF); -} - - - -bool -ThreadStop(TThread * const threadP) { - - return (SuspendThread(threadP->handle) != 0xFFFFFFFF); -} - - - -bool -ThreadKill(TThread * const threadP) { - return (TerminateThread(threadP->handle, 0) != 0); -} - - - -void -ThreadWaitAndRelease(TThread * const threadP) { - - WaitForSingleObject(threadP->handle, INFINITE); - ThreadRelease(threadP); -} - - - -void -ThreadExit(TThread * const threadP, - int const retValue) { - - threadP->threadDone(threadP->userHandle); - - _endthreadex(retValue); -} - - - -void -ThreadRelease(TThread * const threadP) { - - CloseHandle(threadP->handle); - - free(threadP); -} - - - -bool -ThreadForks(void) { - - return FALSE; -} - - - -void -ThreadUpdateStatus(TThread * const threadP ATTR_UNUSED) { - - /* Threads keep their own statuses up to date, so there's nothing - to do here. - */ -} - - - diff --git a/trunk/lib/abyss/src/token.c b/trunk/lib/abyss/src/token.c deleted file mode 100644 index 084ee04e2..000000000 --- a/trunk/lib/abyss/src/token.c +++ /dev/null @@ -1,65 +0,0 @@ -#include - -#include "bool.h" - -#include "token.h" - - -void -NextToken(const char ** const pP) { - - bool gotToken; - - gotToken = false; - - while (!gotToken) { - switch (**pP) { - case '\t': - case ' ': - ++(*pP); - break; - default: - gotToken = true; - }; - } -} - - - -char * -GetToken(char ** const pP) { - - char * p0; - - p0 = *pP; - - while (1) { - switch (**pP) { - case '\t': - case ' ': - case '\r': - case '\n': - case '\0': - if (p0 == *pP) - return NULL; - - if (**pP) { - **pP = '\0'; - ++(*pP); - }; - return p0; - - default: - ++(*pP); - }; - } -} - - - -void -GetTokenConst(char ** const pP, - const char ** const tokenP) { - - *tokenP = GetToken(pP); -} diff --git a/trunk/lib/abyss/src/token.h b/trunk/lib/abyss/src/token.h deleted file mode 100644 index d26e35154..000000000 --- a/trunk/lib/abyss/src/token.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef ABYSS_TOKEN_H_INCLUDED -#define ABYSS_TOKEN_H_INCLUDED - -void -NextToken(const char ** const pP); - -char * -GetToken(char ** const pP); - -void -GetTokenConst(char ** const pP, - const char ** const tokenP); - -#endif diff --git a/trunk/lib/abyss/src/trace.c b/trunk/lib/abyss/src/trace.c deleted file mode 100644 index 807938898..000000000 --- a/trunk/lib/abyss/src/trace.c +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************** -** -** trace.c -** -** This file is part of the ABYSS Web server project. -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -******************************************************************************/ - -#include -#include -#include - -#include "trace.h" - -/********************************************************************* -** Tracing functions -*********************************************************************/ - -static void -TraceVMsg(const char * const fmt, - va_list argptr) { - - vprintf(fmt,argptr); - - printf("\n"); -} - - - -void -TraceMsg(const char * const fmt, ...) { - - va_list argptr; - - va_start(argptr,fmt); - TraceVMsg(fmt,argptr); - va_end(argptr); -} - - - -void -TraceExit(const char * const fmt, ...) { - - va_list argptr; - - va_start(argptr,fmt); - TraceVMsg(fmt,argptr); - va_end(argptr); - - exit(1); -} diff --git a/trunk/lib/abyss/src/trace.h b/trunk/lib/abyss/src/trace.h deleted file mode 100644 index 849c0b3f7..000000000 --- a/trunk/lib/abyss/src/trace.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef TRACE_H_INCLUDED -#define TRACE_H_INCLUDED - -void -TraceMsg(const char * const fmt, ...); - -void -TraceExit(const char * const fmt, ...); - -#endif - diff --git a/trunk/lib/curl_transport/Makefile b/trunk/lib/curl_transport/Makefile deleted file mode 100644 index 03a1973c0..000000000 --- a/trunk/lib/curl_transport/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - LIBDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/curl_transport - -include $(BLDDIR)/config.mk - -default: all - -MODS := xmlrpc_curl_transport curltransaction curlmulti - -.PHONY: all -all: $(MODS:%=%.o) $(MODS:%=%.osh) - -# Rules for the above dependencies are in common.mk, -# courtesy of TARGET_MODS. - -TARGET_MODS = $(MODS) - -OMIT_CURL_TRANSPORT_RULE=Y - -include $(SRCDIR)/common.mk - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -CURL_VERSION := $(shell $(CURL_CONFIG) --vernum) - -# Some time at or before Curl 7.12, became an empty file -# (no-op). Some time after Curl 7.18, ceased to exist. -# curl-config --vernum yields a string of 6 digits; the first two are the -# major version in hexadecimal; the second two are the minor version number -# and so on. So "071000" means 7.16.0. - -NEED_CURL_TYPES_H := $(shell if test $(CURL_VERSION) '<' 071000; then echo Y; fi) - -ifeq ($(NEED_CURL_TYPES_H),Y) - CFLAGS_LOCAL += -DNEED_CURL_TYPES_H -endif - -CURL_INCLUDES := $(shell $(CURL_CONFIG) --cflags) -# We expect that curl-config --cflags just gives us -I options, because -# we need just the -I options for 'make dep'. Plus, it's scary to think -# of what any other compiler flag would do to our compile. - -INCLUDES = \ - -I$(BLDDIR) \ - -I$(BLDDIR)/include \ - -Isrcdir/include \ - -Isrcdir/lib/util/include \ - $(CURL_INCLUDES) - -.PHONY: clean -clean: clean-common - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: tags -tags: TAGS - -.PHONY: distdir -distdir: - -.PHONY: install -install: - -.PHONY: uninstall -uninstall: - -.PHONY: dep -dep: dep-common - -include depend.mk - -# Need this dependency for those who don't use depend.mk. -# Without it, version.h doesn't get created. -xmlrpc_curl_transport.o xmlrpc_curl_transport.osh: version.h diff --git a/trunk/lib/curl_transport/curlmulti.c b/trunk/lib/curl_transport/curlmulti.c deleted file mode 100644 index 47cbb128d..000000000 --- a/trunk/lib/curl_transport/curlmulti.c +++ /dev/null @@ -1,320 +0,0 @@ -/*============================================================================= - curlMulti -=============================================================================== - This is an extension to Curl's CURLM object. The extensions are: - - 1) It has a lock so multiple threads can use it simultaneously. - - 2) Its "select" file descriptor vectors are self-contained. CURLM - requires the user to maintain them separately. -=============================================================================*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include "xmlrpc_config.h" - -#include -#if HAVE_SYS_SELECT_H -#include -#endif - -#include -#ifdef NEED_CURL_TYPES_H -#include -#endif -#include -#include - -#include "mallocvar.h" -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/lock.h" -#include "xmlrpc-c/lock_platform.h" - -#include "curlversion.h" - -#include "curlmulti.h" - - - -static void -interpretCurlMultiError(const char ** const descriptionP, - CURLMcode const code) { - -#if HAVE_CURL_STRERROR - *descriptionP = strdup(curl_multi_strerror(code)); -#else - xmlrpc_asprintf(descriptionP, "Curl error code (CURLMcode) %d", code); -#endif -} - - - -struct curlMulti { - CURLM * curlMultiP; - struct lock * lockP; - /* Hold this lock while accessing or using *curlMultiP. You're - using the multi manager whenever you're calling a Curl - library multi manager function. - */ - /* The following file descriptor sets are an integral part of the - CURLM object; Our curlMulti_fdset() routine binds them to the - CURLM object, and said object expects us to use them in a very - specific way, including doing a select() on them. It is very, - very messy. - */ - fd_set readFdSet; - fd_set writeFdSet; - fd_set exceptFdSet; -}; - - - -curlMulti * -curlMulti_create(void) { - - curlMulti * retval; - curlMulti * curlMultiP; - - MALLOCVAR(curlMultiP); - - if (curlMultiP == NULL) - retval = NULL; - else { - curlMultiP->lockP = xmlrpc_lock_create(); - - if (curlMultiP->lockP == NULL) - retval = NULL; - else { - curlMultiP->curlMultiP = curl_multi_init(); - if (curlMultiP->curlMultiP == NULL) - retval = NULL; - else - retval = curlMultiP; - - if (retval == NULL) - curlMultiP->lockP->destroy(curlMultiP->lockP); - } - if (retval == NULL) - free(curlMultiP); - } - return retval; -} - - - -void -curlMulti_destroy(curlMulti * const curlMultiP) { - - curl_multi_cleanup(curlMultiP->curlMultiP); - - curlMultiP->lockP->destroy(curlMultiP->lockP); - - free(curlMultiP); -} - - - -void -curlMulti_perform(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - bool * const immediateWorkToDoP, - int * const runningHandleCtP) { -/*---------------------------------------------------------------------------- - Do whatever work is ready to be done under the control of multi - manager 'curlMultiP'. E.g. if HTTP response data has recently arrived - from the network, process it as an HTTP response. - - Iff this results in some work being finished from our point of view, - return *immediateWorkToDoP true. (Caller can query the multi manager for - messages and find out what it is). - - Return as *runningHandleCtP the number of Curl easy handles under the - multi manager's control that are still running -- yet to finish. ------------------------------------------------------------------------------*/ - CURLMcode rc; - - curlMultiP->lockP->acquire(curlMultiP->lockP); - - rc = curl_multi_perform(curlMultiP->curlMultiP, runningHandleCtP); - - curlMultiP->lockP->release(curlMultiP->lockP); - - if (rc == CURLM_CALL_MULTI_PERFORM) { - *immediateWorkToDoP = true; - } else { - *immediateWorkToDoP = false; - - if (rc != CURLM_OK) { - const char * reason; - interpretCurlMultiError(&reason, rc); - xmlrpc_faultf(envP, "Impossible failure of curl_multi_perform(): " - "%s", reason); - xmlrpc_strfree(reason); - } - } -} - - - -void -curlMulti_addHandle(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - CURL * const curlSessionP) { - - CURLMcode rc; - - curlMultiP->lockP->acquire(curlMultiP->lockP); - - rc = curl_multi_add_handle(curlMultiP->curlMultiP, curlSessionP); - - curlMultiP->lockP->release(curlMultiP->lockP); - - /* Old libcurl (e.g. 7.12) actually returns CURLM_CALL_MULTI_PERFORM - (by design) when it succeeds. Current libcurl returns CURLM_OK. - */ - - if (rc != CURLM_OK && rc != CURLM_CALL_MULTI_PERFORM) { - const char * reason; - interpretCurlMultiError(&reason, rc); - xmlrpc_faultf(envP, "Could not add Curl session to the " - "curl multi manager. curl_multi_add_handle() " - "failed: %s", reason); - xmlrpc_strfree(reason); - } -} - - - -void -curlMulti_removeHandle(curlMulti * const curlMultiP, - CURL * const curlSessionP) { - - curlMultiP->lockP->acquire(curlMultiP->lockP); - - curl_multi_remove_handle(curlMultiP->curlMultiP, curlSessionP); - - curlMultiP->lockP->release(curlMultiP->lockP); -} - - - -void -curlMulti_getMessage(curlMulti * const curlMultiP, - bool * const endOfMessagesP, - CURLMsg * const curlMsgP) { -/*---------------------------------------------------------------------------- - Get the next message from the queue of things the Curl multi manager - wants to say to us. - - Return the message as *curlMsgP. - - Iff there are no messages in the queue, return *endOfMessagesP == true. ------------------------------------------------------------------------------*/ - int remainingMsgCount; - CURLMsg * privateCurlMsgP; - /* Note that this is a pointer into the multi manager's memory, - so we have to use it under lock. - */ - - curlMultiP->lockP->acquire(curlMultiP->lockP); - - privateCurlMsgP = curl_multi_info_read(curlMultiP->curlMultiP, - &remainingMsgCount); - - if (privateCurlMsgP == NULL) - *endOfMessagesP = true; - else { - *endOfMessagesP = false; - *curlMsgP = *privateCurlMsgP; - } - curlMultiP->lockP->release(curlMultiP->lockP); -} - - - -void -curlMulti_fdset(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - fd_set * const readFdSetP, - fd_set * const writeFdSetP, - fd_set * const exceptFdSetP, - int * const maxFdP) { -/*---------------------------------------------------------------------------- - Set the CURLM object's file descriptor sets to those in the - curlMulti object, update those file descriptor sets with the - current needs of the multi manager, and return the resulting values - of the file descriptor sets. - - This is a bizarre operation, but is necessary because of the nonmodular - way in which the Curl multi interface works with respect to waiting - for work with select(). ------------------------------------------------------------------------------*/ - CURLMcode rc; - - curlMultiP->lockP->acquire(curlMultiP->lockP); - - /* curl_multi_fdset() doesn't _set_ the fdsets. It adds to existing - ones (so you can easily do a select() on other fds and Curl - fds at the same time). So we have to clear first: - */ - FD_ZERO(&curlMultiP->readFdSet); - FD_ZERO(&curlMultiP->writeFdSet); - FD_ZERO(&curlMultiP->exceptFdSet); - - /* WARNING: curl_multi_fdset() doesn't just update the fdsets pointed - to by its arguments. It makes the CURLM object remember those - pointers and refer back to them later! In fact, curl_multi_perform - expects its caller to have done a select() on those masks. No, - really. The man page even admits it. - - Inspection of the Libcurl code in March 2007 indicates that - this isn't actually true -- curl_multi_fdset() updates your - fdset and doesn't remember the pointer at all. I.e. it's just - what you would expect. The man pages still says it's as - described above. My guess is that Libcurl was fixed at some - time and the man page not updated. In any case, we have to - work with old Libcurl if at all possible, so we still maintain - these fdsets as if they belong to the CURLM object. - */ - - rc = curl_multi_fdset(curlMultiP->curlMultiP, - &curlMultiP->readFdSet, - &curlMultiP->writeFdSet, - &curlMultiP->exceptFdSet, - maxFdP); - - *readFdSetP = curlMultiP->readFdSet; - *writeFdSetP = curlMultiP->writeFdSet; - *exceptFdSetP = curlMultiP->exceptFdSet; - - curlMultiP->lockP->release(curlMultiP->lockP); - - if (rc != CURLM_OK) { - const char * reason; - interpretCurlMultiError(&reason, rc); - xmlrpc_faultf(envP, "Impossible failure of curl_multi_fdset(): %s", - reason); - xmlrpc_strfree(reason); - } -} - - - -void -curlMulti_updateFdSet(curlMulti * const curlMultiP, - fd_set const readFdSet, - fd_set const writeFdSet, - fd_set const exceptFdSet) { -/*---------------------------------------------------------------------------- - curl_multi_perform() expects the file descriptor sets, which were bound - to the CURLM object via a prior curlMulti_fdset(), to contain the results - of a recent select(). This subroutine provides you a way to supply those. ------------------------------------------------------------------------------*/ - curlMultiP->readFdSet = readFdSet; - curlMultiP->writeFdSet = writeFdSet; - curlMultiP->exceptFdSet = exceptFdSet; -} - - - diff --git a/trunk/lib/curl_transport/curlmulti.h b/trunk/lib/curl_transport/curlmulti.h deleted file mode 100644 index 265ed0c17..000000000 --- a/trunk/lib/curl_transport/curlmulti.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef CURLMULTI_H_INCLUDED -#define CURLMULTI_H_INCLUDED - -#include "bool.h" -#include "xmlrpc-c/util.h" - -#include "curltransaction.h" - -typedef struct curlMulti curlMulti; - -curlMulti * -curlMulti_create(void); - -void -curlMulti_destroy(curlMulti * const curlMultiP); - -void -curlMulti_perform(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - bool * const immediateWorkToDoP, - int * const runningHandlesP); - -void -curlMulti_addHandle(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - CURL * const curlSessionP); - -void -curlMulti_removeHandle(curlMulti * const curlMultiP, - CURL * const curlSessionP); - -void -curlMulti_getMessage(curlMulti * const curlMultiP, - bool * const endOfMessagesP, - CURLMsg * const curlMsgP); - -void -curlMulti_fdset(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - fd_set * const readFdSetP, - fd_set * const writeFdSetP, - fd_set * const exceptFdSetP, - int * const maxFdP); - -void -curlMulti_updateFdSet(curlMulti * const curlMultiP, - fd_set const readFdSet, - fd_set const writeFdSet, - fd_set const exceptFdSet); - -#endif diff --git a/trunk/lib/curl_transport/curltransaction.c b/trunk/lib/curl_transport/curltransaction.c deleted file mode 100644 index f0aafae8c..000000000 --- a/trunk/lib/curl_transport/curltransaction.c +++ /dev/null @@ -1,1031 +0,0 @@ -/*============================================================================= - curlTransaction -=============================================================================*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include - -#include "mallocvar.h" - -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/client_int.h" -#include "version.h" - -#include -#ifdef NEED_CURL_TYPES_H -#include -#endif -#include - -#include "curlversion.h" - -#include "curltransaction.h" - - -/* ABOUT LIBCURL AND SIGNALS: - - The Curl library has two timeout functions: one on original connection - (including DNS lookup) and another on the individual transactions. In the - original implementation, both use SIGALRM. But it is a terrible idea for a - library to mess with signals, because they are process-global. In fact, if - the program is multithreaded, this can be disastrous as a different thread - can receive the signal from the thread that is waiting. Programs even - crash. - - It is easy enough for Curl to time out the transaction without using - SIGALRM, and in current implementations it does. But for the DNS lookup, - using the traditional DNS lookup library, SIGALRM is the only way. - Therefore, the user must make a choice: have a timeout or have multiple - threads. To reflect that choice, Curl has the CURLOPT_NOSIGNAL setting. - When you set that, Curl does the right thing as keeps its hands off the - signals, but DNS lookups are indefinite. If you don't, then the connect - timeout (which defaults to 5 minutes and is user-settable) is effective - against the DNS lookup, but you had better not have multiple threads. - - For backward compatibilty, the default is to use SIGALRM. That means - single-threaded programs continue to enjoy DNS lookup timeouts even when - using new Curl. - - There is an optional way of building the Curl library -- with the ARES - library -- that allows the connect timeout to work on the DNS lookup without - SIGALRM - - In Xmlrpc-c, we always set CURLOPT_NOSIGNAL, to avoid undefined behavior in - multithreaded programs. This means that if the Curl library was not built - for ARES, the DNS lookup will not time out. For consistency, we also set - CURLOPT_CONNECTTIMEOUT to infinite. That way, users see the same behavior - with ARES. - - It wasn't always this way, Before Xmlrpc-c 1.41, we set CURLOPT_NOSIGNAL - only when the user specified the 'timeout' curl transport option, and we - never set CURLOPT_CONNECTTIMEOUT. This means programs that have a nice 5 - minute (Curl default) DNS lookup timeout with old Xmlrpc-c, (and happen not - to have the SIGALRM-related crash problem) have an indefinite wait with - current Xmlrpc-c. This was an unfortunate break to provide a more usable - interface to future users. - - For the old Curl that does not have CURLOPT_NOSIGNAL, we fail any attempt - to set a timeout (and we provide the user a way to know whether such - failure would occur). -*/ - -struct curlTransaction { - /* This is all stuff that really ought to be in a Curl object, but - the Curl library is a little too simple for that. So we build - a layer on top of Curl, and define this "transaction," as an - object subordinate to a Curl "session." A Curl session has - zero or one transactions in progress. The Curl session - "private data" is a pointer to the CurlTransaction object for - the current transaction. - */ - CURL * curlSessionP; - /* Handle for the Curl session that hosts this transaction. - Note that only one transaction at a time can use a particular - Curl session, so this had better not be a session that some other - transaction is using simultaneously. - */ - curlt_finishFn * finish; - curlt_progressFn * progress; - void * userContextP; - /* Meaningful to our client; opaque to us */ - CURLcode result; - /* Result of the transaction (succeeded, TCP connect failed, etc.). - A properly executed HTTP transaction (request & response) counts - as a successful transaction. When 'result' show success, - curl_easy_get_info() tells you whether the transaction succeeded - at the HTTP level. - */ - char curlError[CURL_ERROR_SIZE]; - /* Error message from Curl */ - struct curl_slist * headerList; - /* The HTTP headers for the transaction */ - const char * serverUrl; /* malloc'ed - belongs to this object */ - xmlrpc_mem_block * postDataP; - /* The data to send for the POST method */ - xmlrpc_mem_block * responseDataP; - /* This is normally where to put the body of the HTTP response. But - because of a quirk of Curl, if the response is not valid HTTP, - rather than this just being irrelevant, it is the place that Curl - puts the server's non-HTTP response. That can be useful for error - reporting. - */ -}; - - - -static void -addHeader(xmlrpc_env * const envP, - struct curl_slist ** const headerListP, - const char * const headerText) { - - struct curl_slist * newHeaderList; - newHeaderList = curl_slist_append(*headerListP, headerText); - if (newHeaderList == NULL) - xmlrpc_faultf(envP, - "Could not add header '%s'. " - "curl_slist_append() failed.", headerText); - else - *headerListP = newHeaderList; -} - - - -static void -addContentTypeHeader(xmlrpc_env * const envP, - struct curl_slist ** const headerListP) { - - addHeader(envP, headerListP, "Content-Type: text/xml"); -} - - - -static const char * -xmlrpcUserAgentPart(bool const reportIt) { - - const char * retval; - - if (reportIt) { - curl_version_info_data * const curlInfoP = - curl_version_info(CURLVERSION_NOW); - char curlVersion[32]; - - XMLRPC_SNPRINTF(curlVersion, sizeof(curlVersion), "%u.%u.%u", - (curlInfoP->version_num >> 16) & 0xff, - (curlInfoP->version_num >> 8) & 0xff, - (curlInfoP->version_num >> 0) & 0xff - ); - - xmlrpc_asprintf(&retval, - "Xmlrpc-c/%s Curl/%s", - XMLRPC_C_VERSION, curlVersion); - } else - xmlrpc_asprintf(&retval, "%s", ""); - - return retval; -} - - - -static void -addUserAgentHeader(xmlrpc_env * const envP, - struct curl_slist ** const headerListP, - bool const reportXmlrpc, - const char * const userAgent) { -/*---------------------------------------------------------------------------- - Add a User-Agent HTTP header to the Curl header list *headerListP, - if appropriate. - - 'reportXmlrpc' means we want to tell the client what XML-RPC agent - is being used -- Xmlrpc-c and layers below. - - 'userAgent' is a string describing the layers above Xmlrpc-c. We - assume it is in the proper format to be included in a User-Agent - header. (We should probably fix that some day -- take ownership - of that format). ------------------------------------------------------------------------------*/ - if (reportXmlrpc || userAgent) { - /* Add the header */ - - /* Note: Curl has a CURLOPT_USERAGENT option that does some of this - work. We prefer to be totally in control, though, so we build - the header explicitly. - */ - - const char * const xmlrpcPart = xmlrpcUserAgentPart(reportXmlrpc); - - if (xmlrpc_strnomem(xmlrpcPart)) - xmlrpc_faultf(envP, "Couldn't allocate memory for " - "User-Agent header"); - else { - const char * const userPart = userAgent ? userAgent : ""; - const char * const space = userAgent && reportXmlrpc ? " " : ""; - - const char * userAgentHeader; - - xmlrpc_asprintf(&userAgentHeader, - "User-Agent: %s%s%s", - userPart, space, xmlrpcPart); - - if (xmlrpc_strnomem(userAgentHeader)) - xmlrpc_faultf(envP, "Couldn't allocate memory for " - "User-Agent header"); - else { - addHeader(envP, headerListP, userAgentHeader); - - xmlrpc_strfree(userAgentHeader); - } - xmlrpc_strfree(xmlrpcPart); - } - } -} - - - -static void -addAuthorizationHeader(xmlrpc_env * const envP, - struct curl_slist ** const headerListP, - const char * const hdrValue) { - - const char * authorizationHeader; - - xmlrpc_asprintf(&authorizationHeader, "Authorization: %s", hdrValue); - - if (xmlrpc_strnomem(authorizationHeader)) - xmlrpc_faultf(envP, "Couldn't allocate memory for " - "Authorization header"); - else { - addHeader(envP, headerListP, authorizationHeader); - - xmlrpc_strfree(authorizationHeader); - } -} - - - -/* - In HTTP 1.1, the client can send the header "Expect: 100-continue", which - tells the server that the client isn't going to send the body until the - server tells it to by sending a "continue" response (HTTP response code 100). - The server is obligated to send that response. - - However, many servers are broken and don't send the Continue response. - - Early libcurl did not send the Expect: header, thus worked fine with such - broken servers. But as of ca. 2007, libcurl sends the Expect:, and waits - for the response, when the body is large. It gives up after 3 seconds and - sends the body anyway. - - To accomodate the broken servers and for backward compatibility, we always - force libcurl not to send the Expect and consequently not to wait for the - response, using the hackish (but according to libcurl design) method of - including an entry in our explicit header list that is an Expect: header - with an empty argument. This causes libcurl not to send any Expect: header. - This is since 1.19; we may find there are also servers and/or libcurl levels - that can't work with that. - - We may find a case where the Expect/Continue protocol is desirable. If we - do, we should add a transport option to request the function and let libcurl - do its thing when the user requests it. - - The purpose of Expect/Continue is to save the client the trouble of - generating and/or sending the body when the server is just going to reject - the transaction based on the headers -- like maybe because the body is - too big. -*/ - - -static void -addExpectHeader(xmlrpc_env * const envP, - struct curl_slist ** const headerListP) { - - addHeader(envP, headerListP, "Expect:"); - /* Don't send Expect header. See explanation above. */ -} - - - -static void -createCurlHeaderList(xmlrpc_env * const envP, - const char * const authHdrValue, - bool const dontAdvertise, - const char * const userAgent, - struct curl_slist ** const headerListP) { - - struct curl_slist * headerList; - - headerList = NULL; /* initial value - empty list */ - - addContentTypeHeader(envP, &headerList); - if (!envP->fault_occurred) { - addUserAgentHeader(envP, &headerList, !dontAdvertise, userAgent); - if (!envP->fault_occurred) { - if (authHdrValue) - addAuthorizationHeader(envP, &headerList, authHdrValue); - } - if (!envP->fault_occurred) - addExpectHeader(envP, &headerList); - } - if (envP->fault_occurred) - curl_slist_free_all(headerList); - - *headerListP = headerList; -} - - - -static size_t -collect(void * const ptr, - size_t const size, - size_t const nmemb, - void * const streamP) { -/*---------------------------------------------------------------------------- - This is a Curl write function. Curl calls this to deliver the - HTTP response body to the Curl client. - - But as a design quirk, Curl also calls this when there is no HTTP body - because the response from the server is not valid HTTP. In that case, - Curl calls this to deliver the raw contents of the response. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * const responseXmlP = streamP; - char * const buffer = ptr; - size_t const length = nmemb * size; - - size_t retval; - xmlrpc_env env; - - xmlrpc_env_init(&env); - xmlrpc_mem_block_append(&env, responseXmlP, buffer, length); - if (env.fault_occurred) - retval = (size_t)-1; - else { - retval = length; - /* Really. Analogy to fread() would require this to be 'nmemb', - but Curl does expect the byte count. - */ - } - - return retval; -} - - - -static int -curlProgress(void * const contextP, - double const dltotal, - double const dlnow, - double const ultotal, - double const ulnow) { -/*---------------------------------------------------------------------------- - This is a Curl "progress function." It's something various Curl functions - call every so often, including whenever something gets interrupted by the - process receiving, and catching, a signal. There are two purposes of a - Curl progress function: 1) lets us log the progress of a long-running - transaction such as a big download, e.g. by displaying a progress bar - somewhere. 2) allows us to tell the Curl function, via our return code, - that calls it that we don't want to wait anymore for the operation to - complete. - - In Curl versions before March 2007, we get called once per second and - signals have no effect. In current Curl, we usually get called immediately - after a signal gets caught while Curl is waiting to receive a response from - the server. But Curl doesn't properly synchronize with signals, so it may - miss one and then we don't get called until the next scheduled - one-per-second call. - - All we do is pass the call through to the curlTransaction's progress - function (the one that the creator of the curlTransaction registered). - - This function is not as important as it once was for interrupting purposes. - This module used to use curl_easy_perform(), which can be interrupted only - via this progress function. But because of the above-mentioned failure of - Curl to properly synchronize signals (and Bryan's failure to get Curl - developers to accept code to fix it), we now use the Curl "multi" facility - instead and do our own pselect(). But this function still normally gets - called by curl_multi_perform(), which the transport tries to call even when - the user has requested interruption, because we don't trust our ability to - abort a running Curl transaction. curl_multi_perform() reliably winds up a - Curl transaction when this function tells it to. ------------------------------------------------------------------------------*/ - curlTransaction * const curlTransactionP = contextP; - - bool abort; - - /* We require anyone setting us up as the Curl progress function to - supply a progress function: - */ - assert(curlTransactionP); - assert(curlTransactionP->progress); - - curlTransactionP->progress(curlTransactionP->userContextP, - dltotal, dlnow, ultotal, ulnow, - &abort); - - return abort; -} - - - -static void -setupAuth(xmlrpc_env * const envP ATTR_UNUSED, - CURL * const curlSessionP, - const xmlrpc_server_info * const serverInfoP, - const char ** const authHdrValueP) { -/*---------------------------------------------------------------------------- - Set the options in the Curl session 'curlSessionP' to set up the HTTP - authentication described by *serverInfoP. - - But we have an odd special function for backward compatibility, because - this code dates to a time when libcurl did not have the ability to - handle authentication, but we provided such function nonetheless by - building our own Authorization: header. But we did this only for - HTTP basic authentication. - - So the special function is this: if libcurl is too old to have - authorization options and *serverInfoP allows basic authentication, return - as *authHdrValueP an appropriate parameter for the Authorization: Basic: - HTTP header. Otherwise, return *authHdrValueP == NULL. ------------------------------------------------------------------------------*/ - CURLcode rc; - - /* We don't worry if libcurl is too old for specific kinds of - authentication; they're defined only as _allowed_ authentication - methods, for when client and server are capable of using it, and unlike - with basic authentication, we have no historical commitment to consider - an old libcurl as capable of doing these. - - Note that curl_easy_setopt(CURLOPT_HTTPAUTH) succeeds even if there are - flags in it argument that weren't defined when it was written. - */ - - if (serverInfoP->userNamePw) - curl_easy_setopt(curlSessionP, CURLOPT_USERPWD, - serverInfoP->userNamePw); - - rc = curl_easy_setopt( - curlSessionP, CURLOPT_HTTPAUTH, - (serverInfoP->allowedAuth.basic ? CURLAUTH_BASIC : 0) | - (serverInfoP->allowedAuth.digest ? CURLAUTH_DIGEST : 0) | - (serverInfoP->allowedAuth.gssnegotiate ? CURLAUTH_GSSNEGOTIATE : 0) | - (serverInfoP->allowedAuth.ntlm ? CURLAUTH_NTLM : 0)); - - if (rc != CURLE_OK) { - /* Curl is too old to do authentication, so we do it ourselves - with an explicit header if we have to. - */ - if (serverInfoP->allowedAuth.basic) { - *authHdrValueP = strdup(serverInfoP->basicAuthHdrValue); - if (*authHdrValueP == NULL) - xmlrpc_faultf(envP, "Unable to allocate memory for basic " - "authentication header"); - } else - *authHdrValueP = NULL; - } else - *authHdrValueP = NULL; -} - - - -static void -setCurlTimeout(CURL * const curlSessionP ATTR_UNUSED, - unsigned int const timeoutMs ATTR_UNUSED) { - -#if HAVE_CURL_NOSIGNAL - unsigned int const timeoutSec = (timeoutMs + 999)/1000; - - assert((long)timeoutSec == (int)timeoutSec); - /* Calling requirement */ - curl_easy_setopt(curlSessionP, CURLOPT_TIMEOUT, (long)timeoutSec); -#else - /* Caller should not have called us */ - abort(); -#endif -} - - - -static void -setCurlConnectTimeout(CURL * const curlSessionP ATTR_UNUSED, - unsigned int const timeoutMs ATTR_UNUSED) { - -#if HAVE_CURL_NOSIGNAL - unsigned int const timeoutSec = (timeoutMs + 999)/1000; - - assert((long)timeoutSec == (int)timeoutSec); - /* Calling requirement */ - curl_easy_setopt(curlSessionP, CURLOPT_CONNECTTIMEOUT, (long)timeoutSec); -#else - /* Caller should not have called us */ - abort(); -#endif -} - - - -static void -assertConstantsMatch(void) { -/*---------------------------------------------------------------------------- - There are some constants that we define as part of the Xmlrpc-c - interface that are identical to constants in the Curl interface to - make curl option setting work. This function asserts such - formally. ------------------------------------------------------------------------------*/ -#define assertMatch(xmlrpc_name, curl_name) \ - assert((unsigned)xmlrpc_name == (unsigned)curl_name) - - assertMatch(XMLRPC_SSLVERSION_DEFAULT , CURL_SSLVERSION_DEFAULT); - assertMatch(XMLRPC_SSLVERSION_TLSv1 , CURL_SSLVERSION_TLSv1 ); - assertMatch(XMLRPC_SSLVERSION_SSLv2 , CURL_SSLVERSION_SSLv2 ); - assertMatch(XMLRPC_SSLVERSION_SSLv3 , CURL_SSLVERSION_SSLv3 ); - - assertMatch(XMLRPC_HTTPAUTH_BASIC , CURLAUTH_BASIC ); - assertMatch(XMLRPC_HTTPAUTH_DIGEST , CURLAUTH_DIGEST ); - assertMatch(XMLRPC_HTTPAUTH_GSSNEGOTIATE , CURLAUTH_GSSNEGOTIATE); - assertMatch(XMLRPC_HTTPAUTH_NTLM , CURLAUTH_NTLM ); - - assertMatch(XMLRPC_HTTPPROXY_HTTP , CURLPROXY_HTTP ); - assertMatch(XMLRPC_HTTPPROXY_SOCKS5 , CURLPROXY_SOCKS5 ); - -#undef assertMatch -} - - - -/* About Curl and GSSAPI credential delegation: - - Up through Curl 7.21.6, libcurl always delegates GSSAPI credentials, which - means it gives the client's secrets to the server so the server can operate - on the client's behalf. In mid-2011, this was noticed to be a major - security exposure, because the server is not necessarily trustworthy. - One is supposed to delegate one's credentials only to a server one trusts. - So in 7.21.7, Curl never delegates GSSAPI credentials. - - But that causes problems for clients that _do_ trust their server, which - had always relied upon Curl's delegation. - - So starting in 7.22.0, Curl gives the user the choice. The default is no - delegation, but the Curl user can set the CURLOPT_GSSAPI_DELEGATION flag to - order delegation. - - Complicating matters is that some people made local variations of Curl - during the transition phase, so the version number alone isn't - determinative, so we rely on it only where we have to. - - So Xmlrpc-c gives the same choice to its own user, via its - 'gssapi_delegation' Curl transport option. - - Current Xmlrpc-c can be linked with, and compiled with, any version of - Curl, so it has to carefully consider all the possibilities. -*/ - - - -static bool -curlAlwaysDelegatesGssapi(void) { -/*---------------------------------------------------------------------------- - The Curl library we're using always delegates GSSAPI credentials - (we don't have a choice). - - This works with Curl as distributed by the Curl project, but there are - other versions of Curl for which it doesn't -- those versions report - older version numbers but in fact don't always delegate. Some never - delegate, and some give the user the option. ------------------------------------------------------------------------------*/ - curl_version_info_data * const curlInfoP = - curl_version_info(CURLVERSION_NOW); - - return (curlInfoP->version_num <= 0x071506); /* 7.21.6 */ -} - - - -static void -requestGssapiDelegation(CURL * const curlSessionP ATTR_UNUSED, - bool * const gotItP) { -/*---------------------------------------------------------------------------- - Set up the Curl session *curlSessionP to delegate its GSSAPI credentials to - the server. - - Return *gotitP is true iff we succeed. We fail when the version of libcurl - for which we are compiled or to which we are linked is not capable of such - delegation. ------------------------------------------------------------------------------*/ -#if HAVE_CURL_GSSAPI_DELEGATION - int rc; - - rc = curl_easy_setopt(curlSessionP, CURLOPT_GSSAPI_DELEGATION, - CURLGSSAPI_DELEGATION_FLAG); - - if (rc == CURLE_OK) - *gotItP = true; - else { - /* The only way curl_easy_setopt() could have failed is that we - are running with an old libcurl from before - CURLOPT_GSSAPI_DELEGATION was invented. - */ - if (curlAlwaysDelegatesGssapi()) { - /* No need to request delegation; we got it anyway */ - *gotItP = true; - } else - *gotItP = false; - } -#else - if (curlAlwaysDelegatesGssapi()) - *gotItP = true; - else { - /* The library may be able to do credential delegation on request, but - we have no way to request it; the Curl for which we are compiled is - too old. - */ - *gotItP = false; - } -#endif -} - - - -static void -setupCurlSession(xmlrpc_env * const envP, - curlTransaction * const transP, - const xmlrpc_server_info * const serverInfoP, - bool const dontAdvertise, - const char * const userAgent, - const struct curlSetup * const curlSetupP) { -/*---------------------------------------------------------------------------- - Set up the Curl session for the transaction *transP so that - a subsequent curl_easy_perform() would perform said transaction. - - *serverInfoP tells what sort of authentication to set up. This is - an embarassment, as the xmlrpc_server_info type is part of the - Xmlrpc-c interface. Some day, we need to replace this with a type - (probably identical) not tied to Xmlrpc-c. ------------------------------------------------------------------------------*/ - CURL * const curlSessionP = transP->curlSessionP; - - assertConstantsMatch(); - - /* A Curl session is serial -- it processes zero or one transaction - at a time. We use the "private" attribute of the Curl session to - indicate which transaction it is presently processing. This is - important when the transaction finishes, because libcurl will just - tell us that something finished on a particular session, not that - a particular transaction finished. - */ - - /* It is our policy to do a libcurl call only where necessary, I.e. not - to set what is the default anyhow. The reduction in calls may save - some time, but mostly, it will save us encountering rare bugs or - suffering from backward incompatibilities in future libcurl. I.e. we - don't exercise any more of libcurl than we have to. - */ - - curl_easy_setopt(curlSessionP, CURLOPT_NOSIGNAL, 1); - /* See discussion of CURLOPT_NOSIGNAL above */ - - curl_easy_setopt(curlSessionP, CURLOPT_PRIVATE, transP); - - curl_easy_setopt(curlSessionP, CURLOPT_POST, 1); - curl_easy_setopt(curlSessionP, CURLOPT_URL, transP->serverUrl); - - XMLRPC_MEMBLOCK_APPEND(char, envP, transP->postDataP, "\0", 1); - if (!envP->fault_occurred) { - curl_easy_setopt(curlSessionP, CURLOPT_POSTFIELDS, - XMLRPC_MEMBLOCK_CONTENTS(char, transP->postDataP)); - curl_easy_setopt(curlSessionP, CURLOPT_WRITEFUNCTION, collect); - curl_easy_setopt(curlSessionP, CURLOPT_FILE, transP->responseDataP); - /* CURLOPT_FILE is the older name for CURLOPT_WRITEDATA */ - curl_easy_setopt(curlSessionP, CURLOPT_HEADER, 0); - curl_easy_setopt(curlSessionP, CURLOPT_ERRORBUFFER, transP->curlError); - if (transP->progress) { - curl_easy_setopt(curlSessionP, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(curlSessionP, CURLOPT_PROGRESSFUNCTION, - curlProgress); - curl_easy_setopt(curlSessionP, CURLOPT_PROGRESSDATA, transP); - } else - curl_easy_setopt(curlSessionP, CURLOPT_NOPROGRESS, 1); - - curl_easy_setopt(curlSessionP, CURLOPT_SSL_VERIFYPEER, - curlSetupP->sslVerifyPeer); - curl_easy_setopt(curlSessionP, CURLOPT_SSL_VERIFYHOST, - curlSetupP->sslVerifyHost ? 2 : 0); - - if (curlSetupP->networkInterface) - curl_easy_setopt(curlSessionP, CURLOPT_INTERFACE, - curlSetupP->networkInterface); - if (curlSetupP->referer) - curl_easy_setopt(curlSessionP, CURLOPT_REFERER, - curlSetupP->referer); - if (curlSetupP->sslCert) - curl_easy_setopt(curlSessionP, CURLOPT_SSLCERT, - curlSetupP->sslCert); - if (curlSetupP->sslCertType) - curl_easy_setopt(curlSessionP, CURLOPT_SSLCERTTYPE, - curlSetupP->sslCertType); - if (curlSetupP->sslCertPasswd) - curl_easy_setopt(curlSessionP, CURLOPT_SSLCERTPASSWD, - curlSetupP->sslCertPasswd); - if (curlSetupP->sslKey) - curl_easy_setopt(curlSessionP, CURLOPT_SSLKEY, - curlSetupP->sslKey); - if (curlSetupP->sslKeyType) - curl_easy_setopt(curlSessionP, CURLOPT_SSLKEYTYPE, - curlSetupP->sslKeyType); - if (curlSetupP->sslKeyPasswd) - curl_easy_setopt(curlSessionP, CURLOPT_SSLKEYPASSWD, - curlSetupP->sslKeyPasswd); - if (curlSetupP->sslEngine) - curl_easy_setopt(curlSessionP, CURLOPT_SSLENGINE, - curlSetupP->sslEngine); - if (curlSetupP->sslEngineDefault) - /* 3rd argument seems to be required by some Curl */ - curl_easy_setopt(curlSessionP, CURLOPT_SSLENGINE_DEFAULT, 1l); - if (curlSetupP->sslVersion != XMLRPC_SSLVERSION_DEFAULT) - curl_easy_setopt(curlSessionP, CURLOPT_SSLVERSION, - curlSetupP->sslVersion); - if (curlSetupP->caInfo) - curl_easy_setopt(curlSessionP, CURLOPT_CAINFO, - curlSetupP->caInfo); - if (curlSetupP->caPath) - curl_easy_setopt(curlSessionP, CURLOPT_CAPATH, - curlSetupP->caPath); - if (curlSetupP->randomFile) - curl_easy_setopt(curlSessionP, CURLOPT_RANDOM_FILE, - curlSetupP->randomFile); - if (curlSetupP->egdSocket) - curl_easy_setopt(curlSessionP, CURLOPT_EGDSOCKET, - curlSetupP->egdSocket); - if (curlSetupP->sslCipherList) - curl_easy_setopt(curlSessionP, CURLOPT_SSL_CIPHER_LIST, - curlSetupP->sslCipherList); - - if (curlSetupP->proxy) - curl_easy_setopt(curlSessionP, CURLOPT_PROXY, curlSetupP->proxy); - if (curlSetupP->proxyAuth != CURLAUTH_BASIC) - /* Note that the Xmlrpc-c default and the Curl default are - different. Xmlrpc-c is none, while Curl is basic. One reason - for this is that it makes our extensible parameter list scheme, - wherein zero always means default, easier. - */ - curl_easy_setopt(curlSessionP, CURLOPT_PROXYAUTH, - curlSetupP->proxyAuth); - if (curlSetupP->proxyPort) - curl_easy_setopt(curlSessionP, CURLOPT_PROXYPORT, - curlSetupP->proxyPort); - if (curlSetupP->proxyUserPwd) - curl_easy_setopt(curlSessionP, CURLOPT_PROXYUSERPWD, - curlSetupP->proxyUserPwd); - if (curlSetupP->proxyType) - curl_easy_setopt(curlSessionP, CURLOPT_PROXYTYPE, - curlSetupP->proxyType); - - if (curlSetupP->verbose) - curl_easy_setopt(curlSessionP, CURLOPT_VERBOSE, 1l); - - if (curlSetupP->timeout) - setCurlTimeout(curlSessionP, curlSetupP->timeout); - - if (curlSetupP->connectTimeout) - setCurlConnectTimeout(curlSessionP, curlSetupP->connectTimeout); - else - curl_easy_setopt(curlSessionP, CURLOPT_CONNECTTIMEOUT, - LONG_MAX/1000); - /* Some documentation says 0 means indefinite and other says 0 - means 5 minutes. The latter appears to be true. Some - libcurl (e.g. 7.12.2, but not 7.21.0) has an apparent bug - in which anything larger than LONG_MAX/1000 results in an - instantaneous timeout. - */ - - if (curlSetupP->gssapiDelegation) { - bool gotIt; - requestGssapiDelegation(curlSessionP, &gotIt); - - if (!gotIt) - xmlrpc_faultf(envP, "Cannot honor 'gssapi_delegation' " - "Curl transport option. " - "This version of libcurl is not " - "capable of delegating GSSAPI credentials"); - } - - if (!envP->fault_occurred) { - const char * authHdrValue; - /* NULL means we don't have to construct an explicit - Authorization: header. non-null means we have to - construct one with this as its value. - */ - - setupAuth(envP, curlSessionP, serverInfoP, &authHdrValue); - if (!envP->fault_occurred) { - struct curl_slist * headerList; - createCurlHeaderList(envP, authHdrValue, - dontAdvertise, userAgent, - &headerList); - if (!envP->fault_occurred) { - curl_easy_setopt( - curlSessionP, CURLOPT_HTTPHEADER, headerList); - transP->headerList = headerList; - } - if (authHdrValue) - xmlrpc_strfree(authHdrValue); - } - } - } -} - - - -void -curlTransaction_create(xmlrpc_env * const envP, - CURL * const curlSessionP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block * const responseXmlP, - bool const dontAdvertise, - const char * const userAgent, - const struct curlSetup * const curlSetupStuffP, - void * const userContextP, - curlt_finishFn * const finish, - curlt_progressFn * const progress, - curlTransaction ** const curlTransactionPP) { - - curlTransaction * curlTransactionP; - - MALLOCVAR(curlTransactionP); - if (curlTransactionP == NULL) - xmlrpc_faultf(envP, "No memory to create Curl transaction."); - else { - curlTransactionP->finish = finish; - curlTransactionP->curlSessionP = curlSessionP; - curlTransactionP->userContextP = userContextP; - curlTransactionP->progress = progress; - - /* Curl sometimes neglects to set 'curlError', so we set it here to - a value that means no explanation available. - */ - curlTransactionP->curlError[0] = '\0'; - - curlTransactionP->serverUrl = strdup(serverP->serverUrl); - if (curlTransactionP->serverUrl == NULL) - xmlrpc_faultf(envP, "Out of memory to store server URL."); - else { - curlTransactionP->postDataP = callXmlP; - curlTransactionP->responseDataP = responseXmlP; - - setupCurlSession(envP, curlTransactionP, - serverP, dontAdvertise, userAgent, - curlSetupStuffP); - - if (envP->fault_occurred) - xmlrpc_strfree(curlTransactionP->serverUrl); - } - if (envP->fault_occurred) - free(curlTransactionP); - } - *curlTransactionPP = curlTransactionP; -} - - - -void -curlTransaction_destroy(curlTransaction * const curlTransactionP) { - - curl_slist_free_all(curlTransactionP->headerList); - xmlrpc_strfree(curlTransactionP->serverUrl); - - free(curlTransactionP); -} - - - -static void -interpretCurlEasyError(const char ** const descriptionP, - CURLcode const code) { - -#if HAVE_CURL_STRERROR - *descriptionP = strdup(curl_easy_strerror(code)); -#else - xmlrpc_asprintf(descriptionP, "Curl error code (CURLcode) %d", code); -#endif -} - - - -/* CURL quirks: - - We have seen Curl report that the transaction completed OK (CURLE_OK) when - the server sent back garbage instead of an HTTP response (because it wasn't - an HTTP server). In that case Curl reports zero in place of the response - code. It's strange that Curl doesn't report that protocol violation at a - higher level (perhaps with more detail), but apparently it does not, so we - go by the HTTP_CODE value. Note that if the server closes the connection - without responding at all, Curl calls the transaction failed with an "empty - reply from server" error code. - - It appears to be the case that when the server sends non-HTTP garbage, Curl - reports it as the HTTP response body. E.g. we had an inetd server respond - with a "library not found" error message because the server connected - Standard Error to the socket. The 'curl' program typed out the error - message, naked, and exited with exit status zero. We exploit this - discovery to give better error reporting to our user. - - We saw this with Curl 7.16.1. -*/ - - - -static const char * -formatDataReceived(curlTransaction * const curlTransactionP) { - - const char * retval; - - if (XMLRPC_MEMBLOCK_SIZE(char, curlTransactionP->responseDataP) == 0) - retval = xmlrpc_strdupsol(""); - else { - xmlrpc_asprintf( - &retval, - "Raw data from server: '%s'\n", - XMLRPC_MEMBLOCK_CONTENTS(char, curlTransactionP->responseDataP)); - } - return retval; -} - - - -void -curlTransaction_getError(curlTransaction * const curlTransactionP, - xmlrpc_env * const envP) { -/*---------------------------------------------------------------------------- - Determine whether the transaction *curlTransactionP was successful in HTTP - terms. Assume the transaction did complete. Return as *envP an indication - of whether the transaction failed and if so, how. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - - xmlrpc_env_init(&env); - - if (curlTransactionP->result != CURLE_OK) { - /* We've seen Curl just return a null string for an explanation - (e.g. when TCP connect() fails because IP address doesn't exist). - */ - const char * explanation; - - if (strlen(curlTransactionP->curlError) == 0) - interpretCurlEasyError(&explanation, curlTransactionP->result); - else - xmlrpc_asprintf(&explanation, "%s", curlTransactionP->curlError); - - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_NETWORK_ERROR, "libcurl failed even to execute the " - "HTTP transaction, explaining: %s", explanation); - - xmlrpc_strfree(explanation); - } else { - CURLcode res; - long http_result; - - res = curl_easy_getinfo(curlTransactionP->curlSessionP, - CURLINFO_HTTP_CODE, &http_result); - /* CURLINFO_HTTP_CODE is the old name for CURLINFO_RESPONSE_CODE */ - - if (res != CURLE_OK) - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_INTERNAL_ERROR, - "Curl performed the HTTP transaction, but was " - "unable to say what the HTTP result code was. " - "curl_easy_getinfo(CURLINFO_HTTP_CODE) says: %s", - curlTransactionP->curlError); - else { - if (http_result == 0) { - /* See above for what this case means */ - const char * const dataReceived = - formatDataReceived(curlTransactionP); - - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_NETWORK_ERROR, - "Server is not an XML-RPC server. Its response to our " - "call is not valid HTTP. Or it's valid HTTP with a " - "response code of zero. %s", dataReceived); - xmlrpc_strfree(dataReceived); - } else if (http_result != 200) - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_NETWORK_ERROR, - "HTTP response code is %ld, not 200", - http_result); - } - } - - if (env.fault_occurred) { - xmlrpc_env_set_fault_formatted( - envP, - env.fault_code, - "HTTP POST to URL '%s' failed. %s", - curlTransactionP->serverUrl, env.fault_string); - } - xmlrpc_env_clean(&env); -} - - - -void -curlTransaction_finish(xmlrpc_env * const envP, - curlTransaction * const curlTransactionP, - CURLcode const result) { - - curlTransactionP->result = result; - - if (curlTransactionP->finish) - curlTransactionP->finish(envP, curlTransactionP->userContextP); -} - - - -CURL * -curlTransaction_curlSession(curlTransaction * const curlTransactionP) { - - return curlTransactionP->curlSessionP; - -} diff --git a/trunk/lib/curl_transport/curltransaction.h b/trunk/lib/curl_transport/curltransaction.h deleted file mode 100644 index fd81090e4..000000000 --- a/trunk/lib/curl_transport/curltransaction.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef CURLTRANSACTION_H_INCLUDED -#define CURLTRANSACTION_H_INCLUDED - -#include "bool.h" -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/client.h" -#include - -typedef struct curlTransaction curlTransaction; - -typedef void curlt_finishFn(xmlrpc_env * const, void * const); -typedef void curlt_progressFn( - void * const, double const, double const, double const, double const, - bool * const); - -struct curlSetup { - - /* This is all client transport properties that are implemented as - simple Curl session properties (i.e. the transport basically just - passes them through to Curl without looking at them). - - People occasionally want to replace all this with something where - the Xmlrpc-c user simply does the curl_easy_setopt() call and this - code need not know about all these options. Unfortunately, that's - a significant modularity violation. Either the Xmlrpc-c user - controls the Curl object or he doesn't. If he does, then he - shouldn't use libxmlrpc_client -- he should just copy some of this - code into his own program. If he doesn't, then he should never see - the Curl library. - - Speaking of modularity: the only reason this is a separate struct - is to make the code easier to manage. Ideally, the fact that these - particular properties of the transport are implemented by simple - Curl session setup would be known only at the lowest level code - that does that setup. - */ - - const char * networkInterface; - /* This identifies the network interface on the local side to - use for the session. It is an ASCIIZ string in the form - that the Curl recognizes for setting its CURLOPT_INTERFACE - option (also the --interface option of the Curl program). - E.g. "9.1.72.189" or "giraffe-data.com" or "eth0". - - It isn't necessarily valid, but it does have a terminating NUL. - - NULL means we have no preference. - */ - const char * referer; - bool sslVerifyPeer; - /* In an SSL connection, we should authenticate the server's SSL - certificate -- refuse to talk to him if it isn't authentic. - This is equivalent to Curl's CURLOPT_SSL_VERIFY_PEER option. - */ - bool sslVerifyHost; - /* In an SSL connection, we should verify that the server's - certificate (independently of whether the certificate is - authentic) indicates the host name that is in the URL we - are using for the server. - */ - - const char * sslCert; - const char * sslCertType; - const char * sslCertPasswd; - const char * sslKey; - const char * sslKeyType; - const char * sslKeyPasswd; - const char * sslEngine; - bool sslEngineDefault; - unsigned int sslVersion; - const char * caInfo; - const char * caPath; - const char * randomFile; - const char * egdSocket; - const char * sslCipherList; - - const char * proxy; - unsigned int proxyPort; - unsigned int proxyAuth; - /* e.g. CURLAUTH_BASIC, CURLAUTH_NTLM, ... */ - const char * proxyUserPwd; - unsigned int proxyType; - /* see enum curl_proxytype: CURLPROXY_HTTP, CURLPROXY_SOCKS4, ... */ - - bool gssapiDelegation; - /* allow GSSAPI credential delegation */ - - unsigned int timeout; - /* 0 = no Curl timeout after connect. This is in milliseconds. */ - - unsigned int connectTimeout; - /* 0 = no Curl timeout on connect. This is in milliseconds. */ - - bool verbose; -}; - - -void -curlTransaction_create(xmlrpc_env * const envP, - CURL * const curlSessionP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block * const responseXmlP, - bool const dontAdvertise, - const char * const userAgent, - const struct curlSetup * const curlSetupStuffP, - void * const userContextP, - curlt_finishFn * const finish, - curlt_progressFn * const progress, - curlTransaction ** const curlTransactionPP); - -void -curlTransaction_destroy(curlTransaction * const curlTransactionP); - -void -curlTransaction_finish(xmlrpc_env * const envP, - curlTransaction * const curlTransactionP, - CURLcode const result); - -void -curlTransaction_getError(curlTransaction * const curlTransactionP, - xmlrpc_env * const envP); - -CURL * -curlTransaction_curlSession(curlTransaction * const curlTransactionP); - -#endif diff --git a/trunk/lib/curl_transport/curlversion.h b/trunk/lib/curl_transport/curlversion.h deleted file mode 100644 index 4ad445a09..000000000 --- a/trunk/lib/curl_transport/curlversion.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef CURLVERSION_H_INCLUDED -#define CURLVERSION_H_INCLUDED - -#define CMAJOR LIBCURL_VERSION_MAJOR -#define CMINOR LIBCURL_VERSION_MINOR -#if CMAJOR > 7 || (CMAJOR == 7 && CMINOR >= 10) - #define HAVE_CURL_NOSIGNAL 1 -#else - #define HAVE_CURL_NOSIGNAL 0 -#endif -#if CMAJOR > 7 || (CMAJOR == 7 && CMINOR >= 12) - #define HAVE_CURL_STRERROR 1 -#else - #define HAVE_CURL_STRERROR 0 -#endif - -#ifdef CURLGSSAPI_DELEGATION_FLAG -#define HAVE_CURL_GSSAPI_DELEGATION 1 -#else -#define HAVE_CURL_GSSAPI_DELEGATION 0 -#endif - -#undef CMAJOR -#undef CMINOR - -#endif diff --git a/trunk/lib/curl_transport/xmlrpc_curl_transport.c b/trunk/lib/curl_transport/xmlrpc_curl_transport.c deleted file mode 100644 index 70ebc6765..000000000 --- a/trunk/lib/curl_transport/xmlrpc_curl_transport.c +++ /dev/null @@ -1,1652 +0,0 @@ -/*============================================================================= - xmlrpc_curl_transport -=============================================================================== - Curl-based client transport for Xmlrpc-c - - By Bryan Henderson 04.12.10. - - Contributed to the public domain by its author. -=============================================================================*/ - -/*---------------------------------------------------------------------------- - Curl global variables: - - Curl maintains some minor information in process-global variables. - One must call curl_global_init() to initialize them before calling - any other Curl library function. This is not state information -- - it is constants. They just aren't the kind of constants that the - library loader knows how to set, so there has to be this explicit - call to set them up. The matching function curl_global_cleanup() - returns resources these use (to wit, the constants live in - malloc'ed storage and curl_global_cleanup() frees the storage). - - So our setup_global_const transport operation calls - curl_global_init() and our teardown_global_const calls - curl_global_cleanup(). - - The Curl library is supposed to maintain a reference count for the - global constants so that multiple modules using the library and - independently calling curl_global_init() and curl_global_cleanup() - are not a problem. But today, it just keeps a flag "I have been - initialized" and the first call to curl_global_cleanup() destroys - the constants for everybody. Therefore, the user of the Xmlrpc-c - Curl client XML transport must make sure not to call - teardownGlobalConstants until everything else in his program is - done using the Curl library. - - Note that curl_global_init() is not threadsafe (with or without the - reference count), therefore our setup_global_const is not, and must - be called when no other thread in the process is running. - Typically, one calls it right at the beginning of the program. - - There are actually two other classes of global variables in the - Curl library, which we are ignoring: debug options and custom - memory allocator function identities. Our code never changes these - global variables from default. If something else in the user's - program does, User is responsible for making sure it doesn't - interfere with our use of the library. - - Note that when we say what the Curl library does, we're also - talking about various other libraries Curl uses internally, and in - fact much of what we're saying about global variables springs from - such subordinate libraries as OpenSSL and Winsock. ------------------------------------------------------------------------------*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include -#if HAVE_SYS_SELECT_H -#include -#endif -#include -#include - -#include "bool.h" -#include "girmath.h" -#include "mallocvar.h" -#include "linklist.h" -#include "girstring.h" - -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/select_int.h" -#include "xmlrpc-c/client_int.h" -#include "xmlrpc-c/transport.h" -#include "xmlrpc-c/time_int.h" -#include "xmlrpc-c/lock.h" -#include "xmlrpc-c/lock_platform.h" - -#include -#ifdef NEED_CURL_TYPES_H -#include -#endif -#include -#include - -#include "curltransaction.h" -#include "curlmulti.h" -#include "curlversion.h" - -#if MSVCRT -#if defined(_DEBUG) -# include -# define new DEBUG_NEW -# define malloc(size) _malloc_dbg( size, _NORMAL_BLOCK, __FILE__, __LINE__) -# undef THIS_FILE - static char THIS_FILE[] = __FILE__; -#endif -#endif - - -typedef struct rpc rpc; - - - -static void -tracev(const char * const fmt, - va_list args) { - - vfprintf(stderr, fmt, args); - - fprintf(stderr, "\n"); -} - - - -static void -trace(const char * const fmt, ...) { - - if (xmlrpc_trace_transport) { - va_list args; - - va_start(args, fmt); - tracev(fmt, args); - va_end(args); - } -} - - - -static int -timeDiffMillisec(xmlrpc_timespec const minuend, - xmlrpc_timespec const subtractor) { - - unsigned int const million = 1000000; - - return (minuend.tv_sec - subtractor.tv_sec) * 1000 + - (minuend.tv_nsec - subtractor.tv_nsec + million/2) / million; -} - - - -static bool -timeIsAfter(xmlrpc_timespec const comparator, - xmlrpc_timespec const comparand) { - - if (comparator.tv_sec > comparand.tv_sec) - return true; - else if (comparator.tv_sec < comparand.tv_sec) - return false; - else { - /* Seconds are equal */ - if (comparator.tv_nsec > comparand.tv_nsec) - return true; - else - return false; - } -} - - - -static void -addMilliseconds(xmlrpc_timespec const addend, - unsigned int const adder, - xmlrpc_timespec * const sumP) { - - unsigned int const million = 1000000; - unsigned int const billion = 1000000000; - - xmlrpc_timespec sum; - - sum.tv_sec = addend.tv_sec + adder / 1000; - sum.tv_nsec = addend.tv_nsec + (adder % 1000) * million; - - if ((uint32_t)sum.tv_nsec >= billion) { - sum.tv_sec += 1; - sum.tv_nsec -= billion; - } - *sumP = sum; -} - - - -struct xmlrpc_client_transport { - CURL * syncCurlSessionP; - /* Handle for a Curl library session object that we use for - all synchronous RPCs. An async RPC has one of its own, - and consequently does not share things such as persistent - connections and cookies with any other RPC. - */ - struct lock * syncCurlSessionLockP; - /* Hold this lock while accessing or using *syncCurlSessionP. - You're using the session from the time you set any - attributes in it or start a transaction with it until any - transaction has finished and you've lost interest in any - attributes of the session. - */ - curlMulti * syncCurlMultiP; - /* The Curl multi manager that this transport uses to execute - Curl transactions for RPCs requested via the synchronous - interface. The fact that there is never more than one such - transaction going at a time might make you wonder why a - "multi" manager is needed. The reason is that it is the only - interface in libcurl that gives us the flexibility to execute - the transaction with proper interruptibility. The only Curl - transaction ever attached to this multi manager is - 'syncCurlSessionP'. - - This is constant (the handle, not the object). - */ - curlMulti * asyncCurlMultiP; - /* The Curl multi manager that this transport uses to execute - Curl transactions for RPCs requested via the asynchronous - interface. Note that there may be multiple such Curl transactions - simultaneously and one can't wait for a particular one to finish; - the collection of asynchronous RPCs are an indivisible mass. - - This is constant (the handle, not the object). - */ - bool dontAdvertise; - /* Don't identify to the server the XML-RPC engine we are using. If - false, include a User-Agent HTTP header in all requests that - identifies the Xmlrpc-c and Curl libraries. - - See also 'userAgent'. - - This is constant. - */ - const char * userAgent; - /* Information to include in a User-Agent HTTP header, reflecting - facilities outside of Xmlrpc-c. - - Null means none. - - The full User-Agent header value is this information (if - 'userAgent' is non-null) followed by identification of Xmlrpc-c - and Curl (if 'dontAdvertise' is false). If 'userAgent' is null - and 'dontAdvertise' is true, we put no User-Agent header at all - in the request. - - This is constant. - */ - struct curlSetup curlSetupStuff; - /* This is constant */ - int * interruptP; - /* Pointer to a value that user sets to nonzero to indicate he wants - the transport to give up on whatever it is doing and return ASAP. - - NULL means none -- transport never gives up. - - This is constant. - */ -}; - - - -struct rpc { - struct xmlrpc_client_transport * transportP; - /* The client XML transport that transports this RPC */ - curlTransaction * curlTransactionP; - /* The object which does the HTTP transaction, with no knowledge - of XML-RPC or Xmlrpc-c. - */ - CURL * curlSessionP; - /* The Curl session to use for the Curl transaction to perform - the RPC. - */ - xmlrpc_mem_block * responseXmlP; - /* Where the response XML for this RPC should go or has gone. */ - xmlrpc_transport_asynch_complete complete; - /* Routine to call to complete the RPC after it is complete HTTP-wise. - NULL if none. - */ - xmlrpc_transport_progress progress; - /* Routine to call periodically to report the progress of transporting - the call and response. NULL if none. - */ - struct xmlrpc_call_info * callInfoP; - /* User's identifier for this RPC */ -}; - - -static void -lockSyncCurlSession(struct xmlrpc_client_transport * const transportP) { - transportP->syncCurlSessionLockP->acquire( - transportP->syncCurlSessionLockP); -} - - - -static void -unlockSyncCurlSession(struct xmlrpc_client_transport * const transportP) { - transportP->syncCurlSessionLockP->release( - transportP->syncCurlSessionLockP); -} - - - -static void -initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { - -#if MSVCRT - /* This is CRITICAL so that cURL-Win32 works properly! */ - - /* So this commenter says, but I wonder why. libcurl should do the - required WSAStartup() itself, and it looks to me like it does. - -Bryan 06.01.01 - */ - WORD wVersionRequested; - WSADATA wsaData; - int err; - wVersionRequested = MAKEWORD(1, 1); - - err = WSAStartup(wVersionRequested, &wsaData); - if (err) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Winsock startup failed. WSAStartup returned rc %d", err); - else { - if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { - /* Tell the user that we couldn't find a useable */ - /* winsock.dll. */ - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Winsock reported that " - "it does not implement the requested version 1.1."); - } - if (envP->fault_occurred) - WSACleanup(); - } -#endif -} - - - -static void -termWindowsStuff(void) { - -#if MSVCRT - WSACleanup(); -#endif -} - - - -static bool -curlHasNosignal(void) { - - bool retval; - -#if HAVE_CURL_NOSIGNAL - curl_version_info_data * const curlInfoP = - curl_version_info(CURLVERSION_NOW); - - retval = (curlInfoP->version_num >= 0x070A00); /* 7.10.0 */ -#else - retval = false; -#endif - return retval; -} - - - -static xmlrpc_timespec -pselectTimeout(xmlrpc_timeoutType const timeoutType, - xmlrpc_timespec const timeoutDt) { -/*---------------------------------------------------------------------------- - Return the value that should be used in the select() call to wait for - there to be work for the Curl multi manager to do, given that the user - wants to timeout according to 'timeoutType' and 'timeoutDt'. ------------------------------------------------------------------------------*/ - unsigned int const million = 1000000; - unsigned int selectTimeoutMillisec; - xmlrpc_timespec retval; - - /* We assume there is work to do at least every 3 seconds, because - the Curl multi manager often has retries and other scheduled work - that doesn't involve file handles on which we can select(). - One thing that might cause work to do without any file handle becoming - ready is Curl timing out a request. - */ - switch (timeoutType) { - case timeout_no: - selectTimeoutMillisec = 3000; - break; - case timeout_yes: { - xmlrpc_timespec nowTime; - int timeLeft; - - xmlrpc_gettimeofday(&nowTime); - timeLeft = timeDiffMillisec(timeoutDt, nowTime); - - selectTimeoutMillisec = MIN(3000, MAX(0, timeLeft)); - } break; - } - retval.tv_sec = selectTimeoutMillisec / 1000; - retval.tv_nsec = (uint32_t)((selectTimeoutMillisec % 1000) * million); - - return retval; -} - - - -static void -processCurlMessages(xmlrpc_env * const envP, - curlMulti * const curlMultiP) { - - bool endOfMessages; - - endOfMessages = false; /* initial assumption */ - - while (!endOfMessages && !envP->fault_occurred) { - CURLMsg curlMsg; - - curlMulti_getMessage(curlMultiP, &endOfMessages, &curlMsg); - - if (!endOfMessages) { - if (curlMsg.msg == CURLMSG_DONE) { - curlTransaction * curlTransactionP; - - curl_easy_getinfo(curlMsg.easy_handle, CURLINFO_PRIVATE, - (void *)&curlTransactionP); - - curlTransaction_finish(envP, - curlTransactionP, curlMsg.data.result); - } - } - } -} - - - -static void -waitForWork(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - xmlrpc_timeoutType const timeoutType, - xmlrpc_timespec const deadline, - sigset_t * const sigmaskP) { -/*---------------------------------------------------------------------------- - Wait for the Curl multi manager to have work to do, time to run out, - or a signal to be received (and caught), whichever comes first. - - Update the Curl multi manager's file descriptor sets to indicate what - work we found for it to do. - - Wait under signal mask *sigmaskP. The point of this is that Caller can - make sure that arrival of a signal of a certain class interrupts our wait, - even if the signal arrives shortly before we begin waiting. Caller blocks - that signal class, then checks whether a signal of that class has already - been received. If not, he calls us with *sigmaskP indicating that class - NOT blocked. Thus, if a signal of that class arrived any time after Caller - checked, we will return immediately and if it arrives while we're waiting, - we will return then. Note that we can provide this service only because - pselect() has the same atomic unblock/wait feature. - - If sigmaskP is NULL, wait under whatever the current signal mask is. ------------------------------------------------------------------------------*/ - fd_set readFdSet; - fd_set writeFdSet; - fd_set exceptFdSet; - int maxFd; - - trace("Waiting for work"); - - curlMulti_fdset(envP, curlMultiP, - &readFdSet, &writeFdSet, &exceptFdSet, &maxFd); - if (!envP->fault_occurred) { - if (maxFd == -1) { - /* There are no Curl file descriptors on which to wait. - So either there's work to do right now or all transactions - are already complete. - */ - } else { - xmlrpc_timespec const pselectTimeoutArg = - pselectTimeout(timeoutType, deadline); - - int rc; - - trace("No work available; waiting for a Curl file descriptor to " - "be ready or %u.%03u sec", - pselectTimeoutArg.tv_sec, pselectTimeoutArg.tv_nsec/1000000); - - rc = xmlrpc_pselect(maxFd+1, &readFdSet, &writeFdSet, &exceptFdSet, - &pselectTimeoutArg, sigmaskP); - - if (rc < 0 && errno != EINTR) - xmlrpc_faultf(envP, "Impossible failure of pselect() " - "with errno %d (%s)", - errno, strerror(errno)); - else { - /* Believe it or not, the Curl multi manager needs the - results of our pselect(). So hand them over: - */ - curlMulti_updateFdSet(curlMultiP, - readFdSet, writeFdSet, exceptFdSet); - } - } - trace("Wait is over"); - } -} - - - -static void -waitForWorkInt(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - xmlrpc_timeoutType const timeoutType, - xmlrpc_timespec const deadline, - int * const interruptP) { -/*---------------------------------------------------------------------------- - Same as waitForWork(), except we guarantee to return if a signal handler - sets or has set *interruptP, whereas waitForWork() can miss a signal - that happens before or just after it starts. - - We mess with global state -- the signal mask -- so we might mess up - a multithreaded program. Therefore, don't call this if - waitForWork() will suffice. ------------------------------------------------------------------------------*/ - sigset_t callerBlockSet; -#if MSVCRT - waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); -#else - sigset_t allSignals; - - assert(interruptP != NULL); - - sigfillset(&allSignals); - - sigprocmask(SIG_BLOCK, &allSignals, &callerBlockSet); - - if (*interruptP == 0) - waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); - else - trace("Not waiting because interrupt flag is set\n"); - - sigprocmask(SIG_SETMASK, &callerBlockSet, NULL); -#endif -} - - - -static void -doCurlWork(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - bool * const transStillRunningP) { -/*---------------------------------------------------------------------------- - Do whatever work is ready to be done by the Curl multi manager - identified by 'curlMultiP'. This typically is transferring data on - an HTTP connection because the server is ready. - - For each transaction for which the multi manager finishes all the - required work, complete the transaction by calling its - "finish" routine. - - Return *transStillRunningP false if this work completes all of the - manager's transactions so that there is no reason to call us ever - again. ------------------------------------------------------------------------------*/ - bool immediateWorkToDo; - int runningHandleCt; - - trace("Calling libcurl to perform all immediate work"); - - immediateWorkToDo = true; /* initial assumption */ - - while (immediateWorkToDo && !envP->fault_occurred) { - curlMulti_perform(envP, curlMultiP, - &immediateWorkToDo, &runningHandleCt); - } - - /* We either did all the work that's ready to do or hit an error. */ - - if (!envP->fault_occurred) { - trace("libcurl has performed all immediate work; %d tasks " - "(file handles) still running", runningHandleCt); - - /* The work we did may have resulted in asynchronous messages - (asynchronous to the thing they refer to, not to us, of course). - In particular the message "Curl transaction has completed". - So we process those now. - */ - processCurlMessages(envP, curlMultiP); - - *transStillRunningP = runningHandleCt > 0; - } -} - - - -static void -finishCurlMulti(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - xmlrpc_timeoutType const timeoutType, - xmlrpc_timespec const deadline, - int * const interruptP) { -/*---------------------------------------------------------------------------- - Prosecute all the Curl transactions under the control of - *curlMultiP. E.g. send data if server is ready to take it, get - data if server has sent some, wind up the transaction if it is - done. - - Don't return until all the Curl transactions are done or we time out. - - if 'interruptP' is non-null, it points to a value which is normally zero, - but is nonzero when Caller wants us to abort all the transactions and - return ASAP. - - The *interruptP flag alone will not interrupt us. We will wait in - spite of it for all Curl transactions to complete. *interruptP - just gives us a hint that the Curl transactions are being - interrupted, so we know there is work to do for them. (The way it - works is Caller sets up a "progress" function that checks the same - interrupt flag and reports "kill me." When we see the interrupt - flag, we tell libcurl to do whatever work there is to do, and as part of - that, libcurl calls the progress function, gets the "kill me" message, - and passes that on to us). ------------------------------------------------------------------------------*/ - /* For integrity, we make sure we don't let *interruptP interrupt our - wait for work more than once. That way, if for any reason libcurl - fails to call the progress function, or the progress function fails - to notice the interrupt flag and tell libcurl to abort, or libcurl - does abort as told, we don't have a busy loop of calls to - doCurlWork(). - - 'curlCalledSinceInterrupt' is part of this logic. - */ - - bool rpcStillRunning; - bool timedOut; - bool curlCalledSinceInterrupt; - - rpcStillRunning = true; /* initial assumption */ - timedOut = false; - curlCalledSinceInterrupt = false; - - while (rpcStillRunning && !timedOut && !envP->fault_occurred) { - - if (interruptP && !curlCalledSinceInterrupt) { - waitForWorkInt(envP, curlMultiP, timeoutType, deadline, - interruptP); - } else - waitForWork(envP, curlMultiP, timeoutType, deadline, NULL); - - if (!envP->fault_occurred) { - xmlrpc_timespec nowTime; - - /* doCurlWork() (among other things) finds Curl transactions that - user wants to abort and finishes them. (This is by virtue - of libcurl calling its progress function when we tell it to do - all available work). - */ - if (interruptP && *interruptP) - curlCalledSinceInterrupt = true; - - doCurlWork(envP, curlMultiP, &rpcStillRunning); - - xmlrpc_gettimeofday(&nowTime); - - timedOut = (timeoutType == timeout_yes && - timeIsAfter(nowTime, deadline)); - } - } -} - - - -static void -getTimeoutParm(xmlrpc_env * const envP, - const struct xmlrpc_curl_xportparms * const curlXportParmsP, - size_t const parmSize, - unsigned int * const timeoutP) { - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(timeout)) - *timeoutP = 0; - else { - if (curlHasNosignal()) { - /* libcurl takes a 'long' in milliseconds for the timeout value */ - if ((unsigned)(long)(curlXportParmsP->timeout) != - curlXportParmsP->timeout) - xmlrpc_faultf(envP, "Timeout value %u is too large.", - curlXportParmsP->timeout); - else - *timeoutP = curlXportParmsP->timeout; - } else - xmlrpc_faultf(envP, "You cannot specify a 'timeout' parameter " - "because the Curl library is too old and is not " - "capable of doing timeouts except by using " - "signals. You need at least Curl 7.10"); - } -} - - - -static void -getConnectTimeoutParm( - xmlrpc_env * const envP, - const struct xmlrpc_curl_xportparms * const curlXportParmsP, - size_t const parmSize, - unsigned int * const timeoutP) { - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(connect_timeout)) - *timeoutP = 0; - else { - if (curlHasNosignal()) { - /* libcurl represents the timeout in milliseconds with a 'long', - giving wrong results if it doesn't fit. - */ - if ((unsigned)(long)(curlXportParmsP->connect_timeout) != - curlXportParmsP->connect_timeout) - xmlrpc_faultf(envP, "Timeout value %u is too large.", - curlXportParmsP->connect_timeout); - else - *timeoutP = curlXportParmsP->connect_timeout; - } else - xmlrpc_faultf(envP, "You cannot specify a " - "'connect_timeout' parameter " - "because the Curl library is too old and is not " - "capable of doing timeouts except by using " - "signals. You need at least Curl 7.10"); - } -} - - - -static void -setVerbose(bool * const verboseP) { - - const char * const xmlrpcTraceCurl = getenv("XMLRPC_TRACE_CURL"); - - if (xmlrpcTraceCurl) - *verboseP = true; - else - *verboseP = false; -} - - - -static void -getXportParms(xmlrpc_env * const envP, - const struct xmlrpc_curl_xportparms * const curlXportParmsP, - size_t const parmSize, - struct xmlrpc_client_transport * const transportP) { -/*---------------------------------------------------------------------------- - Get the parameters out of *curlXportParmsP and update *transportP - to reflect them. - - *curlXportParmsP is a 'parmSize' bytes long prefix of - struct xmlrpc_curl_xportparms. - - curlXportParmsP is something the user created. It's designed to be - friendly to the user, not to this program, and is encumbered by - lots of backward compatibility constraints. In particular, the - user may have coded and/or compiled it at a time that struct - xmlrpc_curl_xportparms was smaller than it is now! - - Also, the user might have specified something invalid. - - So that's why we don't simply attach a copy of *curlXportParmsP to - *transportP. - - To the extent that *curlXportParmsP is too small to contain a parameter, - we return the default value for that parameter. - - Special case: curlXportParmsP == NULL means there is no input at all. - In that case, we return default values for everything. ------------------------------------------------------------------------------*/ - struct curlSetup * const curlSetupP = &transportP->curlSetupStuff; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(user_agent)) - transportP->userAgent = NULL; - else if (curlXportParmsP->user_agent == NULL) - transportP->userAgent = NULL; - else - transportP->userAgent = strdup(curlXportParmsP->user_agent); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(dont_advertise)) - transportP->dontAdvertise = false; - else - transportP->dontAdvertise = curlXportParmsP->dont_advertise; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(network_interface)) - curlSetupP->networkInterface = NULL; - else if (curlXportParmsP->network_interface == NULL) - curlSetupP->networkInterface = NULL; - else - curlSetupP->networkInterface = - strdup(curlXportParmsP->network_interface); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(no_ssl_verifypeer)) - curlSetupP->sslVerifyPeer = true; - else - curlSetupP->sslVerifyPeer = !curlXportParmsP->no_ssl_verifypeer; - - if (!curlXportParmsP || - parmSize < XMLRPC_CXPSIZE(no_ssl_verifyhost)) - curlSetupP->sslVerifyHost = true; - else - curlSetupP->sslVerifyHost = !curlXportParmsP->no_ssl_verifyhost; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(ssl_cert)) - curlSetupP->sslCert = NULL; - else if (curlXportParmsP->ssl_cert == NULL) - curlSetupP->sslCert = NULL; - else - curlSetupP->sslCert = strdup(curlXportParmsP->ssl_cert); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcerttype)) - curlSetupP->sslCertType = NULL; - else if (curlXportParmsP->sslcerttype == NULL) - curlSetupP->sslCertType = NULL; - else - curlSetupP->sslCertType = strdup(curlXportParmsP->sslcerttype); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcertpasswd)) - curlSetupP->sslCertPasswd = NULL; - else if (curlXportParmsP->sslcertpasswd == NULL) - curlSetupP->sslCertPasswd = NULL; - else - curlSetupP->sslCertPasswd = strdup(curlXportParmsP->sslcertpasswd); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkey)) - curlSetupP->sslKey = NULL; - else if (curlXportParmsP->sslkey == NULL) - curlSetupP->sslKey = NULL; - else - curlSetupP->sslKey = strdup(curlXportParmsP->sslkey); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeytype)) - curlSetupP->sslKeyType = NULL; - else if (curlXportParmsP->sslkeytype == NULL) - curlSetupP->sslKeyType = NULL; - else - curlSetupP->sslKeyType = strdup(curlXportParmsP->sslkeytype); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeypasswd)) - curlSetupP->sslKeyPasswd = NULL; - else if (curlXportParmsP->sslkeypasswd == NULL) - curlSetupP->sslKeyPasswd = NULL; - else - curlSetupP->sslKeyPasswd = strdup(curlXportParmsP->sslkeypasswd); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine)) - curlSetupP->sslEngine = NULL; - else if (curlXportParmsP->sslengine == NULL) - curlSetupP->sslEngine = NULL; - else - curlSetupP->sslEngine = strdup(curlXportParmsP->sslengine); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine_default)) - curlSetupP->sslEngineDefault = false; - else - curlSetupP->sslEngineDefault = !!curlXportParmsP->sslengine_default; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslversion)) - curlSetupP->sslVersion = XMLRPC_SSLVERSION_DEFAULT; - else - curlSetupP->sslVersion = curlXportParmsP->sslversion; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(cainfo)) - curlSetupP->caInfo = NULL; - else if (curlXportParmsP->cainfo == NULL) - curlSetupP->caInfo = NULL; - else - curlSetupP->caInfo = strdup(curlXportParmsP->cainfo); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(capath)) - curlSetupP->caPath = NULL; - else if (curlXportParmsP->capath == NULL) - curlSetupP->caPath = NULL; - else - curlSetupP->caPath = strdup(curlXportParmsP->capath); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(randomfile)) - curlSetupP->randomFile = NULL; - else if (curlXportParmsP->randomfile == NULL) - curlSetupP->randomFile = NULL; - else - curlSetupP->randomFile = strdup(curlXportParmsP->randomfile); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(egdsocket)) - curlSetupP->egdSocket = NULL; - else if (curlXportParmsP->egdsocket == NULL) - curlSetupP->egdSocket = NULL; - else - curlSetupP->egdSocket = strdup(curlXportParmsP->egdsocket); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(ssl_cipher_list)) - curlSetupP->sslCipherList = NULL; - else if (curlXportParmsP->ssl_cipher_list == NULL) - curlSetupP->sslCipherList = NULL; - else - curlSetupP->sslCipherList = strdup(curlXportParmsP->ssl_cipher_list); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy)) - curlSetupP->proxy = NULL; - else if (curlXportParmsP->proxy == NULL) - curlSetupP->proxy = NULL; - else - curlSetupP->proxy = strdup(curlXportParmsP->proxy); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy_port)) - curlSetupP->proxyPort = 8080; - else - curlSetupP->proxyPort = curlXportParmsP->proxy_port; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy_auth)) - curlSetupP->proxyAuth = CURLAUTH_BASIC; - else - curlSetupP->proxyAuth = curlXportParmsP->proxy_auth; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy_userpwd)) - curlSetupP->proxyUserPwd = NULL; - else if (curlXportParmsP->proxy_userpwd == NULL) - curlSetupP->proxyUserPwd = NULL; - else - curlSetupP->proxyUserPwd = strdup(curlXportParmsP->proxy_userpwd); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy_type)) - curlSetupP->proxyType = CURLPROXY_HTTP; - else - curlSetupP->proxyType = curlXportParmsP->proxy_type; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(gssapi_delegation)) - curlSetupP->gssapiDelegation = false; - else - curlSetupP->gssapiDelegation = !!curlXportParmsP->gssapi_delegation; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(referer)) - curlSetupP->referer = NULL; - else if (curlXportParmsP->referer == NULL) - curlSetupP->referer = NULL; - else - curlSetupP->referer = strdup(curlXportParmsP->referer); - - getTimeoutParm(envP, curlXportParmsP, parmSize, &curlSetupP->timeout); - - getConnectTimeoutParm(envP, curlXportParmsP, parmSize, - &curlSetupP->connectTimeout); -} - - - -static void -freeXportParms(const struct xmlrpc_client_transport * const transportP) { - - const struct curlSetup * const curlSetupP = &transportP->curlSetupStuff; - - if (curlSetupP->sslCipherList) - xmlrpc_strfree(curlSetupP->sslCipherList); - if (curlSetupP->egdSocket) - xmlrpc_strfree(curlSetupP->egdSocket); - if (curlSetupP->randomFile) - xmlrpc_strfree(curlSetupP->randomFile); - if (curlSetupP->caPath) - xmlrpc_strfree(curlSetupP->caPath); - if (curlSetupP->caInfo) - xmlrpc_strfree(curlSetupP->caInfo); - if (curlSetupP->sslEngine) - xmlrpc_strfree(curlSetupP->sslEngine); - if (curlSetupP->sslKeyPasswd) - xmlrpc_strfree(curlSetupP->sslKeyPasswd); - if (curlSetupP->sslKeyType) - xmlrpc_strfree(curlSetupP->sslKeyType); - if (curlSetupP->sslKey) - xmlrpc_strfree(curlSetupP->sslKey); - if (curlSetupP->sslCertPasswd) - xmlrpc_strfree(curlSetupP->sslCertPasswd); - if (curlSetupP->sslCertType) - xmlrpc_strfree(curlSetupP->sslCertType); - if (curlSetupP->sslCert) - xmlrpc_strfree(curlSetupP->sslCert); - if (curlSetupP->networkInterface) - xmlrpc_strfree(curlSetupP->networkInterface); - if (transportP->userAgent) - xmlrpc_strfree(transportP->userAgent); - if (curlSetupP->proxy) - xmlrpc_strfree(curlSetupP->proxy); - if (curlSetupP->proxyUserPwd) - xmlrpc_strfree(curlSetupP->proxyUserPwd); - if (curlSetupP->referer) - xmlrpc_strfree(curlSetupP->referer); -} - - - -static void -createSyncCurlSession(xmlrpc_env * const envP, - CURL ** const curlSessionPP) { -/*---------------------------------------------------------------------------- - Create a Curl session to be used for multiple serial transactions. - The Curl session we create is not complete -- it still has to be - further set up for each particular transaction. - - We can't set up anything here that changes from one transaction to the - next. - - We don't bother setting up anything that has to be set up for an - asynchronous transaction because code that is common between synchronous - and asynchronous transactions takes care of that anyway. - - That leaves things, such as cookies, that don't exist for - asynchronous transactions, and are common to multiple serial - synchronous transactions. ------------------------------------------------------------------------------*/ - CURL * const curlSessionP = curl_easy_init(); - - if (curlSessionP == NULL) - xmlrpc_faultf(envP, "Could not create Curl session. " - "curl_easy_init() failed."); - else { - /* The following is a trick. CURLOPT_COOKIEFILE is the name - of the file containing the initial cookies for the Curl - session. But setting it is also what turns on the cookie - function itself, whereby the Curl library accepts and - stores cookies from the server and sends them back on - future requests. We don't have a file of initial cookies, but - we want to turn on cookie function, so we set the option to - something we know does not validly name a file. Curl will - ignore the error and just start up cookie function with no - initial cookies. - */ - curl_easy_setopt(curlSessionP, CURLOPT_COOKIEFILE, ""); - - *curlSessionPP = curlSessionP; - } -} - - - -static void -destroySyncCurlSession(CURL * const curlSessionP) { - - curl_easy_cleanup(curlSessionP); -} - - - -static void -makeSyncCurlSession(xmlrpc_env * const envP, - struct xmlrpc_client_transport * const transportP) { - - transportP->syncCurlSessionLockP = xmlrpc_lock_create(); - if (transportP->syncCurlSessionLockP == NULL) - xmlrpc_faultf(envP, "Unable to create lock for " - "synchronous Curl session."); - else { - createSyncCurlSession(envP, &transportP->syncCurlSessionP); - - if (!envP->fault_occurred) { - /* We'll need a multi manager to actually execute this session: */ - transportP->syncCurlMultiP = curlMulti_create(); - - if (transportP->syncCurlMultiP == NULL) - xmlrpc_faultf(envP, "Unable to create Curl multi manager for " - "synchronous RPCs"); - - if (envP->fault_occurred) - destroySyncCurlSession(transportP->syncCurlSessionP); - } - if (envP->fault_occurred) - transportP->syncCurlSessionLockP->destroy( - transportP->syncCurlSessionLockP); - } -} - - - -static void -unmakeSyncCurlSession(struct xmlrpc_client_transport * const transportP) { - - curlMulti_destroy(transportP->syncCurlMultiP); - - destroySyncCurlSession(transportP->syncCurlSessionP); - - transportP->syncCurlSessionLockP->destroy( - transportP->syncCurlSessionLockP); -} - - - -static void -create(xmlrpc_env * const envP, - int const flags ATTR_UNUSED, - const char * const appname ATTR_UNUSED, - const char * const appversion ATTR_UNUSED, - const void * const transportparmsP, - size_t const parm_size, - struct xmlrpc_client_transport ** const handlePP) { -/*---------------------------------------------------------------------------- - This does the 'create' operation for a Curl client transport. ------------------------------------------------------------------------------*/ - const struct xmlrpc_curl_xportparms * const curlXportParmsP = - transportparmsP; - - struct xmlrpc_client_transport * transportP; - - MALLOCVAR(transportP); - if (transportP == NULL) - xmlrpc_faultf(envP, "Unable to allocate transport descriptor."); - else { - setVerbose(&transportP->curlSetupStuff.verbose); - - transportP->interruptP = NULL; - - transportP->asyncCurlMultiP = curlMulti_create(); - - if (transportP->asyncCurlMultiP == NULL) - xmlrpc_faultf(envP, "Unable to create Curl multi manager for " - "asynchronous RPCs"); - else { - getXportParms(envP, curlXportParmsP, parm_size, transportP); - - if (!envP->fault_occurred) { - makeSyncCurlSession(envP, transportP); - - if (envP->fault_occurred) - freeXportParms(transportP); - } - if (envP->fault_occurred) - curlMulti_destroy(transportP->asyncCurlMultiP); - } - if (envP->fault_occurred) - free(transportP); - } - *handlePP = transportP; -} - - - -static void -setInterrupt(struct xmlrpc_client_transport * const clientTransportP, - int * const interruptP) { - - clientTransportP->interruptP = interruptP; -} - - - -static void -assertNoOutstandingCurlWork(curlMulti * const curlMultiP) { - - xmlrpc_env env; - bool immediateWorkToDo; - int runningHandles; - - xmlrpc_env_init(&env); - - curlMulti_perform(&env, curlMultiP, &immediateWorkToDo, &runningHandles); - - /* We know the above was a no-op, since we're asserting that there - is no outstanding work. - */ - XMLRPC_ASSERT(!env.fault_occurred); - XMLRPC_ASSERT(!immediateWorkToDo); - XMLRPC_ASSERT(runningHandles == 0); - xmlrpc_env_clean(&env); -} - - - -static void -destroy(struct xmlrpc_client_transport * const clientTransportP) { -/*---------------------------------------------------------------------------- - This does the 'destroy' operation for a Curl client transport. - - An RPC is a reference to a client XML transport, so you may not - destroy a transport while RPCs are running. To ensure no - asynchronous RPCs are running, you must successfully execute the - transport 'finishAsync' method, with no interruptions or timeouts - allowed. To speed that up, you can set the transport's interrupt - flag to 1 first, which will make all outstanding RPCs fail - immediately. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(clientTransportP != NULL); - - assertNoOutstandingCurlWork(clientTransportP->asyncCurlMultiP); - /* We know this is true because a condition of destroying the - transport is that there be no outstanding asynchronous RPCs. - */ - assertNoOutstandingCurlWork(clientTransportP->syncCurlMultiP); - /* This is because a condition of destroying the transport is - that no transport method be running. The only way a - synchronous RPC can be in progress is for the 'perform' method - to be running. - */ - - unmakeSyncCurlSession(clientTransportP); - - curlMulti_destroy(clientTransportP->asyncCurlMultiP); - - freeXportParms(clientTransportP); - - free(clientTransportP); -} - - - -static void -performCurlTransaction(xmlrpc_env * const envP, - curlTransaction * const curlTransactionP, - curlMulti * const curlMultiP, - int * const interruptP) { - - curlMulti_addHandle(envP, curlMultiP, - curlTransaction_curlSession(curlTransactionP)); - - /* Failure here just means something screwy in the multi manager; - Above does not even begin to perform the HTTP transaction - */ - - if (!envP->fault_occurred) { - xmlrpc_timespec const dummy = {0,0}; - - finishCurlMulti(envP, curlMultiP, timeout_no, dummy, interruptP); - - /* Failure here just means something screwy in the multi - manager; any failure of the HTTP transaction would have been - recorded in *curlTransactionP. - */ - - if (!envP->fault_occurred) { - /* Curl session completed OK. But did HTTP transaction - it prosecuted work? - */ - curlTransaction_getError(curlTransactionP, envP); - } - /* If the CURL transaction is still going, removing the handle - here aborts it. At least it's supposed to. From what I've - seen in the Curl code in 2007, I don't think it does. I - couldn't get Curl maintainers interested in the problem, - except to say, "If you're right, there's a bug." - */ - curlMulti_removeHandle(curlMultiP, - curlTransaction_curlSession(curlTransactionP)); - } -} - - - -static void -startRpc(xmlrpc_env * const envP, - rpc * const rpcP) { - - curlMulti_addHandle(envP, - rpcP->transportP->asyncCurlMultiP, - curlTransaction_curlSession(rpcP->curlTransactionP)); -} - - - -static curlt_finishFn finishRpcCurlTransaction; -static curlt_progressFn curlTransactionProgress; - - - -static void -createRpc(xmlrpc_env * const envP, - struct xmlrpc_client_transport * const clientTransportP, - CURL * const curlSessionP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block * const responseXmlP, - xmlrpc_transport_asynch_complete complete, - xmlrpc_transport_progress progress, - struct xmlrpc_call_info * const callInfoP, - rpc ** const rpcPP) { - - rpc * rpcP; - - MALLOCVAR(rpcP); - if (rpcP == NULL) - xmlrpc_faultf(envP, "Couldn't allocate memory for rpc object"); - else { - curlt_progressFn * curlProgressFn; - - if (progress || clientTransportP->interruptP) - curlProgressFn = &curlTransactionProgress; - else { - /* There's nothing for curlTransactionProgress() to do, so save - the time and complexity of calling it. - */ - curlProgressFn = NULL; - } - rpcP->transportP = clientTransportP; - rpcP->curlSessionP = curlSessionP; - rpcP->callInfoP = callInfoP; - rpcP->complete = complete; - rpcP->progress = progress; - rpcP->responseXmlP = responseXmlP; - - curlTransaction_create(envP, - curlSessionP, - serverP, - callXmlP, responseXmlP, - clientTransportP->dontAdvertise, - clientTransportP->userAgent, - &clientTransportP->curlSetupStuff, - rpcP, - complete ? &finishRpcCurlTransaction : NULL, - curlProgressFn, - &rpcP->curlTransactionP); - if (!envP->fault_occurred) { - if (envP->fault_occurred) - curlTransaction_destroy(rpcP->curlTransactionP); - } - if (envP->fault_occurred) - free(rpcP); - } - *rpcPP = rpcP; -} - - - -static void -destroyRpc(rpc * const rpcP) { - - XMLRPC_ASSERT_PTR_OK(rpcP); - - curlTransaction_destroy(rpcP->curlTransactionP); - - free(rpcP); -} - - - -static void -performRpc(xmlrpc_env * const envP, - rpc * const rpcP, - curlMulti * const curlMultiP, - int * const interruptP) { - - performCurlTransaction(envP, rpcP->curlTransactionP, curlMultiP, - interruptP); -} - - - -static curlt_finishFn finishRpcCurlTransaction; - -static void -finishRpcCurlTransaction(xmlrpc_env * const envP ATTR_UNUSED, - void * const userContextP) { -/*---------------------------------------------------------------------------- - Handle the event that a Curl transaction for an asynchronous RPC has - completed on the Curl session identified by 'curlSessionP'. - - Tell the requester of the RPC the results. - - Remove the Curl session from its Curl multi manager and destroy the - Curl session, the XML response buffer, the Curl transaction, and the RPC. ------------------------------------------------------------------------------*/ - rpc * const rpcP = userContextP; - curlTransaction * const curlTransactionP = rpcP->curlTransactionP; - struct xmlrpc_client_transport * const transportP = rpcP->transportP; - - curlMulti_removeHandle(transportP->asyncCurlMultiP, - curlTransaction_curlSession(curlTransactionP)); - - { - xmlrpc_env env; - - xmlrpc_env_init(&env); - - curlTransaction_getError(curlTransactionP, &env); - - rpcP->complete(rpcP->callInfoP, rpcP->responseXmlP, env); - - xmlrpc_env_clean(&env); - } - - curl_easy_cleanup(rpcP->curlSessionP); - - XMLRPC_MEMBLOCK_FREE(char, rpcP->responseXmlP); - - destroyRpc(rpcP); -} - - - -static curlt_progressFn curlTransactionProgress; - -static void -curlTransactionProgress(void * const context, - double const dlTotal, - double const dlNow, - double const ulTotal, - double const ulNow, - bool * const abortP) { -/*---------------------------------------------------------------------------- - This is equivalent to a Curl "progress function" (the curlTransaction - object just passes through the call from libcurl). - - The curlTransaction calls this once a second telling us how much - data has transferred. If the transport user has set up a progress - function, we call that with this progress information. That - function might e.g. display a progress bar. - - Additionally, the curlTransaction gives us the opportunity to tell it - to abort the transaction, which we do if the user has set his - "interrupt" flag (which he registered with the transport when he - created it). ------------------------------------------------------------------------------*/ - rpc * const rpcP = context; - struct xmlrpc_client_transport * const transportP = rpcP->transportP; - - assert(rpcP); - assert(transportP); - - trace("Progress function called back by libcurl"); - - if (rpcP->progress) { - struct xmlrpc_progress_data progressData; - - trace("Calling transport client's progress function with %u %u %u %u", - dlTotal, dlNow, ulTotal, ulNow); - - progressData.response.total = dlTotal; - progressData.response.now = dlNow; - progressData.call.total = ulTotal; - progressData.call.now = ulNow; - - rpcP->progress(rpcP->callInfoP, progressData); - } - if (transportP->interruptP) { - trace("Interrupt flag is set; " - "directing libcurl to abort the transaction"); - *abortP = *transportP->interruptP; - } else - *abortP = false; -} - - - -static void -sendRequest(xmlrpc_env * const envP, - struct xmlrpc_client_transport * const clientTransportP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_transport_asynch_complete complete, - xmlrpc_transport_progress progress, - struct xmlrpc_call_info * const callInfoP) { -/*---------------------------------------------------------------------------- - Initiate an XML-RPC rpc asynchronously. Don't wait for it to go to - the server. - - Unless we return failure, we arrange to have complete() called when - the rpc completes. - - This does the 'send_request' operation for a Curl client transport. ------------------------------------------------------------------------------*/ - rpc * rpcP; - xmlrpc_mem_block * responseXmlP; - - responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - CURL * const curlSessionP = curl_easy_init(); - - if (curlSessionP == NULL) - xmlrpc_faultf(envP, "Could not create Curl session. " - "curl_easy_init() failed."); - else { - createRpc(envP, clientTransportP, curlSessionP, serverP, - callXmlP, responseXmlP, complete, progress, callInfoP, - &rpcP); - - if (!envP->fault_occurred) { - startRpc(envP, rpcP); - - if (envP->fault_occurred) - destroyRpc(rpcP); - } - if (envP->fault_occurred) - curl_easy_cleanup(curlSessionP); - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, responseXmlP); - } - /* If we're returning success, the user's eventual finish_asynch - call will destroy this RPC, Curl session, and response buffer - and remove the Curl session from the Curl multi manager. - (If we're returning failure, we didn't create any of those). - */ -} - - - -static void -finishAsynch( - struct xmlrpc_client_transport * const clientTransportP, - xmlrpc_timeoutType const timeoutType, - xmlrpc_timeout const timeout) { -/*---------------------------------------------------------------------------- - Wait for the Curl multi manager to finish the Curl transactions for - all outstanding RPCs and destroy those RPCs. - - But give up if a) too much time passes as defined by 'timeoutType' - and 'timeout'; or b) the transport client requests interruption - (i.e. the transport's interrupt flag becomes nonzero). Normally, a - signal must get our attention for us to notice the interrupt flag. - - This does the 'finish_asynch' operation for a Curl client transport. - - It would be cool to replace this with something analogous to the - Curl asynchronous interface: Have something like curl_multi_fdset() - that returns a bunch of file descriptors on which the user can wait - (along with possibly other file descriptors of his own) and - something like curl_multi_perform() to finish whatever RPCs are - ready to finish at that moment. The implementation would be little - more than wrapping curl_multi_fdset() and curl_multi_perform(). - - Note that the user can call this multiple times, because of timeouts, - but must eventually call it once with no timeout so he - knows that all the RPCs are finished. Either that or terminate the - process so it doesn't matter if RPCs are still going. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - - xmlrpc_timespec waitTimeoutTime; - /* The datetime after which we should quit waiting */ - - xmlrpc_env_init(&env); - - if (timeoutType == timeout_yes) { - xmlrpc_timespec waitStartTime; - xmlrpc_gettimeofday(&waitStartTime); - addMilliseconds(waitStartTime, timeout, &waitTimeoutTime); - } - - finishCurlMulti(&env, clientTransportP->asyncCurlMultiP, - timeoutType, waitTimeoutTime, - clientTransportP->interruptP); - - /* If the above fails, it is catastrophic, because it means there is - no way to complete outstanding Curl transactions and RPCs, and - no way to release their resources. - - We should at least expand this interface some day to push the - problem back up to the user, but for now we just do this Hail Mary - response. - - Note that a failure of finish_curlMulti() does not mean that - a session completed with an error or an RPC completed with an - error. Those things are reported up through the user's - xmlrpc_transport_asynch_complete routine. A failure here is - something that stopped us from calling that. - - Note that a timeout causes a successful completion, - but without finishing all the RPCs! - */ - - if (env.fault_occurred) - fprintf(stderr, "finishAsync() failed. Xmlrpc-c Curl transport " - "is now in an unknown state and may not be able to " - "continue functioning. Specifics of the failure: %s\n", - env.fault_string); - - xmlrpc_env_clean(&env); -} - - - -static void -call(xmlrpc_env * const envP, - struct xmlrpc_client_transport * const clientTransportP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block ** const responseXmlPP) { - - xmlrpc_mem_block * responseXmlP; - rpc * rpcP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(callXmlP); - XMLRPC_ASSERT_PTR_OK(responseXmlPP); - - responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - /* Only one RPC at a time can use a Curl session, so we have to - hold the lock as long as our RPC exists. - */ - lockSyncCurlSession(clientTransportP); - createRpc(envP, clientTransportP, clientTransportP->syncCurlSessionP, - serverP, - callXmlP, responseXmlP, - NULL, NULL, NULL, - &rpcP); - - if (!envP->fault_occurred) { - performRpc(envP, rpcP, clientTransportP->syncCurlMultiP, - clientTransportP->interruptP); - - *responseXmlPP = responseXmlP; - - destroyRpc(rpcP); - } - unlockSyncCurlSession(clientTransportP); - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, responseXmlP); - } -} - - - -static void -setupGlobalConstants(xmlrpc_env * const envP) { -/*---------------------------------------------------------------------------- - See longwinded discussion of the global constant issue at the top of - this file. ------------------------------------------------------------------------------*/ - initWindowsStuff(envP); - - if (!envP->fault_occurred) { - CURLcode rc; - - rc = curl_global_init(CURL_GLOBAL_ALL); - - if (rc != CURLE_OK) - xmlrpc_faultf(envP, "curl_global_init() failed with code %d", rc); - } -} - - - -static void -teardownGlobalConstants(void) { -/*---------------------------------------------------------------------------- - See longwinded discussion of the global constant issue at the top of - this file. ------------------------------------------------------------------------------*/ - curl_global_cleanup(); - - termWindowsStuff(); -} - - - -struct xmlrpc_client_transport_ops xmlrpc_curl_transport_ops = { - &setupGlobalConstants, - &teardownGlobalConstants, - &create, - &destroy, - &sendRequest, - &call, - &finishAsynch, - &setInterrupt, -}; diff --git a/trunk/lib/expat/Makefile b/trunk/lib/expat/Makefile deleted file mode 100644 index cf2355302..000000000 --- a/trunk/lib/expat/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - LIBDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/expat - -include $(BLDDIR)/config.mk - -default: all - -SUBDIRS = gennmtab xmlparse xmltok - -PKGCONFIG_FILES_TO_INSTALL := xmlrpc_expat.pc - -include $(SRCDIR)/common.mk - -.PHONY: all -all: $(SUBDIRS:%=%/all) $(PKGCONFIG_FILES_TO_INSTALL) - -# Extra dependencies to make parallel make work in spite of all the submakes -# (See top level make file for details) -xmlparse/all: gennmtab/all xmltok/all -xmltok/all: gennmtab/all - -#----------------------------------------------------------------------------- -# RULES TO MAKE PKGCONFIG FILES -# -# (These are files used by the 'pkg-config' program to get information about -# using the libraries we build) -#----------------------------------------------------------------------------- - -xmlrpc_expat.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_expat" >>$@ - @echo "Description: Xmlrpc-c XML parsing library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_xmlparse -lxmlrpc_xmltok" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -.PHONY: clean -clean: $(SUBDIRS:%=%/clean) clean-common - -.PHONY: distclean -distclean: $(SUBDIRS:%=%/distclean) distclean-common - -.PHONY: tags -tags: $(SUBDIRS:%=%/tags) TAGS - -DISTFILES = - -.PHONY: distdir -distdir: distdir-common - -.PHONY: install -install: install-common $(SUBDIRS:%=%/install) - -.PHONY: uninstall -uninstall: uninstall-common $(SUBDIRS:%=%/uninstall) - -.PHONY: check -check: - -.PHONY: dep -dep: $(SUBDIRS:%=%/dep) - diff --git a/trunk/lib/expat/expat.html b/trunk/lib/expat/expat.html deleted file mode 100644 index c555659b0..000000000 --- a/trunk/lib/expat/expat.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - -expat - - - -

expat - XML Parser Toolkit

- -

This is outdated stuff from the independently developed Expat which -was forked in 2001 to make the Xmlrpc-c embedded version. - -

Version 1.2

- -

Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center -Ltd. Expat is freely available with source under a very liberal license (the MIT license).

- -

This is a production version of expat. Relative to expat 1.1, it -adds support for parsing external DTDs and parameter entities. -Compiling with -DXML_DTD enables this support. There's a new --p option for xmlwf which will cause it to process -external DTDs and parameter entities; this implies the -x -option. See the comment above XML_SetParamEntityParsing -in xmlparse.h for the API addition that enables this.

- -

For Xmlrpc-c, we find no reason to exclude this function from the -library, and ifdefs make code harder to maintain, so we include the -function unconditionally. (i.e. -DXML_DTD does nothing). - -

Expat is an XML 1.0 parser -written in C. It aims to be fully conforming. It is currently not a -validating XML processor. The current production version of expat 1.X -can be downloaded from ftp://ftp.jclark.com/pub/xml/expat.zip.

- -

Development of expat 2.0 is being handled by a team led by Clark -Cooper, hosted by sourceforge.net. See http://expat.sourceforge.net for -the latest on expat 2.0.

- -

The directory xmltok contains a low-level library for -tokenizing XML. The interface is documented in -xmltok/xmltok.h.

- -

The directory xmlparse contains an XML parser library -which is built on top of the xmltok library. The -interface is documented in xmlparse/xmlparse.h. The -directory sample contains a simple example program using -this interface; sample/build.bat is a batch file to build -the example using Visual C++.

- -

The directory xmlwf contains the xmlwf -application, which uses the xmlparse library. The -arguments to xmlwf are one or more files which are each -to be checked for well-formedness. An option -d -dir can be specified; for each well-formed input -file the corresponding canonical XML will -be written to dir/f, where -f is the filename (without any path) of the -input file. A -x option will cause references to -external general entities to be processed. A -s option -will make documents that are not standalone cause an error (a document -is considered standalone if either it is intrinsically standalone -because it has no external subset and no references to parameter -entities in the internal subset or it is declared as standalone in the -XML declaration).

- -

The bin directory contains Win32 executables. The -lib directory contains Win32 import libraries.

- -

Answers to some frequently asked questions about expat can be found -in the expat -FAQ.

- -

- -
- -James Clark - -
- - - - diff --git a/trunk/lib/expat/gennmtab/Makefile b/trunk/lib/expat/gennmtab/Makefile deleted file mode 100644 index 93d4787f6..000000000 --- a/trunk/lib/expat/gennmtab/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - EXPATDIR := $(call updir,$(CURDIR)) - LIBDIR := $(call updir,$(EXPATDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/expat/gennmtab - -include $(BLDDIR)/config.mk - -INCLUDES = -I$(BLDDIR) -Isrcdir/lib/util/include - -default: all - -include $(SRCDIR)/common.mk - -.PHONY: all -all: gennmtab - -.PHONY: clean -clean: clean-common - rm -f gennmtab - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: tags -tags: TAGS - -.PHONY: distdir -distdir: - -.PHONY: install -install: - -.PHONY: uninstall -uninstall: - -.PHONY: dep -dep: dep-common - -gennmtab.o:%.o:%.c - $(CC_FOR_BUILD) -c $< -o $@ $(CFLAGS_ALL_FOR_BUILD) - -gennmtab:%:%.o - $(CC_FOR_BUILD) -o $@ $(LDFLAGS_ALL_FOR_BUILD) $^ - -include depend.mk diff --git a/trunk/lib/expat/gennmtab/gennmtab.c b/trunk/lib/expat/gennmtab/gennmtab.c deleted file mode 100644 index c6bdb7df1..000000000 --- a/trunk/lib/expat/gennmtab/gennmtab.c +++ /dev/null @@ -1,433 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#include -#include -#include - -#include "xmlrpc_config.h" - -struct range { - int start; - int end; -}; - -struct range nmstrt[] = { - { '_', 0 }, - { ':', 0 }, - /* BaseChar */ - { 0x0041, 0x005a }, - { 0x0061, 0x007a }, - { 0x00c0, 0x00d6 }, - { 0x00d8, 0x00f6 }, - { 0x00f8, 0x00ff }, - { 0x0100, 0x0131 }, - { 0x0134, 0x013e }, - { 0x0141, 0x0148 }, - { 0x014a, 0x017e }, - { 0x0180, 0x01c3 }, - { 0x01cd, 0x01f0 }, - { 0x01f4, 0x01f5 }, - { 0x01fa, 0x0217 }, - { 0x0250, 0x02a8 }, - { 0x02bb, 0x02c1 }, - { 0x0386, 0 }, - { 0x0388, 0x038a }, - { 0x038c, 0 }, - { 0x038e, 0x03a1 }, - { 0x03a3, 0x03ce }, - { 0x03d0, 0x03d6 }, - { 0x03da, 0 }, - { 0x03dc, 0 }, - { 0x03de, 0 }, - { 0x03e0, 0 }, - { 0x03e2, 0x03f3 }, - { 0x0401, 0x040c }, - { 0x040e, 0x044f }, - { 0x0451, 0x045c }, - { 0x045e, 0x0481 }, - { 0x0490, 0x04c4 }, - { 0x04c7, 0x04c8 }, - { 0x04cb, 0x04cc }, - { 0x04d0, 0x04eb }, - { 0x04ee, 0x04f5 }, - { 0x04f8, 0x04f9 }, - { 0x0531, 0x0556 }, - { 0x0559, 0 }, - { 0x0561, 0x0586 }, - { 0x05d0, 0x05ea }, - { 0x05f0, 0x05f2 }, - { 0x0621, 0x063a }, - { 0x0641, 0x064a }, - { 0x0671, 0x06b7 }, - { 0x06ba, 0x06be }, - { 0x06c0, 0x06ce }, - { 0x06d0, 0x06d3 }, - { 0x06d5, 0 }, - { 0x06e5, 0x06e6 }, - { 0x0905, 0x0939 }, - { 0x093d, 0 }, - { 0x0958, 0x0961 }, - { 0x0985, 0x098c }, - { 0x098f, 0x0990 }, - { 0x0993, 0x09a8 }, - { 0x09aa, 0x09b0 }, - { 0x09b2, 0 }, - { 0x09b6, 0x09b9 }, - { 0x09dc, 0x09dd }, - { 0x09df, 0x09e1 }, - { 0x09f0, 0x09f1 }, - { 0x0a05, 0x0a0a }, - { 0x0a0f, 0x0a10 }, - { 0x0a13, 0x0a28 }, - { 0x0a2a, 0x0a30 }, - { 0x0a32, 0x0a33 }, - { 0x0a35, 0x0a36 }, - { 0x0a38, 0x0a39 }, - { 0x0a59, 0x0a5c }, - { 0x0a5e, 0 }, - { 0x0a72, 0x0a74 }, - { 0x0a85, 0x0a8b }, - { 0x0a8d, 0 }, - { 0x0a8f, 0x0a91 }, - { 0x0a93, 0x0aa8 }, - { 0x0aaa, 0x0ab0 }, - { 0x0ab2, 0x0ab3 }, - { 0x0ab5, 0x0ab9 }, - { 0x0abd, 0 }, - { 0x0ae0, 0 }, - { 0x0b05, 0x0b0c }, - { 0x0b0f, 0x0b10 }, - { 0x0b13, 0x0b28 }, - { 0x0b2a, 0x0b30 }, - { 0x0b32, 0x0b33 }, - { 0x0b36, 0x0b39 }, - { 0x0b3d, 0 }, - { 0x0b5c, 0x0b5d }, - { 0x0b5f, 0x0b61 }, - { 0x0b85, 0x0b8a }, - { 0x0b8e, 0x0b90 }, - { 0x0b92, 0x0b95 }, - { 0x0b99, 0x0b9a }, - { 0x0b9c, 0 }, - { 0x0b9e, 0x0b9f }, - { 0x0ba3, 0x0ba4 }, - { 0x0ba8, 0x0baa }, - { 0x0bae, 0x0bb5 }, - { 0x0bb7, 0x0bb9 }, - { 0x0c05, 0x0c0c }, - { 0x0c0e, 0x0c10 }, - { 0x0c12, 0x0c28 }, - { 0x0c2a, 0x0c33 }, - { 0x0c35, 0x0c39 }, - { 0x0c60, 0x0c61 }, - { 0x0c85, 0x0c8c }, - { 0x0c8e, 0x0c90 }, - { 0x0c92, 0x0ca8 }, - { 0x0caa, 0x0cb3 }, - { 0x0cb5, 0x0cb9 }, - { 0x0cde, 0 }, - { 0x0ce0, 0x0ce1 }, - { 0x0d05, 0x0d0c }, - { 0x0d0e, 0x0d10 }, - { 0x0d12, 0x0d28 }, - { 0x0d2a, 0x0d39 }, - { 0x0d60, 0x0d61 }, - { 0x0e01, 0x0e2e }, - { 0x0e30, 0 }, - { 0x0e32, 0x0e33 }, - { 0x0e40, 0x0e45 }, - { 0x0e81, 0x0e82 }, - { 0x0e84, 0 }, - { 0x0e87, 0x0e88 }, - { 0x0e8a, 0 }, - { 0x0e8d, 0 }, - { 0x0e94, 0x0e97 }, - { 0x0e99, 0x0e9f }, - { 0x0ea1, 0x0ea3 }, - { 0x0ea5, 0 }, - { 0x0ea7, 0 }, - { 0x0eaa, 0x0eab }, - { 0x0ead, 0x0eae }, - { 0x0eb0, 0 }, - { 0x0eb2, 0x0eb3 }, - { 0x0ebd, 0 }, - { 0x0ec0, 0x0ec4 }, - { 0x0f40, 0x0f47 }, - { 0x0f49, 0x0f69 }, - { 0x10a0, 0x10c5 }, - { 0x10d0, 0x10f6 }, - { 0x1100, 0 }, - { 0x1102, 0x1103 }, - { 0x1105, 0x1107 }, - { 0x1109, 0 }, - { 0x110b, 0x110c }, - { 0x110e, 0x1112 }, - { 0x113c, 0 }, - { 0x113e, 0 }, - { 0x1140, 0 }, - { 0x114c, 0 }, - { 0x114e, 0 }, - { 0x1150, 0 }, - { 0x1154, 0x1155 }, - { 0x1159, 0 }, - { 0x115f, 0x1161 }, - { 0x1163, 0 }, - { 0x1165, 0 }, - { 0x1167, 0 }, - { 0x1169, 0 }, - { 0x116d, 0x116e }, - { 0x1172, 0x1173 }, - { 0x1175, 0 }, - { 0x119e, 0 }, - { 0x11a8, 0 }, - { 0x11ab, 0 }, - { 0x11ae, 0x11af }, - { 0x11b7, 0x11b8 }, - { 0x11ba, 0 }, - { 0x11bc, 0x11c2 }, - { 0x11eb, 0 }, - { 0x11f0, 0 }, - { 0x11f9, 0 }, - { 0x1e00, 0x1e9b }, - { 0x1ea0, 0x1ef9 }, - { 0x1f00, 0x1f15 }, - { 0x1f18, 0x1f1d }, - { 0x1f20, 0x1f45 }, - { 0x1f48, 0x1f4d }, - { 0x1f50, 0x1f57 }, - { 0x1f59, 0 }, - { 0x1f5b, 0 }, - { 0x1f5d, 0 }, - { 0x1f5f, 0x1f7d }, - { 0x1f80, 0x1fb4 }, - { 0x1fb6, 0x1fbc }, - { 0x1fbe, 0 }, - { 0x1fc2, 0x1fc4 }, - { 0x1fc6, 0x1fcc }, - { 0x1fd0, 0x1fd3 }, - { 0x1fd6, 0x1fdb }, - { 0x1fe0, 0x1fec }, - { 0x1ff2, 0x1ff4 }, - { 0x1ff6, 0x1ffc }, - { 0x2126, 0 }, - { 0x212a, 0x212b }, - { 0x212e, 0 }, - { 0x2180, 0x2182 }, - { 0x3041, 0x3094 }, - { 0x30a1, 0x30fa }, - { 0x3105, 0x312c }, - { 0xac00, 0xd7a3 }, - /* Ideographic */ - { 0x4e00, 0x9fa5 }, - { 0x3007, 0 }, - { 0x3021, 0x3029 }, -}; - -/* name chars that are not name start chars */ -struct range name[] = { - { '.', 0 }, - { '-', 0 }, - /* CombiningChar */ - { 0x0300, 0x0345 }, - { 0x0360, 0x0361 }, - { 0x0483, 0x0486 }, - { 0x0591, 0x05a1 }, - { 0x05a3, 0x05b9 }, - { 0x05bb, 0x05bd }, - { 0x05bf, 0 }, - { 0x05c1, 0x05c2 }, - { 0x05c4, 0 }, - { 0x064b, 0x0652 }, - { 0x0670, 0 }, - { 0x06d6, 0x06dc }, - { 0x06dd, 0x06df }, - { 0x06e0, 0x06e4 }, - { 0x06e7, 0x06e8 }, - { 0x06ea, 0x06ed }, - { 0x0901, 0x0903 }, - { 0x093c, 0 }, - { 0x093e, 0x094c }, - { 0x094d, 0 }, - { 0x0951, 0x0954 }, - { 0x0962, 0x0963 }, - { 0x0981, 0x0983 }, - { 0x09bc, 0 }, - { 0x09be, 0 }, - { 0x09bf, 0 }, - { 0x09c0, 0x09c4 }, - { 0x09c7, 0x09c8 }, - { 0x09cb, 0x09cd }, - { 0x09d7, 0 }, - { 0x09e2, 0x09e3 }, - { 0x0a02, 0 }, - { 0x0a3c, 0 }, - { 0x0a3e, 0 }, - { 0x0a3f, 0 }, - { 0x0a40, 0x0a42 }, - { 0x0a47, 0x0a48 }, - { 0x0a4b, 0x0a4d }, - { 0x0a70, 0x0a71 }, - { 0x0a81, 0x0a83 }, - { 0x0abc, 0 }, - { 0x0abe, 0x0ac5 }, - { 0x0ac7, 0x0ac9 }, - { 0x0acb, 0x0acd }, - { 0x0b01, 0x0b03 }, - { 0x0b3c, 0 }, - { 0x0b3e, 0x0b43 }, - { 0x0b47, 0x0b48 }, - { 0x0b4b, 0x0b4d }, - { 0x0b56, 0x0b57 }, - { 0x0b82, 0x0b83 }, - { 0x0bbe, 0x0bc2 }, - { 0x0bc6, 0x0bc8 }, - { 0x0bca, 0x0bcd }, - { 0x0bd7, 0 }, - { 0x0c01, 0x0c03 }, - { 0x0c3e, 0x0c44 }, - { 0x0c46, 0x0c48 }, - { 0x0c4a, 0x0c4d }, - { 0x0c55, 0x0c56 }, - { 0x0c82, 0x0c83 }, - { 0x0cbe, 0x0cc4 }, - { 0x0cc6, 0x0cc8 }, - { 0x0cca, 0x0ccd }, - { 0x0cd5, 0x0cd6 }, - { 0x0d02, 0x0d03 }, - { 0x0d3e, 0x0d43 }, - { 0x0d46, 0x0d48 }, - { 0x0d4a, 0x0d4d }, - { 0x0d57, 0 }, - { 0x0e31, 0 }, - { 0x0e34, 0x0e3a }, - { 0x0e47, 0x0e4e }, - { 0x0eb1, 0 }, - { 0x0eb4, 0x0eb9 }, - { 0x0ebb, 0x0ebc }, - { 0x0ec8, 0x0ecd }, - { 0x0f18, 0x0f19 }, - { 0x0f35, 0 }, - { 0x0f37, 0 }, - { 0x0f39, 0 }, - { 0x0f3e, 0 }, - { 0x0f3f, 0 }, - { 0x0f71, 0x0f84 }, - { 0x0f86, 0x0f8b }, - { 0x0f90, 0x0f95 }, - { 0x0f97, 0 }, - { 0x0f99, 0x0fad }, - { 0x0fb1, 0x0fb7 }, - { 0x0fb9, 0 }, - { 0x20d0, 0x20dc }, - { 0x20e1, 0 }, - { 0x302a, 0x302f }, - { 0x3099, 0 }, - { 0x309a, 0 }, - /* Digit */ - { 0x0030, 0x0039 }, - { 0x0660, 0x0669 }, - { 0x06f0, 0x06f9 }, - { 0x0966, 0x096f }, - { 0x09e6, 0x09ef }, - { 0x0a66, 0x0a6f }, - { 0x0ae6, 0x0aef }, - { 0x0b66, 0x0b6f }, - { 0x0be7, 0x0bef }, - { 0x0c66, 0x0c6f }, - { 0x0ce6, 0x0cef }, - { 0x0d66, 0x0d6f }, - { 0x0e50, 0x0e59 }, - { 0x0ed0, 0x0ed9 }, - { 0x0f20, 0x0f29 }, - /* Extender */ - { 0xb7 , 0 }, - { 0x02d0, 0 }, - { 0x02d1, 0 }, - { 0x0387, 0 }, - { 0x0640, 0 }, - { 0x0e46, 0 }, - { 0x0ec6, 0 }, - { 0x3005, 0 }, - { 0x3031, 0x3035 }, - { 0x309d, 0x309e }, - { 0x30fc, 0x30fe }, -}; - -static void -setTab(char *tab, struct range *ranges, size_t nRanges) -{ - size_t i; - int j; - for (i = 0; i < nRanges; i++) { - if (ranges[i].end) { - for (j = ranges[i].start; j <= ranges[i].end; j++) - tab[j] = 1; - } - else - tab[ranges[i].start] = 1; - } -} - -static void -printTabs(char *tab) -{ - int nBitmaps = 2; - int i, j, k; - unsigned char pageIndex[512]; - - printf( -"static const unsigned namingBitmap[] = {\n\ -0x00000000, 0x00000000, 0x00000000, 0x00000000,\n\ -0x00000000, 0x00000000, 0x00000000, 0x00000000,\n\ -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n\ -0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n"); - for (i = 0; i < 512; i++) { - int kind = tab[i*256]; - for (j = 1; j < 256; j++) - if (tab[i*256 +j] != kind) { - kind = -1; - break; - } - if (i >= 256 && memcmp(tab + (i - 256)*256, tab + i*256, 256) == 0) - pageIndex[i] = pageIndex[i - 256]; - else if (kind == -1) { - pageIndex[i] = nBitmaps++; - for (j = 0; j < 8; j++) { - unsigned val = 0; - for (k = 0; k < 32; k++) { - if (tab[i*256 + j*32 +k]) - val |= (1 << k); - } - printf("0x%08X,", val); - putchar((((j + 1) & 3) == 0) ? '\n' : ' '); - } - } - else - pageIndex[i] = kind; - } - printf("};\n"); - printf("static const unsigned char nmstrtPages[] = {\n"); - for (i = 0; i < 512; i++) { - if (i == 256) - printf("};\nstatic const unsigned char namePages[] = {\n"); - printf("0x%02X,", pageIndex[i]); - putchar((((i + 1) & 7) == 0) ? '\n' : ' '); - } - printf("};\n"); -} - -int -main(int const argc ATTR_UNUSED, - char ** const argv ATTR_UNUSED) { - - char tab[2*65536]; - memset(tab, 0, 65536); - setTab(tab, nmstrt, sizeof(nmstrt)/sizeof(nmstrt[0])); - memcpy(tab + 65536, tab, 65536); - setTab(tab + 65536, name, sizeof(name)/sizeof(name[0])); - printTabs(tab); - return 0; -} diff --git a/trunk/lib/expat/xmlparse/Makefile b/trunk/lib/expat/xmlparse/Makefile deleted file mode 100644 index 9df0d893f..000000000 --- a/trunk/lib/expat/xmlparse/Makefile +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# This directory builds libxmlrpc_xmlparse, an XML parser. This is -# essentially the separately distributed Expat library from 2001, but -# with slight changes. The main reason it is bundled with Xmlrpc-c is -# to make the latter easier to build and use. -# -# The library is about XML in general. There is nothing specific to -# XML-RPC here. -############################################################################### - -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - EXPATDIR := $(call updir,$(CURDIR)) - LIBDIR := $(call updir,$(EXPATDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/expat/xmlparse - -XMLTOKDIR = srcdir/lib/expat/xmltok -UTILDIR = srcdir/lib/util - -default: all - -include $(BLDDIR)/config.mk - -TARGET_LIBRARY_NAMES := libxmlrpc_xmlparse - -STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_xmlparse.a - -SHARED_LIBS_TO_BUILD := libxmlrpc_xmlparse -SHARED_LIBS_TO_INSTALL := libxmlrpc_xmlparse - -TARGET_MODS = xmlparse - -OMIT_XMLPARSE_LIB_RULE=Y -MAJ=3 - # Major number of shared libraries in this directory - -include $(SRCDIR)/common.mk - -INCLUDES = \ - -I$(BLDDIR) \ - -I$(XMLTOKDIR) \ - -I$(UTILDIR)/include \ - -Isrcdir/include \ - -# LIBDEP is the shared libraries on which libxmlrpc_abyss depends. -# The runtime loader should load these libraries when it loads libxmlrpc_abyss. - -LIBDEP = $(LIBXMLRPC_XMLTOK) $(LIBXMLRPC_UTIL) - -XMLPARSE_SHLIB = $(call shlibfn,libxmlrpc_xmlparse) -#XMLPARSE_SHLIB is e.g. libxmlrpc_xmlparse.so.3.1 -XMLPARSE_SHLIBLE = $(call shliblefn,libxmlrpc_xmlparse) -#XMLPARSE_SHLIBLE is e.g. libxmlrpc_xmlparse.so - -.PHONY: all -all: libxmlrpc_xmlparse.a $(TARGET_SHARED_LIBRARIES) $(TARGET_SHARED_LE_LIBS) - -# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES: -$(XMLPARSE_SHLIB): $(TARGET_MODS:%=%.osh) $(LIBDEP) -$(XMLPARSE_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) $(LIBDEP) - -# Rule for this is in common.mk, courtesy of TARGET_STATIC_LIBRARIES: - -libxmlrpc_xmlparse.a: $(TARGET_MODS:%=%.o) -libxmlrpc_xmlparse.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) - -#----------------------------------------------------------------------------- -# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES -#----------------------------------------------------------------------------- - -# Rules to compile object modules from which to build the static and shared -# library are in common.mk, courtesy of TARGET_MODS. - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean distclean -clean: clean-common - -distclean: clean distclean-common - -.PHONY: dep -dep: dep-common - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir - -include depend.mk diff --git a/trunk/lib/expat/xmlparse/xmlparse.c b/trunk/lib/expat/xmlparse/xmlparse.c deleted file mode 100644 index 48adfb33c..000000000 --- a/trunk/lib/expat/xmlparse/xmlparse.c +++ /dev/null @@ -1,5029 +0,0 @@ -/* -Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -/* In 2001, this was part of the Expat package. We copied it into - Xmlrpc-c because it's easier on the user than making him get and - link Expat separately, and we don't expect to benefit from separate - maintenance of Expat. - - But we changed all the external symbols that in Expat are named - "XML_xxxx" to "xmlrpc_XML_xxxx" because people do link Xmlrpc-c - libraries into programs that also link Expat (a good example is - where an Apache module uses Xmlrpc-c). We don't want our names to - collide with Expat's. -*/ - -#include -#include -#include /* UINT_MAX */ -#include /* time() */ - -#include "xmlrpc_config.h" -#include "c_util.h" -#include "girmath.h" -#include "mallocvar.h" -#include "xmlrpc-c/string_int.h" -#include "xmldef.h" -#include "xmlparse.h" - -static const char * -extractXmlSample(const char * const start, - const char * const end, - size_t const maximumLen) { - - size_t const len = MIN(maximumLen, (size_t)(end - start)); - - return xmlrpc_makePrintable_lp(start, len); -} - - - -#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX -#define XmlConvert XmlUtf8Convert -#define XmlGetInternalEncoding xmlrpc_XmlGetUtf8InternalEncoding -#define XmlGetInternalEncodingNS xmlrpc_XmlGetUtf8InternalEncodingNS -#define XmlEncode xmlrpc_XmlUtf8Encode -#define MUST_CONVERT(enc, s) (!(enc)->isUtf8) -typedef char ICHAR; - - -#ifndef XML_NS - -#define XmlInitEncodingNS XmlInitEncoding -#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding -#undef XmlGetInternalEncodingNS -#define XmlGetInternalEncodingNS XmlGetInternalEncoding -#define XmlParseXmlDeclNS XmlParseXmlDecl - -#endif - -/* XML_T is a vestige of conditionally compiled code that was never used in - Xmlrpc-c that made characters 16 bits. In that case, XML_T was defined - differently. -*/ - -#define XML_T(x) x - -/* Round up n to be a multiple of sz, where sz is a power of 2. */ -#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) - -#include "xmltok.h" -#include "xmlrole.h" - -typedef const XML_Char *KEY; - -typedef struct { - KEY name; -} NAMED; - -typedef struct { - NAMED **v; - size_t size; - size_t used; - size_t usedLim; -} HASH_TABLE; - -typedef struct { - NAMED **p; - NAMED **end; -} HASH_TABLE_ITER; - -#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ -#define INIT_DATA_BUF_SIZE 1024 -#define INIT_ATTS_SIZE 16 -#define INIT_BLOCK_SIZE 1024 -#define INIT_BUFFER_SIZE 1024 - -#define EXPAND_SPARE 24 - -typedef struct binding { - struct prefix *prefix; - struct binding *nextTagBinding; - struct binding *prevPrefixBinding; - const struct attribute_id *attId; - XML_Char *uri; - int uriLen; - int uriAlloc; -} BINDING; - -typedef struct prefix { - const XML_Char *name; - BINDING *binding; -} PREFIX; - -typedef struct { - const XML_Char *str; - const XML_Char *localPart; - int uriLen; -} TAG_NAME; - -typedef struct tag { - struct tag *parent; - const char *rawName; - int rawNameLength; - TAG_NAME name; - char *buf; - char *bufEnd; - BINDING *bindings; -} TAG; - -typedef struct { - const XML_Char *name; - const XML_Char *textPtr; - size_t textLen; - const XML_Char *systemId; - const XML_Char *base; - const XML_Char *publicId; - const XML_Char *notation; - char open; -} ENTITY; - -typedef struct block { - struct block *next; - int size; - XML_Char s[1]; -} BLOCK; - -typedef struct { - BLOCK *blocks; - BLOCK *freeBlocks; - const XML_Char *end; - XML_Char *ptr; - XML_Char *start; -} STRING_POOL; - -/* The XML_Char before the name is used to determine whether -an attribute has been specified. */ -typedef struct attribute_id { - XML_Char *name; - PREFIX *prefix; - char maybeTokenized; - char xmlns; -} ATTRIBUTE_ID; - -typedef struct { - const ATTRIBUTE_ID *id; - char isCdata; - const XML_Char *value; -} DEFAULT_ATTRIBUTE; - -typedef struct { - const XML_Char *name; - PREFIX *prefix; - const ATTRIBUTE_ID *idAtt; - int nDefaultAtts; - int allocDefaultAtts; - DEFAULT_ATTRIBUTE *defaultAtts; -} ELEMENT_TYPE; - -typedef struct { - HASH_TABLE generalEntities; - HASH_TABLE elementTypes; - HASH_TABLE attributeIds; - HASH_TABLE prefixes; - STRING_POOL pool; - int complete; - int standalone; - HASH_TABLE paramEntities; - PREFIX defaultPrefix; -} DTD; - -typedef struct open_internal_entity { - const char *internalEventPtr; - const char *internalEventEndPtr; - struct open_internal_entity *next; - ENTITY *entity; -} OPEN_INTERNAL_ENTITY; - -typedef void Processor(XML_Parser parser, - const char * const start, - const char * const end, - const char ** const endPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP); - -static -int setContext(XML_Parser parser, const XML_Char *context); - -#define poolStart(pool) ((pool)->start) -#define poolEnd(pool) ((pool)->ptr) -#define poolLength(pool) ((pool)->ptr - (pool)->start) -#define poolChop(pool) ((void)--(pool->ptr)) -#define poolLastChar(pool) (((pool)->ptr)[-1]) -#define poolDiscard(pool) ((pool)->ptr = (pool)->start) -#define poolFinish(pool) ((pool)->start = (pool)->ptr) - - -typedef struct { - /* The first member must be userData so that the XML_GetUserData macro works. */ - void *m_userData; - void *m_handlerArg; - char *m_buffer; - /* first character to be parsed */ - const char *m_bufferPtr; - /* past last character to be parsed */ - char *m_bufferEnd; - /* allocated end of buffer */ - const char *m_bufferLim; - long m_parseEndByteIndex; - const char *m_parseEndPtr; - XML_Char *m_dataBuf; - XML_Char *m_dataBufEnd; - XML_StartElementHandler m_startElementHandler; - XML_EndElementHandler m_endElementHandler; - XML_CharacterDataHandler m_characterDataHandler; - XML_ProcessingInstructionHandler m_processingInstructionHandler; - XML_CommentHandler m_commentHandler; - XML_StartCdataSectionHandler m_startCdataSectionHandler; - XML_EndCdataSectionHandler m_endCdataSectionHandler; - XML_DefaultHandler m_defaultHandler; - XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; - XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; - XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; - XML_NotationDeclHandler m_notationDeclHandler; - XML_ExternalParsedEntityDeclHandler m_externalParsedEntityDeclHandler; - XML_InternalParsedEntityDeclHandler m_internalParsedEntityDeclHandler; - XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; - XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; - XML_NotStandaloneHandler m_notStandaloneHandler; - XML_ExternalEntityRefHandler m_externalEntityRefHandler; - void *m_externalEntityRefHandlerArg; - XML_UnknownEncodingHandler m_unknownEncodingHandler; - const ENCODING *m_encoding; - INIT_ENCODING m_initEncoding; - const ENCODING *m_internalEncoding; - const XML_Char *m_protocolEncodingName; - /* NULL if no encoding assigned */ - int m_ns; - void *m_unknownEncodingMem; - void *m_unknownEncodingData; - void *m_unknownEncodingHandlerData; - void (*m_unknownEncodingRelease)(void *); - PROLOG_STATE m_prologState; - Processor *m_processor; - /* The next processor to run */ - enum XML_Error m_errorCode; - /* Explanation of the failure of the most recent call to Expat. - XML_ERROR_NONE means it didn't fail. This is redundant with - m_errorString if the latter is non-null. - The latter is newer and better. - */ - const char * m_errorString; - /* malloc'ed string describing the failure of the most recent call - to Expat. NULL means m_errorCode is the only error information - available. - */ - const char *m_eventPtr; - const char *m_eventEndPtr; - const char *m_positionPtr; - OPEN_INTERNAL_ENTITY *m_openInternalEntities; - int m_defaultExpandInternalEntities; - int m_tagLevel; - ENTITY *m_declEntity; - const XML_Char *m_declNotationName; - const XML_Char *m_declNotationPublicId; - ELEMENT_TYPE *m_declElementType; - ATTRIBUTE_ID *m_declAttributeId; - char m_declAttributeIsCdata; - char m_declAttributeIsId; - DTD m_dtd; - const XML_Char *m_curBase; - TAG *m_tagStack; - TAG *m_freeTagList; - BINDING *m_inheritedBindings; - BINDING *m_freeBindingList; - int m_attsSize; - int m_nSpecifiedAtts; - int m_idAttIndex; - ATTRIBUTE *m_atts; - POSITION m_position; - STRING_POOL m_tempPool; - STRING_POOL m_temp2Pool; - char *m_groupConnector; - unsigned m_groupSize; - int m_hadExternalDoctype; - XML_Char m_namespaceSeparator; - enum XML_ParamEntityParsing m_paramEntityParsing; - XML_Parser m_parentParser; - unsigned long m_hash_secret_salt; -} Parser; - -#define userData (((Parser *)parser)->m_userData) -#define handlerArg (((Parser *)parser)->m_handlerArg) -#define startElementHandler (((Parser *)parser)->m_startElementHandler) -#define endElementHandler (((Parser *)parser)->m_endElementHandler) -#define characterDataHandler (((Parser *)parser)->m_characterDataHandler) -#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler) -#define commentHandler (((Parser *)parser)->m_commentHandler) -#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler) -#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler) -#define defaultHandler (((Parser *)parser)->m_defaultHandler) -#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler) -#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler) -#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler) -#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler) -#define externalParsedEntityDeclHandler (((Parser *)parser)->m_externalParsedEntityDeclHandler) -#define internalParsedEntityDeclHandler (((Parser *)parser)->m_internalParsedEntityDeclHandler) -#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler) -#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler) -#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler) -#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler) -#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg) -#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler) -#define initEncoding (((Parser *)parser)->m_initEncoding) -#define internalEncoding (((Parser *)parser)->m_internalEncoding) -#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem) -#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData) -#define unknownEncodingHandlerData \ - (((Parser *)parser)->m_unknownEncodingHandlerData) -#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease) -#define ns (((Parser *)parser)->m_ns) -#define prologState (((Parser *)parser)->m_prologState) -#define processor (((Parser *)parser)->m_processor) -#define errorCode (((Parser *)parser)->m_errorCode) -#define errorString (((Parser *)parser)->m_errorString) -#define eventPtr (((Parser *)parser)->m_eventPtr) -#define eventEndPtr (((Parser *)parser)->m_eventEndPtr) -#define positionPtr (((Parser *)parser)->m_positionPtr) -#define position (((Parser *)parser)->m_position) -#define openInternalEntities (((Parser *)parser)->m_openInternalEntities) -#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities) -#define tagLevel (((Parser *)parser)->m_tagLevel) -#define buffer (((Parser *)parser)->m_buffer) -#define bufferPtr (((Parser *)parser)->m_bufferPtr) -#define bufferEnd (((Parser *)parser)->m_bufferEnd) -#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex) -#define parseEndPtr (((Parser *)parser)->m_parseEndPtr) -#define bufferLim (((Parser *)parser)->m_bufferLim) -#define dataBuf (((Parser *)parser)->m_dataBuf) -#define dataBufEnd (((Parser *)parser)->m_dataBufEnd) -#define dtd (((Parser *)parser)->m_dtd) -#define curBase (((Parser *)parser)->m_curBase) -#define declEntity (((Parser *)parser)->m_declEntity) -#define declNotationName (((Parser *)parser)->m_declNotationName) -#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId) -#define declElementType (((Parser *)parser)->m_declElementType) -#define declAttributeId (((Parser *)parser)->m_declAttributeId) -#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata) -#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId) -#define freeTagList (((Parser *)parser)->m_freeTagList) -#define freeBindingList (((Parser *)parser)->m_freeBindingList) -#define inheritedBindings (((Parser *)parser)->m_inheritedBindings) -#define tagStack (((Parser *)parser)->m_tagStack) -#define atts (((Parser *)parser)->m_atts) -#define attsSize (((Parser *)parser)->m_attsSize) -#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts) -#define idAttIndex (((Parser *)parser)->m_idAttIndex) -#define tempPool (((Parser *)parser)->m_tempPool) -#define temp2Pool (((Parser *)parser)->m_temp2Pool) -#define groupConnector (((Parser *)parser)->m_groupConnector) -#define groupSize (((Parser *)parser)->m_groupSize) -#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype) -#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator) -#define parentParser (((Parser *)parser)->m_parentParser) -#define hash_secret_salt (((Parser *)parser)->m_hash_secret_salt) - - - -static -void poolInit(STRING_POOL *pool) -{ - pool->blocks = 0; - pool->freeBlocks = 0; - pool->start = 0; - pool->ptr = 0; - pool->end = 0; -} - -static -void poolClear(STRING_POOL *pool) -{ - if (!pool->freeBlocks) - pool->freeBlocks = pool->blocks; - else { - BLOCK *p = pool->blocks; - while (p) { - BLOCK *tem = p->next; - p->next = pool->freeBlocks; - pool->freeBlocks = p; - p = tem; - } - } - pool->blocks = 0; - pool->start = 0; - pool->ptr = 0; - pool->end = 0; -} - -static -void poolDestroy(STRING_POOL *pool) -{ - BLOCK *p = pool->blocks; - while (p) { - BLOCK *tem = p->next; - free(p); - p = tem; - } - pool->blocks = 0; - p = pool->freeBlocks; - while (p) { - BLOCK *tem = p->next; - free(p); - p = tem; - } - pool->freeBlocks = 0; - pool->ptr = 0; - pool->start = 0; - pool->end = 0; -} - - - -static void -poolGrowFromFreeBlocks(STRING_POOL * const poolP, - bool * const wasGrownFromFreeBlocksP) { - - if (poolP->freeBlocks) { - if (poolP->start == 0) { - poolP->blocks = poolP->freeBlocks; - poolP->freeBlocks = poolP->freeBlocks->next; - poolP->blocks->next = 0; - poolP->start = poolP->blocks->s; - poolP->end = poolP->start + poolP->blocks->size; - poolP->ptr = poolP->start; - - *wasGrownFromFreeBlocksP = true; - } else if (poolP->end - poolP->start < poolP->freeBlocks->size) { - BLOCK * const newFreeBlocks = poolP->freeBlocks->next; - - poolP->freeBlocks->next = poolP->blocks; - poolP->blocks = poolP->freeBlocks; - poolP->freeBlocks = newFreeBlocks; - memcpy(poolP->blocks->s, poolP->start, - (poolP->end - poolP->start) * sizeof(XML_Char)); - poolP->ptr = poolP->blocks->s + (poolP->ptr - poolP->start); - poolP->start = poolP->blocks->s; - poolP->end = poolP->start + poolP->blocks->size; - - *wasGrownFromFreeBlocksP = true; - } - } else - *wasGrownFromFreeBlocksP = false; -} - - - -static void -poolGrow(STRING_POOL * const poolP, - const char ** const errorP) { - - bool wasGrownFromFreeBlocks; - - poolGrowFromFreeBlocks(poolP, &wasGrownFromFreeBlocks); - - if (wasGrownFromFreeBlocks) - *errorP = NULL; - else { - if (poolP->blocks && poolP->start == poolP->blocks->s) { - size_t const blockSize = (poolP->end - poolP->start)*2; - size_t const newSize = - offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); - - BLOCK * const newBlocks = realloc(poolP->blocks, newSize); - - if (newBlocks) { - poolP->blocks = newBlocks; - poolP->blocks->size = blockSize; - poolP->ptr = poolP->blocks->s + (poolP->ptr - poolP->start); - poolP->start = poolP->blocks->s; - poolP->end = poolP->start + blockSize; - *errorP = NULL; - } else - xmlrpc_asprintf(errorP, - "Failed to allocate %u bytes of memory", - (unsigned)newSize); - } else { - size_t const poolLen = poolP->end - poolP->start; - size_t const blockSize = - poolLen < INIT_BLOCK_SIZE ? INIT_BLOCK_SIZE : poolLen * 2; - size_t const newSize = - offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); - - BLOCK * const newBlocksP = malloc(newSize); - - if (newBlocksP) { - newBlocksP->size = blockSize; - newBlocksP->next = poolP->blocks; - poolP->blocks = newBlocksP; - if (poolP->ptr != poolP->start) - memcpy(newBlocksP->s, poolP->start, - (poolP->ptr - poolP->start) * sizeof(XML_Char)); - poolP->ptr = newBlocksP->s + (poolP->ptr - poolP->start); - poolP->start = newBlocksP->s; - poolP->end = newBlocksP->s + blockSize; - *errorP = NULL; - } else - xmlrpc_asprintf(errorP, - "Failed to allocate %u bytes of memory", - (unsigned)newSize); - } - } -} - - - -static -XML_Char * -poolAppend(STRING_POOL * const poolP, - const ENCODING * const encodingP, - const char * const initialPtr, - const char * const end) { - - const char * ptr; - - ptr = initialPtr; /* initial value */ - - if (!poolP->ptr) { - const char * error; - - poolGrow(poolP, &error); - - if (error) { - xmlrpc_strfree(error); - return NULL; - } - } - - for (;;) { - const char * error; - - XmlConvert(encodingP, &ptr, end, (ICHAR **)&(poolP->ptr), - (ICHAR *)poolP->end); - - if (ptr == end) - break; - - poolGrow(poolP, &error); - - if (error) { - xmlrpc_strfree(error); - return NULL; - } - } - return poolP->start; -} - - - -static bool -poolAppendChar(STRING_POOL * const poolP, - XML_Char const c) { - - bool retval; - const char * error; - - if (poolP->ptr == poolP->end) - poolGrow(poolP, &error); - else - error = NULL; - - if (error) { - xmlrpc_strfree(error); - retval = false; - } else { - *poolP->ptr++ = c; - - retval = true; - } - return retval; -} - - - -static const XML_Char * -poolCopyString(STRING_POOL * const poolP, - const XML_Char * const source) { - - const XML_Char * retval; - const XML_Char * s; - - s = &source[0]; /* initial value */ - - do { - if (!poolAppendChar(poolP, *s)) - return 0; - } while (*s++); - - retval = poolP->start; - - poolFinish(poolP); - - return retval; -} - - - -static const XML_Char * -poolCopyStringN(STRING_POOL * const poolP, - const XML_Char * const source, - int const size) { - - const XML_Char * retval; - const XML_Char * s; - int n; - - s = source; /* initial value */ - n = size; /* initial value */ - - if (!poolP->ptr) { - const char * error; - poolGrow(poolP, &error); - if (error) { - xmlrpc_strfree(error); - return NULL; - } - } - - for (; n > 0; --n, ++s) { - if (!poolAppendChar(poolP, *s)) - return NULL; - } - retval = poolP->start; - - poolFinish(poolP); - - return retval; -} - - - -static XML_Char * -poolStoreString(STRING_POOL * const poolP, - const ENCODING * const encodingP, - const char * const ptr, - const char * const end) { - - if (!poolAppend(poolP, encodingP, ptr, end)) - return NULL; - - if (poolP->ptr == poolP->end) { - const char * error; - poolGrow(poolP, &error); - if (error) { - xmlrpc_strfree(error); - return NULL; - } - } - - *(poolP->ptr)++ = 0; - - return poolP->start; -} - - - -static unsigned long -generate_hash_secret_salt(void) -{ - unsigned int seed = time(NULL) % UINT_MAX; - srand(seed); - return rand(); -} - -static int /* only valid for root parser */ -startParsing(XML_Parser parser) -{ - static - const XML_Char implicitContext[] = { - XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='), - XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'), - XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'), - XML_T('.'), XML_T('w'), XML_T('3'), - XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'), - XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'), - XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'), - XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'), - XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'), - XML_T('\0') - }; - - /* hash functions must be initialized before setContext() is called */ - if (hash_secret_salt == 0) - hash_secret_salt = generate_hash_secret_salt(); - if (parser) - return setContext(parser, implicitContext); - return 0; -} - -#define INIT_SIZE 64 - -static -int keyeq(KEY s1, KEY s2) -{ - for (; *s1 == *s2; s1++, s2++) - if (*s1 == 0) - return 1; - return 0; -} - -static -unsigned long hash(XML_Parser parser, KEY s) -{ - unsigned long h = hash_secret_salt; - while (*s) - h = (h << 5) + h + (unsigned char)*s++; - return h; -} - -static -NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) -{ - size_t i; - if (table->size == 0) { - if (!createSize) - return 0; - table->v = calloc(INIT_SIZE, sizeof(NAMED *)); - if (!table->v) - return 0; - table->size = INIT_SIZE; - table->usedLim = INIT_SIZE / 2; - i = hash(parser, name) & (table->size - 1); - } - else { - unsigned long h = hash(parser, name); - for (i = h & (table->size - 1); - table->v[i]; - i == 0 ? i = table->size - 1 : --i) { - if (keyeq(name, table->v[i]->name)) - return table->v[i]; - } - if (!createSize) - return 0; - if (table->used == table->usedLim) { - /* check for overflow */ - size_t newSize = table->size * 2; - NAMED **newV = calloc(newSize, sizeof(NAMED *)); - if (!newV) - return 0; - for (i = 0; i < table->size; i++) - if (table->v[i]) { - size_t j; - for (j = hash(parser, table->v[i]->name) & (newSize - 1); - newV[j]; - j == 0 ? j = newSize - 1 : --j) - ; - newV[j] = table->v[i]; - } - free(table->v); - table->v = newV; - table->size = newSize; - table->usedLim = newSize/2; - for (i = h & (table->size - 1); - table->v[i]; - i == 0 ? i = table->size - 1 : --i) - ; - } - } - table->v[i] = calloc(1, createSize); - if (!table->v[i]) - return 0; - table->v[i]->name = name; - (table->used)++; - return table->v[i]; -} - -static -void hashTableDestroy(HASH_TABLE *table) -{ - size_t i; - for (i = 0; i < table->size; i++) { - NAMED *p = table->v[i]; - if (p) - free(p); - } - if (table->v) - free(table->v); -} - -static -void hashTableInit(HASH_TABLE *p) -{ - p->size = 0; - p->usedLim = 0; - p->used = 0; - p->v = 0; -} - -static -void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) -{ - iter->p = table->v; - iter->end = iter->p + table->size; -} - -static -NAMED *hashTableIterNext(HASH_TABLE_ITER *iter) -{ - while (iter->p != iter->end) { - NAMED *tem = *(iter->p)++; - if (tem) - return tem; - } - return 0; -} - - - -static int dtdInit(DTD *p) -{ - poolInit(&(p->pool)); - hashTableInit(&(p->generalEntities)); - hashTableInit(&(p->elementTypes)); - hashTableInit(&(p->attributeIds)); - hashTableInit(&(p->prefixes)); - p->complete = 1; - p->standalone = 0; - hashTableInit(&(p->paramEntities)); - p->defaultPrefix.name = 0; - p->defaultPrefix.binding = 0; - return 1; -} - - - -static void dtdSwap(DTD *p1, DTD *p2) -{ - DTD tem; - memcpy(&tem, p1, sizeof(DTD)); - memcpy(p1, p2, sizeof(DTD)); - memcpy(p2, &tem, sizeof(DTD)); -} - - - - -static void dtdDestroy(DTD *p) -{ - HASH_TABLE_ITER iter; - hashTableIterInit(&iter, &(p->elementTypes)); - for (;;) { - ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!e) - break; - if (e->allocDefaultAtts != 0) - free(e->defaultAtts); - } - hashTableDestroy(&(p->generalEntities)); - hashTableDestroy(&(p->paramEntities)); - hashTableDestroy(&(p->elementTypes)); - hashTableDestroy(&(p->attributeIds)); - hashTableDestroy(&(p->prefixes)); - poolDestroy(&(p->pool)); -} - -static int copyEntityTable(XML_Parser oldParser, - HASH_TABLE *newTable, - STRING_POOL *newPool, - const HASH_TABLE *oldTable) -{ - HASH_TABLE_ITER iter; - const XML_Char *cachedOldBase = 0; - const XML_Char *cachedNewBase = 0; - - hashTableIterInit(&iter, oldTable); - - for (;;) { - ENTITY *newE; - const XML_Char *name; - const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); - if (!oldE) - break; - name = poolCopyString(newPool, oldE->name); - if (!name) - return 0; - newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); - if (!newE) - return 0; - if (oldE->systemId) { - const XML_Char *tem = poolCopyString(newPool, oldE->systemId); - if (!tem) - return 0; - newE->systemId = tem; - if (oldE->base) { - if (oldE->base == cachedOldBase) - newE->base = cachedNewBase; - else { - cachedOldBase = oldE->base; - tem = poolCopyString(newPool, cachedOldBase); - if (!tem) - return 0; - cachedNewBase = newE->base = tem; - } - } - } - else { - const XML_Char *tem = - poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); - if (!tem) - return 0; - newE->textPtr = tem; - newE->textLen = oldE->textLen; - } - if (oldE->notation) { - const XML_Char *tem = poolCopyString(newPool, oldE->notation); - if (!tem) - return 0; - newE->notation = tem; - } - } - return 1; -} - - - -/* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise. -The new DTD has already been initialized. */ - -static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd) -{ - HASH_TABLE_ITER iter; - - /* Copy the prefix table. */ - - hashTableIterInit(&iter, &(oldDtd->prefixes)); - for (;;) { - const XML_Char *name; - const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); - if (!oldP) - break; - name = poolCopyString(&(newDtd->pool), oldP->name); - if (!name) - return 0; - if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) - return 0; - } - - hashTableIterInit(&iter, &(oldDtd->attributeIds)); - - /* Copy the attribute id table. */ - - for (;;) { - ATTRIBUTE_ID *newA; - const XML_Char *name; - const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); - - if (!oldA) - break; - /* Remember to allocate the scratch byte before the name. */ - if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) - return 0; - name = poolCopyString(&(newDtd->pool), oldA->name); - if (!name) - return 0; - ++name; - newA = (ATTRIBUTE_ID *) - lookup(oldParser, &(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID)); - if (!newA) - return 0; - newA->maybeTokenized = oldA->maybeTokenized; - if (oldA->prefix) { - newA->xmlns = oldA->xmlns; - if (oldA->prefix == &oldDtd->defaultPrefix) - newA->prefix = &newDtd->defaultPrefix; - else - newA->prefix = (PREFIX *) - lookup(oldParser, &(newDtd->prefixes), oldA->prefix->name, 0); - } - } - - /* Copy the element type table. */ - - hashTableIterInit(&iter, &(oldDtd->elementTypes)); - - for (;;) { - int i; - ELEMENT_TYPE *newE; - const XML_Char *name; - const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); - if (!oldE) - break; - name = poolCopyString(&(newDtd->pool), oldE->name); - if (!name) - return 0; - newE = (ELEMENT_TYPE *) - lookup(oldParser, &(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE)); - if (!newE) - return 0; - if (oldE->nDefaultAtts) { - newE->defaultAtts = (DEFAULT_ATTRIBUTE *) - malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); - if (!newE->defaultAtts) - return 0; - } - if (oldE->idAtt) - newE->idAtt = (ATTRIBUTE_ID *) - lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0); - newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; - if (oldE->prefix) - newE->prefix = (PREFIX *) - lookup(oldParser, &(newDtd->prefixes), oldE->prefix->name, 0); - for (i = 0; i < newE->nDefaultAtts; i++) { - newE->defaultAtts[i].id = (ATTRIBUTE_ID *) - lookup(oldParser, &(newDtd->attributeIds), - oldE->defaultAtts[i].id->name, 0); - newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; - if (oldE->defaultAtts[i].value) { - newE->defaultAtts[i].value = - poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); - if (!newE->defaultAtts[i].value) - return 0; - } - else - newE->defaultAtts[i].value = 0; - } - } - - /* Copy the entity tables. */ - if (!copyEntityTable(oldParser, &(newDtd->generalEntities), - &(newDtd->pool), - &(oldDtd->generalEntities))) - return 0; - - if (!copyEntityTable(oldParser, &(newDtd->paramEntities), - &(newDtd->pool), - &(oldDtd->paramEntities))) - return 0; - - newDtd->complete = oldDtd->complete; - newDtd->standalone = oldDtd->standalone; - return 1; -} - - - -static -int addBinding(XML_Parser parser, - PREFIX *prefix, - const ATTRIBUTE_ID *attId, - const XML_Char *uri, - BINDING **bindingsPtr) -{ - BINDING *b; - int len; - for (len = 0; uri[len]; len++) - ; - if (namespaceSeparator) - len++; - if (freeBindingList) { - b = freeBindingList; - if (len > b->uriAlloc) { - XML_Char *temp = realloc(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); - if (!temp) - return 0; - b->uri = temp; - b->uriAlloc = len + EXPAND_SPARE; - } - freeBindingList = b->nextTagBinding; - } - else { - b = malloc(sizeof(BINDING)); - if (!b) - return 0; - b->uri = malloc(sizeof(XML_Char) * (len + EXPAND_SPARE)); - if (!b->uri) { - free(b); - return 0; - } - b->uriAlloc = len + EXPAND_SPARE; - } - b->uriLen = len; - memcpy(b->uri, uri, len * sizeof(XML_Char)); - if (namespaceSeparator) - b->uri[len - 1] = namespaceSeparator; - b->prefix = prefix; - b->attId = attId; - b->prevPrefixBinding = prefix->binding; - if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix) - prefix->binding = 0; - else - prefix->binding = b; - b->nextTagBinding = *bindingsPtr; - *bindingsPtr = b; - if (startNamespaceDeclHandler) - startNamespaceDeclHandler(handlerArg, prefix->name, - prefix->binding ? uri : 0); - return 1; -} - - - -#define CONTEXT_SEP XML_T('\f') - -static -const XML_Char *getContext(XML_Parser parser) -{ - HASH_TABLE_ITER iter; - int needSep = 0; - - if (dtd.defaultPrefix.binding) { - int i; - int len; - if (!poolAppendChar(&tempPool, XML_T('='))) - return 0; - len = dtd.defaultPrefix.binding->uriLen; - if (namespaceSeparator != XML_T('\0')) - len--; - for (i = 0; i < len; i++) - if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i])) - return 0; - needSep = 1; - } - - hashTableIterInit(&iter, &(dtd.prefixes)); - for (;;) { - int i; - int len; - const XML_Char *s; - PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); - if (!prefix) - break; - if (!prefix->binding) - continue; - if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) - return 0; - for (s = prefix->name; *s; s++) - if (!poolAppendChar(&tempPool, *s)) - return 0; - if (!poolAppendChar(&tempPool, XML_T('='))) - return 0; - len = prefix->binding->uriLen; - if (namespaceSeparator != XML_T('\0')) - len--; - for (i = 0; i < len; i++) - if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) - return 0; - needSep = 1; - } - - - hashTableIterInit(&iter, &(dtd.generalEntities)); - for (;;) { - const XML_Char *s; - ENTITY *e = (ENTITY *)hashTableIterNext(&iter); - if (!e) - break; - if (!e->open) - continue; - if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) - return 0; - for (s = e->name; *s; s++) - if (!poolAppendChar(&tempPool, *s)) - return 0; - needSep = 1; - } - - if (!poolAppendChar(&tempPool, XML_T('\0'))) - return 0; - return tempPool.start; -} - -static -int setContext(XML_Parser parser, const XML_Char *context) -{ - const XML_Char *s = context; - - while (*context != XML_T('\0')) { - if (*s == CONTEXT_SEP || *s == XML_T('\0')) { - ENTITY *e; - if (!poolAppendChar(&tempPool, XML_T('\0'))) - return 0; - e = (ENTITY *)lookup(parser, &dtd.generalEntities, poolStart(&tempPool), - 0); - if (e) - e->open = 1; - if (*s != XML_T('\0')) - s++; - context = s; - poolDiscard(&tempPool); - } - else if (*s == '=') { - PREFIX *prefix; - if (poolLength(&tempPool) == 0) - prefix = &dtd.defaultPrefix; - else { - if (!poolAppendChar(&tempPool, XML_T('\0'))) - return 0; - prefix = (PREFIX *) - lookup(parser, &dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX)); - if (!prefix) - return 0; - if (prefix->name == poolStart(&tempPool)) { - prefix->name = poolCopyString(&dtd.pool, prefix->name); - if (!prefix->name) - return 0; - } - poolDiscard(&tempPool); - } - for (context = s + 1; - *context != CONTEXT_SEP && *context != XML_T('\0'); - ++context) - if (!poolAppendChar(&tempPool, *context)) - return 0; - if (!poolAppendChar(&tempPool, XML_T('\0'))) - return 0; - if (!addBinding(parser, prefix, 0, poolStart(&tempPool), - &inheritedBindings)) - return 0; - poolDiscard(&tempPool); - if (*context != XML_T('\0')) - ++context; - s = context; - } - else { - if (!poolAppendChar(&tempPool, *s)) - return 0; - s++; - } - } - return 1; -} - - - -static void -normalizeLines(XML_Char *s) -{ - XML_Char *p; - for (;; s++) { - if (*s == XML_T('\0')) - return; - if (*s == 0xD) - break; - } - p = s; - do { - if (*s == 0xD) { - *p++ = 0xA; - if (*++s == 0xA) - s++; - } - else - *p++ = *s++; - } while (*s); - *p = XML_T('\0'); -} - - - -struct EventPtr { - const char ** startP; - const char ** endP; -}; - - - -static struct EventPtr -getEventPtr(XML_Parser const xmlParserP, - const ENCODING * const encoderP) { - - Parser * const parserP = xmlParserP; - - struct EventPtr retval; - - if (encoderP == parserP->m_encoding) { - retval.startP = &parserP->m_eventPtr; - retval.endP = &parserP->m_eventEndPtr; - } else { - retval.startP = &parserP->m_openInternalEntities->internalEventPtr; - retval.endP = &parserP->m_openInternalEntities->internalEventEndPtr; - } - - return retval; -} - - - -static void -reportDefault(XML_Parser const xmlParserP, - const ENCODING * const encoderP, - const char * const start, - const char * const end) { - - Parser * const parser = (Parser *)xmlParserP; - - if (MUST_CONVERT(encoderP, start)) { - struct EventPtr const evPtr = getEventPtr(xmlParserP, encoderP); - - const char * inCursor; - - inCursor = start; - do { - ICHAR * dataPtr; - - dataPtr = (ICHAR *)parser->m_dataBuf; /* initial value */ - - XmlConvert(encoderP, &inCursor, end, - &dataPtr, (ICHAR *)parser->m_dataBufEnd); - *evPtr.endP = inCursor; - { - size_t const len = dataPtr - (ICHAR *)parser->m_dataBuf; - assert((size_t)(int)len == len); /* parser requirement */ - defaultHandler(parser->m_handlerArg, - parser->m_dataBuf, (int)len); - } - *evPtr.startP = inCursor; - } while (inCursor != end); - } else { - size_t const len = (XML_Char *)end - (XML_Char *)start; - assert((size_t)(int)len == len); /* parser requirement */ - defaultHandler(parser->m_handlerArg, (XML_Char *)start, len); - } -} - - - -static void -processDataCharsToken(XML_Parser * const xmlParserP, - const ENCODING * const encoderP, - const char * const tokenStart, - const char * const tokenEnd) { - - Parser * const parser = (Parser *)xmlParserP; - /* For use by macros */ - - if (characterDataHandler) { - if (MUST_CONVERT(encoderP, tokenStart)) { - struct EventPtr const evPtr = getEventPtr(xmlParserP, encoderP); - - const char * inCursor; - for (inCursor = tokenStart; inCursor < tokenEnd;) { - - ICHAR * outCursor; - - outCursor = (ICHAR *)dataBuf; - *evPtr.startP = inCursor; - assert((ICHAR *)dataBufEnd - (ICHAR *)dataBuf >= 4); - - XmlConvert(encoderP, &inCursor, tokenEnd, &outCursor, - (ICHAR *)dataBufEnd); - - *evPtr.endP = inCursor; - { - size_t const len = outCursor - (ICHAR *)dataBuf; - assert((size_t)(int)len == len); /* parser reqt */ - characterDataHandler(handlerArg, dataBuf, (int)len); - } - } - } else { - size_t const len = (XML_Char *)tokenEnd - (XML_Char *)tokenStart; - assert((size_t)(int)len == len); /* parser reqt */ - characterDataHandler(handlerArg, (XML_Char *)tokenStart, len); - } - } else if (defaultHandler) - reportDefault(xmlParserP, encoderP, tokenStart, tokenEnd); -} - - - -static int -reportProcessingInstruction(XML_Parser parser, - const ENCODING *enc, - const char *start, - const char *end) -{ - const XML_Char *target; - XML_Char *data; - const char *tem; - if (!processingInstructionHandler) { - if (defaultHandler) - reportDefault(parser, enc, start, end); - return 1; - } - start += enc->minBytesPerChar * 2; - tem = start + XmlNameLength(enc, start); - target = poolStoreString(&tempPool, enc, start, tem); - if (!target) - return 0; - poolFinish(&tempPool); - data = poolStoreString(&tempPool, enc, - XmlSkipS(enc, tem), - end - enc->minBytesPerChar*2); - if (!data) - return 0; - normalizeLines(data); - processingInstructionHandler(handlerArg, target, data); - poolClear(&tempPool); - return 1; -} - -static int -reportComment(XML_Parser parser, - const ENCODING *enc, - const char *start, - const char *end) -{ - XML_Char *data; - if (!commentHandler) { - if (defaultHandler) - reportDefault(parser, enc, start, end); - return 1; - } - data = poolStoreString(&tempPool, - enc, - start + enc->minBytesPerChar * 4, - end - enc->minBytesPerChar * 3); - if (!data) - return 0; - normalizeLines(data); - commentHandler(handlerArg, data); - poolClear(&tempPool); - return 1; -} - - - -static void -initXmlEncoding(XML_Encoding * const xmlEncP) { - - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(xmlEncP->map); ++i) - xmlEncP->map[i] = -1; - - xmlEncP->convert = 0; - xmlEncP->data = 0; - xmlEncP->release = 0; -} - - - -static enum XML_Error -handleUnknownEncoding(XML_Parser const xmlParserP, - const XML_Char * const encodingName) { - - Parser * const parser = (Parser *) xmlParserP; - - if (unknownEncodingHandler) { - XML_Encoding info; - - initXmlEncoding(&info); - - if (unknownEncodingHandler(unknownEncodingHandlerData, - encodingName, &info)) { - ENCODING * enc; - unknownEncodingMem = malloc(xmlrpc_XmlSizeOfUnknownEncoding()); - if (!unknownEncodingMem) { - if (info.release) - info.release(info.data); - return XML_ERROR_NO_MEMORY; - } - enc = (ns - ? xmlrpc_XmlInitUnknownEncodingNS - : xmlrpc_XmlInitUnknownEncoding)(unknownEncodingMem, - info.map, - info.convert, - info.data); - if (enc) { - unknownEncodingData = info.data; - unknownEncodingRelease = info.release; - parser->m_encoding = enc; - return XML_ERROR_NONE; - } - } - if (info.release) - info.release(info.data); - } - return XML_ERROR_UNKNOWN_ENCODING; -} - - - -static enum XML_Error -initializeEncoding(XML_Parser const xmlParserP) { - - Parser * const parser = (Parser *) xmlParserP; - - enum XML_Error retval; - int rc; - - rc = (ns ? xmlrpc_XmlInitEncodingNS : xmlrpc_XmlInitEncoding)( - &parser->m_initEncoding, &parser->m_encoding, - parser->m_protocolEncodingName); - - if (rc == 0) { - /* 'parser->m_protocolEncodingName' is not a recognized name */ - retval = handleUnknownEncoding(xmlParserP, - parser->m_protocolEncodingName); - } else - retval = XML_ERROR_NONE; - - return retval; -} - - - -static void -handleUnknownEncoding0(XML_Parser const xmlParserP, - const char * const encodingName, - const ENCODING * const encoding, - STRING_POOL * const tempPoolP, - enum XML_Error * const resultP) { - - const XML_Char * const s = - poolStoreString(tempPoolP, encoding, encodingName, - encodingName + XmlNameLength(encoding, - encodingName)); - if (s) { - *resultP = handleUnknownEncoding(xmlParserP, s); - poolDiscard(tempPoolP); - } else - *resultP = XML_ERROR_NO_MEMORY; -} - - - -static void -processXmlDecl(XML_Parser const xmlParserP, - int const isGeneralTextEntity, - const char * const s, - const char * const next, - enum XML_Error * const resultP) { -/*---------------------------------------------------------------------------- - Process an XML declaration processing instruction (PI), i.e. - - - If *xmlParserP does not already have an encoding assigned and the - declaration names an encoding, set that up as the encoding for the parser - if possible. - - If *xmlParserP already has an encoding assigned, ignore any encoding - specification in the declaration, even errors in it. ------------------------------------------------------------------------------*/ - Parser * const parserP = (Parser *) xmlParserP; - - const char *encodingName = 0; - const ENCODING *newEncodingP = 0; - const char *version; - int standalone = -1; - bool validSyntax; - - validSyntax = (parserP->m_ns - ? xmlrpc_XmlParseXmlDeclNS - : xmlrpc_XmlParseXmlDecl)(isGeneralTextEntity, - parserP->m_encoding, - s, - next, - &parserP->m_eventPtr, - &version, - &encodingName, - &newEncodingP, - &standalone); - if (!validSyntax) { - *resultP = XML_ERROR_SYNTAX; - /* parserP->m_eventPtr points to the invalid part */ - } else { - if (!isGeneralTextEntity && standalone == 1) { - parserP->m_dtd.standalone = 1; - if (parserP->m_paramEntityParsing == - XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) - parserP->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; - } - if (parserP->m_defaultHandler) - reportDefault(xmlParserP, parserP->m_encoding, s, next); - if (parserP->m_protocolEncodingName) - *resultP = XML_ERROR_NONE; - else { - if (newEncodingP) { - /* The declaration names an encoding and the parser recognized - the name as referring to 'newEncodingP'. - */ - if (newEncodingP->minBytesPerChar != - parserP->m_encoding->minBytesPerChar) { - parserP->m_eventPtr = encodingName; - *resultP = XML_ERROR_INCORRECT_ENCODING; - } else { - parserP->m_encoding = newEncodingP; - *resultP = XML_ERROR_NONE; - } - } else { - if (encodingName) { - /* The declaration names an encoding, but the parser - didn't recognize the name. - */ - enum XML_Error result; - handleUnknownEncoding0(xmlParserP, encodingName, - parserP->m_encoding, - &parserP->m_tempPool, &result); - - if (result == XML_ERROR_UNKNOWN_ENCODING) - parserP->m_eventPtr = encodingName; - - *resultP = result; - } else - /* The declaration doesn't name an encoding */ - *resultP = XML_ERROR_NONE; - } - } - } -} - - - -static ATTRIBUTE_ID * -getAttributeId(XML_Parser parser, - const ENCODING *enc, - const char *start, - const char *end) -{ - ATTRIBUTE_ID *id; - const XML_Char *name; - if (!poolAppendChar(&dtd.pool, XML_T('\0'))) - return 0; - name = poolStoreString(&dtd.pool, enc, start, end); - if (!name) - return 0; - ++name; - id = (ATTRIBUTE_ID *)lookup(parser, &dtd.attributeIds, name, - sizeof(ATTRIBUTE_ID)); - if (!id) - return 0; - if (id->name != name) - poolDiscard(&dtd.pool); - else { - poolFinish(&dtd.pool); - if (!ns) - ; - else if (name[0] == 'x' - && name[1] == 'm' - && name[2] == 'l' - && name[3] == 'n' - && name[4] == 's' - && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) { - if (name[5] == '\0') - id->prefix = &dtd.defaultPrefix; - else - id->prefix = (PREFIX *)lookup(parser, &dtd.prefixes, name + 6, - sizeof(PREFIX)); - id->xmlns = 1; - } - else { - int i; - for (i = 0; name[i]; i++) { - if (name[i] == XML_T(':')) { - int j; - for (j = 0; j < i; j++) { - if (!poolAppendChar(&dtd.pool, name[j])) - return 0; - } - if (!poolAppendChar(&dtd.pool, XML_T('\0'))) - return 0; - id->prefix = (PREFIX *) - lookup(parser, &dtd.prefixes, poolStart(&dtd.pool), - sizeof(PREFIX)); - if (id->prefix->name == poolStart(&dtd.pool)) - poolFinish(&dtd.pool); - else - poolDiscard(&dtd.pool); - break; - } - } - } - } - return id; -} - -static -void normalizePublicId(XML_Char *publicId) -{ - XML_Char *p = publicId; - XML_Char *s; - for (s = publicId; *s; s++) { - switch (*s) { - case 0x20: - case 0xD: - case 0xA: - if (p != publicId && p[-1] != 0x20) - *p++ = 0x20; - break; - default: - *p++ = *s; - } - } - if (p != publicId && p[-1] == 0x20) - --p; - *p = XML_T('\0'); -} - - - -static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) -{ - const XML_Char *name; - for (name = elementType->name; *name; name++) { - if (*name == XML_T(':')) { - PREFIX *prefix; - const XML_Char *s; - for (s = elementType->name; s != name; s++) { - if (!poolAppendChar(&dtd.pool, *s)) - return 0; - } - if (!poolAppendChar(&dtd.pool, XML_T('\0'))) - return 0; - prefix = (PREFIX *) - lookup(parser, &dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX)); - if (!prefix) - return 0; - if (prefix->name == poolStart(&dtd.pool)) - poolFinish(&dtd.pool); - else - poolDiscard(&dtd.pool); - elementType->prefix = prefix; - - } - } - return 1; -} - - - -static enum XML_Error -appendAttributeValue(XML_Parser const xmlParserP, - const ENCODING * const enc, - int const isCdata, - const char * const ptrArg, - const char * const end, - STRING_POOL * const pool) { - - Parser * const parser = (Parser *) xmlParserP; - - const char * ptr; - - ptr = ptrArg; - - for (;;) { - const char *next; - int tok = XmlAttributeValueTok(enc, ptr, end, &next); - switch (tok) { - case XML_TOK_NONE: - return XML_ERROR_NONE; - case XML_TOK_INVALID: - if (enc == parser->m_encoding) - eventPtr = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL: - if (enc == parser->m_encoding) - eventPtr = ptr; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_CHAR_REF: - { - XML_Char buf[XML_ENCODE_MAX]; - int i; - int n = XmlCharRefNumber(enc, ptr); - if (n < 0) { - if (enc == parser->m_encoding) - eventPtr = ptr; - return XML_ERROR_BAD_CHAR_REF; - } - if (!isCdata - && n == 0x20 /* space */ - && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) - break; - n = XmlEncode(n, (ICHAR *)buf); - if (!n) { - if (enc == parser->m_encoding) - eventPtr = ptr; - return XML_ERROR_BAD_CHAR_REF; - } - for (i = 0; i < n; i++) { - if (!poolAppendChar(pool, buf[i])) - return XML_ERROR_NO_MEMORY; - } - } - break; - case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, enc, ptr, next)) - return XML_ERROR_NO_MEMORY; - break; - break; - case XML_TOK_TRAILING_CR: - next = ptr + enc->minBytesPerChar; - /* fall through */ - case XML_TOK_ATTRIBUTE_VALUE_S: - case XML_TOK_DATA_NEWLINE: - if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) - break; - if (!poolAppendChar(pool, 0x20)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_ENTITY_REF: - { - const XML_Char *name; - ENTITY *entity; - XML_Char ch = XmlPredefinedEntityName(enc, - ptr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (ch) { - if (!poolAppendChar(pool, ch)) - return XML_ERROR_NO_MEMORY; - break; - } - name = poolStoreString(&temp2Pool, enc, - ptr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) - return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(parser, &dtd.generalEntities, name, 0); - poolDiscard(&temp2Pool); - if (!entity) { - if (dtd.complete) { - if (enc == parser->m_encoding) - eventPtr = ptr; - return XML_ERROR_UNDEFINED_ENTITY; - } - } - else if (entity->open) { - if (enc == parser->m_encoding) - eventPtr = ptr; - return XML_ERROR_RECURSIVE_ENTITY_REF; - } - else if (entity->notation) { - if (enc == parser->m_encoding) - eventPtr = ptr; - return XML_ERROR_BINARY_ENTITY_REF; - } - else if (!entity->textPtr) { - if (enc == parser->m_encoding) - eventPtr = ptr; - return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; - } - else { - enum XML_Error result; - const XML_Char *textEnd = entity->textPtr + entity->textLen; - entity->open = 1; - result = appendAttributeValue(xmlParserP, internalEncoding, - isCdata, (char *)entity->textPtr, - (char *)textEnd, pool); - entity->open = 0; - if (result) - return result; - } - } - break; - default: - abort(); - } - ptr = next; - } - /* not reached */ -} - - - -static enum XML_Error -storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, - const char *ptr, const char *end, - STRING_POOL *pool) -{ - enum XML_Error result = - appendAttributeValue(parser, enc, isCdata, ptr, end, pool); - if (result) - return result; - if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) - poolChop(pool); - if (!poolAppendChar(pool, XML_T('\0'))) - return XML_ERROR_NO_MEMORY; - return XML_ERROR_NONE; -} - - - -static enum XML_Error -storeEntityValue(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char * const entityTextPtrArg, - const char * const entityTextEnd) { - - Parser * const parser = (Parser *) xmlParserP; - - STRING_POOL * const pool = &(dtd.pool); - const char * entityTextPtr; - - entityTextPtr = entityTextPtrArg; - - for (;;) { - const char * next; - int tok; - - tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); - switch (tok) { - case XML_TOK_PARAM_ENTITY_REF: - if (parentParser || enc != parser->m_encoding) { - enum XML_Error result; - const XML_Char *name; - ENTITY *entity; - name = poolStoreString(&tempPool, enc, - entityTextPtr + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) - return XML_ERROR_NO_MEMORY; - entity = (ENTITY *)lookup(parser, &dtd.paramEntities, name, 0); - poolDiscard(&tempPool); - if (!entity) { - if (enc == parser->m_encoding) - eventPtr = entityTextPtr; - return XML_ERROR_UNDEFINED_ENTITY; - } - if (entity->open) { - if (enc == parser->m_encoding) - eventPtr = entityTextPtr; - return XML_ERROR_RECURSIVE_ENTITY_REF; - } - if (entity->systemId) { - if (enc == parser->m_encoding) - eventPtr = entityTextPtr; - return XML_ERROR_PARAM_ENTITY_REF; - } - entity->open = 1; - result = storeEntityValue(parser, - internalEncoding, - (char *)entity->textPtr, - (char *)(entity->textPtr + entity->textLen)); - entity->open = 0; - if (result) - return result; - break; - } - eventPtr = entityTextPtr; - return XML_ERROR_SYNTAX; - case XML_TOK_NONE: - return XML_ERROR_NONE; - case XML_TOK_ENTITY_REF: - case XML_TOK_DATA_CHARS: - if (!poolAppend(pool, enc, entityTextPtr, next)) - return XML_ERROR_NO_MEMORY; - break; - case XML_TOK_TRAILING_CR: - next = entityTextPtr + enc->minBytesPerChar; - /* fall through */ - case XML_TOK_DATA_NEWLINE: { - if (pool->end == pool->ptr) { - const char * error; - poolGrow(pool, &error); - if (error) { - xmlrpc_strfree(error); - return XML_ERROR_NO_MEMORY; - } - } - *(pool->ptr)++ = 0xA; - } break; - case XML_TOK_CHAR_REF: - { - XML_Char buf[XML_ENCODE_MAX]; - int i; - int n = XmlCharRefNumber(enc, entityTextPtr); - if (n < 0) { - if (enc == parser->m_encoding) - eventPtr = entityTextPtr; - return XML_ERROR_BAD_CHAR_REF; - } - n = XmlEncode(n, (ICHAR *)buf); - if (!n) { - if (enc == parser->m_encoding) - eventPtr = entityTextPtr; - return XML_ERROR_BAD_CHAR_REF; - } - for (i = 0; i < n; i++) { - if (pool->end == pool->ptr) { - const char * error; - poolGrow(pool, &error); - if (error) { - xmlrpc_strfree(error); - return XML_ERROR_NO_MEMORY; - } - } - *(pool->ptr)++ = buf[i]; - } - } - break; - case XML_TOK_PARTIAL: - if (enc == parser->m_encoding) - eventPtr = entityTextPtr; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_INVALID: - if (enc == parser->m_encoding) - eventPtr = next; - return XML_ERROR_INVALID_TOKEN; - default: - abort(); - } - entityTextPtr = next; - } - /* not reached */ -} - - - -static int -defineAttribute(ELEMENT_TYPE *type, - ATTRIBUTE_ID *attId, - int isCdata, - int isId, - const XML_Char *value) -{ - DEFAULT_ATTRIBUTE *att; - if (value || isId) { - /* The handling of default attributes gets messed up if we have - a default which duplicates a non-default. */ - int i; - for (i = 0; i < type->nDefaultAtts; i++) - if (attId == type->defaultAtts[i].id) - return 1; - if (isId && !type->idAtt && !attId->xmlns) - type->idAtt = attId; - } - if (type->nDefaultAtts == type->allocDefaultAtts) { - if (type->allocDefaultAtts == 0) { - type->allocDefaultAtts = 8; - type->defaultAtts = - malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); - if (!type->defaultAtts) - return 0; - } - else { - DEFAULT_ATTRIBUTE *temp; - type->allocDefaultAtts *= 2; - temp = realloc(type->defaultAtts, - type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); - if (!temp) - return 0; - type->defaultAtts = temp; - } - } - att = type->defaultAtts + type->nDefaultAtts; - att->id = attId; - att->value = value; - att->isCdata = isCdata; - if (!isCdata) - attId->maybeTokenized = 1; - type->nDefaultAtts += 1; - return 1; -} - - - -/* If tagNamePtr is non-null, build a real list of attributes, -otherwise just check the attributes for well-formedness. */ - -static enum XML_Error -storeAtts(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char * const attStr, - TAG_NAME * const tagNamePtr, - BINDING ** const bindingsPtr) { - - Parser * const parser = (Parser *)xmlParserP; - - ELEMENT_TYPE *elementType = 0; - int nDefaultAtts = 0; - const XML_Char ** appAtts; - /* the attribute list to pass to the application */ - int attIndex = 0; - int i; - int n; - int nPrefixes = 0; - BINDING *binding; - const XML_Char *localPart; - - /* lookup the element type name */ - if (tagNamePtr) { - elementType = (ELEMENT_TYPE *) - lookup(parser, &dtd.elementTypes, tagNamePtr->str, 0); - if (!elementType) { - tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str); - if (!tagNamePtr->str) - return XML_ERROR_NO_MEMORY; - elementType = (ELEMENT_TYPE *) - lookup(parser, &dtd.elementTypes, tagNamePtr->str, - sizeof(ELEMENT_TYPE)); - if (!elementType) - return XML_ERROR_NO_MEMORY; - if (ns && !setElementTypePrefix(xmlParserP, elementType)) - return XML_ERROR_NO_MEMORY; - } - nDefaultAtts = elementType->nDefaultAtts; - } - /* get the attributes from the tokenizer */ - n = XmlGetAttributes(enc, attStr, attsSize, atts); - if (n + nDefaultAtts > attsSize) { - int oldAttsSize = attsSize; - ATTRIBUTE *temp; - attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; - temp = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE)); - if (!temp) - return XML_ERROR_NO_MEMORY; - atts = temp; - if (n > oldAttsSize) - XmlGetAttributes(enc, attStr, n, atts); - } - appAtts = (const XML_Char **)atts; - for (i = 0; i < n; i++) { - /* add the name and value to the attribute list */ - ATTRIBUTE_ID *attId = getAttributeId(xmlParserP, enc, atts[i].name, - atts[i].name - + XmlNameLength(enc, atts[i].name)); - if (!attId) - return XML_ERROR_NO_MEMORY; - /* detect duplicate attributes */ - if ((attId->name)[-1]) { - if (enc == parser->m_encoding) - eventPtr = atts[i].name; - return XML_ERROR_DUPLICATE_ATTRIBUTE; - } - (attId->name)[-1] = 1; - appAtts[attIndex++] = attId->name; - if (!atts[i].normalized) { - enum XML_Error result; - int isCdata = 1; - - /* figure out whether declared as other than CDATA */ - if (attId->maybeTokenized) { - int j; - for (j = 0; j < nDefaultAtts; j++) { - if (attId == elementType->defaultAtts[j].id) { - isCdata = elementType->defaultAtts[j].isCdata; - break; - } - } - } - - /* normalize the attribute value */ - result = storeAttributeValue(xmlParserP, enc, isCdata, - atts[i].valuePtr, atts[i].valueEnd, - &tempPool); - if (result) - return result; - if (tagNamePtr) { - appAtts[attIndex] = poolStart(&tempPool); - poolFinish(&tempPool); - } - else - poolDiscard(&tempPool); - } - else if (tagNamePtr) { - /* the value did not need normalizing */ - appAtts[attIndex] = - poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd); - if (appAtts[attIndex] == 0) - return XML_ERROR_NO_MEMORY; - poolFinish(&tempPool); - } - /* handle prefixed attribute names */ - if (attId->prefix && tagNamePtr) { - if (attId->xmlns) { - /* deal with namespace declarations here */ - if (!addBinding(xmlParserP, attId->prefix, attId, appAtts[attIndex], - bindingsPtr)) - return XML_ERROR_NO_MEMORY; - --attIndex; - } - else { - /* deal with other prefixed names later */ - attIndex++; - nPrefixes++; - (attId->name)[-1] = 2; - } - } - else - attIndex++; - } - if (tagNamePtr) { - int j; - nSpecifiedAtts = attIndex; - if (elementType->idAtt && (elementType->idAtt->name)[-1]) { - for (i = 0; i < attIndex; i += 2) - if (appAtts[i] == elementType->idAtt->name) { - idAttIndex = i; - break; - } - } - else - idAttIndex = -1; - /* do attribute defaulting */ - for (j = 0; j < nDefaultAtts; j++) { - const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j; - if (!(da->id->name)[-1] && da->value) { - if (da->id->prefix) { - if (da->id->xmlns) { - if (!addBinding(xmlParserP, da->id->prefix, da->id, da->value, - bindingsPtr)) - return XML_ERROR_NO_MEMORY; - } - else { - (da->id->name)[-1] = 2; - nPrefixes++; - appAtts[attIndex++] = da->id->name; - appAtts[attIndex++] = da->value; - } - } - else { - (da->id->name)[-1] = 1; - appAtts[attIndex++] = da->id->name; - appAtts[attIndex++] = da->value; - } - } - } - appAtts[attIndex] = 0; - } - i = 0; - if (nPrefixes) { - /* expand prefixed attribute names */ - for (; i < attIndex; i += 2) { - if (appAtts[i][-1] == 2) { - ATTRIBUTE_ID *id; - ((XML_Char *)(appAtts[i]))[-1] = 0; - id = (ATTRIBUTE_ID *)lookup(parser, &dtd.attributeIds, appAtts[i], 0); - if (id->prefix->binding) { - int j; - const BINDING *b = id->prefix->binding; - const XML_Char *s = appAtts[i]; - for (j = 0; j < b->uriLen; j++) { - if (!poolAppendChar(&tempPool, b->uri[j])) - return XML_ERROR_NO_MEMORY; - } - while (*s++ != ':') - ; - do { - if (!poolAppendChar(&tempPool, *s)) - return XML_ERROR_NO_MEMORY; - } while (*s++); - appAtts[i] = poolStart(&tempPool); - poolFinish(&tempPool); - } - if (!--nPrefixes) - break; - } - else - ((XML_Char *)(appAtts[i]))[-1] = 0; - } - } - /* clear the flags that say whether attributes were specified */ - for (; i < attIndex; i += 2) - ((XML_Char *)(appAtts[i]))[-1] = 0; - if (!tagNamePtr) - return XML_ERROR_NONE; - for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) - binding->attId->name[-1] = 0; - /* expand the element type name */ - if (elementType->prefix) { - binding = elementType->prefix->binding; - if (!binding) - return XML_ERROR_NONE; - localPart = tagNamePtr->str; - while (*localPart++ != XML_T(':')) - ; - } - else if (dtd.defaultPrefix.binding) { - binding = dtd.defaultPrefix.binding; - localPart = tagNamePtr->str; - } - else - return XML_ERROR_NONE; - tagNamePtr->localPart = localPart; - tagNamePtr->uriLen = binding->uriLen; - for (i = 0; localPart[i++];) - ; - n = i + binding->uriLen; - if (n > binding->uriAlloc) { - TAG *p; - XML_Char *uri = malloc((n + EXPAND_SPARE) * sizeof(XML_Char)); - if (!uri) - return XML_ERROR_NO_MEMORY; - binding->uriAlloc = n + EXPAND_SPARE; - memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); - for (p = tagStack; p; p = p->parent) - if (p->name.str == binding->uri) - p->name.str = uri; - free(binding->uri); - binding->uri = uri; - } - memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char)); - tagNamePtr->str = binding->uri; - return XML_ERROR_NONE; -} - - - -static Processor epilogProcessor; - -static void -epilogProcessor(XML_Parser const xmlParserP, - const char * const startArg, - const char * const end, - const char ** const nextPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - const char * s; - - *errorP = NULL; - - s = startArg; - - processor = epilogProcessor; - eventPtr = s; - for (;;) { - const char *next; - int tok = XmlPrologTok(parser->m_encoding, s, end, &next); - eventEndPtr = next; - switch (tok) { - case -XML_TOK_PROLOG_S: - if (defaultHandler) { - eventEndPtr = end; - reportDefault(xmlParserP, parser->m_encoding, s, end); - } - /* fall through */ - case XML_TOK_NONE: - if (nextPtr) - *nextPtr = end; - *errorCodeP = XML_ERROR_NONE; - return; - case XML_TOK_PROLOG_S: - if (defaultHandler) - reportDefault(xmlParserP, parser->m_encoding, s, next); - break; - case XML_TOK_PI: - if (!reportProcessingInstruction(xmlParserP, parser->m_encoding, - s, next)) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - break; - case XML_TOK_COMMENT: - if (!reportComment(xmlParserP, parser->m_encoding, s, next)) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - break; - case XML_TOK_INVALID: - eventPtr = next; - *errorCodeP = XML_ERROR_INVALID_TOKEN; - return; - case XML_TOK_PARTIAL: - if (nextPtr) { - *nextPtr = s; - *errorCodeP = XML_ERROR_NONE; - } else - *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; - return; - case XML_TOK_PARTIAL_CHAR: - if (nextPtr) { - *nextPtr = s; - *errorCodeP = XML_ERROR_NONE; - } else - *errorCodeP = XML_ERROR_PARTIAL_CHAR; - return; - default: - *errorCodeP = XML_ERROR_JUNK_AFTER_DOC_ELEMENT; - return; - } - eventPtr = s = next; - } -} - - - -static enum XML_Error -doCdataSection(XML_Parser const xmlParserP, - const ENCODING * const encoderP, - const char ** const startPtr, - const char * const end, - const char ** const nextPtr) { - - Parser * const parser = (Parser *) xmlParserP; - struct EventPtr const evPtr = getEventPtr(xmlParserP, encoderP); - - const char * s; - - s = *startPtr; /* initial value */ - *evPtr.startP = s; - *startPtr = 0; - for (;;) { - const char *next; - int tok = XmlCdataSectionTok(encoderP, s, end, &next); - *evPtr.endP = next; - switch (tok) { - case XML_TOK_CDATA_SECT_CLOSE: - if (endCdataSectionHandler) - endCdataSectionHandler(handlerArg); - else if (defaultHandler) - reportDefault(xmlParserP, encoderP, s, next); - *startPtr = next; - return XML_ERROR_NONE; - case XML_TOK_DATA_NEWLINE: - if (characterDataHandler) { - XML_Char c = 0xA; - characterDataHandler(handlerArg, &c, 1); - } - else if (defaultHandler) - reportDefault(xmlParserP, encoderP, s, next); - break; - case XML_TOK_DATA_CHARS: - processDataCharsToken(xmlParserP, encoderP, s, next); - break; - case XML_TOK_INVALID: - *evPtr.startP = next; - return XML_ERROR_INVALID_TOKEN; - case XML_TOK_PARTIAL_CHAR: - if (nextPtr) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_PARTIAL_CHAR; - case XML_TOK_PARTIAL: - case XML_TOK_NONE: - if (nextPtr) { - *nextPtr = s; - return XML_ERROR_NONE; - } - return XML_ERROR_UNCLOSED_CDATA_SECTION; - default: - abort(); - } - *evPtr.startP = s = next; - } - /* not reached */ -} - - - -/* Forward declaration for recursive reference: */ -static void -doContent(XML_Parser const xmlParserP, - int const startTagLevel, - const ENCODING * const enc, - const char * const startArg, - const char * const end, - const char ** const nextPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP); - - -static Processor contentProcessor; - -static void -contentProcessor(XML_Parser const xmlParserP, - const char * const start, - const char * const end, - const char ** const endPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - const char * error; - - parser->m_errorString = NULL; - - doContent(xmlParserP, 0, parser->m_encoding, start, end, endPtr, - errorCodeP, &error); - - if (*errorCodeP != XML_ERROR_NONE) { - if (error) { - xmlrpc_asprintf(errorP, "Invalid XML \"content\". %s", error); - - xmlrpc_strfree(error); - } else { - const char * const sampleXml = extractXmlSample(start, end, 40); - - xmlrpc_asprintf(errorP, "Invalid XML \"content\" starting " - "with '%s'. %s", - sampleXml, - xmlrpc_XML_ErrorString(*errorCodeP)); - - xmlrpc_strfree(sampleXml); - } - } else - *errorP = NULL; -} - - - -/* The idea here is to avoid using stack for each CDATA section when -the whole file is parsed with one call. */ - - - -static Processor cdataSectionProcessor; - -static void -cdataSectionProcessor(XML_Parser const xmlParserP, - const char * const startArg, - const char * const end, - const char ** const endPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - enum XML_Error result; - const char * start; - - start = startArg; - - result = - doCdataSection(xmlParserP, parser->m_encoding, &start, end, endPtr); - - if (start) { - processor = contentProcessor; - contentProcessor(xmlParserP, start, end, endPtr, errorCodeP, errorP); - } else { - *errorCodeP = result; - *errorP = NULL; - } -} - - - -static void -doCharacterEntityRef(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char * const s, - const char * const next, - XML_Char const ch, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parserP = (Parser *) xmlParserP; - - if (parserP->m_characterDataHandler) - parserP->m_characterDataHandler(parserP->m_handlerArg, &ch, 1); - else if (parserP->m_defaultHandler) - reportDefault(xmlParserP, enc, s, next); - - *errorCodeP = XML_ERROR_NONE; - *errorP = NULL; -} - - - -static void -doInternalEntityRef(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char * const s, - const char * const next, - ENTITY * const entityP, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parserP = (Parser *) xmlParserP; - - if (parserP->m_defaultHandler && - !parserP->m_defaultExpandInternalEntities) { - reportDefault(xmlParserP, enc, s, next); - *errorCodeP = XML_ERROR_NONE; - *errorP = NULL; - } else { - OPEN_INTERNAL_ENTITY openEntity; - - entityP->open = 1; /* recursion control */ - - openEntity.next = parserP->m_openInternalEntities; - - parserP->m_openInternalEntities = &openEntity; - openEntity.entity = entityP; - openEntity.internalEventPtr = 0; - openEntity.internalEventEndPtr = 0; - - doContent(xmlParserP, - parserP->m_tagLevel, - parserP->m_internalEncoding, - (char *)entityP->textPtr, - (char *)(entityP->textPtr + entityP->textLen), - 0, errorCodeP, errorP); - - entityP->open = 0; /* recursion control */ - parserP->m_openInternalEntities = openEntity.next; - } -} - - - -static void -doExternalEntityRef(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char * const s, - const char * const next, - ENTITY * const entityP, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parserP = (Parser *) xmlParserP; - - *errorP = NULL; - - if (parserP->m_externalEntityRefHandler) { - const XML_Char * contextP; - - entityP->open = 1; - contextP = getContext(xmlParserP); - entityP->open = 0; - - if (!contextP) - *errorCodeP = XML_ERROR_NO_MEMORY; - else { - int rc; - - rc = parserP->m_externalEntityRefHandler( - parserP->m_externalEntityRefHandlerArg, - contextP, - entityP->base, - entityP->systemId, - entityP->publicId); - if (rc != 0) - *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING; - else { - poolDiscard(&parserP->m_tempPool); - *errorCodeP = XML_ERROR_NONE; - } - } - } else if (parserP->m_defaultHandler) { - reportDefault(xmlParserP, enc, s, next); - - *errorCodeP = XML_ERROR_NONE; - } else - *errorCodeP = XML_ERROR_NONE; -} - - - -static void -doEntityRef(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char * const s, - const char * const next, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - XML_Char const ch = XmlPredefinedEntityName(enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - - if (ch) - doCharacterEntityRef(xmlParserP, enc, s, next, ch, errorCodeP, errorP); - else { - Parser * const parserP = (Parser *) xmlParserP; - - const XML_Char * name; - ENTITY * entityP; - - *errorP = NULL; - - name = poolStoreString(&parserP->m_dtd.pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) { - *errorCodeP = XML_ERROR_NO_MEMORY; - } else { - entityP = (ENTITY *) - lookup(parserP, &parserP->m_dtd.generalEntities, name, 0); - poolDiscard(&parserP->m_dtd.pool); - if (!entityP) { - if (parserP->m_dtd.complete || parserP->m_dtd.standalone) - *errorCodeP = XML_ERROR_UNDEFINED_ENTITY; - else { - if (parserP->m_defaultHandler) - reportDefault(xmlParserP, enc, s, next); - *errorCodeP = XML_ERROR_NONE; - } - } else { - if (entityP->open) - *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF; - else if (entityP->notation) - *errorCodeP = XML_ERROR_BINARY_ENTITY_REF; - else { - if (entityP->textPtr) - doInternalEntityRef(xmlParserP, enc, s, next, entityP, - errorCodeP, errorP); - else - doExternalEntityRef(xmlParserP, enc, s, next, entityP, - errorCodeP, errorP); - } - } - } - } -} - - - -static void -doStartTagNoAtts(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char * const s, - const char * const next, - const char ** const nextPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - TAG *tag; - - *errorP = NULL; - - if (freeTagList) { - tag = freeTagList; - freeTagList = freeTagList->parent; - } else { - tag = malloc(sizeof(TAG)); - if (!tag) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - tag->buf = malloc(INIT_TAG_BUF_SIZE); - if (!tag->buf) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; - } - tag->bindings = NULL; - tag->parent = tagStack; - tagStack = tag; - tag->name.localPart = 0; - tag->rawName = s + enc->minBytesPerChar; - tag->rawNameLength = XmlNameLength(enc, tag->rawName); - if (nextPtr) { - /* Need to guarantee that: tag->buf + - ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= - tag->bufEnd - sizeof(XML_Char) - */ - - if (tag->rawNameLength + - (int)(sizeof(XML_Char) - 1) + - (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) { - char *temp; - int bufSize = tag->rawNameLength * 4; - bufSize = ROUND_UP(bufSize, sizeof(XML_Char)); - temp = realloc(tag->buf, bufSize); - if (!temp) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - tag->buf = temp; - tag->bufEnd = tag->buf + bufSize; - } - memcpy(tag->buf, tag->rawName, tag->rawNameLength); - tag->rawName = tag->buf; - } - ++tagLevel; - if (startElementHandler) { - enum XML_Error result; - XML_Char *toPtr; - for (;;) { - const char *rawNameEnd = tag->rawName + tag->rawNameLength; - const char *fromPtr = tag->rawName; - if (nextPtr) - toPtr = (XML_Char *) - (tag->buf + ROUND_UP(tag->rawNameLength, - sizeof(XML_Char))); - else - toPtr = (XML_Char *)tag->buf; - tag->name.str = toPtr; - XmlConvert(enc, - &fromPtr, rawNameEnd, - (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); - if (fromPtr == rawNameEnd) - break; - else { - size_t const bufSize = (tag->bufEnd - tag->buf) << 1; - char *temp = realloc(tag->buf, bufSize); - if (!temp) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - tag->buf = temp; - tag->bufEnd = tag->buf + bufSize; - if (nextPtr) - tag->rawName = tag->buf; - } - } - *toPtr = XML_T('\0'); - result = storeAtts(xmlParserP, enc, s, - &(tag->name), &(tag->bindings)); - if (result) { - *errorCodeP = result; - return; - } - startElementHandler(handlerArg, tag->name.str, - (const XML_Char **)atts); - poolClear(&tempPool); - } else { - tag->name.str = 0; - if (defaultHandler) - reportDefault(xmlParserP, enc, s, next); - } -} - - - -static void -doEmptyElementNoAtts(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char * const s, - const char * const end, - const char * const next, - const char ** const nextPtr, - const char ** const eventPP, - const char ** const eventEndPP, - bool * const doneP, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - if (startElementHandler || endElementHandler) { - const char * const rawName = s + enc->minBytesPerChar; - - enum XML_Error result; - BINDING * bindings; - TAG_NAME name; - - bindings = NULL; /* initial value */ - name.str = poolStoreString(&tempPool, enc, rawName, - rawName + XmlNameLength(enc, rawName)); - if (!name.str) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - poolFinish(&tempPool); - result = storeAtts(xmlParserP, enc, s, &name, &bindings); - if (result) { - *errorCodeP = result; - return; - } - poolFinish(&tempPool); - if (startElementHandler) - startElementHandler(handlerArg, name.str, (const XML_Char **)atts); - if (endElementHandler) { - if (startElementHandler) - *eventPP = *eventEndPP; - endElementHandler(handlerArg, name.str); - } - poolClear(&tempPool); - while (bindings) { - BINDING * const b = bindings; - if (endNamespaceDeclHandler) - endNamespaceDeclHandler(handlerArg, b->prefix->name); - bindings = bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; - b->prefix->binding = b->prevPrefixBinding; - } - } else if (defaultHandler) - reportDefault(xmlParserP, enc, s, next); - - if (tagLevel == 0) { - epilogProcessor(xmlParserP, next, end, nextPtr, errorCodeP, errorP); - *doneP = true; - } else - *doneP = false; -} - - - -static void -doEndTag(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char * const s, - const char * const end, - const char * const next, - const char ** const nextPtr, - int const startTagLevel, - const char ** const eventPP, - bool * const doneP, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - if (tagLevel == startTagLevel) - *errorCodeP = XML_ERROR_ASYNC_ENTITY; - else { - TAG * const tag = tagStack; - - int len; - const char * rawName; - - tagStack = tag->parent; - tag->parent = freeTagList; - freeTagList = tag; - rawName = s + enc->minBytesPerChar*2; - len = XmlNameLength(enc, rawName); - if (len != tag->rawNameLength - || memcmp(tag->rawName, rawName, len) != 0) { - *eventPP = rawName; - *errorCodeP = XML_ERROR_TAG_MISMATCH; - } else { - --tagLevel; - if (endElementHandler && tag->name.str) { - if (tag->name.localPart) { - XML_Char * to; - const XML_Char * from; - to = (XML_Char *)tag->name.str + tag->name.uriLen; - from = tag->name.localPart; - while ((*to++ = *from++) != 0) - ; - } - endElementHandler(handlerArg, tag->name.str); - } else if (defaultHandler) - reportDefault(xmlParserP, enc, s, next); - - while (tag->bindings) { - BINDING * const b = tag->bindings; - if (endNamespaceDeclHandler) - endNamespaceDeclHandler(handlerArg, b->prefix->name); - tag->bindings = tag->bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; - b->prefix->binding = b->prevPrefixBinding; - } - if (tagLevel == 0) { - epilogProcessor(xmlParserP, next, end, nextPtr, - errorCodeP, errorP); - *doneP = true; - } else { - *errorCodeP = XML_ERROR_NONE; - *doneP = false; - } - } - } -} - - - -static void -processContentToken(XML_Parser const xmlParserP, - int const tok, - const ENCODING * const enc, - const char * const s, - const char * const end, - const char ** const nextP, - const char ** const nextPtr, - int const startTagLevel, - bool * const doneP, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - struct EventPtr const evPtr = getEventPtr(xmlParserP, enc); - - *errorP = NULL; - *errorCodeP = XML_ERROR_NONE; - - switch (tok) { - case XML_TOK_TRAILING_CR: - if (nextPtr) { - *nextPtr = s; - *doneP = true; - } else { - *evPtr.endP = end; - - if (characterDataHandler) { - XML_Char c = 0xA; - characterDataHandler(handlerArg, &c, 1); - } else if (defaultHandler) - reportDefault(xmlParserP, enc, s, end); - - if (startTagLevel == 0) - *errorCodeP = XML_ERROR_NO_ELEMENTS; - else if (tagLevel != startTagLevel) { - *errorCodeP = XML_ERROR_ASYNC_ENTITY; - } else - *doneP = true; - } - break; - case XML_TOK_NONE: - if (nextPtr) { - *nextPtr = s; - *doneP = true; - } else if (startTagLevel > 0) { - if (tagLevel != startTagLevel) - *errorCodeP = XML_ERROR_ASYNC_ENTITY; - else - *doneP = true; - } else - *errorCodeP = XML_ERROR_NO_ELEMENTS; - break; - case XML_TOK_INVALID: - *evPtr.startP = *nextP; - *errorCodeP = XML_ERROR_INVALID_TOKEN; - xmlrpc_asprintf(errorP, "Invalid token, starting %ld bytes in", - (long)(*nextP - s)); - break; - case XML_TOK_PARTIAL: - if (nextPtr) { - *nextPtr = s; - *doneP = true; - } else - *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; - break; - case XML_TOK_PARTIAL_CHAR: - if (nextPtr) { - *nextPtr = s; - *doneP = true; - } else - *errorCodeP = XML_ERROR_PARTIAL_CHAR; - break; - case XML_TOK_ENTITY_REF: - doEntityRef(xmlParserP, enc, s, *nextP, errorCodeP, errorP); - break; - case XML_TOK_START_TAG_WITH_ATTS: - if (!startElementHandler) - *errorCodeP = storeAtts(xmlParserP, enc, s, 0, 0); - if (*errorCodeP == XML_ERROR_NONE) - doStartTagNoAtts(xmlParserP, enc, s, *nextP, nextPtr, - errorCodeP, errorP); - break; - case XML_TOK_START_TAG_NO_ATTS: - doStartTagNoAtts(xmlParserP, enc, s, *nextP, nextPtr, - errorCodeP, errorP); - break; - case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: - if (!startElementHandler) - *errorCodeP = storeAtts(xmlParserP, enc, s, 0, 0); - - if (*errorCodeP == XML_ERROR_NONE) - doEmptyElementNoAtts(xmlParserP, enc, s, end, *nextP, nextPtr, - evPtr.startP, evPtr.endP, - doneP, errorCodeP, errorP); - break; - case XML_TOK_EMPTY_ELEMENT_NO_ATTS: - doEmptyElementNoAtts(xmlParserP, enc, s, end, *nextP, nextPtr, - evPtr.startP, evPtr.endP, - doneP, errorCodeP, errorP); - break; - case XML_TOK_END_TAG: - doEndTag(xmlParserP, enc, s, end, *nextP, nextPtr, startTagLevel, - evPtr.startP, doneP, errorCodeP, errorP); - break; - case XML_TOK_CHAR_REF: { - int const n = XmlCharRefNumber(enc, s); - if (n < 0) - *errorCodeP = XML_ERROR_BAD_CHAR_REF; - else { - if (characterDataHandler) { - XML_Char buf[XML_ENCODE_MAX]; - characterDataHandler(handlerArg, buf, - XmlEncode(n, (ICHAR *)buf)); - } else if (defaultHandler) - reportDefault(xmlParserP, enc, s, *nextP); - } - } break; - case XML_TOK_XML_DECL: - *errorCodeP = XML_ERROR_MISPLACED_XML_PI; - break; - case XML_TOK_DATA_NEWLINE: - if (characterDataHandler) { - XML_Char c = 0xA; - characterDataHandler(handlerArg, &c, 1); - } else if (defaultHandler) - reportDefault(xmlParserP, enc, s, *nextP); - break; - case XML_TOK_CDATA_SECT_OPEN: { - enum XML_Error result; - if (startCdataSectionHandler) - startCdataSectionHandler(handlerArg); - else if (defaultHandler) - reportDefault(xmlParserP, enc, s, *nextP); - result = doCdataSection(xmlParserP, enc, nextP, end, nextPtr); - if (!*nextP) { - processor = cdataSectionProcessor; - *errorCodeP = result; - } - } break; - case XML_TOK_TRAILING_RSQB: - if (nextPtr) { - *nextPtr = s; - *errorCodeP = XML_ERROR_NONE; - } else { - if (characterDataHandler) { - if (MUST_CONVERT(enc, s)) { - const char * from; - ICHAR * dataPtr; - from = s; - dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &from, end, &dataPtr, (ICHAR *)dataBufEnd); - { - size_t const len = dataPtr - (ICHAR *)dataBuf; - assert((size_t)(int)len == len); /* parser reqt */ - characterDataHandler(handlerArg, dataBuf, (int)len); - } - } else { - size_t const len = (XML_Char *)end - (XML_Char *)s; - assert((size_t)(int)len == len); /* parser reqt */ - characterDataHandler(handlerArg, (XML_Char *)s, (int)len); - } - } else if (defaultHandler) - reportDefault(xmlParserP, enc, s, end); - - if (startTagLevel == 0) { - *evPtr.startP = end; - *errorCodeP = XML_ERROR_NO_ELEMENTS; - } else if (tagLevel != startTagLevel) { - *evPtr.startP = end; - *errorCodeP = XML_ERROR_ASYNC_ENTITY; - } else - *doneP = true; - } - break; - case XML_TOK_DATA_CHARS: - processDataCharsToken(xmlParserP, enc, s, *nextP); - break; - case XML_TOK_PI: - if (!reportProcessingInstruction(xmlParserP, enc, s, *nextP)) - *errorCodeP = XML_ERROR_NO_MEMORY; - break; - case XML_TOK_COMMENT: - if (!reportComment(xmlParserP, enc, s, *nextP)) - *errorCodeP = XML_ERROR_NO_MEMORY; - break; - default: - if (defaultHandler) - reportDefault(xmlParserP, enc, s, *nextP); - break; - } -} - - - -static void -doContent(XML_Parser const xmlParserP, - int const startTagLevel, - const ENCODING * const enc, - const char * const startArg, - const char * const end, - const char ** const nextPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - struct EventPtr const evPtr = getEventPtr(xmlParserP, enc); - - const char * s; - bool done; - - s = startArg; - *evPtr.startP = s; - done = false; - *errorCodeP = XML_ERROR_NONE; - *errorP = NULL; - - while (*errorCodeP == XML_ERROR_NONE && !done) { - int tok; - const char * next; - const char * error; - - next = s; /* XmlContentTok doesn't always set the last arg */ - /* XmlContentTok() is normally normal_contentTok(), aka - PREFIX(contentTok)() in xmltok/xmltok_impl.c - */ - tok = XmlContentTok(enc, s, end, &next); - *evPtr.endP = next; - - processContentToken(xmlParserP, tok, enc, s, end, &next, nextPtr, - startTagLevel, &done, - errorCodeP, &error); - - if (*errorCodeP != XML_ERROR_NONE) { - const char * const xmlSample = extractXmlSample(s, end, 40); - - if (error) { - xmlrpc_asprintf(errorP, "Problem with token at '%s...': %s", - xmlSample, error); - xmlrpc_strfree(error); - } else - xmlrpc_asprintf(errorP, "Problem with token at '%s...': %s", - xmlSample, - xmlrpc_XML_ErrorString(*errorCodeP)); - - xmlrpc_strfree(xmlSample); - } - *evPtr.startP = s = next; - } -} - - - -static Processor externalEntityContentProcessor; - -static void -externalEntityContentProcessor(XML_Parser const xmlParserP, - const char * const start, - const char * const end, - const char ** const endPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - *errorP = NULL; - - doContent(xmlParserP, 1, parser->m_encoding, start, end, endPtr, - errorCodeP, errorP); -} - - - -static Processor externalEntityInitProcessor3; - -static void -externalEntityInitProcessor3(XML_Parser const xmlParserP, - const char * const startArg, - const char * const end, - const char ** const endPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - const char * start; - const char *next; - int tok; - - tok = XmlContentTok(parser->m_encoding, startArg, end, &next); - - *errorP = NULL; - - start = startArg; - - switch (tok) { - case XML_TOK_XML_DECL: - { - enum XML_Error result; - processXmlDecl(xmlParserP, 1, start, next, &result); - if (result != XML_ERROR_NONE) { - *errorCodeP = result; - return; - } - start = next; - } - break; - case XML_TOK_PARTIAL: - if (endPtr) { - *endPtr = start; - *errorCodeP = XML_ERROR_NONE; - return; - } - eventPtr = start; - *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; - return; - case XML_TOK_PARTIAL_CHAR: - if (endPtr) { - *endPtr = start; - *errorCodeP = XML_ERROR_NONE; - return; - } - eventPtr = start; - *errorCodeP = XML_ERROR_PARTIAL_CHAR; - return; - } - processor = externalEntityContentProcessor; - tagLevel = 1; - doContent(xmlParserP, 1, parser->m_encoding, start, end, endPtr, - errorCodeP, errorP); -} - - - -static Processor externalEntityInitProcessor2; - -static void -externalEntityInitProcessor2(XML_Parser const xmlParserP, - const char * const startArg, - const char * const end, - const char ** const endPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *)xmlParserP; - - const char * start; - const char * next; - int tok; - - tok = XmlContentTok(parser->m_encoding, startArg, end, &next); - - start = startArg; - - switch (tok) { - case XML_TOK_BOM: - start = next; - break; - case XML_TOK_PARTIAL: - if (endPtr) { - *endPtr = start; - *errorCodeP = XML_ERROR_NONE; - *errorP = NULL; - } else { - eventPtr = start; - *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; - *errorP = NULL; - } - return; - case XML_TOK_PARTIAL_CHAR: - if (endPtr) { - *endPtr = start; - *errorCodeP = XML_ERROR_NONE; - *errorP = NULL; - } else { - eventPtr = start; - *errorCodeP = XML_ERROR_PARTIAL_CHAR; - *errorP = NULL; - } - return; - } - processor = externalEntityInitProcessor3; - externalEntityInitProcessor3(xmlParserP, start, end, endPtr, - errorCodeP, errorP); -} - - - -static Processor externalEntityInitProcessor; - -static void -externalEntityInitProcessor(XML_Parser const parser, - const char * const start, - const char * const end, - const char ** const endPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - enum XML_Error result; - - result = initializeEncoding(parser); - - if (result != XML_ERROR_NONE) { - *errorCodeP = result; - *errorP = NULL; - } else { - processor = externalEntityInitProcessor2; - - externalEntityInitProcessor2(parser, start, end, endPtr, - errorCodeP, errorP); - } -} - - - -static enum XML_Error -doIgnoreSection(XML_Parser const xmlParserP, - const ENCODING * const enc, - const char ** const startPtr, - const char * const end, - const char ** const nextPtr) { -/*---------------------------------------------------------------------------- - - We set *startPtr to non-null is the section is closed, and to null if - the section is not yet closed. ------------------------------------------------------------------------------*/ - Parser * const parser = xmlParserP; - struct EventPtr const evPtr = getEventPtr(xmlParserP, enc); - const char * const s = *startPtr; - - enum XML_Error retval; - const char * next; - int tok; - - *evPtr.startP = s; - *startPtr = '\0'; - tok = XmlIgnoreSectionTok(enc, s, end, &next); - *evPtr.endP = next; - - switch (tok) { - case XML_TOK_IGNORE_SECT: - if (defaultHandler) - reportDefault(xmlParserP, enc, s, next); - *startPtr = next; - retval = XML_ERROR_NONE; - break; - case XML_TOK_INVALID: - *evPtr.startP = next; - retval = XML_ERROR_INVALID_TOKEN; - break; - case XML_TOK_PARTIAL_CHAR: - if (nextPtr) { - *nextPtr = s; - retval = XML_ERROR_NONE; - } else - retval = XML_ERROR_PARTIAL_CHAR; - break; - case XML_TOK_PARTIAL: - case XML_TOK_NONE: - if (nextPtr) { - *nextPtr = s; - retval = XML_ERROR_NONE; - } else - retval = XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ - break; - default: - assert(false); /* All possibilities are handled above */ - retval = 99; /* quiet compiler warning */ - } - - return retval; -} - - - -static Processor prologProcessor; - - -/* The idea here is to avoid using stack for each IGNORE section when -the whole file is parsed with one call. */ - -static Processor ignoreSectionProcessor; - -static void -ignoreSectionProcessor(XML_Parser const xmlParserP, - const char * const startArg, - const char * const end, - const char ** const endPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - enum XML_Error result; - const char * start; - - start = startArg; /* initial value */ - - result = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr); - - if (start) { - processor = prologProcessor; - prologProcessor(xmlParserP, start, end, endPtr, errorCodeP, errorP); - } else { - *errorCodeP = result; - *errorP = NULL; - } -} - - - -/* Forward declaration for recursive reference: */ -static void -processInternalParamEntity(XML_Parser const parser, - ENTITY * const entity, - enum XML_Error * const errorCodeP, - const char ** const errorP); - -static void -doProlog(XML_Parser const xmlParserP, - const ENCODING * const encArg, - const char * const startArg, - const char * const end, - int const tokArg, - const char * const nextArg, - const char ** const nextPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = xmlParserP; - struct EventPtr const evPtr = getEventPtr(xmlParserP, encArg); - - int tok; - const char * next; - const ENCODING * enc; - const char * s; - - static const XML_Char externalSubsetName[] = { '#' , '\0' }; - - *errorP = NULL; - - tok = tokArg; - next = nextArg; - enc = encArg; - s = startArg; - - for (;;) { - int role; - *evPtr.startP = s; - *evPtr.endP = next; - if (tok <= 0) { - if (nextPtr != 0 && tok != XML_TOK_INVALID) { - *nextPtr = s; - *errorCodeP = XML_ERROR_NONE; - return; - } - switch (tok) { - case XML_TOK_INVALID: - *evPtr.startP = next; - *errorCodeP = XML_ERROR_INVALID_TOKEN; - return; - case XML_TOK_PARTIAL: - *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; - return; - case XML_TOK_PARTIAL_CHAR: - *errorCodeP = XML_ERROR_PARTIAL_CHAR; - return; - case XML_TOK_NONE: - if (enc != parser->m_encoding) - *errorCodeP = XML_ERROR_NONE; - else { - if (parentParser) { - if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) - == XML_ROLE_ERROR) { - *errorCodeP = XML_ERROR_SYNTAX; - } else { - *errorCodeP = XML_ERROR_NONE; - hadExternalDoctype = 0; - } - } else - *errorCodeP = XML_ERROR_NO_ELEMENTS; - } - return; - default: - tok = -tok; - next = end; - break; - } - } - role = XmlTokenRole(&prologState, tok, s, next, enc); - switch (role) { - case XML_ROLE_XML_DECL: { - enum XML_Error result; - processXmlDecl(xmlParserP, 0, s, next, &result); - if (result != XML_ERROR_NONE) { - *errorCodeP = result; - return; - } - enc = parser->m_encoding; - } - break; - case XML_ROLE_DOCTYPE_NAME: - if (startDoctypeDeclHandler) { - const XML_Char *name = poolStoreString(&tempPool, enc, s, next); - if (!name) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - startDoctypeDeclHandler(handlerArg, name); - poolClear(&tempPool); - } - break; - case XML_ROLE_TEXT_DECL: { - enum XML_Error result; - processXmlDecl(xmlParserP, 1, s, next, &result); - if (result != XML_ERROR_NONE) { - *errorCodeP = result; - return; - } - enc = parser->m_encoding; - } - break; - case XML_ROLE_DOCTYPE_PUBLIC_ID: - declEntity = (ENTITY *)lookup(parser, &dtd.paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!declEntity) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - /* fall through */ - case XML_ROLE_ENTITY_PUBLIC_ID: - if (!XmlIsPublicId(enc, s, next, evPtr.startP)) { - *errorCodeP = XML_ERROR_SYNTAX; - return; - } - if (declEntity) { - XML_Char *tem = poolStoreString(&dtd.pool, - enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!tem) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - normalizePublicId(tem); - declEntity->publicId = tem; - poolFinish(&dtd.pool); - } - break; - case XML_ROLE_DOCTYPE_CLOSE: - if (dtd.complete && hadExternalDoctype) { - dtd.complete = 0; - if (parser->m_paramEntityParsing != XML_PARAM_ENTITY_PARSING_NEVER - && externalEntityRefHandler) { - ENTITY *entity = (ENTITY *)lookup(parser, &dtd.paramEntities, - externalSubsetName, - 0); - if (!externalEntityRefHandler(externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) { - *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING; - return; - } - } - if (!dtd.complete - && !dtd.standalone - && notStandaloneHandler - && !notStandaloneHandler(handlerArg)) { - *errorCodeP = XML_ERROR_NOT_STANDALONE; - return; - } - } - if (endDoctypeDeclHandler) - endDoctypeDeclHandler(handlerArg); - break; - case XML_ROLE_INSTANCE_START: { - processor = contentProcessor; - contentProcessor(xmlParserP, s, end, nextPtr, errorCodeP, errorP); - return; - } - case XML_ROLE_ATTLIST_ELEMENT_NAME: - { - const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); - if (!name) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - declElementType = (ELEMENT_TYPE *) - lookup(parser, &dtd.elementTypes, name, sizeof(ELEMENT_TYPE)); - if (!declElementType) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - if (declElementType->name != name) - poolDiscard(&dtd.pool); - else { - poolFinish(&dtd.pool); - if (!setElementTypePrefix(xmlParserP, declElementType)) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - } - break; - } - case XML_ROLE_ATTRIBUTE_NAME: - declAttributeId = getAttributeId(xmlParserP, enc, s, next); - if (!declAttributeId) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - declAttributeIsCdata = 0; - declAttributeIsId = 0; - break; - case XML_ROLE_ATTRIBUTE_TYPE_CDATA: - declAttributeIsCdata = 1; - break; - case XML_ROLE_ATTRIBUTE_TYPE_ID: - declAttributeIsId = 1; - break; - case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: - case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: - if (dtd.complete - && !defineAttribute(declElementType, declAttributeId, - declAttributeIsCdata, - declAttributeIsId, 0)) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - break; - case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: - case XML_ROLE_FIXED_ATTRIBUTE_VALUE: - { - const XML_Char *attVal; - enum XML_Error result - = storeAttributeValue(xmlParserP, enc, declAttributeIsCdata, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar, - &dtd.pool); - if (result) { - *errorCodeP = result; - return; - } - attVal = poolStart(&dtd.pool); - poolFinish(&dtd.pool); - if (dtd.complete - /* ID attributes aren't allowed to have a default */ - && !defineAttribute(declElementType, declAttributeId, - declAttributeIsCdata, 0, attVal)) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - break; - } - case XML_ROLE_ENTITY_VALUE: - { - enum XML_Error result = storeEntityValue(xmlParserP, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (declEntity) { - declEntity->textPtr = poolStart(&dtd.pool); - declEntity->textLen = poolLength(&dtd.pool); - poolFinish(&dtd.pool); - if (internalParsedEntityDeclHandler - /* Check it's not a parameter entity */ - && ((ENTITY *)lookup(parser, &dtd.generalEntities, - declEntity->name, 0) - == declEntity)) { - *evPtr.endP = s; - internalParsedEntityDeclHandler(handlerArg, - declEntity->name, - declEntity->textPtr, - declEntity->textLen); - } - } - else - poolDiscard(&dtd.pool); - if (result != XML_ERROR_NONE) { - *errorCodeP = result; - return; - } - } - break; - case XML_ROLE_DOCTYPE_SYSTEM_ID: - if (!dtd.standalone - && parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_NEVER - && notStandaloneHandler - && !notStandaloneHandler(handlerArg)) { - *errorCodeP = XML_ERROR_NOT_STANDALONE; - return; - } - hadExternalDoctype = 1; - if (!declEntity) { - declEntity = (ENTITY *)lookup(parser, &dtd.paramEntities, - externalSubsetName, - sizeof(ENTITY)); - if (!declEntity) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - } - /* fall through */ - case XML_ROLE_ENTITY_SYSTEM_ID: - if (declEntity) { - declEntity->systemId = poolStoreString(&dtd.pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!declEntity->systemId) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - declEntity->base = curBase; - poolFinish(&dtd.pool); - } - break; - case XML_ROLE_ENTITY_NOTATION_NAME: - if (declEntity) { - declEntity->notation = poolStoreString(&dtd.pool, enc, s, next); - if (!declEntity->notation) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - poolFinish(&dtd.pool); - if (unparsedEntityDeclHandler) { - *evPtr.endP = s; - unparsedEntityDeclHandler(handlerArg, - declEntity->name, - declEntity->base, - declEntity->systemId, - declEntity->publicId, - declEntity->notation); - } - - } - break; - case XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION: - if (declEntity && externalParsedEntityDeclHandler) { - *evPtr.endP = s; - externalParsedEntityDeclHandler(handlerArg, - declEntity->name, - declEntity->base, - declEntity->systemId, - declEntity->publicId); - } - break; - case XML_ROLE_GENERAL_ENTITY_NAME: - { - const XML_Char *name; - if (XmlPredefinedEntityName(enc, s, next)) { - declEntity = 0; - break; - } - name = poolStoreString(&dtd.pool, enc, s, next); - if (!name) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - if (dtd.complete) { - declEntity = (ENTITY *) - lookup(parser, &dtd.generalEntities, name, sizeof(ENTITY)); - if (!declEntity) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - if (declEntity->name != name) { - poolDiscard(&dtd.pool); - declEntity = 0; - } - else - poolFinish(&dtd.pool); - } - else { - poolDiscard(&dtd.pool); - declEntity = 0; - } - } - break; - case XML_ROLE_PARAM_ENTITY_NAME: - if (dtd.complete) { - const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); - if (!name) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - declEntity = (ENTITY *) - lookup(parser, &dtd.paramEntities, name, sizeof(ENTITY)); - if (!declEntity) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - if (declEntity->name != name) { - poolDiscard(&dtd.pool); - declEntity = 0; - } - else - poolFinish(&dtd.pool); - } - break; - case XML_ROLE_NOTATION_NAME: - declNotationPublicId = 0; - declNotationName = 0; - if (notationDeclHandler) { - declNotationName = poolStoreString(&tempPool, enc, s, next); - if (!declNotationName) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - poolFinish(&tempPool); - } - break; - case XML_ROLE_NOTATION_PUBLIC_ID: - if (!XmlIsPublicId(enc, s, next, evPtr.startP)) { - *errorCodeP = XML_ERROR_SYNTAX; - return; - } - if (declNotationName) { - XML_Char *tem = poolStoreString(&tempPool, - enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!tem) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - normalizePublicId(tem); - declNotationPublicId = tem; - poolFinish(&tempPool); - } - break; - case XML_ROLE_NOTATION_SYSTEM_ID: - if (declNotationName && notationDeclHandler) { - const XML_Char *systemId - = poolStoreString(&tempPool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!systemId) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - *evPtr.endP = s; - notationDeclHandler(handlerArg, - declNotationName, - curBase, - systemId, - declNotationPublicId); - } - poolClear(&tempPool); - break; - case XML_ROLE_NOTATION_NO_SYSTEM_ID: - if (declNotationPublicId && notationDeclHandler) { - *evPtr.endP = s; - notationDeclHandler(handlerArg, - declNotationName, - curBase, - 0, - declNotationPublicId); - } - poolClear(&tempPool); - break; - case XML_ROLE_ERROR: - switch (tok) { - case XML_TOK_PARAM_ENTITY_REF: - *errorCodeP = XML_ERROR_PARAM_ENTITY_REF; - case XML_TOK_XML_DECL: - *errorCodeP = XML_ERROR_MISPLACED_XML_PI; - default: - *errorCodeP = XML_ERROR_SYNTAX; - } - return; - case XML_ROLE_IGNORE_SECT: - { - enum XML_Error result; - if (defaultHandler) - reportDefault(xmlParserP, enc, s, next); - result = doIgnoreSection(xmlParserP, enc, &next, end, nextPtr); - if (!next) { - processor = ignoreSectionProcessor; - *errorCodeP = result; - return; - } - } - break; - case XML_ROLE_GROUP_OPEN: - if (prologState.level >= groupSize) { - if (groupSize) { - char *temp = realloc(groupConnector, groupSize *= 2); - if (!temp) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - groupConnector = temp; - } else { - groupConnector = malloc(groupSize = 32); - if (!groupConnector) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - } - } - groupConnector[prologState.level] = 0; - break; - case XML_ROLE_GROUP_SEQUENCE: - if (groupConnector[prologState.level] == '|') { - *errorCodeP = XML_ERROR_SYNTAX; - return; - } - groupConnector[prologState.level] = ','; - break; - case XML_ROLE_GROUP_CHOICE: - if (groupConnector[prologState.level] == ',') { - *errorCodeP = XML_ERROR_SYNTAX; - return; - } - groupConnector[prologState.level] = '|'; - break; - case XML_ROLE_PARAM_ENTITY_REF: - case XML_ROLE_INNER_PARAM_ENTITY_REF: - if (parser->m_paramEntityParsing != XML_PARAM_ENTITY_PARSING_NEVER - && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) { - const XML_Char *name; - ENTITY *entity; - name = poolStoreString(&dtd.pool, enc, - s + enc->minBytesPerChar, - next - enc->minBytesPerChar); - if (!name) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - entity = (ENTITY *)lookup(parser, &dtd.paramEntities, name, 0); - poolDiscard(&dtd.pool); - if (!entity) { - /* FIXME what to do if !dtd.complete? */ - *errorCodeP = XML_ERROR_UNDEFINED_ENTITY; - return; - } - if (entity->open) { - *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF; - return; - } - if (entity->textPtr) { - processInternalParamEntity(xmlParserP, entity, errorCodeP, errorP); - if (*errorCodeP != XML_ERROR_NONE) - return; - break; - } - if (role == XML_ROLE_INNER_PARAM_ENTITY_REF) { - *errorCodeP = XML_ERROR_PARAM_ENTITY_REF; - return; - } - if (externalEntityRefHandler) { - dtd.complete = 0; - entity->open = 1; - if (!externalEntityRefHandler(externalEntityRefHandlerArg, - 0, - entity->base, - entity->systemId, - entity->publicId)) { - entity->open = 0; - *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING; - return; - } - entity->open = 0; - if (dtd.complete) - break; - } - } - if (!dtd.standalone - && notStandaloneHandler - && !notStandaloneHandler(handlerArg)) { - *errorCodeP = XML_ERROR_NOT_STANDALONE; - return; - } - dtd.complete = 0; - if (defaultHandler) - reportDefault(xmlParserP, enc, s, next); - break; - case XML_ROLE_NONE: - switch (tok) { - case XML_TOK_PI: - if (!reportProcessingInstruction(xmlParserP, enc, s, next)) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - break; - case XML_TOK_COMMENT: - if (!reportComment(xmlParserP, enc, s, next)) { - *errorCodeP = XML_ERROR_NO_MEMORY; - return; - } - break; - } - break; - } - if (defaultHandler) { - switch (tok) { - case XML_TOK_PI: - case XML_TOK_COMMENT: - case XML_TOK_BOM: - case XML_TOK_XML_DECL: - case XML_TOK_IGNORE_SECT: - case XML_TOK_PARAM_ENTITY_REF: - break; - default: - if (role != XML_ROLE_IGNORE_SECT) - reportDefault(xmlParserP, enc, s, next); - } - } - s = next; - tok = XmlPrologTok(enc, s, end, &next); - } - /* not reached */ -} - - - -static Processor prologProcessor; - -static void -prologProcessor(XML_Parser const xmlParserP, - const char * const s, - const char * const end, - const char ** const nextPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - Parser * const parser = (Parser *) xmlParserP; - - const char * next; - int tok; - - *errorP = NULL; - - tok = XmlPrologTok(parser->m_encoding, s, end, &next); - - doProlog(xmlParserP, parser->m_encoding, s, end, tok, next, nextPtr, - errorCodeP, errorP); -} - - - -static Processor prologInitProcessor; - -static void -prologInitProcessor(XML_Parser const parser, - const char * const s, - const char * const end, - const char ** const nextPtr, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - enum XML_Error result; - - *errorP = NULL; - - result = initializeEncoding(parser); - - if (result != XML_ERROR_NONE) - *errorCodeP = result; - else { - processor = prologProcessor; - prologProcessor(parser, s, end, nextPtr, errorCodeP, errorP); - } -} - - - -static void -processInternalParamEntity(XML_Parser const parser, - ENTITY * const entity, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - const char *s, *end, *next; - int tok; - OPEN_INTERNAL_ENTITY openEntity; - - entity->open = 1; - openEntity.next = openInternalEntities; - openInternalEntities = &openEntity; - openEntity.entity = entity; - openEntity.internalEventPtr = 0; - openEntity.internalEventEndPtr = 0; - s = (char *)entity->textPtr; - end = (char *)(entity->textPtr + entity->textLen); - tok = XmlPrologTok(internalEncoding, s, end, &next); - - doProlog(parser, internalEncoding, s, end, tok, next, 0, - errorCodeP, errorP); - - entity->open = 0; - openInternalEntities = openEntity.next; -} - - - -XML_Parser -xmlrpc_XML_ParserCreate(const XML_Char * const encodingName) { - - XML_Parser const xmlParserP = malloc(sizeof(Parser)); - - bool error; - - if (xmlParserP) { - Parser * const parser = (Parser *)xmlParserP; - - parser->m_processor = prologInitProcessor; - xmlrpc_XmlPrologStateInit(&parser->m_prologState); - parser->m_userData = 0; - parser->m_handlerArg = 0; - parser->m_startElementHandler = 0; - parser->m_endElementHandler = 0; - parser->m_characterDataHandler = 0; - parser->m_processingInstructionHandler = 0; - parser->m_commentHandler = 0; - parser->m_startCdataSectionHandler = 0; - parser->m_endCdataSectionHandler = 0; - parser->m_defaultHandler = 0; - parser->m_startDoctypeDeclHandler = 0; - parser->m_endDoctypeDeclHandler = 0; - parser->m_unparsedEntityDeclHandler = 0; - parser->m_notationDeclHandler = 0; - parser->m_externalParsedEntityDeclHandler = 0; - parser->m_internalParsedEntityDeclHandler = 0; - parser->m_startNamespaceDeclHandler = 0; - parser->m_endNamespaceDeclHandler = 0; - parser->m_notStandaloneHandler = 0; - parser->m_externalEntityRefHandler = 0; - parser->m_externalEntityRefHandlerArg = parser; - parser->m_unknownEncodingHandler = 0; - parser->m_buffer = 0; - parser->m_bufferPtr = 0; - parser->m_bufferEnd = 0; - parser->m_parseEndByteIndex = 0; - parser->m_parseEndPtr = 0; - parser->m_bufferLim = 0; - parser->m_declElementType = 0; - parser->m_declAttributeId = 0; - parser->m_declEntity = 0; - parser->m_declNotationName = 0; - parser->m_declNotationPublicId = 0; - memset(&parser->m_position, 0, sizeof(POSITION)); - parser->m_errorCode = XML_ERROR_NONE; - parser->m_errorString = NULL; - parser->m_eventPtr = 0; - parser->m_eventEndPtr = 0; - parser->m_positionPtr = 0; - parser->m_openInternalEntities = 0; - parser->m_tagLevel = 0; - parser->m_tagStack = 0; - parser->m_freeTagList = 0; - parser->m_freeBindingList = 0; - parser->m_inheritedBindings = 0; - parser->m_attsSize = INIT_ATTS_SIZE; - parser->m_atts = malloc(attsSize * sizeof(ATTRIBUTE)); - parser->m_nSpecifiedAtts = 0; - parser->m_dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); - parser->m_groupSize = 0; - parser->m_groupConnector = 0; - parser->m_hadExternalDoctype = 0; - parser->m_unknownEncodingMem = 0; - parser->m_unknownEncodingRelease = 0; - parser->m_unknownEncodingData = 0; - parser->m_unknownEncodingHandlerData = 0; - parser->m_namespaceSeparator = '!'; - parser->m_parentParser = 0; - parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; - parser->m_hash_secret_salt = 0; - parser->m_ns = 0; - poolInit(&parser->m_tempPool); - poolInit(&parser->m_temp2Pool); - parser->m_protocolEncodingName = - encodingName ? - poolCopyString(&parser->m_tempPool, encodingName) : NULL; - parser->m_curBase = 0; - if (!dtdInit(&parser->m_dtd) || !parser->m_atts || !parser->m_dataBuf - || (encodingName && !parser->m_protocolEncodingName)) - error = true; - else { - parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; - xmlrpc_XmlInitEncoding(&parser->m_initEncoding, - &parser->m_encoding, - 0); - parser->m_internalEncoding = XmlGetInternalEncoding(); - error = false; - } - if (error) - xmlrpc_XML_ParserFree(xmlParserP); - } else - error =true; - - return error ? NULL : xmlParserP; -} - -XML_Parser -xmlrpc_XML_ParserCreateNS(const XML_Char * const encodingName, - XML_Char const nsSep) { - - XML_Parser const xmlParserP = xmlrpc_XML_ParserCreate(encodingName); - Parser * const parser = (Parser *)xmlParserP; - - if (xmlParserP) { - xmlrpc_XmlInitEncodingNS(&initEncoding, &parser->m_encoding, 0); - ns = 1; - internalEncoding = XmlGetInternalEncodingNS(); - namespaceSeparator = nsSep; - } - - return xmlParserP; -} - - - -static void -resetErrorString(Parser * const parserP) { - - if (parserP->m_errorString) { - xmlrpc_strfree(parserP->m_errorString); - parserP->m_errorString = NULL; - } -} - - - -int -xmlrpc_XML_SetEncoding(XML_Parser const xmlParserP, - const XML_Char * const encodingName) { - - Parser * const parser = (Parser *) xmlParserP; - - int retval; - - if (!encodingName) { - parser->m_protocolEncodingName = NULL; - retval = 1; - } else { - parser->m_protocolEncodingName = - poolCopyString(&tempPool, encodingName); - if (parser->m_protocolEncodingName) - retval = 1; - else - retval = 0; - } - return retval; -} - - - -XML_Parser -xmlrpc_XML_ExternalEntityParserCreate(XML_Parser oldParser, - const XML_Char *context, - const XML_Char *encodingName) -{ - XML_Parser xmlParserP = oldParser; - Parser * parser = xmlParserP; - DTD *oldDtd = &dtd; - XML_StartElementHandler oldStartElementHandler = startElementHandler; - XML_EndElementHandler oldEndElementHandler = endElementHandler; - XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; - XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler; - XML_CommentHandler oldCommentHandler = commentHandler; - XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler; - XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler; - XML_DefaultHandler oldDefaultHandler = defaultHandler; - XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler; - XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; - XML_ExternalParsedEntityDeclHandler oldExternalParsedEntityDeclHandler = externalParsedEntityDeclHandler; - XML_InternalParsedEntityDeclHandler oldInternalParsedEntityDeclHandler = internalParsedEntityDeclHandler; - XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler; - XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler; - XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; - XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler; - XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler; - void *oldUserData = userData; - void *oldHandlerArg = handlerArg; - int oldDefaultExpandInternalEntities = defaultExpandInternalEntities; - void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; - int oldParamEntityParsing = parser->m_paramEntityParsing; - /* Note that the new parser shares the same hash secret as the old - parser, so that dtdCopy and copyEntityTable can lookup values - from hash tables associated with either parser without us having - to worry which hash secrets each table has. - */ - unsigned long oldhash_secret_salt = hash_secret_salt; - parser = (ns - ? xmlrpc_XML_ParserCreateNS(encodingName, namespaceSeparator) - : xmlrpc_XML_ParserCreate(encodingName)); - if (!parser) - return 0; - startElementHandler = oldStartElementHandler; - endElementHandler = oldEndElementHandler; - characterDataHandler = oldCharacterDataHandler; - processingInstructionHandler = oldProcessingInstructionHandler; - commentHandler = oldCommentHandler; - startCdataSectionHandler = oldStartCdataSectionHandler; - endCdataSectionHandler = oldEndCdataSectionHandler; - defaultHandler = oldDefaultHandler; - unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; - notationDeclHandler = oldNotationDeclHandler; - externalParsedEntityDeclHandler = oldExternalParsedEntityDeclHandler; - internalParsedEntityDeclHandler = oldInternalParsedEntityDeclHandler; - startNamespaceDeclHandler = oldStartNamespaceDeclHandler; - endNamespaceDeclHandler = oldEndNamespaceDeclHandler; - notStandaloneHandler = oldNotStandaloneHandler; - externalEntityRefHandler = oldExternalEntityRefHandler; - unknownEncodingHandler = oldUnknownEncodingHandler; - userData = oldUserData; - if (oldUserData == oldHandlerArg) - handlerArg = userData; - else - handlerArg = parser; - if (oldExternalEntityRefHandlerArg != oldParser) - externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; - defaultExpandInternalEntities = oldDefaultExpandInternalEntities; - hash_secret_salt = oldhash_secret_salt; - parser->m_paramEntityParsing = oldParamEntityParsing; - if (context) { - if (!dtdCopy(oldParser, &dtd, oldDtd) || !setContext(parser, context)) { - xmlrpc_XML_ParserFree(parser); - return 0; - } - processor = externalEntityInitProcessor; - } - else { - dtdSwap(&dtd, oldDtd); - parentParser = oldParser; - xmlrpc_XmlPrologStateInitExternalEntity(&prologState); - dtd.complete = 1; - hadExternalDoctype = 1; - } - return parser; -} - -static -void destroyBindings(BINDING *bindings) -{ - for (;;) { - BINDING *b = bindings; - if (!b) - break; - bindings = b->nextTagBinding; - free(b->uri); - free(b); - } -} - -void -xmlrpc_XML_ParserFree(XML_Parser parser) -{ - for (;;) { - TAG *p; - if (tagStack == 0) { - if (freeTagList == 0) - break; - tagStack = freeTagList; - freeTagList = 0; - } - p = tagStack; - tagStack = tagStack->parent; - free(p->buf); - destroyBindings(p->bindings); - free(p); - } - destroyBindings(freeBindingList); - destroyBindings(inheritedBindings); - poolDestroy(&tempPool); - poolDestroy(&temp2Pool); - if (parentParser) { - if (hadExternalDoctype) - dtd.complete = 0; - dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd); - } - dtdDestroy(&dtd); - free((void *)atts); - free(groupConnector); - free(buffer); - free(dataBuf); - free(unknownEncodingMem); - if (unknownEncodingRelease) - unknownEncodingRelease(unknownEncodingData); - resetErrorString(parser); - free(parser); -} - -void -xmlrpc_XML_UseParserAsHandlerArg(XML_Parser parser) -{ - handlerArg = parser; -} - -void -xmlrpc_XML_SetUserData(XML_Parser parser, void *p) -{ - if (handlerArg == userData) - handlerArg = userData = p; - else - userData = p; -} - -int -xmlrpc_XML_SetBase(XML_Parser parser, const XML_Char *p) -{ - if (p) { - p = poolCopyString(&dtd.pool, p); - if (!p) - return 0; - curBase = p; - } - else - curBase = 0; - return 1; -} - -const XML_Char * -xmlrpc_XML_GetBase(XML_Parser parser) -{ - return curBase; -} - -int -xmlrpc_XML_GetSpecifiedAttributeCount(XML_Parser parser) -{ - return nSpecifiedAtts; -} - -int -xmlrpc_XML_GetIdAttributeIndex(XML_Parser parser) -{ - return idAttIndex; -} - -void -xmlrpc_XML_SetElementHandler(XML_Parser parser, - XML_StartElementHandler start, - XML_EndElementHandler end) -{ - startElementHandler = start; - endElementHandler = end; -} - -void -xmlrpc_XML_SetCharacterDataHandler(XML_Parser parser, - XML_CharacterDataHandler handler) -{ - characterDataHandler = handler; -} - -void -xmlrpc_XML_SetProcessingInstructionHandler( - XML_Parser parser, - XML_ProcessingInstructionHandler handler) -{ - processingInstructionHandler = handler; -} - -void -xmlrpc_XML_SetCommentHandler(XML_Parser parser, - XML_CommentHandler handler) -{ - commentHandler = handler; -} - -void -xmlrpc_XML_SetCdataSectionHandler(XML_Parser parser, - XML_StartCdataSectionHandler start, - XML_EndCdataSectionHandler end) -{ - startCdataSectionHandler = start; - endCdataSectionHandler = end; -} - -void -xmlrpc_XML_SetDefaultHandler(XML_Parser parser, - XML_DefaultHandler handler) -{ - defaultHandler = handler; - defaultExpandInternalEntities = 0; -} - -void -xmlrpc_XML_SetDefaultHandlerExpand(XML_Parser parser, - XML_DefaultHandler handler) -{ - defaultHandler = handler; - defaultExpandInternalEntities = 1; -} - -void -xmlrpc_XML_SetDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start, - XML_EndDoctypeDeclHandler end) -{ - startDoctypeDeclHandler = start; - endDoctypeDeclHandler = end; -} - -void -xmlrpc_XML_SetUnparsedEntityDeclHandler(XML_Parser parser, - XML_UnparsedEntityDeclHandler handler) -{ - unparsedEntityDeclHandler = handler; -} - -void -xmlrpc_XML_SetExternalParsedEntityDeclHandler( - XML_Parser parser, - XML_ExternalParsedEntityDeclHandler handler) -{ - externalParsedEntityDeclHandler = handler; -} - -void -xmlrpc_XML_SetInternalParsedEntityDeclHandler( - XML_Parser parser, - XML_InternalParsedEntityDeclHandler handler) -{ - internalParsedEntityDeclHandler = handler; -} - -void -xmlrpc_XML_SetNotationDeclHandler(XML_Parser parser, - XML_NotationDeclHandler handler) -{ - notationDeclHandler = handler; -} - -void -xmlrpc_XML_SetNamespaceDeclHandler(XML_Parser parser, - XML_StartNamespaceDeclHandler start, - XML_EndNamespaceDeclHandler end) -{ - startNamespaceDeclHandler = start; - endNamespaceDeclHandler = end; -} - -void -xmlrpc_XML_SetNotStandaloneHandler(XML_Parser parser, - XML_NotStandaloneHandler handler) -{ - notStandaloneHandler = handler; -} - -void -xmlrpc_XML_SetExternalEntityRefHandler(XML_Parser parser, - XML_ExternalEntityRefHandler handler) -{ - externalEntityRefHandler = handler; -} - -void -xmlrpc_XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) -{ - if (arg) - externalEntityRefHandlerArg = arg; - else - externalEntityRefHandlerArg = parser; -} - -void -xmlrpc_XML_SetUnknownEncodingHandler(XML_Parser parser, - XML_UnknownEncodingHandler handler, - void *data) -{ - unknownEncodingHandler = handler; - unknownEncodingHandlerData = data; -} - - - -int -xmlrpc_XML_SetParamEntityParsing( - XML_Parser const xmlParserP, - enum XML_ParamEntityParsing const parsing) { - - Parser * const parserP = (Parser *) xmlParserP; - - int retval; - - parserP->m_paramEntityParsing = parsing; - - retval = 1; - - return retval; -} - - - -static Processor errorProcessor; - -static void -errorProcessor(XML_Parser const parser ATTR_UNUSED, - const char * const s ATTR_UNUSED, - const char * const end ATTR_UNUSED, - const char ** const nextPtr ATTR_UNUSED, - enum XML_Error * const errorCodeP, - const char ** const errorP) { - - *errorP = errorString; - *errorCodeP = errorCode; -} - - - -static void -parseFinalLen0(Parser * const parser, - int * const retvalP) { - - positionPtr = bufferPtr; - parseEndPtr = bufferEnd; - - processor(parser, bufferPtr, bufferEnd, 0, &errorCode, &errorString); - - if (errorCode == XML_ERROR_NONE) - *retvalP = 1; - else { - eventEndPtr = eventPtr; - processor = errorProcessor; - *retvalP = 0; - } -} - - - -static void -parseNoBuffer(Parser * const parser, - const char * const s, - size_t const len, - bool const isFinal, - int * const succeededP) { - - parser->m_parseEndByteIndex += len; - parser->m_positionPtr = s; - - if (isFinal) { - parser->m_parseEndPtr = s + len; - parser->m_processor(parser, s, parser->m_parseEndPtr, 0, - &parser->m_errorCode, &parser->m_errorString); - if (parser->m_errorCode == XML_ERROR_NONE) - *succeededP = true; - else { - parser->m_eventEndPtr = parser->m_eventPtr; - parser->m_processor = errorProcessor; - *succeededP = false; - } - } else { - const char * end; - - parser->m_parseEndPtr = s + len; - parser->m_processor(parser, s, s + len, - &end, - &parser->m_errorCode, &parser->m_errorString); - if (parser->m_errorCode != XML_ERROR_NONE) { - parser->m_eventEndPtr = parser->m_eventPtr; - parser->m_processor = errorProcessor; - *succeededP = false; - } else { - int const nLeftOver = s + len - end; - XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, - &parser->m_position); - if (nLeftOver > 0) { - if (buffer == 0 || - nLeftOver > parser->m_bufferLim - parser->m_buffer) { - REALLOCARRAY(parser->m_buffer, len * 2); - if (parser->m_buffer) - parser->m_bufferLim = parser->m_buffer + len * 2; - } - - if (parser->m_buffer) { - memcpy(parser->m_buffer, end, nLeftOver); - parser->m_bufferPtr = parser->m_buffer; - parser->m_bufferEnd = parser->m_buffer + nLeftOver; - *succeededP = true; - } else { - parser->m_errorCode = XML_ERROR_NO_MEMORY; - parser->m_eventPtr = 0; - parser->m_eventEndPtr = 0; - parser->m_processor = errorProcessor; - *succeededP = false; - } - } else - *succeededP = true; - } - } -} - - -int -XML_SetHashSalt(XML_Parser parser, - unsigned long hash_salt) -{ - hash_secret_salt = hash_salt; - return 1; -} - -int -xmlrpc_XML_Parse(XML_Parser const xmlParserP, - const char * const s, - size_t const len, - int const isFinal) { - - Parser * const parser = (Parser *) xmlParserP; - - int retval; - - resetErrorString(parser); - - if (parser->m_parentParser == NULL && !startParsing(parser)) { - errorCode = XML_ERROR_NO_MEMORY; - return 0; - } - - if (len == 0) { - if (!isFinal) - retval = 1; - else - parseFinalLen0(parser, &retval); - } else if (parser->m_bufferPtr == parser->m_bufferEnd) - parseNoBuffer(parser, s, len, isFinal, &retval); - else { - memcpy(xmlrpc_XML_GetBuffer(parser, len), s, len); - retval = xmlrpc_XML_ParseBuffer(parser, len, isFinal); - } - return retval; -} - - - -int -xmlrpc_XML_ParseBuffer(XML_Parser const xmlParserP, - int const len, - int const isFinal) { - - Parser * const parser = (Parser *)xmlParserP; - - const char * const start = bufferPtr; - - resetErrorString(parser); - - if (parser->m_parentParser == NULL && !startParsing(parser)) { - errorCode = XML_ERROR_NO_MEMORY; - return 0; - } - - parser->m_positionPtr = start; - parser->m_bufferEnd += len; - parser->m_parseEndByteIndex += len; - parser->m_parseEndPtr = parser->m_bufferEnd; - parser->m_processor(xmlParserP, start, parser->m_parseEndPtr, - isFinal ? NULL : &parser->m_bufferPtr, - &parser->m_errorCode, &parser->m_errorString); - if (parser->m_errorCode == XML_ERROR_NONE) { - if (!isFinal) - XmlUpdatePosition(parser->m_encoding, - parser->m_positionPtr, parser->m_bufferPtr, - &parser->m_position); - return 1; - } else { - parser->m_eventEndPtr = parser->m_eventPtr; - parser->m_processor = errorProcessor; - return 0; - } -} - - - -void * -xmlrpc_XML_GetBuffer(XML_Parser const xmlParserP, - size_t const len) { - - Parser * const parser = (Parser *)xmlParserP; - - assert(bufferLim >= bufferEnd); - - if (len > (size_t)(bufferLim - bufferEnd)) { - /* FIXME avoid integer overflow */ - size_t neededSize = len + (bufferEnd - bufferPtr); - assert(bufferLim >= buffer); - if (neededSize <= (size_t)(bufferLim - buffer)) { - memmove(buffer, bufferPtr, bufferEnd - bufferPtr); - bufferEnd = buffer + (bufferEnd - bufferPtr); - bufferPtr = buffer; - } else { - size_t bufferSize; - char * newBuf; - - bufferSize = bufferLim > bufferPtr ? - bufferLim - bufferPtr : INIT_BUFFER_SIZE; - - do { - bufferSize *= 2; - } while (bufferSize < neededSize); - newBuf = malloc(bufferSize); - if (newBuf == 0) { - errorCode = XML_ERROR_NO_MEMORY; - return 0; - } - bufferLim = newBuf + bufferSize; - if (bufferPtr) { - memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); - free(buffer); - } - bufferEnd = newBuf + (bufferEnd - bufferPtr); - bufferPtr = buffer = newBuf; - } - } - return bufferEnd; -} - - - -enum XML_Error -xmlrpc_XML_GetErrorCode(XML_Parser const parser) { - - return errorCode; -} - - - -const char * -xmlrpc_XML_GetErrorString(XML_Parser const parser) { - - if (errorString) - return errorString; - else if (errorCode == XML_ERROR_NONE) - return NULL; - else - return xmlrpc_XML_ErrorString(errorCode); -} - - - -long -xmlrpc_XML_GetCurrentByteIndex(XML_Parser const parser) { - - long retval; - - if (eventPtr) { - size_t const bytesLeft = parseEndPtr - eventPtr; - - if ((size_t)(long)(bytesLeft) != bytesLeft) - retval = -1; - else - retval = parseEndByteIndex - (long)bytesLeft; - } else - retval = -1; - - return retval; -} - - - -int -xmlrpc_XML_GetCurrentByteCount(XML_Parser const parser) { - - int retval; - - if (eventEndPtr && eventPtr) { - size_t const byteCount = eventEndPtr - eventPtr; - - assert((size_t)(int)byteCount == byteCount); - - retval = (int)byteCount; - } else - retval = 0; - - return retval; -} - - - -int -xmlrpc_XML_GetCurrentLineNumber(XML_Parser const xmlParserP) { - - Parser * const parser = (Parser *) xmlParserP; - - if (eventPtr) { - XmlUpdatePosition(parser->m_encoding, positionPtr, eventPtr, - &position); - positionPtr = eventPtr; - } - return position.lineNumber + 1; -} - - - -int -xmlrpc_XML_GetCurrentColumnNumber(XML_Parser const xmlParserP) { - - Parser * const parser = (Parser *) xmlParserP; - - if (eventPtr) { - XmlUpdatePosition(parser->m_encoding, positionPtr, eventPtr, - &position); - positionPtr = eventPtr; - } - return position.columnNumber; -} - - - -void -xmlrpc_XML_DefaultCurrent(XML_Parser const xmlParserP) { - - Parser * const parser = (Parser *) xmlParserP; - - if (defaultHandler) { - if (openInternalEntities) - reportDefault(xmlParserP, - internalEncoding, - openInternalEntities->internalEventPtr, - openInternalEntities->internalEventEndPtr); - else - reportDefault(xmlParserP, parser->m_encoding, - eventPtr, eventEndPtr); - } -} - -const XML_LChar * -xmlrpc_XML_ErrorString(int const code) { - - static const XML_LChar * const message[] = { - /* NONE */ NULL, - /* NO_MEMORY */ XML_T("out of memory"), - /* SYNTAX */ XML_T("syntax error"), - /* NO_ELEMENTS */ XML_T("no element found"), - /* INVALID_TOKEN */ XML_T("not well-formed"), - /* UNCLOSED_TOKEN */ XML_T("unclosed token"), - /* PARTIAL_CHAR */ XML_T("unclosed token"), - /* TAG_MISMATCH */ XML_T("mismatched tag"), - /* DUPLICATE_ATTRIBUTE */ XML_T("duplicate attribute"), - /* JUNK_AFTER_DOC_ELEMENT */ XML_T("junk after document element"), - /* PARAM_ENTITY_REF */ - XML_T("illegal parameter entity reference"), - /* UNDEFINED_ENTITY */ XML_T("undefined entity"), - /* RECURSIVE_ENTITY_REF */ XML_T("recursive entity reference"), - /* ASYNC_ENTITY */ XML_T("asynchronous entity"), - /* BAD_CHAR_REF */ - XML_T("reference to invalid character number"), - /* BINARY_ENTITY_REF */ XML_T("reference to binary entity"), - /* ATTRIBUTE_EXTERNAL_ENTITY_REF */ - XML_T("reference to external entity in attribute"), - /* MISPLACED_XML_PI */ - XML_T("xml processing instruction not at start " - "of external entity"), - /* UNKNOWN_ENCODING */ XML_T("unknown encoding"), - /* INCORRECT_ENCODING */ - XML_T("encoding specified in XML declaration is incorrect"), - /* UNCLOSED_CDATA_SECTION */ XML_T("unclosed CDATA section"), - /* EXTERNAL_ENTITY_HANDLING */ - XML_T("error in processing external entity reference"), - /* NOT_STANDALONE */ XML_T("document is not standalone") - }; - - const XML_LChar * retval; - - if (code > 0 && (unsigned)code < ARRAY_SIZE(message)) - retval = message[code]; - else - retval = NULL; - - return retval; -} diff --git a/trunk/lib/expat/xmlparse/xmlparse.h b/trunk/lib/expat/xmlparse/xmlparse.h deleted file mode 100644 index 76cf0db43..000000000 --- a/trunk/lib/expat/xmlparse/xmlparse.h +++ /dev/null @@ -1,584 +0,0 @@ -/* - Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - See the file copying.txt for copying permission. -*/ - -#ifndef XMLPARSE_H_INCLUDED -#define XMLPARSE_H_INCLUDED - -#include "xmlrpc-c/c_util.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *XML_Parser; - -/* Information is UTF-8 encoded. */ -typedef char XML_Char; -typedef char XML_LChar; - -/* Constructs a new parser; encoding is the encoding specified by the external -protocol or null if there is none specified. */ - -XMLRPC_DLLEXPORT -XML_Parser -xmlrpc_XML_ParserCreate(const XML_Char * const encoding); - -/* Constructs a new parser and namespace processor. Element type names -and attribute names that belong to a namespace will be expanded; -unprefixed attribute names are never expanded; unprefixed element type -names are expanded only if there is a default namespace. The expanded -name is the concatenation of the namespace URI, the namespace separator character, -and the local part of the name. If the namespace separator is '\0' then -the namespace URI and the local part will be concatenated without any -separator. When a namespace is not declared, the name and prefix will be -passed through without expansion. */ - -XMLRPC_DLLEXPORT -XML_Parser -xmlrpc_XML_ParserCreateNS(const XML_Char * const encoding, - XML_Char const namespaceSeparator); - - -/* atts is array of name/value pairs, terminated by 0; - names and values are 0 terminated. */ - -typedef void (*XML_StartElementHandler)(void *userData, - const XML_Char *name, - const XML_Char **atts); - -typedef void (*XML_EndElementHandler)(void *userData, - const XML_Char *name); - -/* s is not 0 terminated. */ -typedef void (*XML_CharacterDataHandler)(void *userData, - const XML_Char *s, - int len); - -/* target and data are 0 terminated */ -typedef void (*XML_ProcessingInstructionHandler)(void *userData, - const XML_Char *target, - const XML_Char *data); - -/* data is 0 terminated */ -typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data); - -typedef void (*XML_StartCdataSectionHandler)(void *userData); -typedef void (*XML_EndCdataSectionHandler)(void *userData); - -/* This is called for any characters in the XML document for -which there is no applicable handler. This includes both -characters that are part of markup which is of a kind that is -not reported (comments, markup declarations), or characters -that are part of a construct which could be reported but -for which no handler has been supplied. The characters are passed -exactly as they were in the XML document except that -they will be encoded in UTF-8. Line boundaries are not normalized. -Note that a byte order mark character is not passed to the default handler. -There are no guarantees about how characters are divided between calls -to the default handler: for example, a comment might be split between -multiple calls. */ - -typedef void (*XML_DefaultHandler)(void *userData, - const XML_Char *s, - int len); - -/* This is called for the start of the DOCTYPE declaration when the -name of the DOCTYPE is encountered. */ -typedef void (*XML_StartDoctypeDeclHandler)(void *userData, - const XML_Char *doctypeName); - -/* This is called for the start of the DOCTYPE declaration when the -closing > is encountered, but after processing any external subset. */ -typedef void (*XML_EndDoctypeDeclHandler)(void *userData); - -/* This is called for a declaration of an unparsed (NDATA) -entity. The base argument is whatever was set by XML_SetBase. -The entityName, systemId and notationName arguments will never be null. -The other arguments may be. */ - -typedef void (*XML_UnparsedEntityDeclHandler)(void *userData, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName); - -/* This is called for a declaration of notation. -The base argument is whatever was set by XML_SetBase. -The notationName will never be null. The other arguments can be. */ - -typedef void (*XML_NotationDeclHandler)(void *userData, - const XML_Char *notationName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId); - -typedef void (*XML_ExternalParsedEntityDeclHandler)(void *userData, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId); - -typedef void (*XML_InternalParsedEntityDeclHandler)(void *userData, - const XML_Char *entityName, - const XML_Char *replacementText, - int replacementTextLength); - -/* When namespace processing is enabled, these are called once for -each namespace declaration. The call to the start and end element -handlers occur between the calls to the start and end namespace -declaration handlers. For an xmlns attribute, prefix will be null. -For an xmlns="" attribute, uri will be null. */ - -typedef void (*XML_StartNamespaceDeclHandler)(void *userData, - const XML_Char *prefix, - const XML_Char *uri); - -typedef void (*XML_EndNamespaceDeclHandler)(void *userData, - const XML_Char *prefix); - -/* This is called if the document is not standalone (it has an -external subset or a reference to a parameter entity, but does not -have standalone="yes"). If this handler returns 0, then processing -will not continue, and the parser will return a -XML_ERROR_NOT_STANDALONE error. */ - -typedef int (*XML_NotStandaloneHandler)(void *userData); - -/* This is called for a reference to an external parsed general entity. -The referenced entity is not automatically parsed. -The application can parse it immediately or later using -XML_ExternalEntityParserCreate. -The parser argument is the parser parsing the entity containing the reference; -it can be passed as the parser argument to XML_ExternalEntityParserCreate. -The systemId argument is the system identifier as specified in the entity declaration; -it will not be null. -The base argument is the system identifier that should be used as the base for -resolving systemId if systemId was relative; this is set by XML_SetBase; -it may be null. -The publicId argument is the public identifier as specified in the entity declaration, -or null if none was specified; the whitespace in the public identifier -will have been normalized as required by the XML spec. -The context argument specifies the parsing context in the format -expected by the context argument to -XML_ExternalEntityParserCreate; context is valid only until the handler -returns, so if the referenced entity is to be parsed later, it must be copied. -The handler should return 0 if processing should not continue because of -a fatal error in the handling of the external entity. -In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING -error. -Note that unlike other handlers the first argument is the parser, not userData. */ - -typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser, - const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId); - -/* This structure is filled in by the XML_UnknownEncodingHandler -to provide information to the parser about encodings that are unknown -to the parser. -The map[b] member gives information about byte sequences -whose first byte is b. -If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c. -If map[b] is -1, then the byte sequence is malformed. -If map[b] is -n, where n >= 2, then b is the first byte of an n-byte -sequence that encodes a single Unicode scalar value. -The data member will be passed as the first argument to the convert function. -The convert function is used to convert multibyte sequences; -s will point to a n-byte sequence where map[(unsigned char)*s] == -n. -The convert function must return the Unicode scalar value -represented by this byte sequence or -1 if the byte sequence is malformed. -The convert function may be null if the encoding is a single-byte encoding, -that is if map[b] >= -1 for all bytes b. -When the parser is finished with the encoding, then if release is not null, -it will call release passing it the data member; -once release has been called, the convert function will not be called again. - -Expat places certain restrictions on the encodings that are supported -using this mechanism. - -1. Every ASCII character that can appear in a well-formed XML document, -other than the characters - - $@\^`{}~ - -must be represented by a single byte, and that byte must be the -same byte that represents that character in ASCII. - -2. No character may require more than 4 bytes to encode. - -3. All characters encoded must have Unicode scalar values <= 0xFFFF, -(ie characters that would be encoded by surrogates in UTF-16 -are not allowed). Note that this restriction doesn't apply to -the built-in support for UTF-8 and UTF-16. - -4. No Unicode character may be encoded by more than one distinct sequence -of bytes. */ - -typedef struct { - int map[256]; - void *data; - int (*convert)(void *data, const char *s); - void (*release)(void *data); -} XML_Encoding; - -/* This is called for an encoding that is unknown to the parser. -The encodingHandlerData argument is that which was passed as the -second argument to XML_SetUnknownEncodingHandler. -The name argument gives the name of the encoding as specified in -the encoding declaration. -If the callback can provide information about the encoding, -it must fill in the XML_Encoding structure, and return 1. -Otherwise it must return 0. -If info does not describe a suitable encoding, -then the parser will return an XML_UNKNOWN_ENCODING error. */ - -typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData, - const XML_Char *name, - XML_Encoding *info); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetElementHandler(XML_Parser parser, - XML_StartElementHandler start, - XML_EndElementHandler end); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetCharacterDataHandler(XML_Parser parser, - XML_CharacterDataHandler handler); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetProcessingInstructionHandler( - XML_Parser parser, - XML_ProcessingInstructionHandler handler); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetCommentHandler(XML_Parser parser, - XML_CommentHandler handler); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetCdataSectionHandler(XML_Parser parser, - XML_StartCdataSectionHandler start, - XML_EndCdataSectionHandler end); - -/* This sets the default handler and also inhibits expansion of - internal entities. The entity reference will be passed to the default - handler. -*/ - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetDefaultHandler(XML_Parser parser, - XML_DefaultHandler handler); - -/* This sets the default handler but does not inhibit expansion of internal - entities. The entity reference will not be passed to the default - handler. -*/ - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetDefaultHandlerExpand(XML_Parser parser, - XML_DefaultHandler handler); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetDoctypeDeclHandler(XML_Parser parser, - XML_StartDoctypeDeclHandler start, - XML_EndDoctypeDeclHandler end); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetUnparsedEntityDeclHandler(XML_Parser parser, - XML_UnparsedEntityDeclHandler handler); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetNotationDeclHandler(XML_Parser parser, - XML_NotationDeclHandler handler); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetExternalParsedEntityDeclHandler( - XML_Parser parser, - XML_ExternalParsedEntityDeclHandler handler); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetInternalParsedEntityDeclHandler( - XML_Parser parser, - XML_InternalParsedEntityDeclHandler handler); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetNamespaceDeclHandler(XML_Parser parser, - XML_StartNamespaceDeclHandler start, - XML_EndNamespaceDeclHandler end); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetNotStandaloneHandler(XML_Parser parser, - XML_NotStandaloneHandler handler); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetExternalEntityRefHandler(XML_Parser parser, - XML_ExternalEntityRefHandler handler); - -/* If a non-null value for arg is specified here, then it will be - passed as the first argument to the external entity ref handler - instead of the parser object. -*/ -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg); - -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetUnknownEncodingHandler(XML_Parser parser, - XML_UnknownEncodingHandler handler, - void *encodingHandlerData); - -/* This can be called within a handler for a start element, end element, - processing instruction or character data. It causes the corresponding - markup to be passed to the default handler. -*/ -XMLRPC_DLLEXPORT -void -xmlrpc_XML_DefaultCurrent(XML_Parser parser); - -/* This value is passed as the userData argument to callbacks. */ -XMLRPC_DLLEXPORT -void -xmlrpc_XML_SetUserData(XML_Parser parser, void *userData); - -/* Returns the last value set by XML_SetUserData or null. */ -#define XML_GetUserData(parser) (*(void **)(parser)) - -/* This is equivalent to supplying an encoding argument -to XML_ParserCreate. It must not be called after XML_Parse -or XML_ParseBuffer. */ - -XMLRPC_DLLEXPORT -int -xmlrpc_XML_SetEncoding(XML_Parser const xmlParserP, - const XML_Char * const encodingName); - -/* If this function is called, then the parser will be passed - as the first argument to callbacks instead of userData. - The userData will still be accessible using XML_GetUserData. -*/ -XMLRPC_DLLEXPORT -void -xmlrpc_XML_UseParserAsHandlerArg(XML_Parser parser); - -/* Sets the base to be used for resolving relative URIs in system - identifiers in declarations. Resolving relative identifiers is left - to the application: this value will be passed through as the base - argument to the XML_ExternalEntityRefHandler, XML_NotationDeclHandler - and XML_UnparsedEntityDeclHandler. The base argument will be copied. - Returns zero if out of memory, non-zero otherwise. -*/ -XMLRPC_DLLEXPORT -int -xmlrpc_XML_SetBase(XML_Parser parser, const XML_Char *base); - -XMLRPC_DLLEXPORT -const XML_Char * -xmlrpc_XML_GetBase(XML_Parser parser); - -/* Returns the number of the attribute/value pairs passed in last call - to the XML_StartElementHandler that were specified in the start-tag - rather than defaulted. Each attribute/value pair counts as 2; thus - this correspondds to an index into the atts array passed to the - XML_StartElementHandler. -*/ -XMLRPC_DLLEXPORT -int -xmlrpc_XML_GetSpecifiedAttributeCount(XML_Parser parser); - -/* Returns the index of the ID attribute passed in the last call to - XML_StartElementHandler, or -1 if there is no ID attribute. Each - attribute/value pair counts as 2; thus this correspondds to an index - into the atts array passed to the XML_StartElementHandler. -*/ -XMLRPC_DLLEXPORT -int -xmlrpc_XML_GetIdAttributeIndex(XML_Parser parser); - -/* Parses some input. Returns 0 if a fatal error is detected. - The last call to XML_Parse must have isFinal true; - len may be zero for this call (or any other). -*/ -XMLRPC_DLLEXPORT -int -xmlrpc_XML_Parse(XML_Parser const xmlParserP, - const char * const s, - size_t const len, - int const isFinal); - -XMLRPC_DLLEXPORT -void * -xmlrpc_XML_GetBuffer(XML_Parser const xmlParserP, - size_t const len); - -XMLRPC_DLLEXPORT -int -xmlrpc_XML_ParseBuffer(XML_Parser const parser, - int const len, - int const isFinal); - -/* Creates an XML_Parser object that can parse an external general - entity; context is a '\0'-terminated string specifying the parse - context; encoding is a '\0'-terminated string giving the name of the - externally specified encoding, or null if there is no externally - specified encoding. The context string consists of a sequence of - tokens separated by formfeeds (\f); a token consisting of a name - specifies that the general entity of the name is open; a token of the - form prefix=uri specifies the namespace for a particular prefix; a - token of the form =uri specifies the default namespace. This can be - called at any point after the first call to an - ExternalEntityRefHandler so longer as the parser has not yet been - freed. The new parser is completely independent and may safely be - used in a separate thread. The handlers and userData are initialized - from the parser argument. Returns 0 if out of memory. Otherwise - returns a new XML_Parser object. -*/ -XMLRPC_DLLEXPORT -XML_Parser -xmlrpc_XML_ExternalEntityParserCreate(XML_Parser parser, - const XML_Char *context, - const XML_Char *encoding); - -enum XML_ParamEntityParsing { - XML_PARAM_ENTITY_PARSING_NEVER, - XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, - XML_PARAM_ENTITY_PARSING_ALWAYS -}; - -/* Controls parsing of parameter entities (including the external DTD - subset). If parsing of parameter entities is enabled, then references - to external parameter entities (including the external DTD subset) - will be passed to the handler set with - XML_SetExternalEntityRefHandler. The context passed will be 0. - Unlike external general entities, external parameter entities can only - be parsed synchronously. If the external parameter entity is to be - parsed, it must be parsed during the call to the external entity ref - handler: the complete sequence of XML_ExternalEntityParserCreate, - XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during - this call. After XML_ExternalEntityParserCreate has been called to - create the parser for the external parameter entity (context must be 0 - for this call), it is illegal to make any calls on the old parser - until XML_ParserFree has been called on the newly created parser. If - the library has been compiled without support for parameter entity - parsing (ie without XML_DTD being defined), then - XML_SetParamEntityParsing will return 0 if parsing of parameter - entities is requested; otherwise it will return non-zero. -*/ -XMLRPC_DLLEXPORT -int -xmlrpc_XML_SetParamEntityParsing(XML_Parser parser, - enum XML_ParamEntityParsing parsing); - -/* Sets the hash salt to use for internal hash calculations. - Helps in preventing DoS attacks based on predicting hash - function behavior. This must be called before parsing is started. - Returns 1 if successful, 0 when called after parsing has started. -*/ -int -XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); - -enum XML_Error { - XML_ERROR_NONE, - XML_ERROR_NO_MEMORY, - XML_ERROR_SYNTAX, - XML_ERROR_NO_ELEMENTS, - XML_ERROR_INVALID_TOKEN, - XML_ERROR_UNCLOSED_TOKEN, - XML_ERROR_PARTIAL_CHAR, - XML_ERROR_TAG_MISMATCH, - XML_ERROR_DUPLICATE_ATTRIBUTE, - XML_ERROR_JUNK_AFTER_DOC_ELEMENT, - XML_ERROR_PARAM_ENTITY_REF, - XML_ERROR_UNDEFINED_ENTITY, - XML_ERROR_RECURSIVE_ENTITY_REF, - XML_ERROR_ASYNC_ENTITY, - XML_ERROR_BAD_CHAR_REF, - XML_ERROR_BINARY_ENTITY_REF, - XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, - XML_ERROR_MISPLACED_XML_PI, - XML_ERROR_UNKNOWN_ENCODING, - XML_ERROR_INCORRECT_ENCODING, - XML_ERROR_UNCLOSED_CDATA_SECTION, - XML_ERROR_EXTERNAL_ENTITY_HANDLING, - XML_ERROR_NOT_STANDALONE -}; - -/* If xmlrpc_XML_Parse or xmlrpc_XML_ParseBuffer have returned 0, then - xmlrpc_XML_GetErrorString and xmlrpc_XML_GetErrorCode return - information about the error. -*/ - -XMLRPC_DLLEXPORT -enum XML_Error -xmlrpc_XML_GetErrorCode(XML_Parser const parser); - -XMLRPC_DLLEXPORT -const char * -xmlrpc_XML_GetErrorString(XML_Parser const parser); - -/* These functions return information about the current parse location. - They may be called when XML_Parse or XML_ParseBuffer return 0; - in this case the location is the location of the character at which - the error was detected. - They may also be called from any other callback called to report - some parse event; in this the location is the location of the first - of the sequence of characters that generated the event. -*/ - -XMLRPC_DLLEXPORT -int -xmlrpc_XML_GetCurrentLineNumber(XML_Parser parser); - -XMLRPC_DLLEXPORT -int -xmlrpc_XML_GetCurrentColumnNumber(XML_Parser parser); - -XMLRPC_DLLEXPORT -long -xmlrpc_XML_GetCurrentByteIndex(XML_Parser parser); - -/* Return the number of bytes in the current event. -Returns 0 if the event is in an internal entity. */ - -XMLRPC_DLLEXPORT -int -xmlrpc_XML_GetCurrentByteCount(XML_Parser parser); - -/* For backwards compatibility with previous versions. */ -#define XML_GetErrorLineNumber XML_GetCurrentLineNumber -#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber -#define XML_GetErrorByteIndex XML_GetCurrentByteIndex - -/* Frees memory used by the parser. */ -XMLRPC_DLLEXPORT -void -xmlrpc_XML_ParserFree(XML_Parser parser); - -/* Returns a string describing the error. */ -XMLRPC_DLLEXPORT -const XML_LChar * -xmlrpc_XML_ErrorString(int const code); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/lib/expat/xmltok/Makefile b/trunk/lib/expat/xmltok/Makefile deleted file mode 100644 index 66e706325..000000000 --- a/trunk/lib/expat/xmltok/Makefile +++ /dev/null @@ -1,112 +0,0 @@ -############################################################################### -# This directory builds libxmlrpc_xmltok, an XML token parser. This is -# essentially the separately distributed Expat library from 2001, but -# with slight changes. The main reason it is bundled with Xmlrpc-c is -# to make the latter easier to build and use. -# -# The library is about XML in general. There is nothing specific to -# XML-RPC here. -############################################################################### - -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - EXPATDIR := $(call updir,$(CURDIR)) - LIBDIR := $(call updir,$(EXPATDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/expat/xmltok - -include $(BLDDIR)/config.mk - -# I can't figure out what XML_BYTE_ORDER is, but it doesn't look like the -# code has ever defined it. That means it's treated like 0 in #if. Since -# we started using the Gcc -Wundef option, that generates a warning, so -# se set it explicitly to 0 here. - -CFLAGS_LOCAL = -DXML_BYTE_ORDER=0 - -# -I. is necessary when blddir != srcdir -INCLUDES = -I. -I$(BLDDIR) -Isrcdir/lib/util/include -Isrcdir/include - -default: all - -TARGET_LIBRARY_NAMES := libxmlrpc_xmltok - -STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_xmltok.a - -SHARED_LIBS_TO_BUILD := libxmlrpc_xmltok -SHARED_LIBS_TO_INSTALL := libxmlrpc_xmltok - -TARGET_MODS = xmltok xmlrole - -OMIT_XMLTOK_LIB_RULE = Y -MAJ=3 - # Major number of shared libraries in this directory - -include $(SRCDIR)/common.mk - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -XMLTOK_SHLIB = $(call shlibfn,libxmlrpc_xmltok) -#XMLTOK_SHLIB is e.g. libxmlrpc_xmltok.so.3.1 -XMLTOK_SHLIBLE = $(call shliblefn,libxmlrpc_xmltok) -#XMLTOK_SHLIBLE is e.g. libxmlrpc_xmltok.so - -.PHONY: all -all: libxmlrpc_xmltok.a $(TARGET_SHARED_LIBRARIES) $(TARGET_SHARED_LE_LIBS) - -# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES -$(XMLTOK_SHLIB): $(TARGET_MODS:%=%.osh) -$(XMLTOK_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) - -# Rule for this is in common.mk, courtesy of TARGET_STATIC_LIBRARIES: - -libxmlrpc_xmltok.a: $(TARGET_MODS:%=%.o) -libxmlrpc_xmltok.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) - -#----------------------------------------------------------------------------- -# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES -#----------------------------------------------------------------------------- - -# Rules to compile object modules from which to build the static and shared -# library are in common.mk, courtesy of TARGET_MODS. - - -.PHONY: clean -clean: clean-common - rm -f nametab.h - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: tags -tags: TAGS - -.PHONY: distdir -distdir: - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: dep -dep: dep-common - -GENNMTAB = ../gennmtab/gennmtab - -nametab.h: $(GENNMTAB) - rm -f $@ - $(GENNMTAB) >$@ - -$(GENNMTAB): - $(MAKE) -C $(dir $@) $(notdir $@) - -xmltok.o xmltok.osh: nametab.h xmltok_impl.c - -include depend.mk diff --git a/trunk/lib/expat/xmltok/ascii.h b/trunk/lib/expat/xmltok/ascii.h deleted file mode 100644 index a8a621ce7..000000000 --- a/trunk/lib/expat/xmltok/ascii.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#define ASCII_A 0x41 -#define ASCII_B 0x42 -#define ASCII_C 0x43 -#define ASCII_D 0x44 -#define ASCII_E 0x45 -#define ASCII_F 0x46 -#define ASCII_G 0x47 -#define ASCII_H 0x48 -#define ASCII_I 0x49 -#define ASCII_J 0x4A -#define ASCII_K 0x4B -#define ASCII_L 0x4C -#define ASCII_M 0x4D -#define ASCII_N 0x4E -#define ASCII_O 0x4F -#define ASCII_P 0x50 -#define ASCII_Q 0x51 -#define ASCII_R 0x52 -#define ASCII_S 0x53 -#define ASCII_T 0x54 -#define ASCII_U 0x55 -#define ASCII_V 0x56 -#define ASCII_W 0x57 -#define ASCII_X 0x58 -#define ASCII_Y 0x59 -#define ASCII_Z 0x5A - -#define ASCII_a 0x61 -#define ASCII_b 0x62 -#define ASCII_c 0x63 -#define ASCII_d 0x64 -#define ASCII_e 0x65 -#define ASCII_f 0x66 -#define ASCII_g 0x67 -#define ASCII_h 0x68 -#define ASCII_i 0x69 -#define ASCII_j 0x6A -#define ASCII_k 0x6B -#define ASCII_l 0x6C -#define ASCII_m 0x6D -#define ASCII_n 0x6E -#define ASCII_o 0x6F -#define ASCII_p 0x70 -#define ASCII_q 0x71 -#define ASCII_r 0x72 -#define ASCII_s 0x73 -#define ASCII_t 0x74 -#define ASCII_u 0x75 -#define ASCII_v 0x76 -#define ASCII_w 0x77 -#define ASCII_x 0x78 -#define ASCII_y 0x79 -#define ASCII_z 0x7A - -#define ASCII_0 0x30 -#define ASCII_1 0x31 -#define ASCII_2 0x32 -#define ASCII_3 0x33 -#define ASCII_4 0x34 -#define ASCII_5 0x35 -#define ASCII_6 0x36 -#define ASCII_7 0x37 -#define ASCII_8 0x38 -#define ASCII_9 0x39 - -#define ASCII_TAB 0x09 -#define ASCII_SPACE 0x20 -#define ASCII_EXCL 0x21 -#define ASCII_QUOT 0x22 -#define ASCII_AMP 0x26 -#define ASCII_APOS 0x27 -#define ASCII_MINUS 0x2D -#define ASCII_PERIOD 0x2E -#define ASCII_COLON 0x3A -#define ASCII_SEMI 0x3B -#define ASCII_LT 0x3C -#define ASCII_EQUALS 0x3D -#define ASCII_GT 0x3E -#define ASCII_LSQB 0x5B -#define ASCII_RSQB 0x5D -#define ASCII_UNDERSCORE 0x5F diff --git a/trunk/lib/expat/xmltok/asciitab.h b/trunk/lib/expat/xmltok/asciitab.h deleted file mode 100644 index e994576a7..000000000 --- a/trunk/lib/expat/xmltok/asciitab.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, -/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, -/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, -/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, -/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, -/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, -/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, -/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, -/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, -/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, -/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/trunk/lib/expat/xmltok/dllmain.c b/trunk/lib/expat/xmltok/dllmain.c deleted file mode 100644 index 2ab2b6d0e..000000000 --- a/trunk/lib/expat/xmltok/dllmain.c +++ /dev/null @@ -1,15 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#define STRICT 1 - -#define WIN32_LEAN_AND_MEAN -#include - -BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) -{ - return TRUE; -} - diff --git a/trunk/lib/expat/xmltok/iasciitab.h b/trunk/lib/expat/xmltok/iasciitab.h deleted file mode 100644 index 2694d9d64..000000000 --- a/trunk/lib/expat/xmltok/iasciitab.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ -/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, -/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, -/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, -/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, -/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, -/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, -/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, -/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, -/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, -/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, -/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, -/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, -/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, -/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/trunk/lib/expat/xmltok/latin1tab.h b/trunk/lib/expat/xmltok/latin1tab.h deleted file mode 100644 index 6e01d50e0..000000000 --- a/trunk/lib/expat/xmltok/latin1tab.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, -/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, -/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, -/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, -/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, -/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, -/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, diff --git a/trunk/lib/expat/xmltok/utf8tab.h b/trunk/lib/expat/xmltok/utf8tab.h deleted file mode 100644 index 28d9b5960..000000000 --- a/trunk/lib/expat/xmltok/utf8tab.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - - -/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, -/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, -/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, -/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, -/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, -/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, diff --git a/trunk/lib/expat/xmltok/xmldef.h b/trunk/lib/expat/xmltok/xmldef.h deleted file mode 100644 index 2ef9d494d..000000000 --- a/trunk/lib/expat/xmltok/xmldef.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#include - -#ifdef XML_WINLIB - -#define WIN32_LEAN_AND_MEAN -#ifndef STRICT -#define STRICT 1 -#endif -#include - -#define malloc(x) HeapAlloc(GetProcessHeap(), 0, (x)) -#define calloc(x, y) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)*(y)) -#define free(x) HeapFree(GetProcessHeap(), 0, (x)) -#define realloc(x, y) HeapReAlloc(GetProcessHeap(), 0, x, y) -#define abort() /* as nothing */ - -#else /* not XML_WINLIB */ - -#include - -#endif /* not XML_WINLIB */ - -/* This file can be used for any definitions needed in -particular environments. */ - -/* Mozilla specific defines */ - -#ifdef MOZILLA_CLIENT - -#include "nspr.h" -#define malloc(x) PR_Malloc((size_t)(x)) -#define realloc(x, y) PR_Realloc((x), (size_t)(y)) -#define calloc(x, y) PR_Calloc((x),(y)) -#define free(x) PR_Free(x) -#if PR_BYTES_PER_INT != 4 -#define int int32 -#endif - -/* Enable Unicode string processing in expat. */ -#ifndef XML_UNICODE -#define XML_UNICODE -#endif - -#endif /* MOZILLA_CLIENT */ diff --git a/trunk/lib/expat/xmltok/xmlrole.c b/trunk/lib/expat/xmltok/xmlrole.c deleted file mode 100644 index 821971343..000000000 --- a/trunk/lib/expat/xmltok/xmlrole.c +++ /dev/null @@ -1,1262 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ -#include "xmlrpc_config.h" - -#include "xmldef.h" -#include "xmlrole.h" -#include "ascii.h" - -/* Doesn't check: - - that ,| are not mixed in a model group - content of literals - -*/ - -static const char KW_ANY[] = { ASCII_A, ASCII_N, ASCII_Y, '\0' }; -static const char KW_ATTLIST[] = { ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' }; -static const char KW_CDATA[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_DOCTYPE[] = { ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' }; -static const char KW_ELEMENT[] = { ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' }; -static const char KW_EMPTY[] = { ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' }; -static const char KW_ENTITIES[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' }; -static const char KW_ENTITY[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; -static const char KW_FIXED[] = { ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' }; -static const char KW_ID[] = { ASCII_I, ASCII_D, '\0' }; -static const char KW_IDREF[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; -static const char KW_IDREFS[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; -static const char KW_IGNORE[] = { ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' }; -static const char KW_IMPLIED[] = { ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' }; -static const char KW_INCLUDE[] = { ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' }; -static const char KW_NDATA[] = { ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_NMTOKEN[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; -static const char KW_NMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' }; -static const char KW_NOTATION[] = { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, '\0' }; -static const char KW_PCDATA[] = { ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; -static const char KW_PUBLIC[] = { ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' }; -static const char KW_REQUIRED[] = { ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, '\0' }; -static const char KW_SYSTEM[] = { ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' }; - -#ifndef MIN_BYTES_PER_CHAR -#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) -#endif - -#define setTopLevel(state) \ - ((state)->handler = ((state)->documentEntity \ - ? internalSubset \ - : externalSubset1)) - -typedef int PROLOG_HANDLER(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc); - -static PROLOG_HANDLER - prolog0, prolog1, prolog2, - doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, - internalSubset, - entity0, entity1, entity2, entity3, entity4, entity5, entity6, - entity7, entity8, entity9, - notation0, notation1, notation2, notation3, notation4, - attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, - attlist7, attlist8, attlist9, - element0, element1, element2, element3, element4, element5, element6, - element7, - externalSubset0, externalSubset1, - condSect0, condSect1, condSect2, - declClose, - error; - -static -int common(PROLOG_STATE *state, int tok); - -static -int prolog0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - state->handler = prolog1; - return XML_ROLE_NONE; - case XML_TOK_XML_DECL: - state->handler = prolog1; - return XML_ROLE_XML_DECL; - case XML_TOK_PI: - state->handler = prolog1; - return XML_ROLE_NONE; - case XML_TOK_COMMENT: - state->handler = prolog1; - case XML_TOK_BOM: - return XML_ROLE_NONE; - case XML_TOK_DECL_OPEN: - if (!XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_DOCTYPE)) - break; - state->handler = doctype0; - return XML_ROLE_NONE; - case XML_TOK_INSTANCE_START: - state->handler = error; - return XML_ROLE_INSTANCE_START; - } - return common(state, tok); -} - -static -int prolog1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_PI: - case XML_TOK_COMMENT: - case XML_TOK_BOM: - return XML_ROLE_NONE; - case XML_TOK_DECL_OPEN: - if (!XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_DOCTYPE)) - break; - state->handler = doctype0; - return XML_ROLE_NONE; - case XML_TOK_INSTANCE_START: - state->handler = error; - return XML_ROLE_INSTANCE_START; - } - return common(state, tok); -} - -static -int prolog2(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_PI: - case XML_TOK_COMMENT: - return XML_ROLE_NONE; - case XML_TOK_INSTANCE_START: - state->handler = error; - return XML_ROLE_INSTANCE_START; - } - return common(state, tok); -} - -static -int doctype0(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = doctype1; - return XML_ROLE_DOCTYPE_NAME; - } - return common(state, tok); -} - -static -int doctype1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = internalSubset; - return XML_ROLE_NONE; - case XML_TOK_DECL_CLOSE: - state->handler = prolog2; - return XML_ROLE_DOCTYPE_CLOSE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = doctype3; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = doctype2; - return XML_ROLE_NONE; - } - break; - } - return common(state, tok); -} - -static -int doctype2(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = doctype3; - return XML_ROLE_DOCTYPE_PUBLIC_ID; - } - return common(state, tok); -} - -static -int doctype3(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = doctype4; - return XML_ROLE_DOCTYPE_SYSTEM_ID; - } - return common(state, tok); -} - -static -int doctype4(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = internalSubset; - return XML_ROLE_NONE; - case XML_TOK_DECL_CLOSE: - state->handler = prolog2; - return XML_ROLE_DOCTYPE_CLOSE; - } - return common(state, tok); -} - -static -int doctype5(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_DECL_CLOSE: - state->handler = prolog2; - return XML_ROLE_DOCTYPE_CLOSE; - } - return common(state, tok); -} - -static -int internalSubset(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_DECL_OPEN: - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_ENTITY)) { - state->handler = entity0; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_ATTLIST)) { - state->handler = attlist0; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_ELEMENT)) { - state->handler = element0; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, - ptr + 2 * MIN_BYTES_PER_CHAR(enc), - end, - KW_NOTATION)) { - state->handler = notation0; - return XML_ROLE_NONE; - } - break; - case XML_TOK_PI: - case XML_TOK_COMMENT: - return XML_ROLE_NONE; - case XML_TOK_PARAM_ENTITY_REF: - return XML_ROLE_PARAM_ENTITY_REF; - case XML_TOK_CLOSE_BRACKET: - state->handler = doctype5; - return XML_ROLE_NONE; - } - return common(state, tok); -} - - - -static -int externalSubset0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - state->handler = externalSubset1; - if (tok == XML_TOK_XML_DECL) - return XML_ROLE_TEXT_DECL; - return externalSubset1(state, tok, ptr, end, enc); -} - -static -int externalSubset1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_COND_SECT_OPEN: - state->handler = condSect0; - return XML_ROLE_NONE; - case XML_TOK_COND_SECT_CLOSE: - if (state->includeLevel == 0) - break; - state->includeLevel -= 1; - return XML_ROLE_NONE; - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_CLOSE_BRACKET: - break; - case XML_TOK_NONE: - if (state->includeLevel) - break; - return XML_ROLE_NONE; - default: - return internalSubset(state, tok, ptr, end, enc); - } - return common(state, tok); -} - - - -static -int entity0(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_PERCENT: - state->handler = entity1; - return XML_ROLE_NONE; - case XML_TOK_NAME: - state->handler = entity2; - return XML_ROLE_GENERAL_ENTITY_NAME; - } - return common(state, tok); -} - -static -int entity1(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - state->handler = entity7; - return XML_ROLE_PARAM_ENTITY_NAME; - } - return common(state, tok); -} - -static -int entity2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = entity4; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = entity3; - return XML_ROLE_NONE; - } - break; - case XML_TOK_LITERAL: - state->handler = declClose; - return XML_ROLE_ENTITY_VALUE; - } - return common(state, tok); -} - -static -int entity3(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = entity4; - return XML_ROLE_ENTITY_PUBLIC_ID; - } - return common(state, tok); -} - - -static -int entity4(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = entity5; - return XML_ROLE_ENTITY_SYSTEM_ID; - } - return common(state, tok); -} - -static -int entity5(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { - state->handler = entity6; - return XML_ROLE_NONE; - } - break; - } - return common(state, tok); -} - -static -int entity6(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - state->handler = declClose; - return XML_ROLE_ENTITY_NOTATION_NAME; - } - return common(state, tok); -} - -static -int entity7(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = entity9; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = entity8; - return XML_ROLE_NONE; - } - break; - case XML_TOK_LITERAL: - state->handler = declClose; - return XML_ROLE_ENTITY_VALUE; - } - return common(state, tok); -} - -static -int entity8(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = entity9; - return XML_ROLE_ENTITY_PUBLIC_ID; - } - return common(state, tok); -} - -static -int entity9(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = declClose; - return XML_ROLE_ENTITY_SYSTEM_ID; - } - return common(state, tok); -} - -static -int notation0(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - state->handler = notation1; - return XML_ROLE_NOTATION_NAME; - } - return common(state, tok); -} - -static -int notation1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { - state->handler = notation3; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { - state->handler = notation2; - return XML_ROLE_NONE; - } - break; - } - return common(state, tok); -} - -static -int notation2(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = notation4; - return XML_ROLE_NOTATION_PUBLIC_ID; - } - return common(state, tok); -} - -static -int notation3(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = declClose; - return XML_ROLE_NOTATION_SYSTEM_ID; - } - return common(state, tok); -} - -static -int notation4(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = declClose; - return XML_ROLE_NOTATION_SYSTEM_ID; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_NOTATION_NO_SYSTEM_ID; - } - return common(state, tok); -} - -static -int attlist0(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = attlist1; - return XML_ROLE_ATTLIST_ELEMENT_NAME; - } - return common(state, tok); -} - -static -int attlist1(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = attlist2; - return XML_ROLE_ATTRIBUTE_NAME; - } - return common(state, tok); -} - -static -int attlist2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - { - static const char *types[] = { - KW_CDATA, - KW_ID, - KW_IDREF, - KW_IDREFS, - KW_ENTITY, - KW_ENTITIES, - KW_NMTOKEN, - KW_NMTOKENS, - }; - int i; - for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) - if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { - state->handler = attlist8; - return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; - } - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { - state->handler = attlist5; - return XML_ROLE_NONE; - } - break; - case XML_TOK_OPEN_PAREN: - state->handler = attlist3; - return XML_ROLE_NONE; - } - return common(state, tok); -} - -static -int attlist3(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NMTOKEN: - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = attlist4; - return XML_ROLE_ATTRIBUTE_ENUM_VALUE; - } - return common(state, tok); -} - -static -int attlist4(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_CLOSE_PAREN: - state->handler = attlist8; - return XML_ROLE_NONE; - case XML_TOK_OR: - state->handler = attlist3; - return XML_ROLE_NONE; - } - return common(state, tok); -} - -static -int attlist5(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_PAREN: - state->handler = attlist6; - return XML_ROLE_NONE; - } - return common(state, tok); -} - - -static -int attlist6(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - state->handler = attlist7; - return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; - } - return common(state, tok); -} - -static -int attlist7(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_CLOSE_PAREN: - state->handler = attlist8; - return XML_ROLE_NONE; - case XML_TOK_OR: - state->handler = attlist6; - return XML_ROLE_NONE; - } - return common(state, tok); -} - -/* default value */ -static -int attlist8(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_POUND_NAME: - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_IMPLIED)) { - state->handler = attlist1; - return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; - } - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_REQUIRED)) { - state->handler = attlist1; - return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; - } - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_FIXED)) { - state->handler = attlist9; - return XML_ROLE_NONE; - } - break; - case XML_TOK_LITERAL: - state->handler = attlist1; - return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; - } - return common(state, tok); -} - -static -int attlist9(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_LITERAL: - state->handler = attlist1; - return XML_ROLE_FIXED_ATTRIBUTE_VALUE; - } - return common(state, tok); -} - -static -int element0(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element1; - return XML_ROLE_ELEMENT_NAME; - } - return common(state, tok); -} - -static -int element1(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { - state->handler = declClose; - return XML_ROLE_CONTENT_EMPTY; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { - state->handler = declClose; - return XML_ROLE_CONTENT_ANY; - } - break; - case XML_TOK_OPEN_PAREN: - state->handler = element2; - state->level = 1; - return XML_ROLE_GROUP_OPEN; - } - return common(state, tok); -} - -static -int element2(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_POUND_NAME: - if (XmlNameMatchesAscii(enc, - ptr + MIN_BYTES_PER_CHAR(enc), - end, - KW_PCDATA)) { - state->handler = element3; - return XML_ROLE_CONTENT_PCDATA; - } - break; - case XML_TOK_OPEN_PAREN: - state->level = 2; - state->handler = element6; - return XML_ROLE_GROUP_OPEN; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT; - case XML_TOK_NAME_QUESTION: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_OPT; - case XML_TOK_NAME_ASTERISK: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_REP; - case XML_TOK_NAME_PLUS: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_PLUS; - } - return common(state, tok); -} - -static -int element3(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_CLOSE_PAREN: - case XML_TOK_CLOSE_PAREN_ASTERISK: - state->handler = declClose; - return XML_ROLE_GROUP_CLOSE_REP; - case XML_TOK_OR: - state->handler = element4; - return XML_ROLE_NONE; - } - return common(state, tok); -} - -static -int element4(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element5; - return XML_ROLE_CONTENT_ELEMENT; - } - return common(state, tok); -} - -static -int element5(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_CLOSE_PAREN_ASTERISK: - state->handler = declClose; - return XML_ROLE_GROUP_CLOSE_REP; - case XML_TOK_OR: - state->handler = element4; - return XML_ROLE_NONE; - } - return common(state, tok); -} - -static -int element6(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_PAREN: - state->level += 1; - return XML_ROLE_GROUP_OPEN; - case XML_TOK_NAME: - case XML_TOK_PREFIXED_NAME: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT; - case XML_TOK_NAME_QUESTION: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_OPT; - case XML_TOK_NAME_ASTERISK: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_REP; - case XML_TOK_NAME_PLUS: - state->handler = element7; - return XML_ROLE_CONTENT_ELEMENT_PLUS; - } - return common(state, tok); -} - -static -int element7(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_CLOSE_PAREN: - state->level -= 1; - if (state->level == 0) - state->handler = declClose; - return XML_ROLE_GROUP_CLOSE; - case XML_TOK_CLOSE_PAREN_ASTERISK: - state->level -= 1; - if (state->level == 0) - state->handler = declClose; - return XML_ROLE_GROUP_CLOSE_REP; - case XML_TOK_CLOSE_PAREN_QUESTION: - state->level -= 1; - if (state->level == 0) - state->handler = declClose; - return XML_ROLE_GROUP_CLOSE_OPT; - case XML_TOK_CLOSE_PAREN_PLUS: - state->level -= 1; - if (state->level == 0) - state->handler = declClose; - return XML_ROLE_GROUP_CLOSE_PLUS; - case XML_TOK_COMMA: - state->handler = element6; - return XML_ROLE_GROUP_SEQUENCE; - case XML_TOK_OR: - state->handler = element6; - return XML_ROLE_GROUP_CHOICE; - } - return common(state, tok); -} - - - -static -int condSect0(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_NAME: - if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { - state->handler = condSect1; - return XML_ROLE_NONE; - } - if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { - state->handler = condSect2; - return XML_ROLE_NONE; - } - break; - } - return common(state, tok); -} - - - -static int -condSect1(PROLOG_STATE * state, - int tok, - const char * ptr ATTR_UNUSED, - const char * end ATTR_UNUSED, - const ENCODING * enc ATTR_UNUSED) { - - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = externalSubset1; - state->includeLevel += 1; - return XML_ROLE_NONE; - } - return common(state, tok); -} - - - -static int -condSect2(PROLOG_STATE * state, - int tok, - const char * ptr ATTR_UNUSED, - const char * end ATTR_UNUSED, - const ENCODING * enc ATTR_UNUSED) { - - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_OPEN_BRACKET: - state->handler = externalSubset1; - return XML_ROLE_IGNORE_SECT; - } - return common(state, tok); -} - - - -static -int declClose(PROLOG_STATE *state, - int tok, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - switch (tok) { - case XML_TOK_PROLOG_S: - return XML_ROLE_NONE; - case XML_TOK_DECL_CLOSE: - setTopLevel(state); - return XML_ROLE_NONE; - } - return common(state, tok); -} - -#if 0 - -static -int ignore(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) -{ - switch (tok) { - case XML_TOK_DECL_CLOSE: - state->handler = internalSubset; - return 0; - default: - return XML_ROLE_NONE; - } - return common(state, tok); -} -#endif - -static -int error(PROLOG_STATE *state ATTR_UNUSED, - int tok ATTR_UNUSED, - const char *ptr ATTR_UNUSED, - const char *end ATTR_UNUSED, - const ENCODING *enc ATTR_UNUSED) -{ - return XML_ROLE_NONE; -} - -static -int common(PROLOG_STATE *state, int tok ATTR_UNUSED) -{ - if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) - return XML_ROLE_INNER_PARAM_ENTITY_REF; - state->handler = error; - return XML_ROLE_ERROR; -} - - - -void -xmlrpc_XmlPrologStateInit(PROLOG_STATE * const state) { - - state->handler = prolog0; - state->documentEntity = 1; - state->includeLevel = 0; -} - - - -void -xmlrpc_XmlPrologStateInitExternalEntity(PROLOG_STATE * const state) { - - state->handler = externalSubset0; - state->documentEntity = 0; - state->includeLevel = 0; -} diff --git a/trunk/lib/expat/xmltok/xmlrole.h b/trunk/lib/expat/xmltok/xmlrole.h deleted file mode 100644 index 12695e37b..000000000 --- a/trunk/lib/expat/xmltok/xmlrole.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#ifndef XMLROLE_H_INCLUDED -#define XMLROLE_H_INCLUDED - -#include "xmlrpc-c/c_util.h" -#include "xmltok.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - XML_ROLE_ERROR = -1, - XML_ROLE_NONE = 0, - XML_ROLE_XML_DECL, - XML_ROLE_INSTANCE_START, - XML_ROLE_DOCTYPE_NAME, - XML_ROLE_DOCTYPE_SYSTEM_ID, - XML_ROLE_DOCTYPE_PUBLIC_ID, - XML_ROLE_DOCTYPE_CLOSE, - XML_ROLE_GENERAL_ENTITY_NAME, - XML_ROLE_PARAM_ENTITY_NAME, - XML_ROLE_ENTITY_VALUE, - XML_ROLE_ENTITY_SYSTEM_ID, - XML_ROLE_ENTITY_PUBLIC_ID, - XML_ROLE_ENTITY_NOTATION_NAME, - XML_ROLE_NOTATION_NAME, - XML_ROLE_NOTATION_SYSTEM_ID, - XML_ROLE_NOTATION_NO_SYSTEM_ID, - XML_ROLE_NOTATION_PUBLIC_ID, - XML_ROLE_ATTRIBUTE_NAME, - XML_ROLE_ATTRIBUTE_TYPE_CDATA, - XML_ROLE_ATTRIBUTE_TYPE_ID, - XML_ROLE_ATTRIBUTE_TYPE_IDREF, - XML_ROLE_ATTRIBUTE_TYPE_IDREFS, - XML_ROLE_ATTRIBUTE_TYPE_ENTITY, - XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, - XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, - XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, - XML_ROLE_ATTRIBUTE_ENUM_VALUE, - XML_ROLE_ATTRIBUTE_NOTATION_VALUE, - XML_ROLE_ATTLIST_ELEMENT_NAME, - XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, - XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, - XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, - XML_ROLE_FIXED_ATTRIBUTE_VALUE, - XML_ROLE_ELEMENT_NAME, - XML_ROLE_CONTENT_ANY, - XML_ROLE_CONTENT_EMPTY, - XML_ROLE_CONTENT_PCDATA, - XML_ROLE_GROUP_OPEN, - XML_ROLE_GROUP_CLOSE, - XML_ROLE_GROUP_CLOSE_REP, - XML_ROLE_GROUP_CLOSE_OPT, - XML_ROLE_GROUP_CLOSE_PLUS, - XML_ROLE_GROUP_CHOICE, - XML_ROLE_GROUP_SEQUENCE, - XML_ROLE_CONTENT_ELEMENT, - XML_ROLE_CONTENT_ELEMENT_REP, - XML_ROLE_CONTENT_ELEMENT_OPT, - XML_ROLE_CONTENT_ELEMENT_PLUS, - XML_ROLE_TEXT_DECL, - XML_ROLE_IGNORE_SECT, - XML_ROLE_INNER_PARAM_ENTITY_REF, - XML_ROLE_PARAM_ENTITY_REF, - XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION -}; - -typedef struct prolog_state { - int (*handler)(struct prolog_state *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc); - unsigned level; - unsigned includeLevel; - int documentEntity; -} PROLOG_STATE; - -XMLRPC_DLLEXPORT -void -xmlrpc_XmlPrologStateInit(PROLOG_STATE * const state); - -XMLRPC_DLLEXPORT -void -xmlrpc_XmlPrologStateInitExternalEntity(PROLOG_STATE * const state); - -#define XmlTokenRole(state, tok, ptr, end, enc) \ - (((state)->handler)(state, tok, ptr, end, enc)) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/lib/expat/xmltok/xmltok.c b/trunk/lib/expat/xmltok/xmltok.c deleted file mode 100644 index 7b31fbb4b..000000000 --- a/trunk/lib/expat/xmltok/xmltok.c +++ /dev/null @@ -1,1570 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#include -#include "xmlrpc_config.h" -#include "bool.h" -#include "c_util.h" -#include "xmldef.h" -#include "xmltok.h" -#include "nametab.h" - -#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) - -#define VTABLE1 \ - { PREFIX(prologTok), PREFIX(contentTok), \ - PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ - { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ - PREFIX(sameName), \ - PREFIX(nameMatchesAscii), \ - PREFIX(nameLength), \ - PREFIX(skipS), \ - PREFIX(getAtts), \ - PREFIX(charRefNumber), \ - PREFIX(predefinedEntityName), \ - PREFIX(updatePosition), \ - PREFIX(isPublicId) - -#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) - -#define UCS2_GET_NAMING(pages, hi, lo) \ - (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F))) - -/* A 2 byte UTF-8 representation splits the characters 11 bits -between the bottom 5 and 6 bits of the bytes. -We need 8 bits to index into pages, 3 bits to add to that index and -5 bits to generate the mask. */ -#define UTF8_GET_NAMING2(pages, byte) \ - (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ - + ((((byte)[0]) & 3) << 1) \ - + ((((byte)[1]) >> 5) & 1)] \ - & (1 << (((byte)[1]) & 0x1F))) - -/* A 3 byte UTF-8 representation splits the characters 16 bits -between the bottom 4, 6 and 6 bits of the bytes. -We need 8 bits to index into pages, 3 bits to add to that index and -5 bits to generate the mask. */ -#define UTF8_GET_NAMING3(pages, byte) \ - (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ - + ((((byte)[1]) >> 2) & 0xF)] \ - << 3) \ - + ((((byte)[1]) & 3) << 1) \ - + ((((byte)[2]) >> 5) & 1)] \ - & (1 << (((byte)[2]) & 0x1F))) - -#define UTF8_GET_NAMING(pages, p, n) \ - ((n) == 2 \ - ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ - : ((n) == 3 \ - ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \ - : 0)) - -#define UTF8_INVALID3(p) \ - ((*p) == 0xED \ - ? (((p)[1] & 0x20) != 0) \ - : ((*p) == 0xEF \ - ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \ - : 0)) - -#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0) - -static -int isNever(const ENCODING *enc ATTR_UNUSED, const char *p ATTR_UNUSED) -{ - return 0; -} - -static -int utf8_isName2(const ENCODING *enc ATTR_UNUSED, const char *p) -{ - return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); -} - -static -int utf8_isName3(const ENCODING *enc ATTR_UNUSED, const char *p) -{ - return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); -} - -#define utf8_isName4 isNever - -static -int utf8_isNmstrt2(const ENCODING *enc ATTR_UNUSED, const char *p) -{ - return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); -} - -static -int utf8_isNmstrt3(const ENCODING *enc ATTR_UNUSED, const char *p) -{ - return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); -} - -#define utf8_isNmstrt4 isNever - -#define utf8_isInvalid2 isNever - -static -int utf8_isInvalid3(const ENCODING *enc ATTR_UNUSED, const char *p) -{ - return UTF8_INVALID3((const unsigned char *)p); -} - -static -int utf8_isInvalid4(const ENCODING *enc ATTR_UNUSED, const char *p) -{ - return UTF8_INVALID4((const unsigned char *)p); -} - -struct normal_encoding { - ENCODING enc; - unsigned char type[256]; -#ifdef XML_MIN_SIZE - int (*byteType)(const ENCODING *, const char *); - int (*isNameMin)(const ENCODING *, const char *); - int (*isNmstrtMin)(const ENCODING *, const char *); - int (*byteToAscii)(const ENCODING *, const char *); - int (*charMatches)(const ENCODING *, const char *, int); -#endif /* XML_MIN_SIZE */ - int (*isName2)(const ENCODING *, const char *); - int (*isName3)(const ENCODING *, const char *); - int (*isName4)(const ENCODING *, const char *); - int (*isNmstrt2)(const ENCODING *, const char *); - int (*isNmstrt3)(const ENCODING *, const char *); - int (*isNmstrt4)(const ENCODING *, const char *); - int (*isInvalid2)(const ENCODING *, const char *); - int (*isInvalid3)(const ENCODING *, const char *); - int (*isInvalid4)(const ENCODING *, const char *); -}; - -#ifdef XML_MIN_SIZE - -#define STANDARD_VTABLE(E) \ - E ## byteType, \ - E ## isNameMin, \ - E ## isNmstrtMin, \ - E ## byteToAscii, \ - E ## charMatches, - -#else - -#define STANDARD_VTABLE(E) /* as nothing */ - -#endif - -#define NORMAL_VTABLE(E) \ - E ## isName2, \ - E ## isName3, \ - E ## isName4, \ - E ## isNmstrt2, \ - E ## isNmstrt3, \ - E ## isNmstrt4, \ - E ## isInvalid2, \ - E ## isInvalid3, \ - E ## isInvalid4 - -#define NULL_NORMAL_VTABLE \ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - -static int checkCharRefNumber(int); - -#include "xmltok_impl.h" -#include "ascii.h" - -#ifdef XML_MIN_SIZE -#define sb_isNameMin isNever -#define sb_isNmstrtMin isNever -#endif - -#ifdef XML_MIN_SIZE -#define MINBPC(enc) ((enc)->minBytesPerChar) -#else -/* minimum bytes per character */ -#define MINBPC(enc) 1 -#endif - -#define SB_BYTE_TYPE(enc, p) \ - (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) - -#ifdef XML_MIN_SIZE -static -int sb_byteType(const ENCODING *enc, const char *p) -{ - return SB_BYTE_TYPE(enc, p); -} -#define BYTE_TYPE(enc, p) \ - (((const struct normal_encoding *)(enc))->byteType(enc, p)) -#else -#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) -#endif - -#ifdef XML_MIN_SIZE -#define BYTE_TO_ASCII(enc, p) \ - (((const struct normal_encoding *)(enc))->byteToAscii(enc, p)) -static -int sb_byteToAscii(const ENCODING *enc, const char *p) -{ - return *p; -} -#else -#define BYTE_TO_ASCII(enc, p) (*(p)) -#endif - -#define IS_NAME_CHAR(enc, p, n) \ - (((const struct normal_encoding *)(enc))->isName ## n(enc, p)) -#define IS_NMSTRT_CHAR(enc, p, n) \ - (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p)) -#define IS_INVALID_CHAR(enc, p, n) \ - (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p)) - -#ifdef XML_MIN_SIZE -#define IS_NAME_CHAR_MINBPC(enc, p) \ - (((const struct normal_encoding *)(enc))->isNameMin(enc, p)) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) \ - (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p)) -#else -#define IS_NAME_CHAR_MINBPC(enc, p) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) -#endif - -#ifdef XML_MIN_SIZE -#define CHAR_MATCHES(enc, p, c) \ - (((const struct normal_encoding *)(enc))->charMatches(enc, p, c)) -static -int sb_charMatches(const ENCODING *enc, const char *p, int c) -{ - return *p == c; -} -#else -/* c is an ASCII character */ -#define CHAR_MATCHES(enc, p, c) (*(p) == c) -#endif - -#define PREFIX(ident) normal_ ## ident -#include "xmltok_impl.c" - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR - -enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ - UTF8_cval1 = 0x00, - UTF8_cval2 = 0xc0, - UTF8_cval3 = 0xe0, - UTF8_cval4 = 0xf0 -}; - -static -void utf8_toUtf8(const ENCODING * enc ATTR_UNUSED, - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - char *to; - const char *from; - if (fromLim - *fromP > toLim - *toP) { - /* Avoid copying partial characters. */ - for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--) - if (((unsigned char)fromLim[-1] & 0xc0) != 0x80) - break; - } - for (to = *toP, from = *fromP; from != fromLim; from++, to++) - *to = *from; - *fromP = from; - *toP = to; -} - -static -void utf8_toUtf16(const ENCODING *enc, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ - unsigned short *to = *toP; - const char *from = *fromP; - while (from != fromLim && to != toLim) { - switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { - case BT_LEAD2: - *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f); - from += 2; - break; - case BT_LEAD3: - *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f); - from += 3; - break; - case BT_LEAD4: - { - unsigned long n; - if (to + 1 == toLim) - break; - n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); - n -= 0x10000; - to[0] = (unsigned short)((n >> 10) | 0xD800); - to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); - to += 2; - from += 4; - } - break; - default: - *to++ = *from++; - break; - } - } - *fromP = from; - *toP = to; -} - -static const struct normal_encoding utf8_encoding_ns = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#include "asciitab.h" -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - -static const struct normal_encoding utf8_encoding = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - -static const struct normal_encoding internal_utf8_encoding_ns = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#include "iasciitab.h" -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - -static const struct normal_encoding internal_utf8_encoding = { - { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "utf8tab.h" - }, - STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) -}; - - - -static Utf8Converter latin1_toUtf8; - -static void -latin1_toUtf8(const ENCODING * const enc ATTR_UNUSED, - const char ** const fromP, - const char * const fromLim, - char ** const toP, - const char * const toLim) { -/*---------------------------------------------------------------------------- - Convert the Latin1 string to UTF-8. - - This is a Utf8Converter subroutine. See documentation of the - Utf8Converter type for details. - - Note: a latin1 input character converts to 1 or 2 UTF-8 output - bytes. ------------------------------------------------------------------------------*/ - bool bufferIsFull; - - assert(toLim - *toP >= 2); /* Calling condition */ - - for (bufferIsFull = false; *fromP != fromLim && !bufferIsFull;) { - unsigned char const c = (unsigned char)**fromP; - if (c & 0x80) { - if (toLim - *toP < 2) - bufferIsFull = true; - else { - *(*toP)++ = ((c >> 6) | UTF8_cval2); - *(*toP)++ = ((c & 0x3f) | 0x80); - ++(*fromP); - } - } else { - if (*toP == toLim) - bufferIsFull = true; - else - *(*toP)++ = *(*fromP)++; - } - } -} - - - -static -void latin1_toUtf16(const ENCODING *enc ATTR_UNUSED, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ - while (*fromP != fromLim && *toP != toLim) - *(*toP)++ = (unsigned char)*(*fromP)++; -} - -static const struct normal_encoding latin1_encoding_ns = { - { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(sb_) NULL_NORMAL_VTABLE -}; - -static const struct normal_encoding latin1_encoding = { - { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(sb_) NULL_NORMAL_VTABLE -}; - -static -void ascii_toUtf8(const ENCODING *enc ATTR_UNUSED, - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - while (*fromP != fromLim && *toP != toLim) - *(*toP)++ = *(*fromP)++; -} - -static const struct normal_encoding ascii_encoding_ns = { - { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, - { -#include "asciitab.h" -/* BT_NONXML == 0 */ - }, - STANDARD_VTABLE(sb_) NULL_NORMAL_VTABLE -}; - -static const struct normal_encoding ascii_encoding = { - { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -/* BT_NONXML == 0 */ - }, - STANDARD_VTABLE(sb_) NULL_NORMAL_VTABLE -}; - -static int unicode_byte_type(char hi, char lo) -{ - switch ((unsigned char)hi) { - case 0xD8: case 0xD9: case 0xDA: case 0xDB: - return BT_LEAD4; - case 0xDC: case 0xDD: case 0xDE: case 0xDF: - return BT_TRAIL; - case 0xFF: - switch ((unsigned char)lo) { - case 0xFF: - case 0xFE: - return BT_NONXML; - } - break; - } - return BT_NONASCII; -} - -#define DEFINE_UTF16_TO_UTF8(E) \ -static \ -void E ## toUtf8(const ENCODING *enc ATTR_UNUSED, \ - const char **fromP, const char *fromLim, \ - char **toP, const char *toLim) \ -{ \ - const char *from; \ - for (from = *fromP; from != fromLim; from += 2) { \ - int plane; \ - unsigned char lo2; \ - unsigned char lo = GET_LO(from); \ - unsigned char hi = GET_HI(from); \ - switch (hi) { \ - case 0: \ - if (lo < 0x80) { \ - if (*toP == toLim) { \ - *fromP = from; \ - return; \ - } \ - *(*toP)++ = lo; \ - break; \ - } \ - /* fall through */ \ - case 0x1: case 0x2: case 0x3: \ - case 0x4: case 0x5: case 0x6: case 0x7: \ - if (toLim - *toP < 2) { \ - *fromP = from; \ - return; \ - } \ - *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ - *(*toP)++ = ((lo & 0x3f) | 0x80); \ - break; \ - default: \ - if (toLim - *toP < 3) { \ - *fromP = from; \ - return; \ - } \ - /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ - *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ - *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ - *(*toP)++ = ((lo & 0x3f) | 0x80); \ - break; \ - case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ - if (toLim - *toP < 4) { \ - *fromP = from; \ - return; \ - } \ - plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ - *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ - *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ - from += 2; \ - lo2 = GET_LO(from); \ - *(*toP)++ = (((lo & 0x3) << 4) \ - | ((GET_HI(from) & 0x3) << 2) \ - | (lo2 >> 6) \ - | 0x80); \ - *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ - break; \ - } \ - } \ - *fromP = from; \ -} - -#define DEFINE_UTF16_TO_UTF16(E) \ -static \ -void E ## toUtf16(const ENCODING *enc ATTR_UNUSED, \ - const char **fromP, const char *fromLim, \ - unsigned short **toP, const unsigned short *toLim) \ -{ \ - /* Avoid copying first half only of surrogate */ \ - if (fromLim - *fromP > ((toLim - *toP) << 1) \ - && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \ - fromLim -= 2; \ - for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \ - *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ -} - -#define SET2(ptr, ch) \ - (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8))) -#define GET_LO(ptr) ((unsigned char)(ptr)[0]) -#define GET_HI(ptr) ((unsigned char)(ptr)[1]) - -DEFINE_UTF16_TO_UTF8(little2_) -DEFINE_UTF16_TO_UTF16(little2_) - -#undef SET2 -#undef GET_LO -#undef GET_HI - -#define SET2(ptr, ch) \ - (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF))) -#define GET_LO(ptr) ((unsigned char)(ptr)[1]) -#define GET_HI(ptr) ((unsigned char)(ptr)[0]) - -DEFINE_UTF16_TO_UTF8(big2_) -DEFINE_UTF16_TO_UTF16(big2_) - -#undef SET2 -#undef GET_LO -#undef GET_HI - -#define LITTLE2_BYTE_TYPE(enc, p) \ - ((p)[1] == 0 \ - ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ - : unicode_byte_type((p)[1], (p)[0])) -#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1) -#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c) -#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) -#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) - -#ifdef XML_MIN_SIZE - -static -int little2_byteType(const ENCODING *enc, const char *p) -{ - return LITTLE2_BYTE_TYPE(enc, p); -} - -static -int little2_byteToAscii(const ENCODING *enc, const char *p) -{ - return LITTLE2_BYTE_TO_ASCII(enc, p); -} - -static -int little2_charMatches(const ENCODING *enc, const char *p, int c) -{ - return LITTLE2_CHAR_MATCHES(enc, p, c); -} - -static -int little2_isNameMin(const ENCODING *enc, const char *p) -{ - return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p); -} - -static -int little2_isNmstrtMin(const ENCODING *enc, const char *p) -{ - return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p); -} - -#undef VTABLE -#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 - -#else /* not XML_MIN_SIZE */ - -#undef PREFIX -#define PREFIX(ident) little2_ ## ident -#define MINBPC(enc) 2 -/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ -#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) -#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) -#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c) -#define IS_NAME_CHAR(enc, p, n) 0 -#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) -#define IS_NMSTRT_CHAR(enc, p, n) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) - -#include "xmltok_impl.c" - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR - -#endif /* not XML_MIN_SIZE */ - -static const struct normal_encoding little2_encoding_ns = { - { VTABLE, 2, 0, -#if XML_BYTE_ORDER == 12 - 1 -#else - 0 -#endif - }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_NORMAL_VTABLE -}; - -static const struct normal_encoding little2_encoding = { - { VTABLE, 2, 0, -#if XML_BYTE_ORDER == 12 - 1 -#else - 0 -#endif - }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_NORMAL_VTABLE -}; - -#if XML_BYTE_ORDER != 21 - -static const struct normal_encoding internal_little2_encoding_ns = { - { VTABLE, 2, 0, 1 }, - { -#include "iasciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_NORMAL_VTABLE -}; - -static const struct normal_encoding internal_little2_encoding = { - { VTABLE, 2, 0, 1 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(little2_) NULL_NORMAL_VTABLE -}; - -#endif - - -#define BIG2_BYTE_TYPE(enc, p) \ - ((p)[0] == 0 \ - ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ - : unicode_byte_type((p)[0], (p)[1])) -#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1) -#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c) -#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) -#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ - UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) - -#ifdef XML_MIN_SIZE - -static -int big2_byteType(const ENCODING *enc, const char *p) -{ - return BIG2_BYTE_TYPE(enc, p); -} - -static -int big2_byteToAscii(const ENCODING *enc, const char *p) -{ - return BIG2_BYTE_TO_ASCII(enc, p); -} - -static -int big2_charMatches(const ENCODING *enc, const char *p, int c) -{ - return BIG2_CHAR_MATCHES(enc, p, c); -} - -static -int big2_isNameMin(const ENCODING *enc, const char *p) -{ - return BIG2_IS_NAME_CHAR_MINBPC(enc, p); -} - -static -int big2_isNmstrtMin(const ENCODING *enc, const char *p) -{ - return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p); -} - -#undef VTABLE -#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 - -#else /* not XML_MIN_SIZE */ - -#undef PREFIX -#define PREFIX(ident) big2_ ## ident -#define MINBPC(enc) 2 -/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ -#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) -#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) -#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c) -#define IS_NAME_CHAR(enc, p, n) 0 -#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p) -#define IS_NMSTRT_CHAR(enc, p, n) (0) -#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) - -#include "xmltok_impl.c" - -#undef MINBPC -#undef BYTE_TYPE -#undef BYTE_TO_ASCII -#undef CHAR_MATCHES -#undef IS_NAME_CHAR -#undef IS_NAME_CHAR_MINBPC -#undef IS_NMSTRT_CHAR -#undef IS_NMSTRT_CHAR_MINBPC -#undef IS_INVALID_CHAR - -#endif /* not XML_MIN_SIZE */ - -static const struct normal_encoding big2_encoding_ns = { - { VTABLE, 2, 0, -#if XML_BYTE_ORDER == 21 - 1 -#else - 0 -#endif - }, - { -#include "asciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_NORMAL_VTABLE -}; - -static const struct normal_encoding big2_encoding = { - { VTABLE, 2, 0, -#if XML_BYTE_ORDER == 21 - 1 -#else - 0 -#endif - }, - { -#define BT_COLON BT_NMSTRT -#include "asciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_NORMAL_VTABLE -}; - -#if XML_BYTE_ORDER != 12 - -static const struct normal_encoding internal_big2_encoding_ns = { - { VTABLE, 2, 0, 1 }, - { -#include "iasciitab.h" -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_NORMAL_VTABLE -}; - -static const struct normal_encoding internal_big2_encoding = { - { VTABLE, 2, 0, 1 }, - { -#define BT_COLON BT_NMSTRT -#include "iasciitab.h" -#undef BT_COLON -#include "latin1tab.h" - }, - STANDARD_VTABLE(big2_) NULL_NORMAL_VTABLE -}; - -#endif - -#undef PREFIX - -static -int streqci(const char *s1, const char *s2) -{ - for (;;) { - char c1 = *s1++; - char c2 = *s2++; - if (ASCII_a <= c1 && c1 <= ASCII_z) - c1 += ASCII_A - ASCII_a; - if (ASCII_a <= c2 && c2 <= ASCII_z) - c2 += ASCII_A - ASCII_a; - if (c1 != c2) - return 0; - if (!c1) - break; - } - return 1; -} - -static -void initUpdatePosition(const ENCODING *enc ATTR_UNUSED, const char *ptr, - const char *end, POSITION *pos) -{ - normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); -} - -static -int toAscii(const ENCODING *enc, const char *ptr, const char *end) -{ - char buf[1]; - char *p = buf; - XmlUtf8Convert(enc, &ptr, end, &p, p + 1); - if (p == buf) - return -1; - else - return buf[0]; -} - -static -int isSpace(int c) -{ - switch (c) { - case 0x20: - case 0xD: - case 0xA: - case 0x9: - return 1; - } - return 0; -} - -/* Return 1 if there's just optional white space -or there's an S followed by name=val. */ -static -int parsePseudoAttribute(const ENCODING *enc, - const char *ptr, - const char *end, - const char **namePtr, - const char **nameEndPtr, - const char **valPtr, - const char **nextTokPtr) -{ - int c; - char open; - if (ptr == end) { - *namePtr = 0; - return 1; - } - if (!isSpace(toAscii(enc, ptr, end))) { - *nextTokPtr = ptr; - return 0; - } - do { - ptr += enc->minBytesPerChar; - } while (isSpace(toAscii(enc, ptr, end))); - if (ptr == end) { - *namePtr = 0; - return 1; - } - *namePtr = ptr; - for (;;) { - c = toAscii(enc, ptr, end); - if (c == -1) { - *nextTokPtr = ptr; - return 0; - } - if (c == ASCII_EQUALS) { - *nameEndPtr = ptr; - break; - } - if (isSpace(c)) { - *nameEndPtr = ptr; - do { - ptr += enc->minBytesPerChar; - } while (isSpace(c = toAscii(enc, ptr, end))); - if (c != ASCII_EQUALS) { - *nextTokPtr = ptr; - return 0; - } - break; - } - ptr += enc->minBytesPerChar; - } - if (ptr == *namePtr) { - *nextTokPtr = ptr; - return 0; - } - ptr += enc->minBytesPerChar; - c = toAscii(enc, ptr, end); - while (isSpace(c)) { - ptr += enc->minBytesPerChar; - c = toAscii(enc, ptr, end); - } - if (c != ASCII_QUOT && c != ASCII_APOS) { - *nextTokPtr = ptr; - return 0; - } - open = c; - ptr += enc->minBytesPerChar; - *valPtr = ptr; - for (;; ptr += enc->minBytesPerChar) { - c = toAscii(enc, ptr, end); - if (c == open) - break; - if (!(ASCII_a <= c && c <= ASCII_z) - && !(ASCII_A <= c && c <= ASCII_Z) - && !(ASCII_0 <= c && c <= ASCII_9) - && c != ASCII_PERIOD - && c != ASCII_MINUS - && c != ASCII_UNDERSCORE) { - *nextTokPtr = ptr; - return 0; - } - } - *nextTokPtr = ptr + enc->minBytesPerChar; - return 1; -} - -static const char KW_version[] = { - ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0' -}; - -static const char KW_encoding[] = { - ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0' -}; - -static const char KW_standalone[] = { - ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0' -}; - -static const char KW_yes[] = { - ASCII_y, ASCII_e, ASCII_s, '\0' -}; - -static const char KW_no[] = { - ASCII_n, ASCII_o, '\0' -}; - -static -int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, - const char *, - const char *), - int isGeneralTextEntity, - const ENCODING *enc, - const char *ptr, - const char *end, - const char **badPtr, - const char **versionPtr, - const char **encodingName, - const ENCODING **encoding, - int *standalone) -{ - const char *val = 0; - const char *name = 0; - const char *nameEnd = 0; - ptr += 5 * enc->minBytesPerChar; - end -= 2 * enc->minBytesPerChar; - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) { - *badPtr = ptr; - return 0; - } - if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { - if (!isGeneralTextEntity) { - *badPtr = name; - return 0; - } - } - else { - if (versionPtr) - *versionPtr = val; - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { - *badPtr = ptr; - return 0; - } - if (!name) { - if (isGeneralTextEntity) { - /* a TextDecl must have an EncodingDecl */ - *badPtr = ptr; - return 0; - } - return 1; - } - } - if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { - int c = toAscii(enc, val, end); - if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) { - *badPtr = val; - return 0; - } - if (encodingName) - *encodingName = val; - if (encoding) - *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); - if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { - *badPtr = ptr; - return 0; - } - if (!name) - return 1; - } - if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) { - *badPtr = name; - return 0; - } - if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { - if (standalone) - *standalone = 1; - } - else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { - if (standalone) - *standalone = 0; - } - else { - *badPtr = val; - return 0; - } - while (isSpace(toAscii(enc, ptr, end))) - ptr += enc->minBytesPerChar; - if (ptr != end) { - *badPtr = ptr; - return 0; - } - return 1; -} - -static -int checkCharRefNumber(int result) -{ - switch (result >> 8) { - case 0xD8: case 0xD9: case 0xDA: case 0xDB: - case 0xDC: case 0xDD: case 0xDE: case 0xDF: - return -1; - case 0: - if (latin1_encoding.type[result] == BT_NONXML) - return -1; - break; - case 0xFF: - if (result == 0xFFFE || result == 0xFFFF) - return -1; - break; - } - return result; -} - - - -int -xmlrpc_XmlUtf8Encode(int const c, - char * const buf) { - - enum { - /* minN is minimum legal resulting value for N byte sequence */ - min2 = 0x80, - min3 = 0x800, - min4 = 0x10000 - }; - - if (c < 0) - return 0; - if (c < min2) { - buf[0] = (c | UTF8_cval1); - return 1; - } - if (c < min3) { - buf[0] = ((c >> 6) | UTF8_cval2); - buf[1] = ((c & 0x3f) | 0x80); - return 2; - } - if (c < min4) { - buf[0] = ((c >> 12) | UTF8_cval3); - buf[1] = (((c >> 6) & 0x3f) | 0x80); - buf[2] = ((c & 0x3f) | 0x80); - return 3; - } - if (c < 0x110000) { - buf[0] = ((c >> 18) | UTF8_cval4); - buf[1] = (((c >> 12) & 0x3f) | 0x80); - buf[2] = (((c >> 6) & 0x3f) | 0x80); - buf[3] = ((c & 0x3f) | 0x80); - return 4; - } - return 0; -} - - - -int -xmlrpc_XmlUtf16Encode(int const charNumArg, - unsigned short * const buf) { - - int charNum; - - charNum = charNumArg; /* initial value */ - - if (charNum < 0) - return 0; - if (charNum < 0x10000) { - buf[0] = charNum; - return 1; - } - if (charNum < 0x110000) { - charNum -= 0x10000; - buf[0] = (charNum >> 10) + 0xD800; - buf[1] = (charNum & 0x3FF) + 0xDC00; - return 2; - } - return 0; -} - - - -struct unknown_encoding { - struct normal_encoding normal; - int (*convert)(void *userData, const char *p); - void *userData; - unsigned short utf16[256]; - char utf8[256][4]; -}; - - - -int -xmlrpc_XmlSizeOfUnknownEncoding(void) { - - return sizeof(struct unknown_encoding); -} - - - -static -int unknown_isName(const ENCODING *enc, const char *p) -{ - int c = ((const struct unknown_encoding *)enc) - ->convert(((const struct unknown_encoding *)enc)->userData, p); - if (c & ~0xFFFF) - return 0; - return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); -} - -static -int unknown_isNmstrt(const ENCODING *enc, const char *p) -{ - int c = ((const struct unknown_encoding *)enc) - ->convert(((const struct unknown_encoding *)enc)->userData, p); - if (c & ~0xFFFF) - return 0; - return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); -} - -static -int unknown_isInvalid(const ENCODING *enc, const char *p) -{ - int c = ((const struct unknown_encoding *)enc) - ->convert(((const struct unknown_encoding *)enc)->userData, p); - return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; -} - -static -void unknown_toUtf8(const ENCODING *enc, - const char **fromP, const char *fromLim, - char **toP, const char *toLim) -{ - char buf[XML_UTF8_ENCODE_MAX]; - for (;;) { - const char *utf8; - int n; - if (*fromP == fromLim) - break; - utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP]; - n = *utf8++; - if (n == 0) { - int c = ((const struct unknown_encoding *)enc) - ->convert(((const struct unknown_encoding *)enc)->userData, *fromP); - n = xmlrpc_XmlUtf8Encode(c, buf); - if (n > toLim - *toP) - break; - utf8 = buf; - *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP] - - (BT_LEAD2 - 2); - } - else { - if (n > toLim - *toP) - break; - (*fromP)++; - } - do { - *(*toP)++ = *utf8++; - } while (--n != 0); - } -} - -static -void unknown_toUtf16(const ENCODING *enc, - const char **fromP, const char *fromLim, - unsigned short **toP, const unsigned short *toLim) -{ - while (*fromP != fromLim && *toP != toLim) { - unsigned short c - = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP]; - if (c == 0) { - c = (unsigned short)((const struct unknown_encoding *)enc) - ->convert(((const struct unknown_encoding *)enc)->userData, *fromP); - *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP] - - (BT_LEAD2 - 2); - } - else - (*fromP)++; - *(*toP)++ = c; - } -} - -ENCODING * -xmlrpc_XmlInitUnknownEncoding(void * const mem, - int * const table, - int (*convert)(void *userData, const char *p), - void * const userData) { - - int i; - struct unknown_encoding *e = mem; - for (i = 0; i < (int)sizeof(struct normal_encoding); i++) - ((char *)mem)[i] = ((char *)&latin1_encoding)[i]; - for (i = 0; i < 128; i++) - if (latin1_encoding.type[i] != BT_OTHER - && latin1_encoding.type[i] != BT_NONXML - && table[i] != i) - return 0; - for (i = 0; i < 256; i++) { - int c = table[i]; - if (c == -1) { - e->normal.type[i] = BT_MALFORM; - /* This shouldn't really get used. */ - e->utf16[i] = 0xFFFF; - e->utf8[i][0] = 1; - e->utf8[i][1] = 0; - } - else if (c < 0) { - if (c < -4) - return 0; - e->normal.type[i] = BT_LEAD2 - (c + 2); - e->utf8[i][0] = 0; - e->utf16[i] = 0; - } - else if (c < 0x80) { - if (latin1_encoding.type[c] != BT_OTHER - && latin1_encoding.type[c] != BT_NONXML - && c != i) - return 0; - e->normal.type[i] = latin1_encoding.type[c]; - e->utf8[i][0] = 1; - e->utf8[i][1] = (char)c; - e->utf16[i] = c == 0 ? 0xFFFF : c; - } - else if (checkCharRefNumber(c) < 0) { - e->normal.type[i] = BT_NONXML; - /* This shouldn't really get used. */ - e->utf16[i] = 0xFFFF; - e->utf8[i][0] = 1; - e->utf8[i][1] = 0; - } - else { - if (c > 0xFFFF) - return 0; - if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) - e->normal.type[i] = BT_NMSTRT; - else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) - e->normal.type[i] = BT_NAME; - else - e->normal.type[i] = BT_OTHER; - e->utf8[i][0] = (char)xmlrpc_XmlUtf8Encode(c, e->utf8[i] + 1); - e->utf16[i] = c; - } - } - e->userData = userData; - e->convert = convert; - if (convert) { - e->normal.isName2 = unknown_isName; - e->normal.isName3 = unknown_isName; - e->normal.isName4 = unknown_isName; - e->normal.isNmstrt2 = unknown_isNmstrt; - e->normal.isNmstrt3 = unknown_isNmstrt; - e->normal.isNmstrt4 = unknown_isNmstrt; - e->normal.isInvalid2 = unknown_isInvalid; - e->normal.isInvalid3 = unknown_isInvalid; - e->normal.isInvalid4 = unknown_isInvalid; - } - e->normal.enc.utf8Convert = unknown_toUtf8; - e->normal.enc.utf16Convert = unknown_toUtf16; - return &(e->normal.enc); -} - -/* If this enumeration is changed, getEncodingIndex and encodings -must also be changed. */ -enum { - UNKNOWN_ENC = -1, - ISO_8859_1_ENC = 0, - US_ASCII_ENC, - UTF_8_ENC, - UTF_16_ENC, - UTF_16BE_ENC, - UTF_16LE_ENC, - /* must match encodingNames up to here */ - NO_ENC -}; - -static const char KW_ISO_8859_1[] = { - ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0' -}; -static const char KW_US_ASCII[] = { - ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, '\0' -}; -static const char KW_UTF_8[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0' -}; -static const char KW_UTF_16[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0' -}; -static const char KW_UTF_16BE[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, '\0' -}; -static const char KW_UTF_16LE[] = { - ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, '\0' -}; - -static int -getEncodingIndex(const char * const name) { -/*---------------------------------------------------------------------------- - Return the index into the encodings[] table of the encoding named 'name'. - - If 'name' is NULL, return NO_ENC. - - If the name is non-NULL, but not one we recognize, return UNKNOWN_ENC. - Note that UNKNOWN_ENC is not actually an index (but NO_ENC is). ------------------------------------------------------------------------------*/ - if (name == NULL) - return NO_ENC; - else { - static const char * const encodingNames[] = { - KW_ISO_8859_1, - KW_US_ASCII, - KW_UTF_8, - KW_UTF_16, - KW_UTF_16BE, - KW_UTF_16LE, - }; - unsigned int i; - for (i = 0; i < (unsigned int)(ARRAY_SIZE(encodingNames)); i++) { - if (streqci(name, encodingNames[i])) - return i; - } - return UNKNOWN_ENC; - } -} - -/* For binary compatibility, we store the index of the encoding specified -at initialization in the isUtf16 member. */ - -#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) -#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) - -/* This is what detects the encoding. -encodingTable maps from encoding indices to encodings; -INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding; -state is XML_CONTENT_STATE if we're parsing an external text entity, -and XML_PROLOG_STATE otherwise. -*/ - - -static -int initScan(const ENCODING **encodingTable, - const INIT_ENCODING *enc, - int state, - const char *ptr, - const char *end, - const char **nextTokPtr) -{ - const ENCODING **encPtr; - - if (ptr == end) - return XML_TOK_NONE; - encPtr = enc->encPtr; - if (ptr + 1 == end) { - /* only a single byte available for auto-detection */ - /* so we're parsing an external text entity... */ - /* if UTF-16 was externally specified, then we need at least 2 bytes */ - switch (INIT_ENC_INDEX(enc)) { - case UTF_16_ENC: - case UTF_16LE_ENC: - case UTF_16BE_ENC: - return XML_TOK_PARTIAL; - } - switch ((unsigned char)*ptr) { - case 0xFE: - case 0xFF: - case 0xEF: /* possibly first byte of UTF-8 BOM */ - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) - break; - /* fall through */ - case 0x00: - case 0x3C: - return XML_TOK_PARTIAL; - } - } - else { - switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { - case 0xFEFF: - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) - break; - *nextTokPtr = ptr + 2; - *encPtr = encodingTable[UTF_16BE_ENC]; - return XML_TOK_BOM; - /* 00 3C is handled in the default case */ - case 0x3C00: - if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC - || INIT_ENC_INDEX(enc) == UTF_16_ENC) - && state == XML_CONTENT_STATE) - break; - *encPtr = encodingTable[UTF_16LE_ENC]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - case 0xFFFE: - if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC - && state == XML_CONTENT_STATE) - break; - *nextTokPtr = ptr + 2; - *encPtr = encodingTable[UTF_16LE_ENC]; - return XML_TOK_BOM; - case 0xEFBB: - /* Maybe a UTF-8 BOM (EF BB BF) */ - /* If there's an explicitly specified (external) encoding - of ISO-8859-1 or some flavour of UTF-16 - and this is an external text entity, - don't look for the BOM, - because it might be a legal data. */ - if (state == XML_CONTENT_STATE) { - int e = INIT_ENC_INDEX(enc); - if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC) - break; - } - if (ptr + 2 == end) - return XML_TOK_PARTIAL; - if ((unsigned char)ptr[2] == 0xBF) { - *encPtr = encodingTable[UTF_8_ENC]; - return XML_TOK_BOM; - } - break; - default: - if (ptr[0] == '\0') { - /* 0 isn't a legal data character. Furthermore a document entity can only - start with ASCII characters. So the only way this can fail to be big-endian - UTF-16 if it it's an external parsed general entity that's labelled as - UTF-16LE. */ - if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) - break; - *encPtr = encodingTable[UTF_16BE_ENC]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - } - else if (ptr[1] == '\0') { - /* We could recover here in the case: - - parsing an external entity - - second byte is 0 - - no externally specified encoding - - no encoding declaration - by assuming UTF-16LE. But we don't, because this would mean when - presented just with a single byte, we couldn't reliably determine - whether we needed further bytes. */ - if (state == XML_CONTENT_STATE) - break; - *encPtr = encodingTable[UTF_16LE_ENC]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); - } - break; - } - } - *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; - return XmlTok(*encPtr, state, ptr, end, nextTokPtr); -} - - -#define NS(x) x -#define ns(x) x -#include "xmltok_ns.c" -#undef NS -#undef ns - -#define NS(x) x ## NS -#define ns(x) x ## _ns - -#include "xmltok_ns.c" - -#undef NS -#undef ns - -ENCODING * -xmlrpc_XmlInitUnknownEncodingNS(void * const mem, - int * const table, - int (*convert)(void *userData, const char *p), - void * const userData) { - - ENCODING * const enc = - xmlrpc_XmlInitUnknownEncoding(mem, table, convert, userData); - if (enc) - ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; - return enc; -} diff --git a/trunk/lib/expat/xmltok/xmltok.h b/trunk/lib/expat/xmltok/xmltok.h deleted file mode 100644 index 7d7bdf238..000000000 --- a/trunk/lib/expat/xmltok/xmltok.h +++ /dev/null @@ -1,356 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#ifndef XMLTOK_H_INCLUDED -#define XMLTOK_H_INCLUDED - -#include "xmlrpc-c/c_util.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* The following token may be returned by XmlContentTok */ -#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of - illegal ]]> sequence */ -/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ -#define XML_TOK_NONE -4 /* The string to be scanned is empty */ -#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan; - might be part of CRLF sequence */ -#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ -#define XML_TOK_PARTIAL -1 /* only part of a token */ -#define XML_TOK_INVALID 0 - -/* The following tokens are returned by XmlContentTok; some are also - returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */ - -#define XML_TOK_START_TAG_WITH_ATTS 1 -#define XML_TOK_START_TAG_NO_ATTS 2 -#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag */ -#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 -#define XML_TOK_END_TAG 5 -#define XML_TOK_DATA_CHARS 6 -#define XML_TOK_DATA_NEWLINE 7 -#define XML_TOK_CDATA_SECT_OPEN 8 -#define XML_TOK_ENTITY_REF 9 -#define XML_TOK_CHAR_REF 10 /* numeric character reference */ - -/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ -#define XML_TOK_PI 11 /* processing instruction */ -#define XML_TOK_XML_DECL 12 /* XML decl or text decl */ -#define XML_TOK_COMMENT 13 -#define XML_TOK_BOM 14 /* Byte order mark */ - -/* The following tokens are returned only by XmlPrologTok */ -#define XML_TOK_PROLOG_S 15 -#define XML_TOK_DECL_OPEN 16 /* */ -#define XML_TOK_NAME 18 -#define XML_TOK_NMTOKEN 19 -#define XML_TOK_POUND_NAME 20 /* #name */ -#define XML_TOK_OR 21 /* | */ -#define XML_TOK_PERCENT 22 -#define XML_TOK_OPEN_PAREN 23 -#define XML_TOK_CLOSE_PAREN 24 -#define XML_TOK_OPEN_BRACKET 25 -#define XML_TOK_CLOSE_BRACKET 26 -#define XML_TOK_LITERAL 27 -#define XML_TOK_PARAM_ENTITY_REF 28 -#define XML_TOK_INSTANCE_START 29 - -/* The following occur only in element type declarations */ -#define XML_TOK_NAME_QUESTION 30 /* name? */ -#define XML_TOK_NAME_ASTERISK 31 /* name* */ -#define XML_TOK_NAME_PLUS 32 /* name+ */ -#define XML_TOK_COND_SECT_OPEN 33 /* */ -#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ -#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ -#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ -#define XML_TOK_COMMA 38 - -/* The following token is returned only by XmlAttributeValueTok */ -#define XML_TOK_ATTRIBUTE_VALUE_S 39 - -/* The following token is returned only by XmlCdataSectionTok */ -#define XML_TOK_CDATA_SECT_CLOSE 40 - -/* With namespace processing this is returned by XmlPrologTok - for a name with a colon. */ -#define XML_TOK_PREFIXED_NAME 41 - -#define XML_TOK_IGNORE_SECT 42 - -#define XML_N_STATES 4 - -#define XML_PROLOG_STATE 0 -#define XML_CONTENT_STATE 1 -#define XML_CDATA_SECTION_STATE 2 -#define XML_IGNORE_SECTION_STATE 3 - -#define XML_N_LITERAL_TYPES 2 -#define XML_ATTRIBUTE_VALUE_LITERAL 0 -#define XML_ENTITY_VALUE_LITERAL 1 - -/* The size of the buffer passed to XmlUtf8Encode must be at least this. */ -#define XML_UTF8_ENCODE_MAX 4 -/* The size of the buffer passed to XmlUtf16Encode must be at least this. */ -#define XML_UTF16_ENCODE_MAX 2 - -typedef struct position { - /* first line and first column are 0 not 1 */ - unsigned long lineNumber; - unsigned long columnNumber; -} POSITION; - -typedef struct { - const char *name; - const char *valuePtr; - const char *valueEnd; - char normalized; -} ATTRIBUTE; - -struct encoding; -typedef struct encoding ENCODING; - -/* It's pretty silly to have the 'const' on the argument names below, but MSVC - thinks the definitions of Utf8Converter functions that do have that - qualifier on the argument variables don't match this declaration if we - don't. -*/ -typedef void Utf8Converter(const ENCODING * const encP, - const char ** const fromP, - const char * const fromLim, - char ** const toP, - const char * const toLim); -/*---------------------------------------------------------------------------- - A Utf8Converter is an encoder method that converts from the encoder's - code to UTF-8: - - Convert the string that starts at *fromP and ends at 'fromLim' to UTF8 in - the buffer that starts at *toP and ends at 'toLim'. - - Go from left to right and stop when the output buffer is full. - - Note that the buffer can be full while still having a few bytes left in it - because an input character may require multiple bytes of the output buffer. - - The encoding may require up to 4 UTF-8 bytes for a single input character. - - Leave *fromP and *toP pointing after the last character converted. - - The output buffer must be at least 4 bytes. Results are undefined if not. - - We necessarily advance *fromP at least one character if 'fromLim' allows. ------------------------------------------------------------------------------*/ - - - -struct encoding { - int (*scanners[XML_N_STATES])(const ENCODING *, - const char *, - const char *, - const char **); - int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *, - const char *, - const char *, - const char **); - int (*sameName)(const ENCODING *, - const char *, const char *); - int (*nameMatchesAscii)(const ENCODING *, - const char *, const char *, const char *); - size_t (*nameLength)(const ENCODING *, const char *); - const char *(*skipS)(const ENCODING *, const char *); - int (*getAtts)(const ENCODING *enc, const char *ptr, - int attsMax, ATTRIBUTE *atts); - int (*charRefNumber)(const ENCODING *enc, const char *ptr); - int (*predefinedEntityName)(const ENCODING *, const char *, const char *); - void (*updatePosition)(const ENCODING *, - const char *ptr, - const char *end, - POSITION *); - int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end, - const char **badPtr); - Utf8Converter * utf8Convert; - void (*utf16Convert)(const ENCODING *enc, - const char **fromP, - const char *fromLim, - unsigned short **toP, - const unsigned short *toLim); - int minBytesPerChar; - char isUtf8; - char isUtf16; -}; - -/* -Scan the string starting at ptr until the end of the next complete token, -but do not scan past eptr. Return an integer giving the type of token. - -Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. - -Return XML_TOK_PARTIAL when the string does not contain a complete token; -nextTokPtr will not be set. - -Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr -will be set to point to the character which made the token invalid. - -Otherwise the string starts with a valid token; nextTokPtr will be set to point -to the character following the end of that token. - -Each data character counts as a single token, but adjacent data characters -may be returned together. Similarly for characters in the prolog outside -literals, comments and processing instructions. -*/ - - -#define XmlTok(enc, state, ptr, end, nextTokPtr) \ - (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) - -#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) - -#define XmlContentTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) - -#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) - -#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ - XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) - -/* This is used for performing a 2nd-level tokenization on -the content of a literal that has already been returned by XmlTok. */ - -#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ - (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) - -#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ - XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) - -#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ - XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) - -#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) - -#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ - (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) - -#define XmlNameLength(enc, ptr) \ - (((enc)->nameLength)(enc, ptr)) - -#define XmlSkipS(enc, ptr) \ - (((enc)->skipS)(enc, ptr)) - -#define XmlGetAttributes(enc, ptr, attsMax, atts) \ - (((enc)->getAtts)(enc, ptr, attsMax, atts)) - -#define XmlCharRefNumber(enc, ptr) \ - (((enc)->charRefNumber)(enc, ptr)) - -#define XmlPredefinedEntityName(enc, ptr, end) \ - (((enc)->predefinedEntityName)(enc, ptr, end)) - -#define XmlUpdatePosition(enc, ptr, end, pos) \ - (((enc)->updatePosition)(enc, ptr, end, pos)) - -#define XmlIsPublicId(enc, ptr, end, badPtr) \ - (((enc)->isPublicId)(enc, ptr, end, badPtr)) - -#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ - (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) - -#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ - (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) - -typedef struct { - ENCODING initEnc; - const ENCODING **encPtr; -} INIT_ENCODING; - -XMLRPC_DLLEXPORT -int -xmlrpc_XmlParseXmlDecl(int const isGeneralTextEntity, - const ENCODING * const enc, - const char * const ptr, - const char * const end, - const char ** const badPtr, - const char ** const versionPtr, - const char ** const encodingNamePtr, - const ENCODING ** const namedEncodingPtr, - int * const standalonePtr); - -XMLRPC_DLLEXPORT -const ENCODING * -xmlrpc_XmlGetUtf8InternalEncoding(void); - -XMLRPC_DLLEXPORT -const ENCODING * -xmlrpc_XmlGetUtf16InternalEncoding(void); - -XMLRPC_DLLEXPORT -int -xmlrpc_XmlInitEncoding(INIT_ENCODING * const p, - const ENCODING ** const encPtr, - const char * const name); - -XMLRPC_DLLEXPORT -int -xmlrpc_XmlUtf8Encode(int const c, - char * const buf); - -XMLRPC_DLLEXPORT -int -xmlrpc_XmlUtf16Encode(int const charNum, - unsigned short * const buf); - -XMLRPC_DLLEXPORT -int -xmlrpc_XmlSizeOfUnknownEncoding(void); - -XMLRPC_DLLEXPORT -ENCODING * -xmlrpc_XmlInitUnknownEncoding(void * const mem, - int * const table, - int (*convert)(void *userData, const char *p), - void * const userData); - -XMLRPC_DLLEXPORT -int -xmlrpc_XmlParseXmlDeclNS(int const isGeneralTextEntity, - const ENCODING * const enc, - const char * const ptr, - const char * const end, - const char ** const badPtr, - const char ** const versionPtr, - const char ** const encodingNamePtr, - const ENCODING ** const namedEncodingPtr, - int * const standalonePtr); - -XMLRPC_DLLEXPORT -int -xmlrpc_XmlInitEncodingNS(INIT_ENCODING * const p, - const ENCODING ** const encPtr, - const char * const name); - -XMLRPC_DLLEXPORT -const ENCODING * -xmlrpc_XmlGetUtf8InternalEncodingNS(void); - -XMLRPC_DLLEXPORT -const ENCODING * -xmlrpc_XmlGetUtf16InternalEncodingNS(void); - -XMLRPC_DLLEXPORT -ENCODING * -xmlrpc_XmlInitUnknownEncodingNS(void * const mem, - int * const table, - int (*convert)(void *userData, const char *p), - void * const userData); - -#ifdef __cplusplus -} -#endif - -#endif /* not XmlTok_INCLUDED */ diff --git a/trunk/lib/expat/xmltok/xmltok_impl.c b/trunk/lib/expat/xmltok/xmltok_impl.c deleted file mode 100644 index cf0091d1d..000000000 --- a/trunk/lib/expat/xmltok/xmltok_impl.c +++ /dev/null @@ -1,1889 +0,0 @@ -/*============================================================================= - xmltok_impl.c -=============================================================================== - - This is an inclusion for xmltok.c. You define various macros to control - what code this file generates. xmltok.c includes it multiple times with - different macro definitions to get different code. - - For example, the PREFIX macro becomes part of the symbol names we define, - and can be "normal_", "little2_", or "big2_". -=============================================================================*/ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#ifndef IS_INVALID_CHAR -#define IS_INVALID_CHAR(enc, ptr, n) (0) -#endif - -#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_INVALID_CHAR(enc, ptr, n)) { \ - *(nextTokPtr) = (ptr); \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define INVALID_CASES(ptr, nextTokPtr) \ - INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ - INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ - INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ - case BT_NONXML: \ - case BT_MALFORM: \ - case BT_TRAIL: \ - *(nextTokPtr) = (ptr); \ - return XML_TOK_INVALID - -#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (!IS_NAME_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ - case BT_NONASCII: \ - if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - case BT_NMSTRT: \ - case BT_HEX: \ - case BT_DIGIT: \ - case BT_NAME: \ - case BT_MINUS: \ - ptr += MINBPC(enc); \ - break; \ - CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ - CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ - CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) - -#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - ptr += n; \ - break; - -#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ - case BT_NONASCII: \ - if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; \ - } \ - case BT_NMSTRT: \ - case BT_HEX: \ - ptr += MINBPC(enc); \ - break; \ - CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ - CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ - CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) - -#ifndef PREFIX -#define PREFIX(ident) ident -#endif - -/* ptr points to character following " */ - switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { - case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr; - return XML_TOK_DECL_OPEN; - break; - case BT_S: case BT_CR: case BT_LF: - *nextTokPtr = ptr; - return XML_TOK_DECL_OPEN; - case BT_NMSTRT: - case BT_HEX: - ptr += MINBPC(enc); - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -static -int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, - const char * end, - int * tokPtr) -{ - int upper = 0; - *tokPtr = XML_TOK_PI; - if (end - ptr != MINBPC(enc)*3) - return 1; - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_x: - break; - case ASCII_X: - upper = 1; - break; - default: - return 1; - } - ptr += MINBPC(enc); - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_m: - break; - case ASCII_M: - upper = 1; - break; - default: - return 1; - } - ptr += MINBPC(enc); - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_l: - break; - case ASCII_L: - upper = 1; - break; - default: - return 1; - } - if (upper) - return 0; - *tokPtr = XML_TOK_XML_DECL; - return 1; -} - -/* ptr points to character following " 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - if (n == 0) - return XML_TOK_PARTIAL; - end = ptr + n; - } - } - switch (BYTE_TYPE(enc, ptr)) { - case BT_RSQB: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) - break; - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr -= MINBPC(enc); - break; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CDATA_SECT_CLOSE; - case BT_CR: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - case BT_LF: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - INVALID_CASES(ptr, nextTokPtr); - default: - ptr += MINBPC(enc); - break; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ - *nextTokPtr = ptr; \ - return XML_TOK_DATA_CHARS; \ - } \ - ptr += n; \ - break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NONXML: - case BT_MALFORM: - case BT_TRAIL: - case BT_CR: - case BT_LF: - case BT_RSQB: - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -/* ptr points to character following " 1) { - size_t const length = inputEnd - inputStart; - if (length & (MINBPC(enc) - 1)) { - size_t const roundedLen = length & ~(MINBPC(enc) - 1); - *choppedEndP = inputStart + roundedLen; - } else - *choppedEndP = inputEnd; - } else - *choppedEndP = inputEnd; -} - - - -static void -PREFIX(processBtRsqb)(const ENCODING * const enc ATTR_UNUSED, - const char * const start, - const char * const end, - unsigned int * const countP, - bool * const invalidP) { - - if (start + MINBPC(enc) < end) { - if (!CHAR_MATCHES(enc, start + MINBPC(enc), ASCII_RSQB)) { - *countP = MINBPC(enc); - *invalidP = false; - } else { - if (start + 2*MINBPC(enc) < end) { - if (!CHAR_MATCHES(enc, start + 2*MINBPC(enc), ASCII_GT)) { - *countP = MINBPC(enc); - *invalidP = false; - } else { - *countP = 2 * MINBPC(enc); - *invalidP = true; - } - } else { - *countP = 0; - *invalidP = false; - } - } - } else { - *countP = 0; - *invalidP = false; - } -} - - - -static int -PREFIX(contentTok)(const ENCODING * const enc, - const char * const inputStart, - const char * const inputEnd, - const char ** const nextTokPtr) { -/*---------------------------------------------------------------------------- - Parse off a token from the string that starts at 'inputStart' and ends at - 'inputEnd'. Return the class of that token. - - Return *nextTokPtr pointing just after the parsed-off token in the string. - - Sometimes, there is no token we can parse, so our return value is a - disposition code indicating that situation and *nextTokPtr points to the - beginning of the string. ------------------------------------------------------------------------------*/ - if (inputEnd == inputStart) { - *nextTokPtr = inputStart; - return XML_TOK_NONE; - } else { - const char * ptr; - const char * end; - /* The virtual end of the string; we look at only whole - characters; e.g. if there are 2 bytes per character and the - buffer is 9 bytes, we look at only the first 8 and 'end' points - after the 8th byte. - */ - PREFIX(chopToWholeCharacters)(inputStart, inputEnd, &end); - - if (end == inputStart) { - *nextTokPtr = inputStart; - return XML_TOK_PARTIAL; - } - ptr = inputStart; /* Start at the beginning */ - - switch (BYTE_TYPE(enc, ptr)) { - case BT_LT: - return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_AMP: - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_CR: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - case BT_LF: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - case BT_RSQB: - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_RSQB; - if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) - break; - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_RSQB; - if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr -= MINBPC(enc); - break; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - INVALID_CASES(ptr, nextTokPtr); - default: - ptr += MINBPC(enc); - break; - } - while (ptr < end) { - switch (BYTE_TYPE(enc, ptr)) { - LEAD_CASE(2); - LEAD_CASE(3); - LEAD_CASE(4); - case BT_RSQB: { - bool invalid; - unsigned int count; - PREFIX(processBtRsqb)(enc, ptr, end, &count, &invalid); - ptr += count; - if (invalid) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - } break; - case BT_AMP: - case BT_LT: - case BT_NONXML: - case BT_MALFORM: - case BT_TRAIL: - case BT_CR: - case BT_LF: - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - } -} - -#undef LEAD_CASE - - - -/* ptr points to character following "%" */ - -static -int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: - *nextTokPtr = ptr; - return XML_TOK_PERCENT; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_SEMI: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_PARAM_ENTITY_REF; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return XML_TOK_PARTIAL; -} - -static -int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_CR: case BT_LF: case BT_S: - case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: - *nextTokPtr = ptr; - return XML_TOK_POUND_NAME; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return -XML_TOK_POUND_NAME; -} - -static -int PREFIX(scanLit)(int open, const ENCODING *enc, - const char *ptr, const char *end, - const char **nextTokPtr) -{ - while (ptr != end) { - int t = BYTE_TYPE(enc, ptr); - switch (t) { - INVALID_CASES(ptr, nextTokPtr); - case BT_QUOT: - case BT_APOS: - ptr += MINBPC(enc); - if (t != open) - break; - if (ptr == end) - return -XML_TOK_LITERAL; - *nextTokPtr = ptr; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_CR: case BT_LF: - case BT_GT: case BT_PERCNT: case BT_LSQB: - return XML_TOK_LITERAL; - default: - return XML_TOK_INVALID; - } - default: - ptr += MINBPC(enc); - break; - } - } - return XML_TOK_PARTIAL; -} - -static -int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - int tok; - if (ptr == end) - return XML_TOK_NONE; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - if (n == 0) - return XML_TOK_PARTIAL; - end = ptr + n; - } - } - switch (BYTE_TYPE(enc, ptr)) { - case BT_QUOT: - return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_APOS: - return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_LT: - { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; - switch (BYTE_TYPE(enc, ptr)) { - case BT_EXCL: - return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_QUEST: - return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_NMSTRT: - case BT_HEX: - case BT_NONASCII: - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - *nextTokPtr = ptr - MINBPC(enc); - return XML_TOK_INSTANCE_START; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - case BT_CR: - if (ptr + MINBPC(enc) == end) - return -XML_TOK_PROLOG_S; - /* fall through */ - case BT_S: case BT_LF: - for (;;) { - ptr += MINBPC(enc); - if (ptr == end) - break; - switch (BYTE_TYPE(enc, ptr)) { - case BT_S: case BT_LF: - break; - case BT_CR: - /* don't split CR/LF pair */ - if (ptr + MINBPC(enc) == end) { - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; - } - break; - default: - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; - } - } - *nextTokPtr = ptr; - return XML_TOK_PROLOG_S; - case BT_PERCNT: - return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); - case BT_COMMA: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_COMMA; - case BT_LSQB: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_OPEN_BRACKET; - case BT_RSQB: - ptr += MINBPC(enc); - if (ptr == end) - return -XML_TOK_CLOSE_BRACKET; - if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { - *nextTokPtr = ptr + 2*MINBPC(enc); - return XML_TOK_COND_SECT_CLOSE; - } - } - *nextTokPtr = ptr; - return XML_TOK_CLOSE_BRACKET; - case BT_LPAR: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_OPEN_PAREN; - case BT_RPAR: - ptr += MINBPC(enc); - if (ptr == end) - return -XML_TOK_CLOSE_PAREN; - switch (BYTE_TYPE(enc, ptr)) { - case BT_AST: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CLOSE_PAREN_ASTERISK; - case BT_QUEST: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CLOSE_PAREN_QUESTION; - case BT_PLUS: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_CLOSE_PAREN_PLUS; - case BT_CR: case BT_LF: case BT_S: - case BT_GT: case BT_COMMA: case BT_VERBAR: - case BT_RPAR: - *nextTokPtr = ptr; - return XML_TOK_CLOSE_PAREN; - } - *nextTokPtr = ptr; - return XML_TOK_INVALID; - case BT_VERBAR: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_OR; - case BT_GT: - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DECL_CLOSE; - case BT_NUM: - return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - if (end - ptr < n) \ - return XML_TOK_PARTIAL_CHAR; \ - if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NAME; \ - break; \ - } \ - if (IS_NAME_CHAR(enc, ptr, n)) { \ - ptr += n; \ - tok = XML_TOK_NMTOKEN; \ - break; \ - } \ - *nextTokPtr = ptr; \ - return XML_TOK_INVALID; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NMSTRT: - case BT_HEX: - tok = XML_TOK_NAME; - ptr += MINBPC(enc); - break; - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - case BT_COLON: - tok = XML_TOK_NMTOKEN; - ptr += MINBPC(enc); - break; - case BT_NONASCII: - if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NAME; - break; - } - if (IS_NAME_CHAR_MINBPC(enc, ptr)) { - ptr += MINBPC(enc); - tok = XML_TOK_NMTOKEN; - } else { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - break; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - case BT_GT: case BT_RPAR: case BT_COMMA: - case BT_VERBAR: case BT_LSQB: case BT_PERCNT: - case BT_S: case BT_CR: case BT_LF: - *nextTokPtr = ptr; - return tok; - case BT_COLON: - ptr += MINBPC(enc); - switch (tok) { - case XML_TOK_NAME: - if (ptr == end) - return XML_TOK_PARTIAL; - tok = XML_TOK_PREFIXED_NAME; - switch (BYTE_TYPE(enc, ptr)) { - CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) - default: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case XML_TOK_PREFIXED_NAME: - tok = XML_TOK_NMTOKEN; - break; - } - break; - case BT_PLUS: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_PLUS; - case BT_AST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_ASTERISK; - case BT_QUEST: - if (tok == XML_TOK_NMTOKEN) { - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_NAME_QUESTION; - default: - *nextTokPtr = ptr; - return XML_TOK_INVALID; - } - } - return -tok; -} - -static -int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - const char *start; - if (ptr == end) - return XML_TOK_NONE; - start = ptr; - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_AMP: - if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_LT: - /* this is for inside entity references */ - *nextTokPtr = ptr; - return XML_TOK_INVALID; - case BT_LF: - if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_CR: - if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_S: - if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_ATTRIBUTE_VALUE_S; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - -static -int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - const char *start; - if (ptr == end) - return XML_TOK_NONE; - start = ptr; - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { -#define LEAD_CASE(n) \ - case BT_LEAD ## n: ptr += n; break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_AMP: - if (ptr == start) - return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_PERCNT: - if (ptr == start) - return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_LF: - if (ptr == start) { - *nextTokPtr = ptr + MINBPC(enc); - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - case BT_CR: - if (ptr == start) { - ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_TRAILING_CR; - if (BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - *nextTokPtr = ptr; - return XML_TOK_DATA_NEWLINE; - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; - default: - ptr += MINBPC(enc); - break; - } - } - *nextTokPtr = ptr; - return XML_TOK_DATA_CHARS; -} - - - -static -int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - int level = 0; - if (MINBPC(enc) > 1) { - size_t n = end - ptr; - if (n & (MINBPC(enc) - 1)) { - n &= ~(MINBPC(enc) - 1); - end = ptr + n; - } - } - while (ptr != end) { - switch (BYTE_TYPE(enc, ptr)) { - INVALID_CASES(ptr, nextTokPtr); - case BT_LT: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { - ++level; - ptr += MINBPC(enc); - } - } - break; - case BT_RSQB: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; - if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { - ptr += MINBPC(enc); - if (level == 0) { - *nextTokPtr = ptr; - return XML_TOK_IGNORE_SECT; - } - --level; - } - } - break; - default: - ptr += MINBPC(enc); - break; - } - } - return XML_TOK_PARTIAL; -} - - - -static bool -PREFIX(isSpecialChar)(char const c) { - - switch (c) { - case 0x24: /* $ */ - case 0x40: /* @ */ - return true; - default: - return false; - } -} - - - -static -int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, - const char **badPtr) -{ - ptr += MINBPC(enc); - end -= MINBPC(enc); - for (; ptr != end; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_DIGIT: - case BT_HEX: - case BT_MINUS: - case BT_APOS: - case BT_LPAR: - case BT_RPAR: - case BT_PLUS: - case BT_COMMA: - case BT_SOL: - case BT_EQUALS: - case BT_QUEST: - case BT_CR: - case BT_LF: - case BT_SEMI: - case BT_EXCL: - case BT_AST: - case BT_PERCNT: - case BT_NUM: - case BT_COLON: - break; - case BT_S: - if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { - *badPtr = ptr; - return 0; - } - break; - case BT_NAME: - case BT_NMSTRT: - if (BYTE_TO_ASCII(enc, ptr) & ~0x7f) { - if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { - *badPtr = ptr; - return 0; - } - } - break; - default: - if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { - *badPtr = ptr; - return 0; - } - } - } - return 1; -} - -/* This must only be called for a well-formed start-tag or empty element tag. -Returns the number of attributes. Pointers to the first attsMax attributes -are stored in atts. */ - -static -int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, - int attsMax, ATTRIBUTE *atts) -{ - enum { other, inName, inValue } state = inName; - int nAtts = 0; - int open = 0; /* defined when state == inValue; - initialization just to shut up compilers */ - - for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { - switch (BYTE_TYPE(enc, ptr)) { -#define START_NAME \ - if (state == other) { \ - if (nAtts < attsMax) { \ - atts[nAtts].name = ptr; \ - atts[nAtts].normalized = 1; \ - } \ - state = inName; \ - } -#define LEAD_CASE(n) \ - case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; - LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) -#undef LEAD_CASE - case BT_NONASCII: - case BT_NMSTRT: - case BT_HEX: - START_NAME - break; -#undef START_NAME - case BT_QUOT: - if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); - state = inValue; - open = BT_QUOT; - } - else if (open == BT_QUOT) { - state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; - } - break; - case BT_APOS: - if (state != inValue) { - if (nAtts < attsMax) - atts[nAtts].valuePtr = ptr + MINBPC(enc); - state = inValue; - open = BT_APOS; - } - else if (open == BT_APOS) { - state = other; - if (nAtts < attsMax) - atts[nAtts].valueEnd = ptr; - nAtts++; - } - break; - case BT_AMP: - if (nAtts < attsMax) - atts[nAtts].normalized = 0; - break; - case BT_S: - if (state == inName) - state = other; - else if (state == inValue - && nAtts < attsMax - && atts[nAtts].normalized - && (ptr == atts[nAtts].valuePtr - || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE - || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE - || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) - atts[nAtts].normalized = 0; - break; - case BT_CR: case BT_LF: - /* This case ensures that the first attribute name is counted - Apart from that we could just change state on the quote. */ - if (state == inName) - state = other; - else if (state == inValue && nAtts < attsMax) - atts[nAtts].normalized = 0; - break; - case BT_GT: - case BT_SOL: - if (state != inValue) - return nAtts; - break; - default: - break; - } - } - /* not reached */ -} - -static -int PREFIX(charRefNumber)(const ENCODING *enc ATTR_UNUSED, const char *ptr) -{ - int result = 0; - /* skip &# */ - ptr += 2*MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_x)) { - for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { - int c = BYTE_TO_ASCII(enc, ptr); - switch (c) { - case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: - case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: - result <<= 4; - result |= (c - ASCII_0); - break; - case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F: - result <<= 4; - result += 10 + (c - ASCII_A); - break; - case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f: - result <<= 4; - result += 10 + (c - ASCII_a); - break; - } - if (result >= 0x110000) - return -1; - } - } - else { - for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { - int c = BYTE_TO_ASCII(enc, ptr); - result *= 10; - result += (c - ASCII_0); - if (result >= 0x110000) - return -1; - } - } - return checkCharRefNumber(result); -} - -static -int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, - const char * ptr, - const char * end) -{ - switch ((end - ptr)/MINBPC(enc)) { - case 2: - if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_l: - return ASCII_LT; - case ASCII_g: - return ASCII_GT; - } - } - break; - case 3: - if (CHAR_MATCHES(enc, ptr, ASCII_a)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_m)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_p)) - return ASCII_AMP; - } - } - break; - case 4: - switch (BYTE_TO_ASCII(enc, ptr)) { - case ASCII_q: - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_u)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_t)) - return ASCII_QUOT; - } - } - break; - case ASCII_a: - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_p)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_o)) { - ptr += MINBPC(enc); - if (CHAR_MATCHES(enc, ptr, ASCII_s)) - return ASCII_APOS; - } - } - break; - } - } - return 0; -} - -static -int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) -{ - for (;;) { - switch (BYTE_TYPE(enc, ptr1)) { - case BT_LEAD4: - if (*ptr1++ != *ptr2++) - return 0; - if (*ptr1++ != *ptr2++) - return 0; - if (*ptr1++ != *ptr2++) - return 0; - if (*ptr1++ != *ptr2++) - return 0; - break; - case BT_LEAD3: - if (*ptr1++ != *ptr2++) - return 0; - if (*ptr1++ != *ptr2++) - return 0; - if (*ptr1++ != *ptr2++) - return 0; - break; - case BT_LEAD2: - if (*ptr1++ != *ptr2++) - return 0; - if (*ptr1++ != *ptr2++) - return 0; - break; - case BT_NONASCII: - case BT_NMSTRT: - case BT_COLON: - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 1) { - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 2) { - if (*ptr2++ != *ptr1++) - return 0; - if (MINBPC(enc) > 3) { - if (*ptr2++ != *ptr1++) - return 0; - } - } - } - break; - default: - if (MINBPC(enc) == 1 && *ptr1 == *ptr2) - return 1; - switch (BYTE_TYPE(enc, ptr2)) { - case BT_LEAD2: - case BT_LEAD3: - case BT_LEAD4: - case BT_NONASCII: - case BT_NMSTRT: - case BT_COLON: - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - return 0; - default: - return 1; - } - } - } - /* not reached */ -} - -static -int PREFIX(nameMatchesAscii)(const ENCODING * enc ATTR_UNUSED, - const char * ptr1, - const char * end1, - const char * ptr2) -{ - for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { - if (ptr1 == end1) - return 0; - if (!CHAR_MATCHES(enc, ptr1, *ptr2)) - return 0; - } - return ptr1 == end1; -} - - - -#define LEAD_CASE(n) case BT_LEAD ## n: ptr += n; break - -static size_t -PREFIX(nameLength)(const ENCODING * const enc, - const char * const start) { - - const char * ptr; - - for (ptr = start;;) { - switch (BYTE_TYPE(enc, ptr)) { - LEAD_CASE(2); - LEAD_CASE(3); - LEAD_CASE(4); - case BT_NONASCII: - case BT_NMSTRT: - case BT_COLON: - case BT_HEX: - case BT_DIGIT: - case BT_NAME: - case BT_MINUS: - ptr += MINBPC(enc); - break; - default: - return ptr - start; - } - } -} -#undef LEAD_CASE - - - -static -const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr) -{ - for (;;) { - switch (BYTE_TYPE(enc, ptr)) { - case BT_LF: - case BT_CR: - case BT_S: - ptr += MINBPC(enc); - break; - default: - return ptr; - } - } -} - - - -#define LEAD_CASE(n) \ - case BT_LEAD ## n: \ - ptr += n; \ - break - -static void -PREFIX(updatePosition)(const ENCODING * const enc, - const char * const start, - const char * const end, - POSITION * const posP) { - - const char * ptr; - - for (ptr = start; ptr < end;) { - switch (BYTE_TYPE(enc, ptr)) { - LEAD_CASE(2); - LEAD_CASE(3); - LEAD_CASE(4); - case BT_LF: - posP->columnNumber = (unsigned)-1; - ++posP->lineNumber; - ptr += MINBPC(enc); - break; - case BT_CR: - ++posP->lineNumber; - ptr += MINBPC(enc); - if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) - ptr += MINBPC(enc); - posP->columnNumber = (unsigned)-1; - break; - default: - ptr += MINBPC(enc); - break; - } - ++posP->columnNumber; - } -} - -#undef LEAD_CASE - - -#undef DO_LEAD_CASE -#undef MULTIBYTE_CASES -#undef INVALID_CASES -#undef CHECK_NAME_CASE -#undef CHECK_NAME_CASES -#undef CHECK_NMSTRT_CASE -#undef CHECK_NMSTRT_CASES diff --git a/trunk/lib/expat/xmltok/xmltok_impl.h b/trunk/lib/expat/xmltok/xmltok_impl.h deleted file mode 100644 index eb92802a0..000000000 --- a/trunk/lib/expat/xmltok/xmltok_impl.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -enum { - BT_NONXML, - BT_MALFORM, - BT_LT, - BT_AMP, - BT_RSQB, - BT_LEAD2, - BT_LEAD3, - BT_LEAD4, - BT_TRAIL, - BT_CR, - BT_LF, - BT_GT, - BT_QUOT, - BT_APOS, - BT_EQUALS, - BT_QUEST, - BT_EXCL, - BT_SOL, - BT_SEMI, - BT_NUM, - BT_LSQB, - BT_S, - BT_NMSTRT, - BT_COLON, - BT_HEX, - BT_DIGIT, - BT_NAME, - BT_MINUS, - BT_OTHER, /* known not to be a name or name start character */ - BT_NONASCII, /* might be a name or name start character */ - BT_PERCNT, - BT_LPAR, - BT_RPAR, - BT_AST, - BT_PLUS, - BT_COMMA, - BT_VERBAR -}; - -#include diff --git a/trunk/lib/expat/xmltok/xmltok_ns.c b/trunk/lib/expat/xmltok/xmltok_ns.c deleted file mode 100644 index 739399b6b..000000000 --- a/trunk/lib/expat/xmltok/xmltok_ns.c +++ /dev/null @@ -1,148 +0,0 @@ -const ENCODING * -NS(xmlrpc_XmlGetUtf8InternalEncoding)(void) { - - return &ns(internal_utf8_encoding).enc; -} - - - -const ENCODING * -NS(xmlrpc_XmlGetUtf16InternalEncoding)(void) { - -#if XML_BYTE_ORDER == 12 - return &ns(internal_little2_encoding).enc; -#elif XML_BYTE_ORDER == 21 - return &ns(internal_big2_encoding).enc; -#else - const short n = 1; - return *(const char *)&n ? - &ns(internal_little2_encoding).enc : - &ns(internal_big2_encoding).enc; -#endif -} - -static -const ENCODING *NS(encodings)[] = { - &ns(latin1_encoding).enc, - &ns(ascii_encoding).enc, - &ns(utf8_encoding).enc, - &ns(big2_encoding).enc, - &ns(big2_encoding).enc, - &ns(little2_encoding).enc, - &ns(utf8_encoding).enc /* NO_ENC */ -}; - -static -int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr); -} - -static -int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, - const char **nextTokPtr) -{ - return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr); -} - - - -int -NS(xmlrpc_XmlInitEncoding)(INIT_ENCODING * const p, - const ENCODING ** const encPP, - const char * const name) { - - int const index = getEncodingIndex(name); - - int retval; - - if (index == UNKNOWN_ENC) - retval = 0; - else { - SET_INIT_ENC_INDEX(p, index); - p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); - p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); - p->initEnc.updatePosition = initUpdatePosition; - p->encPtr = encPP; - *encPP = &(p->initEnc); - - retval = 1; - } - return retval; -} - - - -static -const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) -{ -#define ENCODING_MAX 128 - char buf[ENCODING_MAX]; - char *p = buf; - int i; - XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); - if (ptr != end) - return 0; - *p = 0; - if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) - return enc; - i = getEncodingIndex(buf); - if (i == UNKNOWN_ENC) - return 0; - return NS(encodings)[i]; -} - - - -int -NS(xmlrpc_XmlParseXmlDecl)(int const isGeneralTextEntity, - const ENCODING * const encodingOfDecl, - const char * const piText, - const char * const end, - const char ** const badP, - const char ** const versionP, - const char ** const encodingNameP, - const ENCODING ** const encodingPP, - int * const standaloneP) { -/*---------------------------------------------------------------------------- - Parse an XML declaration XML Processing Instruction (PI), i.e. - ". - - 'piText' points to the beginning of the PI (to the "<"). - - 'end' points to the end of the PI (just past the ">"). - - 'encodingOfDecl' is the character encoding of the declaration. - - Return as *encodingNameP the value of the "encoding" pseudo-attribute in - the declaration. Furthermore, return as *encodingPP a handle for the - encoding so named, or NULL if we don't recognize the name. - - Return as *standaloneP 1 if the value of the "standalone" pseudo-attribute - in the declaration is "yes"; 0 if it is "no". - - Return as *versionP the value of the "version" pseudo-attribute in the - declaration. - - For all the return values, the pointer may be null, and in that case we - just don't return that information. - - For all the return values, if the pseudo-attribute does not appear in - the declaration, we just leave the pointed-to variable unchanged. - (THIS IS WRONG; WE NEED TO FIX THIS). - - Iff the declaration has invalid syntax, return return value 1 and return as - *badP a pointer to the part of the declaration that is bad. ------------------------------------------------------------------------------*/ - return doParseXmlDecl(NS(findEncoding), - isGeneralTextEntity, - encodingOfDecl, - piText, - end, - badP, - versionP, - encodingNameP, - encodingPP, - standaloneP); -} diff --git a/trunk/lib/expat/xmlwf/Makefile.in b/trunk/lib/expat/xmlwf/Makefile.in deleted file mode 100644 index 08601470c..000000000 --- a/trunk/lib/expat/xmlwf/Makefile.in +++ /dev/null @@ -1,209 +0,0 @@ -# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = ../../.. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ -ABYSS_SUBDIR = @ABYSS_SUBDIR@ -AS = @AS@ -ASYNCH_CLIENT = @ASYNCH_CLIENT@ -AUTH_CLIENT = @AUTH_CLIENT@ -AVAILABLE_MODULES = @AVAILABLE_MODULES@ -CC = @CC@ -CC_WARN_FLAGS = @CC_WARN_FLAGS@ -CLIENTTEST = @CLIENTTEST@ -CONFIGURE_DATE = @CONFIGURE_DATE@ -CPPTEST = @CPPTEST@ -CPP_WARN_FLAGS = @CPP_WARN_FLAGS@ -CXX = @CXX@ -DLLTOOL = @DLLTOOL@ -EFRPCTEST = @EFRPCTEST@ -EFRPCTEST_WRAPPER = @EFRPCTEST_WRAPPER@ -INTEROP_CGI = @INTEROP_CGI@ -INTEROP_CLIENT_SUBDIR = @INTEROP_CLIENT_SUBDIR@ -LIBTOOL = @LIBTOOL@ -LIBWWW_CFLAGS = @LIBWWW_CFLAGS@ -LIBWWW_CONFIG = @LIBWWW_CONFIG@ -LIBWWW_LDADD = @LIBWWW_LDADD@ -LIBWWW_LIBDIR = @LIBWWW_LIBDIR@ -LIBWWW_RPATH = @LIBWWW_RPATH@ -LIBWWW_WL_RPATH = @LIBWWW_WL_RPATH@ -LIBXMLRPC_ABYSS_SERVER_LA = @LIBXMLRPC_ABYSS_SERVER_LA@ -LIBXMLRPC_CGI_LA = @LIBXMLRPC_CGI_LA@ -LIBXMLRPC_CLIENT_LA = @LIBXMLRPC_CLIENT_LA@ -LIBXMLRPC_CPP_A = @LIBXMLRPC_CPP_A@ -LN_S = @LN_S@ -MAKEINFO = @MAKEINFO@ -MEERKAT_APP_LIST = @MEERKAT_APP_LIST@ -OBJDUMP = @OBJDUMP@ -PACKAGE = @PACKAGE@ -QUERY_MEERKAT = @QUERY_MEERKAT@ -RANLIB = @RANLIB@ -SAMPLE_CGI_CGI = @SAMPLE_CGI_CGI@ -SERVER = @SERVER@ -SERVERTEST = @SERVERTEST@ -SYNCH_CLIENT = @SYNCH_CLIENT@ -VALIDATEE = @VALIDATEE@ -VERSION = @VERSION@ -VERSION_INFO = @VERSION_INFO@ -XMLRPCCPP_H = @XMLRPCCPP_H@ -XMLRPC_ABYSS_H = @XMLRPC_ABYSS_H@ -XMLRPC_CGI_H = @XMLRPC_CGI_H@ -XMLRPC_CLIENT_H = @XMLRPC_CLIENT_H@ -XML_RPC_API2CPP_SUBDIR = @XML_RPC_API2CPP_SUBDIR@ - -EXTRA_DIST = codepage.c filemap.h unixfilemap.c xmlfile.c xmltchar.h xmlwf.dsp codepage.h readfilemap.c win32filemap.c xmlfile.h xmlwf.c - -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = ../../../xmlrpc_config.h -CONFIG_CLEAN_FILES = -DIST_COMMON = Makefile.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -all: all-redirect -.SUFFIXES: - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - -tags: TAGS -TAGS: - - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -subdir = lib/expat/xmlwf - -distdir: $(DISTFILES) - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: all-am -check: check-am -installcheck-am: -installcheck: installcheck-am -install-exec-am: -install-exec: install-exec-am - -install-data-am: -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: -uninstall: uninstall-am -all-am: Makefile -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-generic mostlyclean-am - -clean: clean-am - -distclean-am: distclean-generic clean-am - -rm -f libtool - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: tags distdir info-am info dvi-am dvi check check-am \ -installcheck-am installcheck install-exec-am install-exec \ -install-data-am install-data install-am install uninstall-am uninstall \ -all-redirect all-am all installdirs mostlyclean-generic \ -distclean-generic clean-generic maintainer-clean-generic clean \ -mostlyclean distclean maintainer-clean - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/trunk/lib/expat/xmlwf/codepage.c b/trunk/lib/expat/xmlwf/codepage.c deleted file mode 100644 index 2e1d13af5..000000000 --- a/trunk/lib/expat/xmlwf/codepage.c +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#include "xmlrpc_config.h" - -#include "codepage.h" - -#if MSVCRT -#define STRICT 1 -#define WIN32_LEAN_AND_MEAN -#include - -int codepageMap(int cp, int *map) -{ - int i; - CPINFO info; - if (!GetCPInfo(cp, &info) || info.MaxCharSize > 2) - return 0; - for (i = 0; i < 256; i++) - map[i] = -1; - if (info.MaxCharSize > 1) { - for (i = 0; i < MAX_LEADBYTES; i++) { - int j, lim; - if (info.LeadByte[i] == 0 && info.LeadByte[i + 1] == 0) - break; - lim = info.LeadByte[i + 1]; - for (j = info.LeadByte[i]; j < lim; j++) - map[j] = -2; - } - } - for (i = 0; i < 256; i++) { - if (map[i] == -1) { - char c = i; - unsigned short n; - if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, - &c, 1, &n, 1) == 1) - map[i] = n; - } - } - return 1; -} - -int codepageConvert(int cp, const char *p) -{ - unsigned short c; - if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, - p, 2, &c, 1) == 1) - return c; - return -1; -} - -#else /* MSVCRT */ - -int codepageMap(int cp, int *map) -{ - return 0; -} - -int codepageConvert(int cp, const char *p) -{ - return -1; -} - -#endif /* MSVCRT */ diff --git a/trunk/lib/expat/xmlwf/codepage.h b/trunk/lib/expat/xmlwf/codepage.h deleted file mode 100644 index b19a7f66b..000000000 --- a/trunk/lib/expat/xmlwf/codepage.h +++ /dev/null @@ -1,7 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -int codepageMap(int cp, int *map); -int codepageConvert(int cp, const char *p); diff --git a/trunk/lib/expat/xmlwf/filemap.h b/trunk/lib/expat/xmlwf/filemap.h deleted file mode 100644 index a0a18474f..000000000 --- a/trunk/lib/expat/xmlwf/filemap.h +++ /dev/null @@ -1,17 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - - -#include - -#ifdef XML_UNICODE -int filemap(const wchar_t *name, - void (*processor)(const void *, size_t, const wchar_t *, void *arg), - void *arg); -#else -int filemap(const char *name, - void (*processor)(const void *, size_t, const char *, void *arg), - void *arg); -#endif diff --git a/trunk/lib/expat/xmlwf/readfilemap.c b/trunk/lib/expat/xmlwf/readfilemap.c deleted file mode 100644 index 249af3ec0..000000000 --- a/trunk/lib/expat/xmlwf/readfilemap.c +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#include -#include -#include -#include -#include - -#ifndef S_ISREG -#ifndef S_IFREG -#define S_IFREG _S_IFREG -#endif -#ifndef S_IFMT -#define S_IFMT _S_IFMT -#endif -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif /* not S_ISREG */ - -#ifndef O_BINARY -#ifdef _O_BINARY -#define O_BINARY _O_BINARY -#else -#define O_BINARY 0 -#endif -#endif - -int filemap(const char *name, - void (*processor)(const void *, size_t, const char *, void *arg), - void *arg) -{ - size_t nbytes; - int fd; - int n; - struct stat sb; - void *p; - - fd = open(name, O_RDONLY|O_BINARY); - if (fd < 0) { - perror(name); - return 0; - } - if (fstat(fd, &sb) < 0) { - perror(name); - return 0; - } - if (!S_ISREG(sb.st_mode)) { - fprintf(stderr, "%s: not a regular file\n", name); - return 0; - } - nbytes = sb.st_size; - p = malloc(nbytes); - if (!p) { - fprintf(stderr, "%s: out of memory\n", name); - return 0; - } - n = read(fd, p, nbytes); - if (n < 0) { - perror(name); - close(fd); - return 0; - } - if (n != nbytes) { - fprintf(stderr, "%s: read unexpected number of bytes\n", name); - close(fd); - return 0; - } - processor(p, nbytes, name, arg); - free(p); - close(fd); - return 1; -} diff --git a/trunk/lib/expat/xmlwf/unixfilemap.c b/trunk/lib/expat/xmlwf/unixfilemap.c deleted file mode 100644 index 4944b02ac..000000000 --- a/trunk/lib/expat/xmlwf/unixfilemap.c +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -#include "filemap.h" - -int filemap(const char *name, - void (*processor)(const void *, size_t, const char *, void *arg), - void *arg) -{ - int fd; - size_t nbytes; - struct stat sb; - void *p; - - fd = open(name, O_RDONLY); - if (fd < 0) { - perror(name); - return 0; - } - if (fstat(fd, &sb) < 0) { - perror(name); - close(fd); - return 0; - } - if (!S_ISREG(sb.st_mode)) { - close(fd); - fprintf(stderr, "%s: not a regular file\n", name); - return 0; - } - - nbytes = sb.st_size; - p = (void *)mmap((caddr_t)0, (size_t)nbytes, PROT_READ, - MAP_FILE|MAP_PRIVATE, fd, (off_t)0); - if (p == (void *)-1) { - perror(name); - close(fd); - return 0; - } - processor(p, nbytes, name, arg); - munmap((caddr_t)p, nbytes); - close(fd); - return 1; -} diff --git a/trunk/lib/expat/xmlwf/win32filemap.c b/trunk/lib/expat/xmlwf/win32filemap.c deleted file mode 100644 index 79b9f47d3..000000000 --- a/trunk/lib/expat/xmlwf/win32filemap.c +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#define STRICT 1 -#define WIN32_LEAN_AND_MEAN 1 - -#ifdef XML_UNICODE_WCHAR_T -#ifndef XML_UNICODE -#define XML_UNICODE -#endif -#endif - -#ifdef XML_UNICODE -#define UNICODE -#define _UNICODE -#endif /* XML_UNICODE */ -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include "filemap.h" - -static void win32perror(const TCHAR *); - -int filemap(const TCHAR *name, - void (*processor)(const void *, size_t, const TCHAR *, void *arg), - void *arg) -{ - HANDLE f; - HANDLE m; - DWORD size; - DWORD sizeHi; - void *p; - - f = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (f == INVALID_HANDLE_VALUE) { - win32perror(name); - return 0; - } - size = GetFileSize(f, &sizeHi); - if (size == (DWORD)-1) { - win32perror(name); - return 0; - } - if (sizeHi) { - _ftprintf(stderr, _T("%s: bigger than 2Gb\n"), name); - return 0; - } - /* CreateFileMapping barfs on zero length files */ - if (size == 0) { - static const char c = '\0'; - processor(&c, 0, name, arg); - CloseHandle(f); - return 1; - } - m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL); - if (m == NULL) { - win32perror(name); - CloseHandle(f); - return 0; - } - p = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0); - if (p == NULL) { - win32perror(name); - CloseHandle(m); - CloseHandle(f); - return 0; - } - processor(p, size, name, arg); - UnmapViewOfFile(p); - CloseHandle(m); - CloseHandle(f); - return 1; -} - -static -void win32perror(const TCHAR *s) -{ - LPVOID buf; - if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &buf, - 0, - NULL)) { - _ftprintf(stderr, _T("%s: %s"), s, buf); - fflush(stderr); - LocalFree(buf); - } - else - _ftprintf(stderr, _T("%s: unknown Windows error\n"), s); -} diff --git a/trunk/lib/expat/xmlwf/xmlfile.c b/trunk/lib/expat/xmlwf/xmlfile.c deleted file mode 100644 index b7403d63e..000000000 --- a/trunk/lib/expat/xmlwf/xmlfile.c +++ /dev/null @@ -1,223 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "xmlparse.h" -#include "xmlfile.h" -#include "xmltchar.h" -#include "filemap.h" - -#if MSVCRT -#include -#endif - -#ifdef _XOPEN_SOURCE 600 -#include -#endif - -#ifndef O_BINARY -#ifdef _O_BINARY -#define O_BINARY _O_BINARY -#else -#define O_BINARY 0 -#endif -#endif - -#ifdef _DEBUG -#define READ_SIZE 16 -#else -#define READ_SIZE (1024*8) -#endif - - - -typedef struct { - XML_Parser parser; - int *retPtr; -} PROCESS_ARGS; - -static -void reportError(XML_Parser parser, const XML_Char *filename) -{ - int code = XML_GetErrorCode(parser); - const XML_Char *message = XML_ErrorString(code); - if (message) - ftprintf(stdout, T("%s:%d:%d: %s\n"), - filename, - XML_GetErrorLineNumber(parser), - XML_GetErrorColumnNumber(parser), - message); - else - ftprintf(stderr, T("%s: (unknown message %d)\n"), filename, code); -} - -static -void processFile(const void *data, - size_t size, - const XML_Char *filename, - void *args) -{ - XML_Parser parser = ((PROCESS_ARGS *)args)->parser; - int *retPtr = ((PROCESS_ARGS *)args)->retPtr; - if (!XML_Parse(parser, data, size, 1)) { - reportError(parser, filename); - *retPtr = 0; - } - else - *retPtr = 1; -} - -#if MSVCRT - -static -int isAsciiLetter(XML_Char c) -{ - return (T('a') <= c && c <= T('z')) || (T('A') <= c && c <= T('Z')); -} - -#endif /* MSVCRT */ - -static -const XML_Char * -resolveSystemId(const XML_Char *base, - const XML_Char *systemId, - XML_Char **toFree) -{ - XML_Char *s; - *toFree = 0; - if (!base - || *systemId == T('/') -#if MSVCRT - || *systemId == T('\\') - || (isAsciiLetter(systemId[0]) && systemId[1] == T(':')) -#endif - ) - return systemId; - *toFree = (XML_Char *) - malloc((tcslen(base) + tcslen(systemId) + 2)*sizeof(XML_Char)); - if (!*toFree) - return systemId; - tcscpy(*toFree, base); - s = *toFree; - if (tcsrchr(s, T('/'))) - s = tcsrchr(s, T('/')) + 1; -#if MSVCRT - if (tcsrchr(s, T('\\'))) - s = tcsrchr(s, T('\\')) + 1; -#endif - tcscpy(s, systemId); - return *toFree; -} - -static -int externalEntityRefFilemap(XML_Parser parser, - const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) -{ - int result; - XML_Char *s; - const XML_Char *filename; - XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0); - PROCESS_ARGS args; - args.retPtr = &result; - args.parser = entParser; - filename = resolveSystemId(base, systemId, &s); - XML_SetBase(entParser, filename); - if (!filemap(filename, processFile, &args)) - result = 0; - free(s); - XML_ParserFree(entParser); - return result; -} - -static -int processStream(const XML_Char *filename, XML_Parser parser) -{ - int fd = topen(filename, O_BINARY|O_RDONLY); - if (fd < 0) { - tperror(filename); - return 0; - } - for (;;) { - int nread; - char *buf = XML_GetBuffer(parser, READ_SIZE); - if (!buf) { - close(fd); - ftprintf(stderr, T("%s: out of memory\n"), filename); - return 0; - } - nread = read(fd, buf, READ_SIZE); - if (nread < 0) { - tperror(filename); - close(fd); - return 0; - } - if (!XML_ParseBuffer(parser, nread, nread == 0)) { - reportError(parser, filename); - close(fd); - return 0; - } - if (nread == 0) { - close(fd); - break;; - } - } - return 1; -} - -static -int externalEntityRefStream(XML_Parser parser, - const XML_Char *context, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) -{ - XML_Char *s; - const XML_Char *filename; - int ret; - XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0); - filename = resolveSystemId(base, systemId, &s); - XML_SetBase(entParser, filename); - ret = processStream(filename, entParser); - free(s); - XML_ParserFree(entParser); - return ret; -} - -int XML_ProcessFile(XML_Parser parser, - const XML_Char *filename, - unsigned flags) -{ - int result; - - if (!XML_SetBase(parser, filename)) { - ftprintf(stderr, T("%s: out of memory"), filename); - exit(1); - } - - if (flags & XML_EXTERNAL_ENTITIES) - XML_SetExternalEntityRefHandler(parser, - (flags & XML_MAP_FILE) - ? externalEntityRefFilemap - : externalEntityRefStream); - if (flags & XML_MAP_FILE) { - PROCESS_ARGS args; - args.retPtr = &result; - args.parser = parser; - if (!filemap(filename, processFile, &args)) - result = 0; - } - else - result = processStream(filename, parser); - return result; -} diff --git a/trunk/lib/expat/xmlwf/xmlfile.h b/trunk/lib/expat/xmlwf/xmlfile.h deleted file mode 100644 index 0c7ac1935..000000000 --- a/trunk/lib/expat/xmlwf/xmlfile.h +++ /dev/null @@ -1,11 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#define XML_MAP_FILE 01 -#define XML_EXTERNAL_ENTITIES 02 - -extern int XML_ProcessFile(XML_Parser parser, - const XML_Char *filename, - unsigned flags); diff --git a/trunk/lib/expat/xmlwf/xmltchar.h b/trunk/lib/expat/xmlwf/xmltchar.h deleted file mode 100644 index 108857551..000000000 --- a/trunk/lib/expat/xmlwf/xmltchar.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifdef XML_UNICODE -#ifndef XML_UNICODE_WCHAR_T -#error xmlwf requires a 16-bit Unicode-compatible wchar_t -#endif -#define T(x) L ## x -#define ftprintf fwprintf -#define tfopen _wfopen -#define fputts fputws -#define puttc putwc -#define tcscmp wcscmp -#define tcscpy wcscpy -#define tcscat wcscat -#define tcschr wcschr -#define tcsrchr wcsrchr -#define tcslen wcslen -#define tperror _wperror -#define topen _wopen -#define tmain wmain -#define tremove _wremove -#else /* not XML_UNICODE */ -#define T(x) x -#define ftprintf fprintf -#define tfopen fopen -#define fputts fputs -#define puttc putc -#define tcscmp strcmp -#define tcscpy strcpy -#define tcscat strcat -#define tcschr strchr -#define tcsrchr strrchr -#define tcslen strlen -#define tperror perror -#define topen open -#define tmain main -#define tremove remove -#endif /* not XML_UNICODE */ diff --git a/trunk/lib/expat/xmlwf/xmlwf.c b/trunk/lib/expat/xmlwf/xmlwf.c deleted file mode 100644 index cdfc21c87..000000000 --- a/trunk/lib/expat/xmlwf/xmlwf.c +++ /dev/null @@ -1,767 +0,0 @@ -/* -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd -See the file copying.txt for copying permission. -*/ - -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "xmlparse.h" -#include "codepage.h" -#include "xmlfile.h" -#include "xmltchar.h" - -#if MSVCRT -#include -#endif - -/* This ensures proper sorting. */ - -#define NSSEP T('\001') - -static void characterData(void *userData, const XML_Char *s, int len) -{ - FILE *fp = userData; - for (; len > 0; --len, ++s) { - switch (*s) { - case T('&'): - fputts(T("&"), fp); - break; - case T('<'): - fputts(T("<"), fp); - break; - case T('>'): - fputts(T(">"), fp); - break; -#ifdef W3C14N - case 13: - fputts(T(" "), fp); - break; -#else - case T('"'): - fputts(T("""), fp); - break; - case 9: - case 10: - case 13: - ftprintf(fp, T("&#%d;"), *s); - break; -#endif - default: - puttc(*s, fp); - break; - } - } -} - -static void attributeValue(FILE *fp, const XML_Char *s) -{ - puttc(T('='), fp); - puttc(T('"'), fp); - for (;;) { - switch (*s) { - case 0: - case NSSEP: - puttc(T('"'), fp); - return; - case T('&'): - fputts(T("&"), fp); - break; - case T('<'): - fputts(T("<"), fp); - break; - case T('"'): - fputts(T("""), fp); - break; -#ifdef W3C14N - case 9: - fputts(T(" "), fp); - break; - case 10: - fputts(T(" "), fp); - break; - case 13: - fputts(T(" "), fp); - break; -#else - case T('>'): - fputts(T(">"), fp); - break; - case 9: - case 10: - case 13: - ftprintf(fp, T("&#%d;"), *s); - break; -#endif - default: - puttc(*s, fp); - break; - } - s++; - } -} - -/* Lexicographically comparing UTF-8 encoded attribute values, -is equivalent to lexicographically comparing based on the character number. */ - -static int attcmp(const void *att1, const void *att2) -{ - return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2); -} - -static void startElement(void *userData, const XML_Char *name, const XML_Char **atts) -{ - int nAtts; - const XML_Char **p; - FILE *fp = userData; - puttc(T('<'), fp); - fputts(name, fp); - - p = atts; - while (*p) - ++p; - nAtts = (p - atts) >> 1; - if (nAtts > 1) - qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp); - while (*atts) { - puttc(T(' '), fp); - fputts(*atts++, fp); - attributeValue(fp, *atts); - atts++; - } - puttc(T('>'), fp); -} - -static void endElement(void *userData, const XML_Char *name) -{ - FILE *fp = userData; - puttc(T('<'), fp); - puttc(T('/'), fp); - fputts(name, fp); - puttc(T('>'), fp); -} - -static int nsattcmp(const void *p1, const void *p2) -{ - const XML_Char *att1 = *(const XML_Char **)p1; - const XML_Char *att2 = *(const XML_Char **)p2; - int sep1 = (tcsrchr(att1, NSSEP) != 0); - int sep2 = (tcsrchr(att1, NSSEP) != 0); - if (sep1 != sep2) - return sep1 - sep2; - return tcscmp(att1, att2); -} - -static void startElementNS(void *userData, const XML_Char *name, const XML_Char **atts) -{ - int nAtts; - int nsi; - const XML_Char **p; - FILE *fp = userData; - const XML_Char *sep; - puttc(T('<'), fp); - - sep = tcsrchr(name, NSSEP); - if (sep) { - fputts(T("n1:"), fp); - fputts(sep + 1, fp); - fputts(T(" xmlns:n1"), fp); - attributeValue(fp, name); - nsi = 2; - } - else { - fputts(name, fp); - nsi = 1; - } - - p = atts; - while (*p) - ++p; - nAtts = (p - atts) >> 1; - if (nAtts > 1) - qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, nsattcmp); - while (*atts) { - name = *atts++; - sep = tcsrchr(name, NSSEP); - puttc(T(' '), fp); - if (sep) { - ftprintf(fp, T("n%d:"), nsi); - fputts(sep + 1, fp); - } - else - fputts(name, fp); - attributeValue(fp, *atts); - if (sep) { - ftprintf(fp, T(" xmlns:n%d"), nsi++); - attributeValue(fp, name); - } - atts++; - } - puttc(T('>'), fp); -} - -static void endElementNS(void *userData, const XML_Char *name) -{ - FILE *fp = userData; - const XML_Char *sep; - puttc(T('<'), fp); - puttc(T('/'), fp); - sep = tcsrchr(name, NSSEP); - if (sep) { - fputts(T("n1:"), fp); - fputts(sep + 1, fp); - } - else - fputts(name, fp); - puttc(T('>'), fp); -} - -#ifndef W3C14N - -static void processingInstruction(void *userData, const XML_Char *target, const XML_Char *data) -{ - FILE *fp = userData; - puttc(T('<'), fp); - puttc(T('?'), fp); - fputts(target, fp); - puttc(T(' '), fp); - fputts(data, fp); - puttc(T('?'), fp); - puttc(T('>'), fp); -} - -#endif /* not W3C14N */ - -static void defaultCharacterData(XML_Parser parser, const XML_Char *s, int len) -{ - XML_DefaultCurrent(parser); -} - -static void defaultStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts) -{ - XML_DefaultCurrent(parser); -} - -static void defaultEndElement(XML_Parser parser, const XML_Char *name) -{ - XML_DefaultCurrent(parser); -} - -static void defaultProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data) -{ - XML_DefaultCurrent(parser); -} - -static void nopCharacterData(XML_Parser parser, const XML_Char *s, int len) -{ -} - -static void nopStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts) -{ -} - -static void nopEndElement(XML_Parser parser, const XML_Char *name) -{ -} - -static void nopProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data) -{ -} - -static void markup(XML_Parser parser, const XML_Char *s, int len) -{ - FILE *fp = XML_GetUserData(parser); - for (; len > 0; --len, ++s) - puttc(*s, fp); -} - -static -void metaLocation(XML_Parser parser) -{ - const XML_Char *uri = XML_GetBase(parser); - if (uri) - ftprintf(XML_GetUserData(parser), T(" uri=\"%s\""), uri); - ftprintf(XML_GetUserData(parser), - T(" byte=\"%ld\" nbytes=\"%d\" line=\"%d\" col=\"%d\""), - XML_GetCurrentByteIndex(parser), - XML_GetCurrentByteCount(parser), - XML_GetCurrentLineNumber(parser), - XML_GetCurrentColumnNumber(parser)); -} - -static -void metaStartDocument(XML_Parser parser) -{ - fputts(T("\n"), XML_GetUserData(parser)); -} - -static -void metaEndDocument(XML_Parser parser) -{ - fputts(T("\n"), XML_GetUserData(parser)); -} - -static -void metaStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts) -{ - FILE *fp = XML_GetUserData(parser); - const XML_Char **specifiedAttsEnd - = atts + XML_GetSpecifiedAttributeCount(parser); - const XML_Char **idAttPtr; - int idAttIndex = XML_GetIdAttributeIndex(parser); - if (idAttIndex < 0) - idAttPtr = 0; - else - idAttPtr = atts + idAttIndex; - - ftprintf(fp, T("\n"), fp); - do { - ftprintf(fp, T("= specifiedAttsEnd) - fputts(T("\" defaulted=\"yes\"/>\n"), fp); - else if (atts == idAttPtr) - fputts(T("\" id=\"yes\"/>\n"), fp); - else - fputts(T("\"/>\n"), fp); - } while (*(atts += 2)); - fputts(T("\n"), fp); - } - else - fputts(T("/>\n"), fp); -} - -static -void metaEndElement(XML_Parser parser, const XML_Char *name) -{ - FILE *fp = XML_GetUserData(parser); - ftprintf(fp, T("\n"), fp); -} - -static -void metaProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data) -{ - FILE *fp = XML_GetUserData(parser); - ftprintf(fp, T("\n"), fp); -} - -static -void metaComment(XML_Parser parser, const XML_Char *data) -{ - FILE *fp = XML_GetUserData(parser); - fputts(T("\n"), fp); -} - -static -void metaStartCdataSection(XML_Parser parser) -{ - FILE *fp = XML_GetUserData(parser); - fputts(T("\n"), fp); -} - -static -void metaEndCdataSection(XML_Parser parser) -{ - FILE *fp = XML_GetUserData(parser); - fputts(T("\n"), fp); -} - -static -void metaCharacterData(XML_Parser parser, const XML_Char *s, int len) -{ - FILE *fp = XML_GetUserData(parser); - fputts(T("\n"), fp); -} - -static -void metaStartDoctypeDecl(XML_Parser parser, const XML_Char *doctypeName) -{ - FILE *fp = XML_GetUserData(parser); - ftprintf(fp, T("\n"), fp); -} - -static -void metaEndDoctypeDecl(XML_Parser parser) -{ - FILE *fp = XML_GetUserData(parser); - fputts(T("\n"), fp); -} - -static -void metaUnparsedEntityDecl(XML_Parser parser, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName) -{ - FILE *fp = XML_GetUserData(parser); - ftprintf(fp, T("\n"), fp); -} - -static -void metaNotationDecl(XML_Parser parser, - const XML_Char *notationName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) -{ - FILE *fp = XML_GetUserData(parser); - ftprintf(fp, T("\n"), fp); -} - - -static -void metaExternalParsedEntityDecl(XML_Parser parser, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId) -{ - FILE *fp = XML_GetUserData(parser); - ftprintf(fp, T("\n"), fp); -} - -static -void metaInternalParsedEntityDecl(XML_Parser parser, - const XML_Char *entityName, - const XML_Char *text, - int textLen) -{ - FILE *fp = XML_GetUserData(parser); - ftprintf(fp, T("'), fp); - characterData(fp, text, textLen); - fputts(T("\n"), fp); -} - -static -void metaStartNamespaceDecl(XML_Parser parser, - const XML_Char *prefix, - const XML_Char *uri) -{ - FILE *fp = XML_GetUserData(parser); - fputts(T("\n"), fp); - } - else - fputts(T("/>\n"), fp); -} - -static -void metaEndNamespaceDecl(XML_Parser parser, const XML_Char *prefix) -{ - FILE *fp = XML_GetUserData(parser); - if (!prefix) - fputts(T("\n"), fp); - else - ftprintf(fp, T("\n"), prefix); -} - -static -int unknownEncodingConvert(void *data, const char *p) -{ - return codepageConvert(*(int *)data, p); -} - -static -int unknownEncoding(void *userData, - const XML_Char *name, - XML_Encoding *info) -{ - int cp; - static const XML_Char prefixL[] = T("windows-"); - static const XML_Char prefixU[] = T("WINDOWS-"); - int i; - - for (i = 0; prefixU[i]; i++) - if (name[i] != prefixU[i] && name[i] != prefixL[i]) - return 0; - - cp = 0; - for (; name[i]; i++) { - static const XML_Char digits[] = T("0123456789"); - const XML_Char *s = tcschr(digits, name[i]); - if (!s) - return 0; - cp *= 10; - cp += s - digits; - if (cp >= 0x10000) - return 0; - } - if (!codepageMap(cp, info->map)) - return 0; - info->convert = unknownEncodingConvert; - /* We could just cast the code page integer to a void *, - and avoid the use of release. */ - info->release = free; - info->data = malloc(sizeof(int)); - if (!info->data) - return 0; - *(int *)info->data = cp; - return 1; -} - -static -int notStandalone(void *userData) -{ - return 0; -} - -static -void usage(const XML_Char *prog) -{ - ftprintf(stderr, T("usage: %s [-n] [-p] [-r] [-s] [-w] [-x] [-d output-dir] [-e encoding] file ...\n"), prog); - exit(1); -} - -int tmain(int argc, XML_Char **argv) -{ - int i, j; - const XML_Char *outputDir = 0; - const XML_Char *encoding = 0; - unsigned processFlags = XML_MAP_FILE; - int windowsCodePages = 0; - int outputType = 0; - int useNamespaces = 0; - int requireStandalone = 0; - int paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; - -#if MSVCRT - _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF); -#endif - - i = 1; - j = 0; - while (i < argc) { - if (j == 0) { - if (argv[i][0] != T('-')) - break; - if (argv[i][1] == T('-') && argv[i][2] == T('\0')) { - i++; - break; - } - j++; - } - switch (argv[i][j]) { - case T('r'): - processFlags &= ~XML_MAP_FILE; - j++; - break; - case T('s'): - requireStandalone = 1; - j++; - break; - case T('n'): - useNamespaces = 1; - j++; - break; - case T('p'): - paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS; - /* fall through */ - case T('x'): - processFlags |= XML_EXTERNAL_ENTITIES; - j++; - break; - case T('w'): - windowsCodePages = 1; - j++; - break; - case T('m'): - outputType = 'm'; - j++; - break; - case T('c'): - outputType = 'c'; - useNamespaces = 0; - j++; - break; - case T('t'): - outputType = 't'; - j++; - break; - case T('d'): - if (argv[i][j + 1] == T('\0')) { - if (++i == argc) - usage(argv[0]); - outputDir = argv[i]; - } - else - outputDir = argv[i] + j + 1; - i++; - j = 0; - break; - case T('e'): - if (argv[i][j + 1] == T('\0')) { - if (++i == argc) - usage(argv[0]); - encoding = argv[i]; - } - else - encoding = argv[i] + j + 1; - i++; - j = 0; - break; - case T('\0'): - if (j > 1) { - i++; - j = 0; - break; - } - /* fall through */ - default: - usage(argv[0]); - } - } - if (i == argc) - usage(argv[0]); - for (; i < argc; i++) { - FILE *fp = 0; - XML_Char *outName = 0; - int result; - XML_Parser parser; - if (useNamespaces) - parser = XML_ParserCreateNS(encoding, NSSEP); - else - parser = XML_ParserCreate(encoding); - if (requireStandalone) - XML_SetNotStandaloneHandler(parser, notStandalone); - XML_SetParamEntityParsing(parser, paramEntityParsing); - if (outputType == 't') { - /* This is for doing timings; this gives a more realistic estimate of - the parsing time. */ - outputDir = 0; - XML_SetElementHandler(parser, nopStartElement, nopEndElement); - XML_SetCharacterDataHandler(parser, nopCharacterData); - XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction); - } - else if (outputDir) { - const XML_Char *file = argv[i]; - if (tcsrchr(file, T('/'))) - file = tcsrchr(file, T('/')) + 1; -#if MSVCRT - if (tcsrchr(file, T('\\'))) - file = tcsrchr(file, T('\\')) + 1; -#endif - outName = malloc((tcslen(outputDir) + tcslen(file) + 2) * sizeof(XML_Char)); - tcscpy(outName, outputDir); - tcscat(outName, T("/")); - tcscat(outName, file); - fp = tfopen(outName, T("wb")); - if (!fp) { - tperror(outName); - exit(1); - } - setvbuf(fp, NULL, _IOFBF, 16384); -#ifdef XML_UNICODE - puttc(0xFEFF, fp); -#endif - XML_SetUserData(parser, fp); - switch (outputType) { - case 'm': - XML_UseParserAsHandlerArg(parser); - XML_SetElementHandler(parser, metaStartElement, metaEndElement); - XML_SetProcessingInstructionHandler(parser, metaProcessingInstruction); - XML_SetCommentHandler(parser, metaComment); - XML_SetCdataSectionHandler(parser, metaStartCdataSection, metaEndCdataSection); - XML_SetCharacterDataHandler(parser, metaCharacterData); - XML_SetDoctypeDeclHandler(parser, metaStartDoctypeDecl, metaEndDoctypeDecl); - XML_SetUnparsedEntityDeclHandler(parser, metaUnparsedEntityDecl); - XML_SetNotationDeclHandler(parser, metaNotationDecl); - XML_SetExternalParsedEntityDeclHandler(parser, metaExternalParsedEntityDecl); - XML_SetInternalParsedEntityDeclHandler(parser, metaInternalParsedEntityDecl); - XML_SetNamespaceDeclHandler(parser, metaStartNamespaceDecl, metaEndNamespaceDecl); - metaStartDocument(parser); - break; - case 'c': - XML_UseParserAsHandlerArg(parser); - XML_SetDefaultHandler(parser, markup); - XML_SetElementHandler(parser, defaultStartElement, defaultEndElement); - XML_SetCharacterDataHandler(parser, defaultCharacterData); - XML_SetProcessingInstructionHandler(parser, defaultProcessingInstruction); - break; - default: - if (useNamespaces) - XML_SetElementHandler(parser, startElementNS, endElementNS); - else - XML_SetElementHandler(parser, startElement, endElement); - XML_SetCharacterDataHandler(parser, characterData); -#ifndef W3C14N - XML_SetProcessingInstructionHandler(parser, processingInstruction); -#endif /* not W3C14N */ - break; - } - } - if (windowsCodePages) - XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0); - result = XML_ProcessFile(parser, argv[i], processFlags); - if (outputDir) { - if (outputType == 'm') - metaEndDocument(parser); - fclose(fp); - if (!result) - tremove(outName); - free(outName); - } - XML_ParserFree(parser); - } - return 0; -} diff --git a/trunk/lib/expat/xmlwf/xmlwf.dsp b/trunk/lib/expat/xmlwf/xmlwf.dsp deleted file mode 100644 index 1ca4f42e9..000000000 --- a/trunk/lib/expat/xmlwf/xmlwf.dsp +++ /dev/null @@ -1,136 +0,0 @@ -# Microsoft Developer Studio Project File - Name="xmlwf" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=xmlwf - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "xmlwf.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "xmlwf.mak" CFG="xmlwf - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "xmlwf - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "xmlwf - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "xmlwf - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir ".\Release" -# PROP BASE Intermediate_Dir ".\Release" -# PROP BASE Target_Dir "." -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\Release" -# PROP Intermediate_Dir ".\Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "." -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\xmlparse" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllimport) /YX /FD /c -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 setargv.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"..\bin\xmlwf.exe" - -!ELSEIF "$(CFG)" == "xmlwf - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir ".\Debug" -# PROP BASE Intermediate_Dir ".\Debug" -# PROP BASE Target_Dir "." -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\Debug" -# PROP Intermediate_Dir ".\Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "." -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".\xmlparse" /I "..\xmlparse" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllimport) /YX /FD /c -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 -# ADD LINK32 setargv.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\dbgbin\xmlwf.exe" - -!ENDIF - -# Begin Target - -# Name "xmlwf - Win32 Release" -# Name "xmlwf - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90" -# Begin Source File - -SOURCE=.\codepage.c -# End Source File -# Begin Source File - -SOURCE=.\readfilemap.c -# PROP Exclude_From_Build 1 -# End Source File -# Begin Source File - -SOURCE=.\unixfilemap.c -# PROP Exclude_From_Build 1 -# End Source File -# Begin Source File - -SOURCE=.\win32filemap.c -# End Source File -# Begin Source File - -SOURCE=.\xmlfile.c -# End Source File -# Begin Source File - -SOURCE=.\xmlwf.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" -# Begin Source File - -SOURCE=.\codepage.h -# End Source File -# Begin Source File - -SOURCE=.\xmlfile.h -# End Source File -# Begin Source File - -SOURCE=.\xmltchar.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/trunk/lib/libutil++/Lock.cpp b/trunk/lib/libutil++/Lock.cpp deleted file mode 100644 index a2895a23f..000000000 --- a/trunk/lib/libutil++/Lock.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include "xmlrpc-c/girerr.hpp" -using girerr::error; - -#include "xmlrpc-c/Lock.hpp" - - -namespace xmlrpc_c { - -Lock::Holder::Holder(Lock * const lockP) -/*----------------------------------------------------------------------------- - Construct a holder of lock *lockP -- as long as this object exists, *lockP - is locked. - - If *lockP is already locked, wait for it to be unlocked. ------------------------------------------------------------------------------*/ - : - lockP(lockP) -{ - lockP->acquire(); -} - - - -Lock::Holder::~Holder() { - - this->lockP->release(); -} - - - -Lock::Lock() : - c_lockP(xmlrpc_lock_create()){ - - if (this->c_lockP == NULL) - throw(error("Failed to create lock. xmlrpc_lock_create() failed")); -} - - - -Lock::~Lock() { - - this->c_lockP->destroy(this->c_lockP); -} - - - -void -Lock::acquire() { - - this->c_lockP->acquire(this->c_lockP); -} - - - -void -Lock::release() { - - this->c_lockP->release(this->c_lockP); -} - - - -} // namespace diff --git a/trunk/lib/libutil++/Makefile b/trunk/lib/libutil++/Makefile deleted file mode 100644 index 9c1fba11f..000000000 --- a/trunk/lib/libutil++/Makefile +++ /dev/null @@ -1,133 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - srcDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(srcDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/libutil++ - -include $(BLDDIR)/config.mk - -default: all - -TARGET_LIB_NAMES_PP = libxmlrpc_util++ - -STATIC_LIBRARIES_TO_INSTALL = $(TARGET_STATIC_LIBRARIES) - -SHARED_LIBS_TO_BUILD = $(TARGET_LIB_NAMES_PP) -SHARED_LIBS_TO_INSTALL = $(TARGET_LIB_NAMES_PP) - -# INCLUDES and DEP_SOURCES are used by dep-common target -INCLUDES = $(BASIC_INCLUDES) -DEP_SOURCES = *.cpp - -LIBXMLRPC_UTILPP_MODS = Lock base64 env_wrap girerr girmem - -TARGET_MODS_PP = \ - $(LIBXMLRPC_UTILPP_MODS) \ - -PKGCONFIG_FILES_TO_INSTALL := xmlrpc_util++.pc - -OMIT_LIBXMLRPC_UTILPP_RULE = Y -MAJ = 8 - # Major number of shared libraries in this directory - -include $(SRCDIR)/common.mk - - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -BASIC_INCLUDES = \ - -Iblddir/include \ - -Isrcdir/include \ - -Iblddir \ - -Isrcdir/lib/util/include - - -# TARGET_STATIC_LIBARIES, etc. are set by common.mk, based on -# TARGET_LIB_NAMES_PP. - -all: \ - $(TARGET_STATIC_LIBRARIES) \ - $(TARGET_SHARED_LIBS_PP) \ - $(TARGET_SHARED_LE_LIBS) \ - $(PKGCONFIG_FILES_TO_INSTALL) \ - - -#----------------------------------------------------------------------------- -# RULES TO LINK LIBRARIES -#----------------------------------------------------------------------------- - -# Rules for these are in common.mk, courtesy of TARGET_LIB_NAMES_PP: - -# shlibfn generates e.g. libxmlrpc.so.3.1 -# shliblefn generates e.g. libxmlrpc.so - -# Sometimes -lpthread is necessary when link-editing a shared library that -# uses pthread services, and sometimes it is not. We've seen links on -# Windows and AIX fail without it. It seems to be a good idea in all cases, -# as it declares an actual dependency of the shared library. - -LIBXMLRPC_UTILPP_SH = $(call shlibfn, libxmlrpc_util++) - -$(LIBXMLRPC_UTILPP_SH): $(LIBXMLRPC_UTILPP_MODS:%=%.osh) \ - $(LIBXMLRPC_UTIL) \ - -$(LIBXMLRPC_UTILPP_SH): LIBOBJECTS = $(LIBXMLRPC_UTILPP_MODS:%=%.osh) -$(LIBXMLRPC_UTILPP_SH): LIBDEP = \ - -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ - $(THREAD_LIBS) \ - -libxmlrpc_util++.a: $(LIBXMLRPC_UTILPP_MODS:%=%.o) -libxmlrpc_util++.a: LIBOBJECTS = $(LIBXMLRPC_UTILPP_MODS:%=%.o) - -#----------------------------------------------------------------------------- -# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES -#----------------------------------------------------------------------------- - -# Rules for these are in common.mk, courtesy of TARGET_MODS_PP. - - -#----------------------------------------------------------------------------- -# RULES TO MAKE PKGCONFIG FILES -# -# (These are files used by the 'pkg-config' program to get information about -# using the libraries we build) -#----------------------------------------------------------------------------- - -xmlrpc_util++.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_util++" >>$@ - @echo "Description: Xmlrpc-c C++ utility functions library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_util++" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -#----------------------------------------------------------------------------- -# MISCELLANEOUS RULES -#----------------------------------------------------------------------------- - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean clean-local distclean distclean-local -clean: clean-common clean-local -clean-local: - -distclean: clean distclean-local distclean-common - -distclean-local: - -.PHONY: dep -dep: dep-common - -include depend.mk diff --git a/trunk/lib/libutil++/base64.cpp b/trunk/lib/libutil++/base64.cpp deleted file mode 100644 index c72707a06..000000000 --- a/trunk/lib/libutil++/base64.cpp +++ /dev/null @@ -1,254 +0,0 @@ -#include -#include -#include -#include -#include // min - -using namespace std; - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/base64.hpp" - -using namespace xmlrpc_c; - - - -namespace { - -char const base64Pad('='); -size_t const base64MaxChunkSize(57); - // Max binary chunk size (76 character line) -#define BASE64_LINE_SZ 128 /* Buffer size for a single line. */ - -unsigned char const table_b2a_base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -} // namespace - - - -class bitBuffer { -public: - bitBuffer() : bitsInBuffer(0) {}; - - void - shiftIn8Bits(unsigned char const newBits) { - // Shift in 8 bits to the right end of the buffer - - this->buffer = (this->buffer << 8) | newBits; - this->bitsInBuffer += 8; - - assert(this->bitsInBuffer <= 12); - } - - void - shiftIn6Bits(unsigned char const newBits) { - // Shift in 6 bits to the right end of the buffer - - this->buffer = (this->buffer << 6) | newBits; - this->bitsInBuffer += 6; - - assert(this->bitsInBuffer <= 12); - } - - void - shiftOut6Bits(unsigned char * const outputP) { - // Shift out 6 bits from the left end of the buffer - - assert(bitsInBuffer >= 6); - - *outputP = (this->buffer >> (this->bitsInBuffer - 6)) & 0x3f; - this->bitsInBuffer -= 6; - } - - void - shiftOut8Bits(unsigned char * const outputP) { - // Shift out 8 bits from the left end of the buffer - - assert(bitsInBuffer >= 8); - - *outputP = (this->buffer >> (this->bitsInBuffer - 8)) & 0xff; - this->bitsInBuffer -= 8; - } - - void - shiftOutResidue(unsigned char * const outputP) { - // Shift out the residual 2 or 4 bits, padded on the right with 0 - // to 6 bits. - - while (this->bitsInBuffer < 6) { - this->buffer <<= 2; - this->bitsInBuffer += 2; - } - - this->shiftOut6Bits(outputP); - } - - void - discardResidue() { - assert(bitsInBuffer < 8); - - this->bitsInBuffer = 0; - } - - unsigned int - bitCount() { - return bitsInBuffer; - } - -private: - unsigned int buffer; - unsigned int bitsInBuffer; -}; - - -namespace xmlrpc_c { - - -static void -encodeChunk(vector const& bytes, - size_t const lineStart, - size_t const chunkSize, - string * const outputP) { - - bitBuffer buffer; - // A buffer in which we accumulate bits (up to 12 bits) - // until we have enough (6) for a base64 character. - - // I suppose this would be more efficient with an iterator on - // 'bytes' and/or *outputP. I'd have to find out how to use one. - - for (size_t linePos = 0; linePos < chunkSize; ++linePos) { - // Shift the data into our buffer - buffer.shiftIn8Bits(bytes[lineStart + linePos]); - - // Encode any complete 6 bit groups - while (buffer.bitCount() >= 6) { - unsigned char theseBits; - buffer.shiftOut6Bits(&theseBits); - outputP->append(1, table_b2a_base64[theseBits]); - } - } - if (buffer.bitCount() > 0) { - // Handle residual bits in the buffer - unsigned char theseBits; - buffer.shiftOutResidue(&theseBits); - - outputP->append(1, table_b2a_base64[theseBits]); - - // Pad to a multiple of 4 characters (24 bits) - assert(outputP->length() % 4 > 0); - outputP->append(4-outputP->length() % 4, base64Pad); - } else { - assert(outputP->length() % 4 == 0); - } -} - - - -string -base64FromBytes(vector const& bytes, - newlineCtl const newlineCtl) { - - string retval; - - if (bytes.size() == 0) { - if (newlineCtl == NEWLINE_YES) - retval = "\r\n"; - else - retval = ""; - } else { - // It would be good to preallocate retval. Need to look up - // how to do that. - for (size_t chunkStart = 0; - chunkStart < bytes.size(); - chunkStart += base64MaxChunkSize) { - - size_t const chunkSize( - min(base64MaxChunkSize, bytes.size() - chunkStart)); - - encodeChunk(bytes, chunkStart, chunkSize, &retval); - - if (newlineCtl == NEWLINE_YES) - // Append a courtesy crlf - retval += "\r\n"; - } - } - return retval; -} - - - -static unsigned char -base64CharValue(char const base64Char) { -/*---------------------------------------------------------------------------- - The 6 bits represented by 'base64Char' in Base 64. - - Throw an error if 'base64Char' is not a valid Base64 character. ------------------------------------------------------------------------------*/ - static int const table_a2b_base64[] = { - /* Indexed by the ASCII code for a base64 character, this gives the - numerical value that that character encodes. When indexed by - anything else, this gives -1. Note that the table size is 128, so - you can't index it with just any old byte. - */ - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */ - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 - }; - - assert((unsigned int)base64Char < 128); - - unsigned int const tableIndex(base64Char); - - if (table_a2b_base64[tableIndex] < 0) - throwf("Contains non-base64 character " - "with ASCII code 0x%02x", base64Char); - - return (unsigned char)table_a2b_base64[tableIndex]; -} - - - -vector -bytesFromBase64(string const& base64) { - - vector retval; - bitBuffer buffer; - - for (unsigned int cursor = 0; cursor < base64.length(); ++cursor) { - char const thisChar(base64[cursor] & 0x7f); - - if (thisChar == '\r' || thisChar == '\n' || thisChar == ' ') { - // ignore this punctuation - } else { - if (thisChar == base64Pad) { - // This pad character is here to synchronize a chunk to - // a multiple of 24 bits (4 base64 characters; 3 bytes). - buffer.discardResidue(); - } else { - buffer.shiftIn6Bits(base64CharValue(thisChar)); - - if (buffer.bitCount() >= 8) { - unsigned char thisByte; - buffer.shiftOut8Bits(&thisByte); - retval.push_back(thisByte); - } - } - } - } - - if (buffer.bitCount() > 0) - throwf("Not a multiple of 4 characters"); - - return retval; -} - -} //namespace diff --git a/trunk/lib/libutil++/env_wrap.cpp b/trunk/lib/libutil++/env_wrap.cpp deleted file mode 100644 index 64cae0ac3..000000000 --- a/trunk/lib/libutil++/env_wrap.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "xmlrpc-c/util.h" - -#include "xmlrpc-c/env_wrap.hpp" - -namespace xmlrpc_c { - -env_wrap::env_wrap() { - xmlrpc_env_init(&this->env_c); -} - - - -env_wrap::~env_wrap() { - xmlrpc_env_clean(&this->env_c); -} - - -} // namespace diff --git a/trunk/lib/libutil++/girerr.cpp b/trunk/lib/libutil++/girerr.cpp deleted file mode 100644 index 953a2f9d6..000000000 --- a/trunk/lib/libutil++/girerr.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include - -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/girerr.hpp" - -using namespace std; - -namespace girerr { - -void -throwf(const char * const format, ...) { - - va_list varargs; - va_start(varargs, format); - - const char * value; - xmlrpc_vasprintf(&value, format, varargs); - - string const valueString(value); - - xmlrpc_strfree(value); - - throw(girerr::error(valueString)); - - va_end(varargs); -} - -} // namespace diff --git a/trunk/lib/libutil++/girmem.cpp b/trunk/lib/libutil++/girmem.cpp deleted file mode 100644 index f9825507d..000000000 --- a/trunk/lib/libutil++/girmem.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "xmlrpc-c/Lock.hpp" - -#include "xmlrpc-c/girmem.hpp" - -using namespace std; -using namespace xmlrpc_c; - - -namespace girmem { - - -class autoObject::Impl { - - Lock refcountLock; - unsigned int refcount; - -public: - Impl(); - - ~Impl(); - - void - incref(); - - void - decref(bool * const unreferencedP); -}; - - - -autoObject::Impl::Impl() { - - this->refcount = 0; -} - - - -autoObject::Impl::~Impl() { - - assert(this->refcount == 0); -} - - - -void -autoObject::Impl::incref() { - - Lock::Holder(&this->refcountLock); - - ++this->refcount; -} - - - -void -autoObject::Impl::decref(bool * const unreferencedP) { - - if (this->refcount == 0) - throw(error("Decrementing ref count of unreferenced object")); - - Lock::Holder(&this->refcountLock); - - --this->refcount; - *unreferencedP = (this->refcount == 0); -} - - - -autoObject::autoObject() : implP(auto_ptr(new Impl)) {} - - - -autoObject::autoObject(autoObject const&) { - // This method is declared private, so we can be running now: - assert(false); -} - - - -autoObject::~autoObject() {} - - - -void -autoObject::incref() { - this->implP->incref(); -} - - - -void -autoObject::decref(bool * const unreferencedP) { - this->implP->decref(unreferencedP); -} - - - -autoObjectPtr::autoObjectPtr() : objectP(NULL) {} - - - -autoObjectPtr::autoObjectPtr(autoObject * const objectP) { - - // Note: When someone attempts to use this constructor with a null - // argument, it's normally because a 'new' of the autoObject - // failed, before calling the autoObject's constructor, thus - // generating a null pointer. - - // E.g. the following code, where the system is out of memory: - // - // class client : public autoObject { ... } - // class clientPtr : public autoObjectPtr { ... } - // clientPtr clientP(new client); - - if (objectP == NULL) - throw(error("Object creation failed; trying to create autoObjectPtr " - "with a null autoObject pointer")); - - this->objectP = objectP; - objectP->incref(); -} - - - -autoObjectPtr::autoObjectPtr(autoObjectPtr const& autoObjectPtr) { - // copy constructor - - this->objectP = autoObjectPtr.objectP; - if (this->objectP) - this->objectP->incref(); -} - - - -autoObjectPtr::~autoObjectPtr() { - - this->unpoint(); -} - - - -void -autoObjectPtr::point(autoObject * const objectP) { - - if (this->objectP != NULL) - throw(error("Already pointing")); - this->objectP = objectP; - objectP->incref(); -} - - - -void -autoObjectPtr::unpoint() { - - if (this->objectP) { - bool dead; - this->objectP->decref(&dead); - if (dead) { - delete(this->objectP); - this->objectP = NULL; - } - } -} - - - -autoObjectPtr -autoObjectPtr::operator=(autoObjectPtr const& source) { - - // If we're overwriting a variable that already points to something, - // we have to unpoint it from what it points to now before we can point - // it to what 'source' points to. But if the source and destination - // are the same object, we just want to leave the pointing alone. - - if (this == &source) { - // Assignment of variable to itself; no-op - } else { - this->unpoint(); - this->objectP = source.objectP; - if (this->objectP) - this->objectP->incref(); - } - return *this; -} - - - -autoObject * -autoObjectPtr::operator->() const { - if (this->objectP == NULL) - throw(error("attempt to dereference autoObjectPtr " - "which does not point to anything")); - return this->objectP; -} - - - -autoObject * -autoObjectPtr::get() const { - - return this->objectP; -} - -} // namespace diff --git a/trunk/lib/libutil/Makefile b/trunk/lib/libutil/Makefile deleted file mode 100644 index 71c99ad17..000000000 --- a/trunk/lib/libutil/Makefile +++ /dev/null @@ -1,137 +0,0 @@ -############################################################################### -# This directory builds libxmlrpc_util, which contains utility -# functions that are used by the Xmlprc-c libraries, and also -# directly by Xmlrpc-c programs. Some of them are documented for use -# by Xmlrpc-c users, as facilities of the libxmlrpc library (which -# prerequires libxmlrpc_util). -# -# The functions in this library are characterized by being general purpose -# programming functions, such as one might wish were in the standard C -# library, which have nothing in particular to do with XML-RPC. -############################################################################### - -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - LIBDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/libutil - -include $(BLDDIR)/config.mk - -default: all - -TARGET_LIBRARY_NAMES := libxmlrpc_util - -STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_util.a - -SHARED_LIBS_TO_BUILD := libxmlrpc_util -SHARED_LIBS_TO_INSTALL := libxmlrpc_util - -ifeq ($(HAVE_PTHREAD),yes) - LOCK_PTHREAD = lock_pthread -else - LOCK_PTHREAD = -endif - -ifeq ($(MSVCRT),yes) - LOCK_WINDOWS = lock_windows -else - LOCK_WINDOWS = -endif - -TARGET_MODS = \ - asprintf \ - base64 \ - error \ - lock_platform \ - $(LOCK_PTHREAD) \ - $(LOCK_WINDOWS) \ - lock_none \ - make_printable \ - memblock \ - mempool \ - select \ - sleep \ - string_number \ - time \ - utf8 \ - -OMIT_LIBXMLRPC_UTIL_RULE=Y -MAJ=4 - # Major number of shared libraries in this directory - -include $(SRCDIR)/common.mk - -INCLUDES = -I$(BLDDIR) -Isrcdir \ - -I$(BLDDIR)/include -Isrcdir/include -Isrcdir/lib/util/include - -UTIL_SHLIB = $(call shlibfn,libxmlrpc_util) -#UTIL_SHLIB is e.g. libxmlrpc_util.so.3.1 -UTIL_SHLIBLE = $(call shliblefn,libxmlrpc_util) -#UTIL_SHLIBLE is e.g. libxmlrpc_util.so - -PKGCONFIG_FILES_TO_INSTALL := xmlrpc_util.pc - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -.PHONY: all -all: libxmlrpc_util.a \ - $(TARGET_SHARED_LIBRARIES) \ - $(TARGET_SHARED_LE_LIBS) \ - $(PKGCONFIG_FILES_TO_INSTALL) \ - -# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES: -$(UTIL_SHLIB): $(TARGET_MODS:%=%.osh) -$(UTIL_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) -$(UTIL_SHLIB): LIBDEP += $(SOCKET_LIBOPT) $(THREAD_LIBS) - -# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES: - -libxmlrpc_util.a: $(TARGET_MODS:%=%.o) -libxmlrpc_util.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) - -#----------------------------------------------------------------------------- -# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES -#----------------------------------------------------------------------------- - -# Rules to compile object modules from which to build the static and shared -# library are in common.mk, courtesy of TARGET_MODS. - -#----------------------------------------------------------------------------- -# RULES TO MAKE PKGCONFIG FILES -# -# (These are files used by the 'pkg-config' program to get information about -# using the libraries we build) -#----------------------------------------------------------------------------- - -xmlrpc_util.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_util" >>$@ - @echo "Description: Xmlrpc-c utility functions library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: " >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_util" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean distclean -clean: clean-common - -distclean: clean distclean-common - -.PHONY: dep -dep: dep-common - -include depend.mk diff --git a/trunk/lib/libutil/asprintf.c b/trunk/lib/libutil/asprintf.c deleted file mode 100644 index d79e1bad7..000000000 --- a/trunk/lib/libutil/asprintf.c +++ /dev/null @@ -1,199 +0,0 @@ -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ -#define _GNU_SOURCE /* But only when HAVE_ASPRINTF */ -#include -#include -#include -#include - -#include "xmlrpc_config.h" /* For HAVE_ASPRINTF, __inline__ */ -#include "xmlrpc-c/string_int.h" -#include "bool.h" - - - -static __inline__ void -newVsnprintf(char * const buffer, - size_t const bufferSize, - const char * const fmt, - va_list varargs, - size_t * const formattedSizeP) { -/*---------------------------------------------------------------------------- - This is vsnprintf() with the new behavior, where not fitting in the buffer - is not a failure. - - Unfortunately, we can't practically return the size of the formatted string - if the C library has old vsnprintf() and the formatted string doesn't fit - in the buffer, so in that case we just return something larger than the - buffer. ------------------------------------------------------------------------------*/ - if (bufferSize > INT_MAX/2) { - /* There's a danger we won't be able to coerce the return value - of XMLRPC_VSNPRINTF to an integer (which we have to do because, - while for POSIX its return value is ssize_t, on Windows it is int), - or return double the buffer size. - */ - *formattedSizeP = 0; - } else { - int rc; - - rc = XMLRPC_VSNPRINTF(buffer, bufferSize, fmt, varargs); - - if (rc < 0) { - /* We have old vsnprintf() (or Windows) and the formatted value - doesn't fit in the buffer, but we don't know how big a buffer it - needs. - */ - *formattedSizeP = bufferSize * 2; - } else { - /* Either the string fits in the buffer or we have new vsnprintf() - which tells us how big the string is regardless. - */ - *formattedSizeP = rc; - } - } -} - - - -static __inline__ int -simpleVasprintf(char ** const resultP, - const char * const fmt, - va_list varargs) { -/*---------------------------------------------------------------------------- - This is a poor man's implementation of vasprintf(), of GNU fame. ------------------------------------------------------------------------------*/ - int retval; - char * buffer; - size_t bufferSize; - bool outOfMemory; - - for (buffer = NULL, bufferSize = 4096, outOfMemory = false; - !buffer && !outOfMemory; - ) { - - buffer = malloc(bufferSize); - if (!buffer) - outOfMemory = true; - else { - size_t bytesNeeded; - newVsnprintf(buffer, bufferSize, fmt, varargs, &bytesNeeded); - if (bytesNeeded > bufferSize) { - free(buffer); - buffer = NULL; - bufferSize = bytesNeeded; - } - } - } - if (outOfMemory) - retval = -1; - else { - retval = strlen(buffer); - *resultP = buffer; - } - return retval; -} - - - -static const char * const xmlrpc_strsol = - "[insufficient memory to build string]"; - - - -bool -xmlrpc_strnomem(const char * const string) { -/*---------------------------------------------------------------------------- - The string 'string' was generated by a function in this file because it - couldn't get enough memory to generate the string that it was supposed to - generate. I.e. a preceding call to a string function failed. ------------------------------------------------------------------------------*/ - return string == xmlrpc_strsol; -} - - - -const char * -xmlrpc_strnomemval() { - - return xmlrpc_strsol; -} - - - -void -xmlrpc_vasprintf(const char ** const retvalP, - const char * const fmt, - va_list varargs) { - - char * string; - int rc; - -#if HAVE_ASPRINTF - rc = vasprintf(&string, fmt, varargs); -#else - rc = simpleVasprintf(&string, fmt, varargs); -#endif - - if (rc < 0) - *retvalP = xmlrpc_strsol; - else - *retvalP = string; -} - - - -void XMLRPC_PRINTF_ATTR(2,3) -xmlrpc_asprintf(const char ** const retvalP, const char * const fmt, ...) { - - va_list varargs; /* mysterious structure used by variable arg facility */ - - va_start(varargs, fmt); /* start up the mysterious variable arg facility */ - - xmlrpc_vasprintf(retvalP, fmt, varargs); - - va_end(varargs); -} - - - -const char * -xmlrpc_strdupsol(const char * const string) { - - const char * retvalOrNull; - - retvalOrNull = strdup(string); - - return retvalOrNull ? retvalOrNull : xmlrpc_strsol; -} - - - -void -xmlrpc_strfree(const char * const string) { - - if (string != xmlrpc_strsol) - free((void *)string); -} - - - -const char * -xmlrpc_strdupnull(const char * const string) { - - if (string) - return strdup(string); - else - return NULL; -} - - - -void -xmlrpc_strfreenull(const char * const string) { - - if (string) - xmlrpc_strfree(string); -} - - - diff --git a/trunk/lib/libutil/base64.c b/trunk/lib/libutil/base64.c deleted file mode 100644 index 1e7c6e705..000000000 --- a/trunk/lib/libutil/base64.c +++ /dev/null @@ -1,333 +0,0 @@ -#include - -#include "xmlrpc_config.h" - -#include "bool.h" -#include "xmlrpc-c/util_int.h" -#include "int.h" -#include "xmlrpc-c/base64_int.h" - - - -void -xmlrpc_base64Encode(const char * const chars, - char * const base64) { -/*---------------------------------------------------------------------------- - This is for internal use by Xmlrpc-c libraries. It is useful for - libraries such as Abyss that don't use xmlrpc_memblock and xmlrpc_env. ------------------------------------------------------------------------------*/ - /* Conversion table. */ - static char tbl[64] = { - 'A','B','C','D','E','F','G','H', - 'I','J','K','L','M','N','O','P', - 'Q','R','S','T','U','V','W','X', - 'Y','Z','a','b','c','d','e','f', - 'g','h','i','j','k','l','m','n', - 'o','p','q','r','s','t','u','v', - 'w','x','y','z','0','1','2','3', - '4','5','6','7','8','9','+','/' - }; - - unsigned int i; - uint32_t length; - char * p; - const char * s; - - length = strlen(chars); /* initial value */ - s = &chars[0]; /* initial value */ - p = &base64[0]; /* initial value */ - /* Transform the 3x8 bits to 4x6 bits, as required by base64. */ - for (i = 0; i < length; i += 3) { - *p++ = tbl[s[0] >> 2]; - *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)]; - *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)]; - *p++ = tbl[s[2] & 0x3f]; - s += 3; - } - - /* Pad the result if necessary... */ - if (i == length + 1) - *(p - 1) = '='; - else if (i == length + 2) - *(p - 1) = *(p - 2) = '='; - - /* ...and zero-terminate it. */ - *p = '\0'; -} - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -** There is more copyright information in the bottom half of this file. -** Please see it for more details. */ - - -/*========================================================================= -** XML-RPC Base64 Utilities -**========================================================================= -** This code was swiped from Jack Jansen's code in Python 1.5.2 and -** modified to work with our data types. -*/ - -#define CRLF "\015\012" -#define CR '\015' -#define LF '\012' - - -/*********************************************************** -Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum, -Amsterdam, The Netherlands. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Stichting Mathematisch -Centrum or CWI or Corporation for National Research Initiatives or -CNRI not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -While CWI is the initial source for this software, a modified version -is made available by the Corporation for National Research Initiatives -(CNRI) at the Internet address ftp://ftp.python.org. - -STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH -CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - -******************************************************************/ - -static char table_a2b_base64[] = { - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */ - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -}; - -#define BASE64_PAD '=' -#define BASE64_MAXBIN 57 /* Max binary chunk size (76 char line) */ -#define BASE64_LINE_SZ 128 /* Buffer size for a single line. */ - -static unsigned char const table_b2a_base64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - - -static xmlrpc_mem_block * -base64Encode(xmlrpc_env * const envP, - const unsigned char * const binData, - size_t const binLen, - bool const wantNewlines) { - - size_t chunkStart, chunkLeft; - unsigned char * asciiData; - int leftbits; - unsigned char thisCh; - unsigned int leftchar; - xmlrpc_mem_block * outputP; - unsigned char lineBuffer[BASE64_LINE_SZ]; - const unsigned char * cursor; - - /* Create a block to hold our lines when we finish them. */ - outputP = xmlrpc_mem_block_new(envP, 0); - XMLRPC_FAIL_IF_FAULT(envP); - - /* Deal with empty data blocks gracefully. Yuck. */ - if (binLen == 0) { - if (wantNewlines) - XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, CRLF, 2); - goto cleanup; - } - - /* Process our binary data in line-sized chunks. */ - for (chunkStart = 0, cursor = &binData[0]; - chunkStart < binLen; - chunkStart += BASE64_MAXBIN) { - - /* Set up our per-line state. */ - asciiData = &lineBuffer[0]; - chunkLeft = binLen - chunkStart; - if (chunkLeft > BASE64_MAXBIN) - chunkLeft = BASE64_MAXBIN; - leftbits = 0; - leftchar = 0; - - for(; chunkLeft > 0; --chunkLeft, ++cursor) { - /* Shift the data into our buffer */ - leftchar = (leftchar << 8) | *cursor; - leftbits += 8; - - /* See if there are 6-bit groups ready */ - while (leftbits >= 6) { - thisCh = (leftchar >> (leftbits-6)) & 0x3f; - leftbits -= 6; - *asciiData++ = table_b2a_base64[thisCh]; - } - } - if (leftbits == 2) { - *asciiData++ = table_b2a_base64[(leftchar&3) << 4]; - *asciiData++ = BASE64_PAD; - *asciiData++ = BASE64_PAD; - } else if (leftbits == 4) { - *asciiData++ = table_b2a_base64[(leftchar&0xf) << 2]; - *asciiData++ = BASE64_PAD; - } - - /* Append a courtesy CRLF. */ - if (wantNewlines) { - *asciiData++ = CR; - *asciiData++ = LF; - } - - /* Save our line. */ - XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, lineBuffer, - asciiData - &lineBuffer[0]); - XMLRPC_FAIL_IF_FAULT(envP); - } - - cleanup: - if (envP->fault_occurred) { - if (outputP) - xmlrpc_mem_block_free(outputP); - return NULL; - } - return outputP; -} - - - -xmlrpc_mem_block * -xmlrpc_base64_encode(xmlrpc_env * const envP, - const unsigned char * const binData, - size_t const binLen) { - - return base64Encode(envP, binData, binLen, true); -} - - - -xmlrpc_mem_block * -xmlrpc_base64_encode_without_newlines(xmlrpc_env * const envP, - const unsigned char * const binData, - size_t const binLen) { - - return base64Encode(envP, binData, binLen, false); -} - - - -xmlrpc_mem_block * -xmlrpc_base64_decode(xmlrpc_env * const envP, - const char * const asciiData, - size_t const acsiiLen) { - - unsigned char * binData; - int leftbits; - unsigned char thisCh; - unsigned int leftchar; - size_t npad; - size_t binLen, bufferSize; - xmlrpc_mem_block * outputP; - const char * nextCharP; - size_t remainingLen; - - /* Create a block to hold our chunks when we finish them. - ** We overestimate the size now, and fix it later. */ - bufferSize = ((acsiiLen + 3) / 4) * 3; - outputP = xmlrpc_mem_block_new(envP, bufferSize); - XMLRPC_FAIL_IF_FAULT(envP); - - /* Set up our decoder state. */ - leftbits = 0; - leftchar = 0; - npad = 0; - binData = XMLRPC_MEMBLOCK_CONTENTS(unsigned char, outputP); - binLen = 0; - - for (remainingLen = acsiiLen, nextCharP = asciiData; - remainingLen > 0; - --remainingLen, ++nextCharP) { - - /* Skip some punctuation. */ - thisCh = (*nextCharP & 0x7f); - if (thisCh == '\r' || thisCh == '\n' || thisCh == ' ') - continue; - if (thisCh == BASE64_PAD) - ++npad; - thisCh = table_a2b_base64[(*nextCharP) & 0x7f]; - - /* XXX - We just throw away invalid characters. Is this right? */ - if (thisCh == (unsigned char) -1) - continue; - - /* Shift it in on the low end, and see if there's a byte ready for - output. - */ - leftchar = (leftchar << 6) | (thisCh); - leftbits += 6; - if (leftbits >= 8) { - leftbits -= 8; - XMLRPC_ASSERT(binLen < bufferSize); - *binData++ = (leftchar >> leftbits) & 0xFF; - leftchar &= ((1 << leftbits) - 1); - ++binLen; - } - } - - /* Check that no bits are left. */ - if (leftbits) - XMLRPC_FAIL(envP, XMLRPC_PARSE_ERROR, "Incorrect Base64 padding"); - - /* Check to make sure we have a sane amount of padding. */ - if (npad > binLen || npad > 2) - XMLRPC_FAIL(envP, XMLRPC_PARSE_ERROR, "Malformed Base64 data"); - - /* Remove any padding and set the correct size. */ - binLen -= npad; - XMLRPC_MEMBLOCK_RESIZE(char, envP, outputP, binLen); - XMLRPC_ASSERT(!envP->fault_occurred); - - cleanup: - if (envP->fault_occurred) { - if (outputP) - xmlrpc_mem_block_free(outputP); - return NULL; - } - return outputP; -} diff --git a/trunk/lib/libutil/error.c b/trunk/lib/libutil/error.c deleted file mode 100644 index 473755773..000000000 --- a/trunk/lib/libutil/error.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright information is at end of file */ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/util.h" - - - -void -xmlrpc_assertion_failed(const char * const fileName, - int const lineNumber) { - - fprintf(stderr, "%s:%d: assertion failed\n", fileName, lineNumber); - abort(); -} - - - -static const char * const default_fault_string = - "Not enough memory for error message"; - -void -xmlrpc_env_init (xmlrpc_env* env) { - XMLRPC_ASSERT(env != NULL); - - env->fault_occurred = 0; - env->fault_code = 0; - env->fault_string = NULL; -} - - - -void -xmlrpc_env_clean(xmlrpc_env * const envP) { - - XMLRPC_ASSERT(envP != NULL); - XMLRPC_ASSERT(envP->fault_string != XMLRPC_BAD_POINTER); - - /* env->fault_string may be one of three things: - ** 1) a NULL pointer - ** 2) a pointer to the default_fault_string - ** 3) a pointer to a malloc'd fault string - ** If we have case (3), we'll need to free it. */ - if (envP->fault_string && envP->fault_string != default_fault_string) - free(envP->fault_string); - envP->fault_string = XMLRPC_BAD_POINTER; -} - - - -void -xmlrpc_env_set_fault(xmlrpc_env * const envP, - int const faultCode, - const char * const faultDescription) { - - char * buffer; - - XMLRPC_ASSERT(envP != NULL); - XMLRPC_ASSERT(faultDescription != NULL); - - /* Clean up any leftover pointers. */ - xmlrpc_env_clean(envP); - - envP->fault_occurred = 1; - envP->fault_code = faultCode; - - /* Try to copy the fault string. If this fails, use a default. */ - buffer = strdup(faultDescription); - if (buffer == NULL) - envP->fault_string = (char *)default_fault_string; - else { - xmlrpc_force_to_utf8(buffer); - xmlrpc_force_to_xml_chars(buffer); - envP->fault_string = buffer; - } -} - - - -void -xmlrpc_set_fault_formatted_v(xmlrpc_env * const envP, - int const code, - const char * const format, - va_list args) { - - const char * faultDescription; - - xmlrpc_vasprintf(&faultDescription, format, args); - - xmlrpc_env_set_fault(envP, code, faultDescription); - - xmlrpc_strfree(faultDescription); -} - - - -void -xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP, - int const code, - const char * const format, - ...) { - va_list args; - - XMLRPC_ASSERT(envP != NULL); - XMLRPC_ASSERT(format != NULL); - - /* Print our error message to the buffer. */ - va_start(args, format); - xmlrpc_set_fault_formatted_v(envP, code, format, args); - va_end(args); -} - - - -void -xmlrpc_faultf(xmlrpc_env * const envP, - const char * const format, - ...) { - - va_list args; - - XMLRPC_ASSERT(envP != NULL); - XMLRPC_ASSERT(format != NULL); - - /* Print our error message to the buffer. */ - va_start(args, format); - xmlrpc_set_fault_formatted_v(envP, XMLRPC_INTERNAL_ERROR, format, args); - va_end(args); - -} - - - -/* 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. */ - diff --git a/trunk/lib/libutil/lock_none.c b/trunk/lib/libutil/lock_none.c deleted file mode 100644 index 6a577fdc4..000000000 --- a/trunk/lib/libutil/lock_none.c +++ /dev/null @@ -1,61 +0,0 @@ -/*============================================================================= - lock_none -=============================================================================== - This is an inter-thread lock class for a system in which there is no - inter-thread conflict, e.g. where no two threads every share memory. - - The locking is therefore trivial: no-op -=============================================================================*/ -#include - -#include "mallocvar.h" -#include "xmlrpc-c/lock.h" - -#include "xmlrpc-c/lock_none.h" - -static lockAcquireFn acquire; - -static void -acquire(struct lock * const lockP ATTR_UNUSED) { - -} - - - -static lockReleaseFn release; - -static void -release(struct lock * const lockP ATTR_UNUSED) { - -} - - - -static lockDestroyFn destroy; - -static void -destroy(struct lock * const lockP ATTR_UNUSED) { - - free(lockP); -} - - - -struct lock * -xmlrpc_lock_create_none(void) { - - struct lock * lockP; - - MALLOCVAR(lockP); - - if (lockP) { - lockP->implementationP = NULL; - lockP->acquire = &acquire; - lockP->release = &release; - lockP->destroy = &destroy; - } - return lockP; -} - - - diff --git a/trunk/lib/libutil/lock_platform.c b/trunk/lib/libutil/lock_platform.c deleted file mode 100644 index 387a5cf85..000000000 --- a/trunk/lib/libutil/lock_platform.c +++ /dev/null @@ -1,48 +0,0 @@ -/*============================================================================= - lock_platform -=============================================================================== - - This module provides locking services appropriate for the platform for - which Xmlrpc-c is being built. I.e. services chosen by the build - configuration. - -============================================================================*/ - -#include "xmlrpc_config.h" - -#include "xmlrpc-c/lock_platform.h" - -#if HAVE_PTHREAD -#include "xmlrpc-c/lock_pthread.h" -#endif - -#if HAVE_WINDOWS_THREAD -#include "xmlrpc-c/lock_windows.h" -#endif - -struct lock * -xmlrpc_lock_create(void) { - -#if HAVE_PTHREAD - return xmlrpc_lock_create_pthread(); -#elif HAVE_WINDOWS_THREAD - return xmlrpc_lock_create_windows(); -#else - #error "You don't have any thread facility. (According to " - #error "HAVE_PTHREAD and HAVE_WINDOWS_THREAD macros defined in " - #error "xmlrpc_config.h)" - - /* One might consider using xmlrpc_lock_create_none() here, but that would - be dangerous. If the system really does have threads that share memory, - and there's just some configuration error here (which is the most likely - case), we would silently build a broken library, which breakage would be - difficult for the user to detect and then diagnose. - - If we encounter some actual need for lock_none in the future, we'll - revisit the issue of when the build system should select it - */ -#endif - -} - - diff --git a/trunk/lib/libutil/lock_pthread.c b/trunk/lib/libutil/lock_pthread.c deleted file mode 100644 index cab9b445b..000000000 --- a/trunk/lib/libutil/lock_pthread.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include - -#include "mallocvar.h" - -#include "xmlrpc-c/lock.h" - -#include "xmlrpc-c/lock_pthread.h" - -static lockAcquireFn acquire; - -static void -acquire(struct lock * const lockP) { - - pthread_mutex_t * const mutexP = lockP->implementationP; - - pthread_mutex_lock(mutexP); -} - - - -static lockReleaseFn release; - -static void -release(struct lock * const lockP) { - - pthread_mutex_t * const mutexP = lockP->implementationP; - - pthread_mutex_unlock(mutexP); -} - - - -static lockDestroyFn destroy; - -static void -destroy(struct lock * const lockP) { - - pthread_mutex_t * const mutexP = lockP->implementationP; - - pthread_mutex_destroy(mutexP); - - free(mutexP); - - free(lockP); -} - - - -struct lock * -xmlrpc_lock_create_pthread(void) { - - struct lock * lockP; - - MALLOCVAR(lockP); - - if (lockP) { - pthread_mutex_t * mutexP; - - MALLOCVAR(mutexP); - - if (mutexP) { - pthread_mutex_init(mutexP, NULL); - - lockP->implementationP = mutexP; - lockP->acquire = &acquire; - lockP->release = &release; - lockP->destroy = &destroy; - } else { - free(lockP); - lockP = NULL; - } - } - return lockP; -} - - - diff --git a/trunk/lib/libutil/lock_windows.c b/trunk/lib/libutil/lock_windows.c deleted file mode 100644 index 22631536f..000000000 --- a/trunk/lib/libutil/lock_windows.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "xmlrpc_config.h" - -/* We define WIN32_WIN_LEAN_AND_MEAN to make contain less - junk; nothing in Xmlrpc-c needs that stuff. One significant thing it cuts - out is , which would conflict with the that our - includer might use. -*/ -#define WIN32_WIN_LEAN_AND_MEAN -#include - -#include "mallocvar.h" - -#include "xmlrpc-c/lock.h" - -#include "xmlrpc-c/lock_windows.h" - -static lockAcquireFn acquire; - -static void -acquire(struct lock * lockP) { - - CRITICAL_SECTION * const criticalSectionP = lockP->implementationP; - - EnterCriticalSection(criticalSectionP); -} - - - -static lockReleaseFn release; - -static void -release(struct lock * lockP) { - - CRITICAL_SECTION * const criticalSectionP = lockP->implementationP; - - LeaveCriticalSection(criticalSectionP); -} - - - -static lockDestroyFn destroy; - -static void -destroy(struct lock * const lockP) { - - CRITICAL_SECTION * const criticalSectionP = lockP->implementationP; - - DeleteCriticalSection(criticalSectionP); - - free(criticalSectionP); - - free(lockP); -} - - - -struct lock * -xmlrpc_lock_create_windows(void) { - - struct lock * lockP; - - MALLOCVAR(lockP); - - if (lockP) { - CRITICAL_SECTION * criticalSectionP; - - MALLOCVAR(criticalSectionP); - - if (criticalSectionP) { - InitializeCriticalSection(criticalSectionP); - - lockP->implementationP = criticalSectionP; - lockP->acquire = &acquire; - lockP->release = &release; - lockP->destroy = &destroy; - } else { - free(lockP); - lockP = NULL; - } - } - return lockP; -} - - - diff --git a/trunk/lib/libutil/make_printable.c b/trunk/lib/libutil/make_printable.c deleted file mode 100644 index e9415ea5e..000000000 --- a/trunk/lib/libutil/make_printable.c +++ /dev/null @@ -1,101 +0,0 @@ -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "xmlrpc-c/string_int.h" - - - -const char * -xmlrpc_makePrintable_lp(const char * const input, - size_t const inputLength) { -/*---------------------------------------------------------------------------- - Convert an arbitrary string of characters in length-pointer form to - printable ASCII. E.g. convert newlines to "\n". - - Return the result in newly malloc'ed storage. Return NULL if we can't - get the storage. ------------------------------------------------------------------------------*/ - char * output; - - output = malloc(inputLength*4+1); - /* Worst case, we render a character like \x01 -- 4 characters */ - - if (output != NULL) { - unsigned int inputCursor, outputCursor; - - for (inputCursor = 0, outputCursor = 0; - inputCursor < inputLength; - ++inputCursor) { - - if (0) { - } else if (input[inputCursor] == '\\') { - output[outputCursor++] = '\\'; - output[outputCursor++] = '\\'; - } else if (input[inputCursor] == '\n') { - output[outputCursor++] = '\\'; - output[outputCursor++] = 'n'; - } else if (input[inputCursor] == '\t') { - output[outputCursor++] = '\\'; - output[outputCursor++] = 't'; - } else if (input[inputCursor] == '\a') { - output[outputCursor++] = '\\'; - output[outputCursor++] = 'a'; - } else if (input[inputCursor] == '\r') { - output[outputCursor++] = '\\'; - output[outputCursor++] = 'r'; - } else if (isprint(input[inputCursor])) { - output[outputCursor++] = input[inputCursor]; - } else { - XMLRPC_SNPRINTF(&output[outputCursor], 5, "\\x%02x", - (unsigned char)input[inputCursor]); - outputCursor += 4; - } - } - output[outputCursor++] = '\0'; - } - return output; -} - - - -const char * -xmlrpc_makePrintable(const char * const input) { -/*---------------------------------------------------------------------------- - Convert an arbitrary string of characters (NUL-terminated, though) to - printable ASCII. E.g. convert newlines to "\n". - - Return the result in newly malloc'ed storage. Return NULL if we can't - get the storage. ------------------------------------------------------------------------------*/ - return xmlrpc_makePrintable_lp(input, strlen(input)); -} - - - -const char * -xmlrpc_makePrintableChar(char const input) { -/*---------------------------------------------------------------------------- - Return an ASCIIZ string consisting of the character 'input', - properly escaped so as to be printable. E.g., in C notation, '\n' - turns into "\\n" ------------------------------------------------------------------------------*/ - const char * retval; - - if (input == '\0') - retval = strdup("\\0"); - else { - char buffer[2]; - - buffer[0] = input; - buffer[1] = '\0'; - - retval = xmlrpc_makePrintable(buffer); - } - return retval; -} diff --git a/trunk/lib/libutil/memblock.c b/trunk/lib/libutil/memblock.c deleted file mode 100644 index 9469d0118..000000000 --- a/trunk/lib/libutil/memblock.c +++ /dev/null @@ -1,272 +0,0 @@ -/* Copyright information is at end of file */ -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include - -#include "bool.h" -#include "girmath.h" -#include "mallocvar.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/util.h" - -#define BLOCK_ALLOC_MIN (16) - -static bool const tracingMemory = -#ifdef EFENCE - true -#else - false -#endif - ; - - - -struct _xmlrpc_mem_block { - xmlrpc_mem_pool * poolP; - /* Pool this block is in; NULL if it is not in a pool */ - size_t size; - /* Size of the block */ - size_t allocated; - /* How much memory we've allocated from the system for this block - (pointed to by 'blockP') - */ - void * blockP; -}; - - - -xmlrpc_mem_block * -xmlrpc_mem_block_new_pool(xmlrpc_env * const envP, - size_t const size, - xmlrpc_mem_pool * const poolP) { -/*---------------------------------------------------------------------------- - Create an xmlrpc_mem_block of size 'size' in pool *poolP. - - If 'poolP' is NULL, don't put it in any pool. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * blockP; - - XMLRPC_ASSERT_ENV_OK(envP); - - if (!envP->fault_occurred) { - MALLOCVAR(blockP); - - if (blockP == NULL) - xmlrpc_faultf(envP, "Can't allocate memory block descriptor"); - else { - blockP->poolP = poolP; - - blockP->size = size; - - if (tracingMemory) - blockP->allocated = size; - else - blockP->allocated = MAX(BLOCK_ALLOC_MIN, size); - - if (poolP) - xmlrpc_mem_pool_alloc(envP, poolP, blockP->allocated); - - if (!envP->fault_occurred) { - blockP->blockP = malloc(blockP->allocated); - if (!blockP->blockP) - xmlrpc_faultf(envP, "Can't allocate %u-byte memory block", - (unsigned)blockP->allocated); - - - if (envP->fault_occurred) - xmlrpc_mem_pool_release(poolP, blockP->allocated); - } - if (envP->fault_occurred) { - free(blockP); - blockP = NULL; - } - } - } - return blockP; -} - - - -xmlrpc_mem_block * -xmlrpc_mem_block_new(xmlrpc_env * const envP, - size_t const size) { -/*---------------------------------------------------------------------------- - Create an xmlrpc_mem_block of size 'size', not in any pool ------------------------------------------------------------------------------*/ - return xmlrpc_mem_block_new_pool(envP, size, NULL); -} - - - -void -xmlrpc_mem_block_free(xmlrpc_mem_block * const blockP) { -/*---------------------------------------------------------------------------- - Destroy xmlrpc_mem_block *blockP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(blockP != NULL); - XMLRPC_ASSERT(blockP->blockP != NULL); - - if (blockP->poolP) - xmlrpc_mem_pool_release(blockP->poolP, blockP->allocated); - - free(blockP->blockP); - - free(blockP); -} - - - -size_t -xmlrpc_mem_block_size(const xmlrpc_mem_block * const blockP) { -/*---------------------------------------------------------------------------- - The size of the xmlrpc_mem_block. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(blockP != NULL); - return blockP->size; -} - - - -void * -xmlrpc_mem_block_contents(const xmlrpc_mem_block * const blockP) { -/*---------------------------------------------------------------------------- - The contents of the xmlrpc_mem_block ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(blockP != NULL); - return blockP->blockP; -} - - - -static size_t -allocSize(size_t const requestedSize) { -/*---------------------------------------------------------------------------- - The size we allocate when the user requests to resize to 'requesteddSize'. - - We give him more than he requested in an attempt to avoid lots of copying - when Caller repeatedly resizes by small amounts. - - We make some arbitrary judgments about how much memory or copying - constitutes lots. ------------------------------------------------------------------------------*/ - size_t const oneMegabyte = 1024*1024; - - size_t retval; - - if (tracingMemory) - retval = requestedSize; - else { - /* We make it a power of two unless it is more than a megabyte, - in which case we just make it a multiple of a megabyte. - */ - if (requestedSize >= oneMegabyte) - retval = ROUNDUPU(requestedSize, oneMegabyte); - else { - unsigned int i; - for (i = BLOCK_ALLOC_MIN; i < requestedSize; i *= 2); - retval = i; - } - } - return retval; -} - - - -void -xmlrpc_mem_block_resize(xmlrpc_env * const envP, - xmlrpc_mem_block * const blockP, - size_t const size) { -/*---------------------------------------------------------------------------- - Resize an xmlrpc_mem_block by allocating new memory for it and copying - whatever might be in it to the new memory. ------------------------------------------------------------------------------*/ - size_t const newAllocSize = allocSize(size); - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(blockP != NULL); - - if (newAllocSize > blockP->allocated) { - /* Reallocate */ - - if (blockP->poolP) - xmlrpc_mem_pool_alloc(envP, blockP->poolP, - newAllocSize - blockP->allocated); - - if (!envP->fault_occurred) { - void * newMem; - - newMem = malloc(newAllocSize); - if (!newMem) - xmlrpc_faultf(envP, - "Failed to allocate %u bytes of memory " - "from the OS", - (unsigned) size); - else { - /* Copy over the data */ - size_t const sizeToCopy = MIN(blockP->size, size); - assert(sizeToCopy <= newAllocSize); - memcpy(newMem, blockP->blockP, sizeToCopy); - - free(blockP->blockP); - - blockP->blockP = newMem; - blockP->allocated = newAllocSize; - } - if (envP->fault_occurred) - xmlrpc_mem_pool_release(blockP->poolP, - newAllocSize - blockP->allocated); - } - } - blockP->size = size; -} - - - -void -xmlrpc_mem_block_append(xmlrpc_env * const envP, - xmlrpc_mem_block * const blockP, - const void * const data, - size_t const len) { - - size_t const originalSize = blockP->size; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(blockP != NULL); - - xmlrpc_mem_block_resize(envP, blockP, originalSize + len); - if (!envP->fault_occurred) { - memcpy(((unsigned char*) blockP->blockP) + originalSize, data, 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. -*/ diff --git a/trunk/lib/libutil/mempool.c b/trunk/lib/libutil/mempool.c deleted file mode 100644 index 52584ec14..000000000 --- a/trunk/lib/libutil/mempool.c +++ /dev/null @@ -1,98 +0,0 @@ -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include - -#include "bool.h" -#include "girmath.h" -#include "mallocvar.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/util.h" - -struct _xmlrpc_mem_pool { - size_t size; - size_t allocated; -}; - - - -xmlrpc_mem_pool * -xmlrpc_mem_pool_new(xmlrpc_env * const envP, - size_t const size) { -/*---------------------------------------------------------------------------- - Create an xmlrpc_mem_pool of size 'size' bytes. ------------------------------------------------------------------------------*/ - xmlrpc_mem_pool * poolP; - - XMLRPC_ASSERT_ENV_OK(envP); - - MALLOCVAR(poolP); - - if (poolP == NULL) - xmlrpc_faultf(envP, "Can't allocate memory pool descriptor"); - else { - poolP->size = size; - - poolP->allocated = 0; - - if (envP->fault_occurred) - free(poolP); - } - return poolP; -} - - - -void -xmlrpc_mem_pool_free(xmlrpc_mem_pool * const poolP) { -/*---------------------------------------------------------------------------- - Destroy xmlrpc_mem_pool *poolP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(poolP != NULL); - - XMLRPC_ASSERT(poolP->allocated == 0); - - free(poolP); -} - - - -void -xmlrpc_mem_pool_alloc(xmlrpc_env * const envP, - xmlrpc_mem_pool * const poolP, - size_t const size) { -/*---------------------------------------------------------------------------- - Take 'size' bytes from pool *poolP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(poolP->allocated <= poolP->size); - - if (poolP->size - poolP->allocated < size) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_LIMIT_EXCEEDED_ERROR, - "Memory pool is out of memory. %u-byte pool is %u bytes short", - (unsigned)poolP->size, - (unsigned)(poolP->allocated + size - poolP->size)); - else - poolP->allocated += size; -} - - - -void -xmlrpc_mem_pool_release(xmlrpc_mem_pool * const poolP, - size_t const size) { -/*---------------------------------------------------------------------------- - Return 'size' bytes to pool *poolP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(poolP != NULL); - - XMLRPC_ASSERT(poolP->allocated >= size); - - poolP->allocated -= size; -} - - - diff --git a/trunk/lib/libutil/select.c b/trunk/lib/libutil/select.c deleted file mode 100644 index 01856adcb..000000000 --- a/trunk/lib/libutil/select.c +++ /dev/null @@ -1,62 +0,0 @@ -#define _XOPEN_SOURCE 600 /* Get pselect() in */ - -#include "xmlrpc_config.h" - -#if MSVCRT -#include -#else -/* In some systems (SUS), the select() interface comes from ; - in others, from , and others from both. Including both - in this order appears to work on all. -*/ -#include -#if HAVE_SYS_SELECT_H -#include -#include /* For struct timespec on some systems */ -#endif -#endif -#include - -#include "xmlrpc-c/select_int.h" - - -/* xmlrpc_pselect() is just for use with sockets. In a POSIX system, - it technically works for any file descriptor, but in Windows, select() - is part of the socket facility. -*/ - -int -xmlrpc_pselect(int const n, - fd_set * const readfdsP, - fd_set * const writefdsP, - fd_set * const exceptfdsP, - const xmlrpc_timespec * const timeoutP, - sigset_t * const sigmaskP) { - - int retval; - -#if HAVE_PSELECT -#if !HAVE_TIMESPEC - #error "Impossible configuration -- has pselect(), but not struct timespec" -#else - retval = pselect(n, readfdsP, writefdsP, exceptfdsP, timeoutP, sigmaskP); -#endif -#else /* HAVE_PSELECT */ - struct timeval timeout; - - timeout.tv_sec = timeoutP->tv_sec; - timeout.tv_usec = timeoutP->tv_nsec/1000; -#if MSVCRT - retval = select(n, readfdsP, writefdsP, exceptfdsP, &timeout); -#else - { - sigset_t origmask; - sigprocmask(SIG_SETMASK, sigmaskP, &origmask); - retval = select(n, readfdsP, writefdsP, exceptfdsP, &timeout); - sigprocmask(SIG_SETMASK, &origmask, NULL); - } -#endif -#endif - - return retval; -} diff --git a/trunk/lib/libutil/sleep.c b/trunk/lib/libutil/sleep.c deleted file mode 100644 index a708b1280..000000000 --- a/trunk/lib/libutil/sleep.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "xmlrpc_config.h" -#include "bool.h" - -#include "xmlrpc-c/sleep_int.h" - -#if MSVCRT -# define WIN32_LEAN_AND_MEAN -# include -# include -#else -# include -#endif - - -void -xmlrpc_millisecond_sleep(unsigned int const milliseconds) { - -#if MSVCRT - SleepEx(milliseconds, true); -#else - usleep(milliseconds * 1000); -#endif -} diff --git a/trunk/lib/libutil/string_number.c b/trunk/lib/libutil/string_number.c deleted file mode 100644 index 1c284afdf..000000000 --- a/trunk/lib/libutil/string_number.c +++ /dev/null @@ -1,46 +0,0 @@ -/*============================================================================ - string_number -============================================================================== - This file contains utilities for dealing with text string representation - of numbers. -============================================================================*/ -#include -#include -#include - -#include -#include -#include -#include "xmlrpc_config.h" -#include "int.h" - -#include - - - -void -xmlrpc_parse_int64(xmlrpc_env * const envP, - const char * const str, - xmlrpc_int64 * const i64P) { - - xmlrpc_int64 i64val; - - char * tail; - - errno = 0; - i64val = XMLRPC_STRTOLL(str, &tail, 10); - - if (errno == ERANGE) - xmlrpc_faultf(envP, "Number cannot be represented in 64 bits. " - "Must be in the range " - "[%" XMLRPC_PRId64 " - %" XMLRPC_PRId64 "]", - XMLRPC_INT64_MIN, XMLRPC_INT64_MAX); - else if (errno != 0) - xmlrpc_faultf(envP, "unexpected error: " - "strtoll() failed with errno %d (%s)", - errno, strerror(errno)); - else if (tail[0] != '\0') - xmlrpc_faultf(envP, "contains non-numerical junk: '%s'", tail); - else - *i64P = i64val; -} diff --git a/trunk/lib/libutil/time.c b/trunk/lib/libutil/time.c deleted file mode 100644 index 6eee1d458..000000000 --- a/trunk/lib/libutil/time.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "xmlrpc_config.h" -#include -#include - -#if HAVE_GETTIMEOFDAY -# include -#endif - -#if MSVCRT -# define WIN32_LEAN_AND_MEAN -# include -#endif - -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/time_int.h" - - -/* A note about struct timeval and Windows: There is a 'struct - timeval' type in Windows, but it is just an argument to select(), - which is just part of the sockets interface. It's defined - identically to the POSIX type of the same name, but not meant for - general timekeeping as the POSIX type is. -*/ - -#if HAVE_GETTIMEOFDAY -static void -gettimeofdayPosix(xmlrpc_timespec * const todP) { - - struct timeval tv; - - gettimeofday(&tv, NULL); - - todP->tv_sec = tv.tv_sec; - todP->tv_nsec = tv.tv_usec * 1000; -} -#endif - - - -#if MSVCRT -static void -gettimeofdayWindows(xmlrpc_timespec * const todP) { - - __int64 const epochOffset = 116444736000000000ll; - /* Number of 100-nanosecond units between the beginning of the - Windows epoch (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970). - */ - FILETIME ft; - LARGE_INTEGER li; - __int64 t; - - GetSystemTimeAsFileTime(&ft); - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - t = (li.QuadPart - epochOffset) * 100; /* nanoseconds */ - todP->tv_sec = (long)(t / 1E9); - todP->tv_nsec = (long)(t - (__int64)todP->tv_sec * 1E9); -} -#endif - - - -void -xmlrpc_gettimeofday(xmlrpc_timespec * const todP) { - - assert(todP); - -#if HAVE_GETTIMEOFDAY - gettimeofdayPosix(todP); -#else -#if MSVCRT - gettimeofdayWindows(todP); -#else - #error "We don't know how to get the time of day on this system" -#endif -#endif /* HAVE_GETTIMEOFDAY */ -} - - - -static bool -isLeapYear(unsigned int const yearOfAd) { - - return - (yearOfAd % 4) == 0 && - ((yearOfAd % 100) != 0 || (yearOfAd % 400) == 0); -} - - - -void -xmlrpc_timegm(const struct tm * const tmP, - time_t * const timeValueP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - This does what GNU libc's timegm() does. ------------------------------------------------------------------------------*/ - if (tmP->tm_year < 70 || - tmP->tm_mon > 11 || - tmP->tm_mon < 0 || - tmP->tm_mday > 31 || - tmP->tm_min > 60 || - tmP->tm_sec > 60 || - tmP->tm_hour > 24) { - - xmlrpc_asprintf(errorP, "Invalid time specification; a member " - "of struct tm is out of range"); - } else { - static unsigned int const monthDaysNonLeap[12] = - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - - unsigned int totalDays; - unsigned int year; - unsigned int month; - - totalDays = 0; /* initial value */ - - for (year = 70; year < (unsigned int)tmP->tm_year; ++year) - totalDays += isLeapYear(1900 + year) ? 366 : 365; - - for (month = 0; month < (unsigned int)tmP->tm_mon; ++month) - totalDays += monthDaysNonLeap[month]; - - if (tmP->tm_mon > 1 && isLeapYear(1900 + tmP->tm_year)) - totalDays += 1; - - totalDays += tmP->tm_mday - 1; - - *errorP = NULL; - - *timeValueP = ((totalDays * 24 + - tmP->tm_hour) * 60 + - tmP->tm_min) * 60 + - tmP->tm_sec; - } -} - - - -void -xmlrpc_localtime(time_t const datetime, - struct tm * const tmP) { -/*---------------------------------------------------------------------------- - Convert datetime from standard to broken-down format in the local - time zone. - - For Windows, this is not thread-safe. If you run a version of Abyss - with multiple threads, you can get arbitrary results here. ------------------------------------------------------------------------------*/ -#if HAVE_LOCALTIME_R - localtime_r(&datetime, tmP); -#else - *tmP = *localtime(&datetime); -#endif -} - - - -void -xmlrpc_gmtime(time_t const datetime, - struct tm * const resultP) { -/*---------------------------------------------------------------------------- - Convert datetime from standard to broken-down UTC format. - - For Windows, this is not thread-safe. If you run a version of Abyss - with multiple threads, you can get arbitrary results here. ------------------------------------------------------------------------------*/ - -#if HAVE_GMTIME_R - gmtime_r(&datetime, resultP); -#else - *resultP = *gmtime(&datetime); -#endif -} diff --git a/trunk/lib/libutil/utf8.c b/trunk/lib/libutil/utf8.c deleted file mode 100644 index 7f749dc1b..000000000 --- a/trunk/lib/libutil/utf8.c +++ /dev/null @@ -1,608 +0,0 @@ -/* Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -/*========================================================================= -** XML-RPC UTF-8 Utilities -**========================================================================= -** Routines for validating, encoding and decoding UTF-8 data. We try to -** be very, very strict about invalid UTF-8 data. -** -** All of the code in this file assumes that your machine represents -** wchar_t as a 16-bit (or wider) character containing UCS-2 data. If this -** assumption is incorrect, you may need to replace this file. -** -** For lots of information on Unicode and UTF-8 decoding, see: -** http://www.cl.cam.ac.uk/~mgk25/unicode.html -*/ - -#include -#include "int.h" - -#include "xmlrpc_config.h" -#include "bool.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/util_int.h" - -/*========================================================================= -** Tables and Constants -**========================================================================= -** We use a variety of tables and constants to help decode and validate -** UTF-8 data. -*/ - -static unsigned char utf8SeqLength[256] = { - - /* utf8SeqLength[B] is the number of bytes in a UTF-8 sequence that starts - with byte B. Except zero indicates an illegal initial byte. - - Fredrik Lundh's UTF-8 decoder Python 2.0 uses a similar table. But since - Python 2.0 has the icky CNRI license, I generated this table from scratch - and wrote my own decoder. - */ - - /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - /* 0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 1 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 2 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 3 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 5 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 6 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 7 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* A */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* B */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* C */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - /* D */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - /* E */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - /* F */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0 -}; - -/* The minimum legal character value for a UTF-8 sequence of the given -** length. We have to check this to avoid accepting "overlong" UTF-8 -** sequences, which use more bytes than necessary to encode a given -** character. Such sequences are commonly used by evil people to bypass -** filters and security checks. This table is based on the UTF-8-test.txt -** file by Markus Kuhn . */ -static uint32_t const utf8_min_char_for_length[] = { - 0, /* Length 0: Not used (meaningless) */ - 0x0000, /* Length 1: Not used (special-cased) */ - 0x0080, /* Length 2 */ - 0x0800, /* Length 3 */ - 0x00010000, /* Length 4 */ - 0x00200000, /* Length 5 */ - 0x04000000 /* Length 6 */ -}; - -/* This is the maximum legal 16-byte (UCS-2) character. Again, this -** information is based on UTF-8-test.txt. */ -#define UCS2_MAX_LEGAL_CHARACTER (0xFFFD) - -/* First and last UTF-16 surrogate characters. These are *not* legal UCS-2 -** characters--they're used to code for UCS-4 characters when using -** UTF-16. They should never appear in decoded UTF-8 data! Again, these -** could hypothetically be used to bypass security measures on some machines. -** Based on UTF-8-test.txt. */ -#define UTF16_FIRST_SURROGATE (0xD800) -#define UTF16_LAST_SURROGATE (0xDFFF) - -/* Is the character 'c' a UTF-8 continuation character? */ -#define IS_CONTINUATION(c) (((c) & 0xC0) == 0x80) - -#define MAX_ENCODED_BYTES (3) - /* Maximum number of bytes needed to encode in UTF-8 a character - in the Basic Multilingual Plane. - */ - - -#if HAVE_UNICODE_WCHAR - - -static void -validateContinuation(xmlrpc_env * const envP, - char const c) { - - if (!IS_CONTINUATION(c)) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INVALID_UTF8_ERROR, - "UTF-8 multibyte sequence contains character 0x%02x, " - "which does not indicate continuation.", c); -} - - - -static void -validateUtf16(xmlrpc_env * const envP, - wchar_t const wc) { -/*---------------------------------------------------------------------------- - Validate that the string is a legal UTF16 encoding of a Unicode - character. - - Actually, we validate that it is UCS-2. The set of UCS-2 encodings is a - subset of the set of UTF16 encodings. In particular, it is the set of - UTF16 encodings that are 16 bits. UCS-2 is a fixed-length encoding, with - 16 bits per character, whereas UTF16 is variable length, with 1 or more 16 - bit units per character. - - The name of the subroutine reflects the fact that in concept, we _should_ - accept any UTF16, but we haven't taken the time yet to figure out how to do - that (in the big picture, not just this subroutine). The user will notice - only if he uses those really arcane 3.1% of the Unicode characters that - take more than 16 bits to represent in UTF16. ------------------------------------------------------------------------------*/ - if (wc > UCS2_MAX_LEGAL_CHARACTER) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INVALID_UTF8_ERROR, - "Xmlrpc-c is not capable of handling UTF16 character encodings " - "longer than 16 bits, which means you can't have a code point " - "> U+FFFD. " - "This string contains 0x%04x", - (unsigned)wc); - else if (UTF16_FIRST_SURROGATE <= wc && wc <= UTF16_LAST_SURROGATE) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INVALID_UTF8_ERROR, - "UTF-16 surrogates may not appear in UTF-8 data. " - "String contains %04x", (unsigned)wc); -} - - - -/* Microsoft Visual C in debug mode produces code that complains about - returning an undefined value from xmlrpc_datetime_new_str(). It's a bogus - complaint, because this function is defined to return nothing meaningful - those cases. So we disable the check. -*/ -#pragma runtime_checks("u", off) - -static void -decodeMultibyte(xmlrpc_env * const envP, - const char * const utf8_seq, - size_t const length, - wchar_t * const wcP) { -/*---------------------------------------------------------------------------- - Decode the multibyte UTF-8 sequence which is 'length' characters - at 'utf8_data'. - - Return the character in UTF-16 format as *wcP. ------------------------------------------------------------------------------*/ - wchar_t wc; - - assert(utf8_seq[0] & 0x80); /* High bit set: this is multibyte seq */ - - switch (length) { - case 2: - /* 110xxxxx 10xxxxxx */ - validateContinuation(envP, utf8_seq[1]); - - if (!envP->fault_occurred) - wc = ((((wchar_t) (utf8_seq[0] & 0x1F)) << 6) | - (((wchar_t) (utf8_seq[1] & 0x3F)))); - break; - - case 3: - /* 1110xxxx 10xxxxxx 10xxxxxx */ - validateContinuation(envP, utf8_seq[1]); - if (!envP->fault_occurred) { - validateContinuation(envP, utf8_seq[2]); - if (!envP->fault_occurred) - wc = ((((wchar_t) (utf8_seq[0] & 0x0F)) << 12) | - (((wchar_t) (utf8_seq[1] & 0x3F)) << 6) | - (((wchar_t) (utf8_seq[2] & 0x3F)))); - } - break; - - case 4: - /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ - case 5: - /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ - case 6: - /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ - /* This would require more than 16 bits in UTF-16, so - it can't be represented in UCS-2, so it's beyond - our capability. Characters in the BMP fit in 16 - bits. - */ - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INVALID_UTF8_ERROR, - "UTF-8 string contains a character not in the " - "Basic Multilingual Plane (first byte 0x%02x)", - utf8_seq[0]); - break; - - default: - xmlrpc_faultf(envP, - "Internal error: Impossible UTF-8 sequence length %u", - (unsigned)length); - } - - if (!envP->fault_occurred) - validateUtf16(envP, wc); - - if (!envP->fault_occurred) - if ((uint32_t)wc < utf8_min_char_for_length[length]) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INVALID_UTF8_ERROR, - "Overlong UTF-8 sequence not allowed"); - - *wcP = wc; -} - -#pragma runtime_checks("u", restore) - - - -static void -decodeUtf8(xmlrpc_env * const envP, - const char * const utf8_data, - size_t const utf8_len, - wchar_t * const ioBuff, - size_t * const outBuffLenP) { -/*---------------------------------------------------------------------------- - Decode to UCS-2 (or validate as UTF-8 that can be decoded to UCS-2) - a UTF-8 string. To validate, set ioBuff and outBuffLenP to NULL. - To decode, allocate a sufficiently large buffer, pass it as ioBuff, - and pass a pointer as as outBuffLenP. The data will be written to - the buffer, and the length to outBuffLenP. - - We assume that wchar_t holds a single UCS-2 character in native-endian - byte ordering. ------------------------------------------------------------------------------*/ - size_t utf8Cursor; - size_t outPos; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(utf8_data); - XMLRPC_ASSERT((!ioBuff && !outBuffLenP) || (ioBuff && outBuffLenP)); - - for (utf8Cursor = 0, outPos = 0; - utf8Cursor < utf8_len && !envP->fault_occurred; - ) { - - char const init = utf8_data[utf8Cursor]; - /* Initial byte of the UTF-8 sequence */ - - wchar_t wc; - - if ((init & 0x80) == 0x00) { - /* Convert ASCII character to wide character. */ - wc = init; - ++utf8Cursor; - } else { - /* Look up the length of this UTF-8 sequence. */ - size_t const length = utf8SeqLength[(unsigned char) init]; - /* Special value 0 means no length could be determined because - it is not a valid initial byte for a UTF-8 sequence. - */ - if (length == 0) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INVALID_UTF8_ERROR, - "Unrecognized UTF-8 initial byte value 0x%02x", - (unsigned char)init); - else { - /* Make sure we have enough bytes to convert. */ - if (utf8Cursor + length > utf8_len) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INVALID_UTF8_ERROR, - "Invalid UTF-8 sequence indicates a %u-byte sequence " - "when only %u bytes are left in the string", - (unsigned)length, (unsigned)(utf8_len - utf8Cursor)); - } else { - decodeMultibyte(envP, &utf8_data[utf8Cursor], length, &wc); - - /* Advance to the end of the sequence. */ - utf8Cursor += length; - } - } - } - - if (!envP->fault_occurred) { - /* If we have a buffer, write our character to it. */ - if (ioBuff) - ioBuff[outPos++] = wc; - } - } - - if (outBuffLenP) - *outBuffLenP = envP->fault_occurred ? 0 : outPos; -} - - - -xmlrpc_mem_block * -xmlrpc_utf8_to_wcs(xmlrpc_env * const envP, - const char * const utf8_data, - size_t const utf8_len) { -/*---------------------------------------------------------------------------- - Decode UTF-8 string to a "wide character string". This function - returns an xmlrpc_mem_block with an element type of wchar_t. Don't - try to intepret the block in a bytewise fashion--it won't work in - any useful or portable fashion. - - For backward compatibility, we return a meaningful value even when we - fail. We return NULL when we fail. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * wcsP; - size_t wcs_length; - - /* Allocate a memory block large enough to hold any possible output. - We assume that each byte of the input may decode to a whcar_t. - */ - wcsP = XMLRPC_MEMBLOCK_NEW(wchar_t, envP, utf8_len); - if (!envP->fault_occurred) { - /* Decode the UTF-8 data. */ - decodeUtf8(envP, utf8_data, utf8_len, - XMLRPC_MEMBLOCK_CONTENTS(wchar_t, wcsP), - &wcs_length); - if (!envP->fault_occurred) { - /* We can't have overrun our buffer. */ - XMLRPC_ASSERT(wcs_length <= utf8_len); - - /* Correct the length of the memory block. */ - XMLRPC_MEMBLOCK_RESIZE(wchar_t, envP, wcsP, wcs_length); - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(wchar_t, wcsP); - } - if (envP->fault_occurred) - return NULL; - else - return wcsP; -} - - - -xmlrpc_mem_block * -xmlrpc_wcs_to_utf8(xmlrpc_env * const envP, - const wchar_t * const wcs_data, - size_t const wcs_len) { -/*---------------------------------------------------------------------------- - Encode a "wide character string" as UTF-8. - - For backward compatibility, we return a meaningful value even when we - fail. We return NULL when we fail. ------------------------------------------------------------------------------*/ - size_t const estimate = wcs_len * MAX_ENCODED_BYTES; - /* Our conservative estimate of how big the output will be; - i.e. we know it won't be larger than this. For the estimate, - we assume that every wchar might encode to the maximum length. - */ - xmlrpc_mem_block * utf8P; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(wcs_data); - - utf8P = XMLRPC_MEMBLOCK_NEW(char, envP, estimate); - if (!envP->fault_occurred) { - unsigned char * const buffer = - XMLRPC_MEMBLOCK_CONTENTS(unsigned char, utf8P); - size_t bytesUsed; - size_t i; - - bytesUsed = 0; - for (i = 0; i < wcs_len && !envP->fault_occurred; ++i) { - wchar_t const wc = wcs_data[i]; - if (wc <= 0x007F) - buffer[bytesUsed++] = wc & 0x7F; - else if (wc <= 0x07FF) { - /* 110xxxxx 10xxxxxx */ - buffer[bytesUsed++] = 0xC0 | (wc >> 6); - buffer[bytesUsed++] = 0x80 | (wc & 0x3F); - } else if (wc <= 0xFFFF) { - /* 1110xxxx 10xxxxxx 10xxxxxx */ - buffer[bytesUsed++] = 0xE0 | (wc >> 12); - buffer[bytesUsed++] = 0x80 | ((wc >> 6) & 0x3F); - buffer[bytesUsed++] = 0x80 | (wc & 0x3F); - } else - xmlrpc_faultf(envP, - "Don't know how to encode UCS-4 characters yet"); - } - if (!envP->fault_occurred) { - XMLRPC_ASSERT(bytesUsed <= estimate); - - XMLRPC_MEMBLOCK_RESIZE(char, envP, utf8P, bytesUsed); - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, utf8P); - } - - if (envP->fault_occurred) - return NULL; - else - return utf8P; -} - - - -#else /* HAVE_UNICODE_WCHAR */ - -xmlrpc_mem_block * -xmlrpc_utf8_to_wcs(xmlrpc_env * const envP, - const char * const utf8_data ATTR_UNUSED, - size_t const utf8_len ATTR_UNUSED) { - - xmlrpc_faultf(envP, "INTERNAL ERROR: xmlrpc_utf8_to_wcs() called " - "on a system that doesn't do Unicode!"); - - return NULL; -} -#endif /* HAVE_UNICODE_WCHAR */ - - -void -xmlrpc_force_to_utf8(char * const buffer) { -/*---------------------------------------------------------------------------- - Force the contents of 'buffer' to be valid UTF-8, any way possible. - The buffer ends with a NUL character, and the mutation does not make - it longer. - - The most common reason for a string that's supposed to be UTF-8 not to be - UTF-8 is that it was supposed to be ASCII but instead includes garbage with - the high bit on (ASCII characters always have the high bit off), or maybe a - primitive 8-bit ASCII extension such as Latin1 (ISO 8859-1). Therefore, - we force it to UTF-8 by replacing some bytes that have the high bit set - with DEL (0x7F). That would leave the other characters meaningful. - - I've heard a standard way to do this is to substitute the Unicode character - U+FFFD for the garbage. But that makes it harder to keep the length of - the code the same, and in the case that the originator of these bits - wasn't thinking UTF-8 at all, it does more violence to the string than - our DEL method. ------------------------------------------------------------------------------*/ - char * p; - - for (p = &buffer[0]; *p;) { - unsigned int const length = utf8SeqLength[(unsigned char) *p]; - - bool forceDel; - uint32_t decoded; - - forceDel = false; /* initial value */ - - switch (length) { - case 1: - /* One-byte UTF-8 characters are easy. */ - decoded = *p; - break; - case 2: - /* 110xxxxx 10xxxxxx */ - if (!*(p+1) || !(*p+2)) - forceDel = true; - else if (!IS_CONTINUATION(*(p+1))) - forceDel = true; - else - decoded = - ((uint32_t)(*(p+0) & 0x1F) << 6) | - ((uint32_t)(*(p+1) & 0x3F) << 0); - break; - case 3: - /* 1110xxxx 10xxxxxx 10xxxxxx */ - if (!*(p+1) || !(*p+2) || !(*p+3)) - forceDel = true; - else if (!IS_CONTINUATION(*(p+1)) || !IS_CONTINUATION(*(p+2))) - forceDel = true; - else - decoded = - ((uint32_t)(*(p+0) & 0x0F) << 12) | - ((uint32_t)(*(p+1) & 0x3F) << 6) | - ((uint32_t)(*(p+2) & 0x3F) << 0); - break; - default: - forceDel = true; - } - - if (!forceDel) { - if (decoded > UCS2_MAX_LEGAL_CHARACTER) - forceDel = true; - else if (UTF16_FIRST_SURROGATE <= decoded && - decoded <= UTF16_LAST_SURROGATE) - forceDel = true; - else if (decoded < utf8_min_char_for_length[length]) - forceDel = true; - } - - if (forceDel) { - /* Not a valid UTF-8 character, so replace the first byte - with a nice simple ASCII DEL. - */ - *p = 0x7F; - p += 1; - } else - p += length; - } -} - - - -void -xmlrpc_force_to_xml_chars(char * const buffer) { -/*---------------------------------------------------------------------------- - Modify 'buffer' so that it contains nothing but valid XML - characters. The buffer ends with a NUL character, and the mutation - does not make it longer. - - Note that the valid characters in an XML document are all Unicode - codepoints except the ASCII control characters, plus CR, LF, and - Tab. - - We change all non-XML characters to DEL (0x7F). - - Assume input is valid UTF-8. ------------------------------------------------------------------------------*/ - char * p; - - for (p = &buffer[0]; *p;) { - unsigned int const length = utf8SeqLength[(unsigned char) *p]; - - if (length == 1) { - if (*p < 0x20 && *p != '\r' && *p != '\n' && *p != '\t') - /* Not valid XML. Force to DEL */ - *p = 0x7f; - } else { - /* We assume here that all other UTF-8 characters are - valid XML, but it's apparently not actually true. - */ - } - - { - unsigned int i; - /* Advance to next UTF-8 character */ - for (i = 0; i < length && *p; ++i) - ++p; - } - } -} - - - -void -xmlrpc_validate_utf8(xmlrpc_env * const envP, - const char * const utf8_data, - size_t const utf8_len) { -/*---------------------------------------------------------------------------- - Validate that a string is valid UTF-8. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - - xmlrpc_env_init(&env); - -#if HAVE_UNICODE_WCHAR - decodeUtf8(&env, utf8_data, utf8_len, NULL, NULL); -#else - /* We don't have a convenient way to validate, so we just fake it and - call it valid. - */ -#endif - - if (env.fault_occurred) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INVALID_UTF8_ERROR, - "%" XMLRPC_PRId64 "-byte " - "supposed UTF-8 string is not valid UTF-8. %s", - (XMLRPC_INT64)utf8_len, env.fault_string); - } - xmlrpc_env_clean(&env); -} diff --git a/trunk/lib/libwww_transport/Makefile b/trunk/lib/libwww_transport/Makefile deleted file mode 100644 index ed5c0aa69..000000000 --- a/trunk/lib/libwww_transport/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - LIBDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/libwww_transport - -include $(BLDDIR)/config.mk - -default: all - -.PHONY: all -all: xmlrpc_libwww_transport.o xmlrpc_libwww_transport.osh - -# Rules for the above dependencies are in common.mk, -# courtesy of TARGET_MODS. - -TARGET_MODS = xmlrpc_libwww_transport - -OMIT_LIBWWW_TRANSPORT_RULE=Y - -include $(SRCDIR)/common.mk - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -LIBWWW_INCLUDES := $(shell libwww-config --cflags) - -INCLUDES = \ - -I$(BLDDIR) \ - -I$(BLDDIR)/include \ - -Isrcdir/include \ - -Isrcdir/lib/util/include \ - $(LIBWWW_INCLUDES) - -.PHONY: clean -clean: clean-common - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: tags -tags: TAGS - -.PHONY: distdir -distdir: - -.PHONY: install -install: - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: dep -dep: dep-common - -include depend.mk - -# Need this dependency for those who don't use depend.mk. -# Without it, version.h doesn't get created. -xmlrpc_libwww_transport.o xmlrpc_libwww_transport.osh: version.h diff --git a/trunk/lib/libwww_transport/xmlrpc_libwww_transport.c b/trunk/lib/libwww_transport/xmlrpc_libwww_transport.c deleted file mode 100644 index c5594f915..000000000 --- a/trunk/lib/libwww_transport/xmlrpc_libwww_transport.c +++ /dev/null @@ -1,956 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include - -#include "bool.h" -#include "mallocvar.h" - -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/client_int.h" -#include "xmlrpc-c/transport.h" - -/* The libwww interface */ - -/* These headers mistakenly define the macro PACKAGE. As - xmlrpc_config.h already defines PACKAGE according to the package we're - actually part of, this causes a conflict. So we undef here and then - to avoid possible problems with an incorrect PACKAGE, we undef it again - after. -*/ -#undef PACKAGE -#include "WWWLib.h" -#include "WWWHTTP.h" -#include "WWWInit.h" -#undef PACKAGE - -/* Include our libwww SSL headers, if available. */ -#if HAVE_LIBWWW_SSL -#include "WWWSSL.h" -#endif - -/* This value was discovered by Rick Blair. His efforts shaved two seconds -** off of every request processed. Many thanks. */ -#define SMALLEST_LEGAL_LIBWWW_TIMEOUT (21) - -#define XMLRPC_CLIENT_USE_TIMEOUT (2) - - -struct xmlrpc_client_transport { - int saved_flags; - HTList *xmlrpc_conversions; - void * cookieJarP; - /* This is a collection of all the cookies that servers have set - via responses to prior requests. It's not implemented today. - */ - bool tracingOn; -}; - -static struct xmlrpc_client_transport clientTransport; - - -typedef struct { -/*---------------------------------------------------------------------------- - This object represents one RPC. ------------------------------------------------------------------------------*/ - struct xmlrpc_client_transport * clientTransportP; - - /* These fields are used when performing synchronous calls. */ - bool is_done; - int http_status; - - /* Low-level information used by libwww. */ - HTRequest * request; - HTChunk * response_data; - HTParentAnchor * source_anchor; - HTAnchor * dest_anchor; - - xmlrpc_transport_asynch_complete complete; - struct xmlrpc_call_info * callInfoP; -} rpc; - - - -static void -createCookieJar(xmlrpc_env * const envP ATTR_UNUSED, - void ** const cookieJarP ATTR_UNUSED) { - - /* Cookies not implemented yet */ -} - - - -static void -destroyCookieJar(void * cookieJarP ATTR_UNUSED) { - - /* Cookies not implemented yet */ -} - - - -static void -initLibwww(const char * const appname, - const char * const appversion) { - - /* We initialize the library using a robot profile, because we don't - care about redirects or HTTP authentication, and we want to - reduce our application footprint as much as possible. - - This takes the place of HTLibInit(). - */ - HTProfile_newRobot(appname, appversion); - - /* Ilya Goldberg provided the following code to access - ** SSL-protected servers. */ -#if HAVE_LIBWWW_SSL - /* Set the SSL protocol method. By default, it is the highest - ** available protocol. Setting it up to SSL_V23 allows the client - ** to negotiate with the server and set up either TSLv1, SSLv3, - ** or SSLv2 */ - HTSSL_protMethod_set(HTSSL_V23); - - /* Set the certificate verification depth to 2 in order to be able to - ** validate self-signed certificates */ - HTSSL_verifyDepth_set(2); - - /* Register SSL stuff for handling ssl access. The parameter we pass - ** is NO because we can't be pre-emptive with POST */ - HTSSLhttps_init(NO); -#endif /* HAVE_LIBWWW_SSL */ - - /* For interoperability with Frontier, we need to tell libwww *not* - ** to send 'Expect: 100-continue' headers. But if we're not sending - ** these, we shouldn't wait for them. So set our built-in delays to - ** the smallest legal values. */ - HTTP_setBodyWriteDelay (SMALLEST_LEGAL_LIBWWW_TIMEOUT, - SMALLEST_LEGAL_LIBWWW_TIMEOUT); - - /* We attempt to disable all of libwww's chatty, interactive - ** prompts. Let's hope this works. */ - HTAlert_setInteractive(NO); - - /* Here are some alternate setup calls which will help greatly - ** with debugging, should the need arise. - ** - ** HTProfile_newNoCacheClient(appname, appversion); - ** HTAlert_setInteractive(YES); - ** HTPrint_setCallback(printer); - ** HTTrace_setCallback(tracer); */ -} - - - -static void -create(xmlrpc_env * const envP, - int const flags, - const char * const appname, - const char * const appversion, - const void * const transportParmsP ATTR_UNUSED, - size_t const parm_size ATTR_UNUSED, - struct xmlrpc_client_transport ** const handlePP) { -/*---------------------------------------------------------------------------- - This does the 'create' operation for a Libwww client transport. - - TODO: put 'appname' and 'appversion' in *transportParmsP and - deprecate the create() arguments. Reason: these are particular to - the Libwww transport. They're create() arguments because originally, - Libwww was the only transport. ------------------------------------------------------------------------------*/ - /* The Libwww transport is not re-entrant -- you can have only one - per program instance. Even if we changed the Xmlrpc-c code not - to use global variables, that wouldn't help because Libwww - itself is not re-entrant. - - So we use a global variable ('clientTransport') for our transport state. - */ - struct xmlrpc_client_transport * const clientTransportP = &clientTransport; - *handlePP = clientTransportP; - - clientTransportP->saved_flags = flags; - - createCookieJar(envP, &clientTransportP->cookieJarP); - if (!envP->fault_occurred) { - if (!(clientTransportP->saved_flags & - XMLRPC_CLIENT_SKIP_LIBWWW_INIT)) - initLibwww(appname, appversion); - - /* Set up our list of conversions for XML-RPC requests. This is a - ** massively stripped-down version of the list in libwww's HTInit.c. - ** XXX - This is hackish; 10.0 is an arbitrary, large quality factor - ** designed to override the built-in converter for XML. */ - clientTransportP->xmlrpc_conversions = HTList_new(); - HTConversion_add(clientTransportP->xmlrpc_conversions, - "text/xml", "*/*", - HTThroughLine, 10.0, 0.0, 0.0); - - if (envP->fault_occurred) - destroyCookieJar(clientTransportP->cookieJarP); - } - if (getenv("XMLRPC_LIBWWW_TRACE")) - clientTransportP->tracingOn = TRUE; - else - clientTransportP->tracingOn = FALSE; -} - - - -static void -destroy(struct xmlrpc_client_transport * const clientTransportP) { -/*---------------------------------------------------------------------------- - This does the 'destroy' operation for a Libwww client transport. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(clientTransportP != NULL); - - if (!(clientTransportP->saved_flags & XMLRPC_CLIENT_SKIP_LIBWWW_INIT)) { - HTProfile_delete(); - /* This takes the place of HTLibTerminate() */ - } - destroyCookieJar(clientTransportP->cookieJarP); - HTConversion_deleteAll(clientTransportP->xmlrpc_conversions); - HTProfile_delete(); -} - - - -/*========================================================================= -** HTTP Error Reporting -**=======================================================================*/ - -static void -formatLibwwwError(HTRequest * const requestP, - const char ** const msgP) { -/*---------------------------------------------------------------------------- - When something fails in a Libwww request, Libwww generates a stack - of error information (precious little information, of course, in the - Unix tradition) and attaches it to the request object. We make a message - out of that information. - - We rely on Libwww's HTDialog_errorMessage() to do the bulk of the - formatting; we might be able to coax more information out of the request - if we interpreted the error stack directly. ------------------------------------------------------------------------------*/ - HTList * const errStack = HTRequest_error(requestP); - - if (errStack == NULL) - xmlrpc_asprintf(msgP, "Libwww supplied no error details"); - else { - /* Get an error message from libwww. The middle three - parameters to HTDialog_errorMessage appear to be ignored. - XXX - The documentation for this API is terrible, so we may - be using it incorrectly. - */ - const char * const msg = - HTDialog_errorMessage(requestP, HT_A_MESSAGE, HT_MSG_NULL, - "An error occurred", errStack); - - if (msg == NULL) - xmlrpc_asprintf(msgP, "Libwww supplied some error detail, " - "but its HTDialog_errorMessage() subroutine " - "mysteriously failed to interpret it for us."); - else - *msgP = msg; - } -} - - - -static void -set_fault_from_http_request(xmlrpc_env * const envP, - int const status, - HTRequest * const requestP) { -/*---------------------------------------------------------------------------- - Assuming 'requestP' identifies a completed libwww HTTP request, set - *envP according to its success/error status. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_PTR_OK(requestP); - - if (status == 200) { - /* No error. Don't set one in *envP */ - } else { - const char * libwwwMsg; - formatLibwwwError(requestP, &libwwwMsg); - - if (status == -1) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NETWORK_ERROR, - "Unable to complete the HTTP request. %s", libwwwMsg); - else { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NETWORK_ERROR, - "HTTP request completed with HTTp error %d. %s", - status, libwwwMsg); - } - xmlrpc_strfree(libwwwMsg); - } -} - - - -static BOOL -setCookie(HTRequest * const request, - HTCookie * const cookieP ATTR_UNUSED, - void * const param ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - This is the callback from libwww to tell us the server (according to - its response) wants us to store a cookie (and include it in future - requests). - - We assume that the cookies "domain" is the server's host name - (there are options on the libwww connection to make libwww call this - callback only when that's the case). ------------------------------------------------------------------------------*/ - rpc * const rpcP = HTRequest_context(request); - struct xmlrpc_client_transport * const clientTransportP = - rpcP->clientTransportP; - - BOOL retval; - - /* Avoid unused variable warning */ - if (clientTransportP->cookieJarP == clientTransportP->cookieJarP) {} - /* Cookies are not implemented today */ - retval = NO; - - return retval; -} - - - -static HTAssocList * -cookiesForHost(const char * const host ATTR_UNUSED, - void * const cookieJarP ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - Find and return all the cookies in jar 'cookieJarP' that are for the - host 'host'. ------------------------------------------------------------------------------*/ - HTAssocList * hisCookiesP; - - hisCookiesP = HTAssocList_new(); - - if (hisCookiesP) { - /* Cookies are not implemented yet */ - /* Library/Examples/cookie.c in the w3c-libwww source tree contains - an example of constructing the cookie list we are supposed to - return. But today, we return an empty list. - */ - } - return hisCookiesP; -} - - - -static HTAssocList * -findCookie(HTRequest * const request, - void * const param ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - This is the callback from libwww to get the cookies to include in a - request (presumably values the server set via a prior response). ------------------------------------------------------------------------------*/ - rpc * const rpcP = HTRequest_context(request); - struct xmlrpc_client_transport * const clientTransportP = - rpcP->clientTransportP; - const char * const addr = - HTAnchor_address((HTAnchor *) HTRequest_anchor(request)); - const char * const host = HTParse(addr, "", PARSE_HOST); - - return cookiesForHost(host, clientTransportP->cookieJarP); -} - - - -static void -deleteSourceAnchor(HTParentAnchor * const anchor) { - - /* We need to clear the document first, or else libwww won't - ** really delete the anchor. */ - HTAnchor_setDocument(anchor, NULL); - - /* XXX - Deleting this anchor causes HTLibTerminate to dump core. */ - /* HTAnchor_delete(anchor); */ -} - - - -static void -createSourceAnchor(xmlrpc_env * const envP, - HTParentAnchor ** const sourceAnchorPP, - xmlrpc_mem_block * const xmlP) { - - HTParentAnchor * const sourceAnchorP = HTTmpAnchor(NULL); - - if (sourceAnchorP == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Unable to build source anchor. HTTmpAnchor() failed."); - else { - HTAnchor_setDocument(sourceAnchorP, - XMLRPC_MEMBLOCK_CONTENTS(char, xmlP)); - HTAnchor_setFormat(sourceAnchorP, HTAtom_for("text/xml")); - HTAnchor_setLength(sourceAnchorP, XMLRPC_MEMBLOCK_SIZE(char, xmlP)); - - *sourceAnchorPP = sourceAnchorP; - } -} - - - -static void -createDestAnchor(xmlrpc_env * const envP, - HTAnchor ** const destAnchorPP, - const xmlrpc_server_info * const serverP) { - - *destAnchorPP = HTAnchor_findAddress(serverP->serverUrl); - - if (*destAnchorPP == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Could not build destination anchor. HTAnchor_findAddress() " - "failed."); -} - - - -static void -rpcCreate(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, - rpc ** const rpcPP) { - - rpc *rpcP; - HTRqHd request_headers; - HTStream *target_stream; - - /* Allocate our structure. */ - MALLOCVAR(rpcP); - XMLRPC_FAIL_IF_NULL(rpcP, envP, XMLRPC_INTERNAL_ERROR, - "Out of memory in rpcCreate()"); - - /* Set up our basic members. */ - rpcP->clientTransportP = clientTransportP; - rpcP->is_done = FALSE; - rpcP->http_status = 0; - rpcP->complete = complete; - rpcP->callInfoP = callInfoP; - - /* Start cookie handler. */ - HTCookie_init(); - HTCookie_setCallbacks(setCookie, NULL, findCookie, NULL); - HTCookie_setCookieMode(HT_COOKIE_ACCEPT | - HT_COOKIE_SEND | - HT_COOKIE_SAME_HOST); - - /* Cookies aren't implemented today; reset. */ - HTCookie_setCookieMode(0); - - /* Create a HTRequest object. */ - rpcP->request = HTRequest_new(); - XMLRPC_FAIL_IF_NULL(rpcP, envP, XMLRPC_INTERNAL_ERROR, - "HTRequest_new failed"); - - /* Install ourselves as the request context. */ - HTRequest_setContext(rpcP->request, rpcP); - - /* XXX - Disable the 'Expect:' header so we can talk to Frontier. */ - request_headers = HTRequest_rqHd(rpcP->request); - request_headers = request_headers & ~HT_C_EXPECT; - HTRequest_setRqHd(rpcP->request, request_headers); - - /* Send an authorization header if we need one. */ - if (serverP->allowedAuth.basic) - HTRequest_addCredentials(rpcP->request, "Authorization", - (char *)serverP->basicAuthHdrValue); - - /* Make sure there is no XML conversion handler to steal our data. - ** The 'override' parameter is currently ignored by libwww, so our - ** list of conversions must be designed to co-exist with the built-in - ** conversions. */ - HTRequest_setConversion(rpcP->request, - clientTransportP->xmlrpc_conversions, NO); - - /* Set up our response buffer. */ - target_stream = HTStreamToChunk(rpcP->request, &rpcP->response_data, 0); - XMLRPC_FAIL_IF_NULL(rpcP->response_data, envP, XMLRPC_INTERNAL_ERROR, - "HTStreamToChunk failed"); - XMLRPC_ASSERT(target_stream != NULL); - HTRequest_setOutputStream(rpcP->request, target_stream); - HTRequest_setOutputFormat(rpcP->request, WWW_SOURCE); - - createSourceAnchor(envP, &rpcP->source_anchor, xmlP); - - if (!envP->fault_occurred) { - createDestAnchor(envP, &rpcP->dest_anchor, serverP); - - if (envP->fault_occurred) - /* See below for comments about deleting the source and dest - ** anchors. This is a bit of a black art. */ - deleteSourceAnchor(rpcP->source_anchor); - } - - cleanup: - if (envP->fault_occurred) { - if (rpcP) { - if (rpcP->request) - HTRequest_delete(rpcP->request); - if (rpcP->response_data) - HTChunk_delete(rpcP->response_data); - free(rpcP); - } - } - *rpcPP = rpcP; -} - - - -static void -rpcDestroy(rpc * const rpcP) { - - XMLRPC_ASSERT_PTR_OK(rpcP); - XMLRPC_ASSERT(rpcP->request != NULL); - XMLRPC_ASSERT(rpcP->response_data != NULL); - - /* Junji Kanemaru reports on 05.04.11 that with asynch calls, he - get a segfault, and reversing the order of deleting the request - and the response chunk buffer cured it. But we find no reason - that should be so, so we're waiting for someone to arrive at an - explanation before changing anything. HTRequest_delete() does - destroy the output stream, and the output stream refers to the - response chunk, but HTRequest_delete() explicitly refrains from - destroying the response chunk. And the response chunk does not - refer to the request. - */ - - HTRequest_delete(rpcP->request); - rpcP->request = NULL; - HTChunk_delete(rpcP->response_data); - rpcP->response_data = NULL; - - /* This anchor points to private data, so we're allowed to delete it. */ - deleteSourceAnchor(rpcP->source_anchor); - - /* WARNING: We can't delete the destination anchor, because this points - ** to something in the outside world, and lives in a libwww hash table. - ** Under certain circumstances, this anchor may have been reissued to - ** somebody else. So over time, the anchor cache will grow. If this - ** is a problem for your application, read the documentation for - ** HTAnchor_deleteAll. - ** - ** However, we CAN check to make sure that no documents have been - ** attached to the anchor. This assertion may fail if you're using - ** libwww for something else, so please feel free to comment it out. */ - /* XMLRPC_ASSERT(HTAnchor_document(rpcP->dest_anchor) == NULL); - */ - - HTCookie_deleteCallbacks(); - HTCookie_terminate(); - - free(rpcP); -} - - - -static void -extract_response_chunk(xmlrpc_env * const envP, - rpc * const rpcP, - xmlrpc_mem_block ** const responseXmlPP) { - - /* Implementation warning: A Libwww chunk has nothing to do with - an HTTP chunk. HTTP chunks (as in a chunked response) are not - visible to us; Libwww delivers the entire unchunked body to us - at once (we never see chunk headers and trailers). This - subroutine is about a Libwww chunk, which is just a memory - buffer. (Libwww is capable of delivering the response in a - number of ways other than a chunk, e.g. it can write it to a - file. - */ - - /* Check to make sure that w3c-libwww actually sent us some data. - ** XXX - This may happen if libwww is shut down prematurely, believe it - ** or not--we'll get a 200 OK and no data. Gag me with a bogus design - ** decision. This may also fail if some naughty libwww converter - ** ate our data unexpectedly. */ - if (!HTChunk_data(rpcP->response_data)) - xmlrpc_env_set_fault(envP, XMLRPC_NETWORK_ERROR, - "w3c-libwww returned no data"); - else { - *responseXmlPP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - if (rpcP->clientTransportP->tracingOn) { - fprintf(stderr, "HTTP chunk received: %u bytes: '%.*s'", - HTChunk_size(rpcP->response_data), - HTChunk_size(rpcP->response_data), - HTChunk_data(rpcP->response_data)); - } - - XMLRPC_MEMBLOCK_APPEND(char, envP, *responseXmlPP, - HTChunk_data(rpcP->response_data), - HTChunk_size(rpcP->response_data)); - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, *responseXmlPP); - } - } -} - - - -static int -synch_terminate_handler(HTRequest * const request, - HTResponse * const response ATTR_UNUSED, - void * const param ATTR_UNUSED, - int const status) { -/*---------------------------------------------------------------------------- - This is a libwww request completion handler. - - HTEventList_newLoop() calls this when it completes a request (with this - registered as the completion handler). ------------------------------------------------------------------------------*/ - rpc *rpcP; - - rpcP = HTRequest_context(request); - - rpcP->is_done = TRUE; - rpcP->http_status = status; - - HTEventList_stopLoop(); - - return HT_OK; -} - - - -static void -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) { -/*---------------------------------------------------------------------------- - This does the 'call' operation for a Libwww client transport. ------------------------------------------------------------------------------*/ - rpc * rpcP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(xmlP); - XMLRPC_ASSERT_PTR_OK(responsePP); - - rpcCreate(envP, clientTransportP, serverP, xmlP, NULL, NULL, &rpcP); - if (!envP->fault_occurred) { - int ok; - - /* Install our request handler. */ - HTRequest_addAfter(rpcP->request, &synch_terminate_handler, - NULL, NULL, HT_ALL, HT_FILTER_LAST, NO); - - /* Start our request running. */ - ok = HTPostAnchor(rpcP->source_anchor, - rpcP->dest_anchor, - rpcP->request); - if (!ok) - xmlrpc_env_set_fault( - envP, XMLRPC_NETWORK_ERROR, - "Libwww HTPostAnchor() failed to start POST request"); - else { - /* Run our event-processing loop. HTEventList_newLoop() - is what calls synch_terminate_handler(), by virtue of - it being registered as a handler. It may return for - other reasons than the request being complete, though. - so we call it in a loop until synch_terminate_handler() - really has been called. - */ - while (!rpcP->is_done) - HTEventList_newLoop(); - - /* Fail if we didn't get a "200 OK" response from the server */ - if (rpcP->http_status != 200) - set_fault_from_http_request( - envP, rpcP->http_status, - rpcP->request); - else { - /* XXX - Check to make sure response type is text/xml here. */ - - extract_response_chunk(envP, rpcP, responsePP); - } - } - rpcDestroy(rpcP); - } -} - - - -/*========================================================================= -** Event Loop -**========================================================================= -** We manage a fair bit of internal state about our event loop. This is -** needed to determine when (and if) we should exit the loop. -*/ - -static int outstanding_asynch_calls = 0; -static int event_loop_flags = 0; -static int timer_called = 0; - -static void -register_asynch_call(void) { - XMLRPC_ASSERT(outstanding_asynch_calls >= 0); - ++outstanding_asynch_calls; -} - - - -static void -unregister_asynch_call(void) { - - XMLRPC_ASSERT(outstanding_asynch_calls > 0); - --outstanding_asynch_calls; - if (outstanding_asynch_calls == 0) - HTEventList_stopLoop(); -} - - - -static int -timer_callback(HTTimer * const timer ATTR_UNUSED, - void * const user_data ATTR_UNUSED, - HTEventType const event ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - A handy timer callback which cancels the running event loop. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(event == HTEvent_TIMEOUT); - timer_called = 1; - HTEventList_stopLoop(); - - /* XXX - The meaning of this return value is undocumented, but close - ** inspection of libwww's source suggests that we want to return HT_OK. */ - return HT_OK; -} - - - -static void -eventLoopRun(int const flags, - xmlrpc_timeout const milliseconds) { -/*---------------------------------------------------------------------------- - Process all responses from outstanding requests as they come in. - Return when there are no more outstanding responses. - - Or, if 'flags' has the XMLRPC_CLIENT_USE_TIMEOUT flag set, return - when 'milliseconds' milliseconds have elapsed, regardless of whether - there are still outstanding responses. - - The processing we do consists of telling libwww to process the - completion of the libwww request. That normally includes calling - the xmlrpc_libwww_transport request termination handler, because - the submitter of the libwww request would have registered that as a - callback. ------------------------------------------------------------------------------*/ - if (outstanding_asynch_calls > 0) { - HTTimer *timer; - - event_loop_flags = flags; - - /* Run an appropriate event loop. The HTEeventList_newLoop() - is what calls asynch_terminate_handler(), by virtue of it - being registered as a handler. - */ - if (event_loop_flags & XMLRPC_CLIENT_USE_TIMEOUT) { - - /* Run our event loop with a timer. Note that we need to be very - ** careful about race conditions--timers can be fired in either - ** HTimer_new or HTEventList_newLoop. And if our callback were to - ** get called before we entered the loop, we would never exit. - ** So we use a private flag of our own--we can't even rely on - ** HTTimer_hasTimerExpired, because that only checks the time, - ** not whether our callback has been run. Yuck. */ - timer_called = 0; - timer = HTTimer_new(NULL, &timer_callback, NULL, - milliseconds, YES, NO); - XMLRPC_ASSERT(timer != NULL); - if (!timer_called) - HTEventList_newLoop(); - HTTimer_delete(timer); - - } else { - /* Run our event loop without a timer. */ - HTEventList_newLoop(); - } - - /* Reset our flags, so we don't interfere with direct calls to the - ** libwww event loop functions. */ - event_loop_flags = 0; - } else { - /* There are *no* calls to process. This may mean that none - of the asynch calls were ever set up, and the client's - callbacks have already been called with an error, or that - all outstanding calls were completed during a previous - synchronous call. - */ - } -} - - - -static void -finishAsynch( - struct xmlrpc_client_transport * const clientTransportP ATTR_UNUSED, - xmlrpc_timeoutType const timeoutType, - xmlrpc_timeout const timeout) { -/*---------------------------------------------------------------------------- - This does the 'finish_asynch' operation for a Libwww client transport. ------------------------------------------------------------------------------*/ - eventLoopRun(timeoutType == timeout_yes ? XMLRPC_CLIENT_USE_TIMEOUT : 0, - timeout); -} - - - -static int -asynch_terminate_handler(HTRequest * const request, - HTResponse * const response ATTR_UNUSED, - void * const param ATTR_UNUSED, - int const status) { -/*---------------------------------------------------------------------------- - Handle the completion of a libwww request. - - This is the bottom half of the xmlrpc_libwww_transport asynchronous - call dispatcher. It's what the dispatcher registers with libwww as - a "local after filter" so that libwww calls it when a request that - xmlrpc_libwww_transport submitted to it is complete. - - We destroy the RPC, including the request which is our argument. - Strange as that may seem, it is apparently legal for an after filter - to destroy the request that was passed to it -- or not. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - rpc * rpcP; - xmlrpc_mem_block * responseXmlP; - - XMLRPC_ASSERT_PTR_OK(request); - - xmlrpc_env_init(&env); - - rpcP = HTRequest_context(request); - - /* Unregister this call from the event loop. Among other things, this - ** may decide to stop the event loop. - **/ - unregister_asynch_call(); - - /* Give up if an error occurred. */ - if (status != 200) - set_fault_from_http_request(&env, status, request); - else { - /* XXX - Check to make sure response type is text/xml here. */ - extract_response_chunk(&env, rpcP, &responseXmlP); - } - rpcP->complete(rpcP->callInfoP, responseXmlP, env); - - if (!env.fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, responseXmlP); - - rpcDestroy(rpcP); - - xmlrpc_env_clean(&env); - return HT_OK; -} - - - -static void -sendRequest(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, - xmlrpc_transport_progress progress ATTR_UNUSED, - struct xmlrpc_call_info * const callInfoP) { -/*---------------------------------------------------------------------------- - Initiate an XML-RPC rpc asynchronously. Don't wait for it to go to - the server. - - Unless we return failure, we arrange to have complete() called when - the rpc completes. - - This does the 'send_request' operation for a Libwww client transport. ------------------------------------------------------------------------------*/ - rpc * rpcP; - - XMLRPC_ASSERT_PTR_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(xmlP); - XMLRPC_ASSERT_PTR_OK(callInfoP); - - rpcCreate(envP, clientTransportP, serverP, xmlP, complete, callInfoP, - &rpcP); - if (!envP->fault_occurred) { - int ok; - - /* Install our request handler. */ - HTRequest_addAfter(rpcP->request, &asynch_terminate_handler, - NULL, NULL, HT_ALL, HT_FILTER_LAST, NO); - - /* Register our asynchronous call with the event loop. This means - the user's callback is guaranteed to be called eventually. - */ - register_asynch_call(); - - /* This makes the TCP connection and sends the XML to the server - as an HTTP POST request. - - There was a comment here that said this might return failure - (!ok) and still invoke our completion handler - (asynch_terminate_handler(). The code attempted to deal with - that. Well, it's impossible to deal with that, so if it really - happens, we must fix Libwww. -Bryan 04.11.23. - */ - - ok = HTPostAnchor(rpcP->source_anchor, - rpcP->dest_anchor, - rpcP->request); - if (!ok) { - unregister_asynch_call(); - xmlrpc_env_set_fault(envP, XMLRPC_NETWORK_ERROR, - "Libwww (HTPostAnchor()) failed to start the " - "POST request."); - } - if (envP->fault_occurred) - rpcDestroy(rpcP); - } -} - - - -struct xmlrpc_client_transport_ops xmlrpc_libwww_transport_ops = { - NULL, - NULL, - &create, - &destroy, - &sendRequest, - &call, - &finishAsynch, - NULL, -}; diff --git a/trunk/lib/openssl/Makefile b/trunk/lib/openssl/Makefile deleted file mode 100644 index 87fda28af..000000000 --- a/trunk/lib/openssl/Makefile +++ /dev/null @@ -1,121 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - LIBDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/openssl - -include $(BLDDIR)/config.mk - -default: all - -MODS := xmlrpc_openssl_thread - -TARGET_MODS = $(MODS) - -TARGET_LIBRARY_NAMES := libxmlrpc_openssl - -STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_openssl.a - -SHARED_LIBS_TO_BUILD := libxmlrpc_openssl -SHARED_LIBS_TO_INSTALL := libxmlrpc_openssl - -PKGCONFIG_FILES_TO_INSTALL := xmlrpc_openssl.pc - -MAJ := 1 - -OPENSSL_INCLUDES := $(shell pkg-config openssl --cflags) -OPENSSL_LIBS := $(shell pkg-config openssl --libs) - -include $(SRCDIR)/common.mk - -OPENSSL_SHLIB = $(call shlibfn,libxmlrpc_openssl) -#OPENSSL_SHLIB is e.g. libxmlrpc_openssl.so.3.1 -OPENSSL_SHLIBLE = $(call shliblefn,libxmlrpc_openssl) -#OPENSSL_SHLIBLE is e.g. libxmlrpc_openssl.so - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -.PHONY: all -all: libxmlrpc_openssl.a \ - $(TARGET_SHARED_LIBRARIES) \ - $(TARGET_SHARED_LE_LIBS) \ - $(PKGCONFIG_FILES_TO_INSTALL) \ - -# Rules for the above dependencies are in common.mk, -# courtesy of TARGET_MODS. - -# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES -$(OPENSSL_SHLIB): $(TARGET_MODS:%=%.osh) \ - $(LIBXMLRPC_UTIL) -$(OPENSSL_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) -$(OPENSSL_SHLIB): LIBDEP = $(LIBXMLRPC_UTIL_LIBDEP) $(OPENSSL_LIBS) - -# Rule for this is in common.mk, courtesy of TARGET_STATIC_LIBRARIES: - -libxmlrpc_openssl.a: $(TARGET_MODS:%=%.o) -libxmlrpc_openssl.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) - -#----------------------------------------------------------------------------- -# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES -#----------------------------------------------------------------------------- - -INCLUDES = \ - -I$(BLDDIR) \ - -I$(BLDDIR)/include \ - -Isrcdir/include \ - -Isrcdir/lib/util/include \ - $(OPENSSL_INCLUDES) - -#----------------------------------------------------------------------------- -# RULES TO MAKE PKGCONFIG FILES -# -# (These are files used by the 'pkg-config' program to get information about -# using the libraries we build) -#----------------------------------------------------------------------------- - -xmlrpc_openssl.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_openssl" >>$@ - @echo "Description: Openssl convenience function from Xmlrpc-c package" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_openssl" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -#----------------------------------------------------------------------------- -# MISCELLANEOUS -#----------------------------------------------------------------------------- - -.PHONY: clean -clean: clean-common - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: tags -tags: TAGS - -.PHONY: distdir -distdir: - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: dep -dep: dep-common - -include depend.mk - -# Need this dependency for those who don't use depend.mk. -# Without it, version.h doesn't get created. -xmlrpc_curl_transport.o xmlrpc_curl_transport.osh: version.h diff --git a/trunk/lib/openssl/xmlrpc_openssl_thread.c b/trunk/lib/openssl/xmlrpc_openssl_thread.c deleted file mode 100644 index a7a7b46fe..000000000 --- a/trunk/lib/openssl/xmlrpc_openssl_thread.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "xmlrpc_config.h" -#include -#include -#include - -#include "mallocvar.h" - -#include "xmlrpc-c/string_int.h" - -#include "xmlrpc-c/openssl_thread.h" - - -/* These ugly global variables are necessary and appropriate because our - purpose is to manipulate OpenSSL's ugly global state. -*/ - -static pthread_mutex_t * opensslMutex; - /* Dynamically allocated array with an entry for each lock OpenSSL - has created. opensslMutex[N] is the mutex for the lock known by - OpenSSL with ID N. - */ - -static unsigned int maxLockCt; - - - -static void -lock(int const mode, - int const lockId, - const char * const fileName ATTR_UNUSED, - int const lineNum ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - This is a locking function for OpenSSL to call when it wants to lock or - unlock a lock. ------------------------------------------------------------------------------*/ - assert(lockId >= 0); - assert((unsigned int)lockId < maxLockCt); - - pthread_mutex_t * const mutexP = &opensslMutex[lockId]; - - if (mode & CRYPTO_LOCK) - pthread_mutex_lock(mutexP); - else - pthread_mutex_unlock(mutexP); -} - - - -static unsigned long -id(void) { -/*---------------------------------------------------------------------------- - This is an ID function for OpenSSL to call when it wants a unique - identifier of the executing thread. ------------------------------------------------------------------------------*/ - return ((unsigned long)pthread_self()); -} - - - -void -xmlrpc_openssl_thread_setup(const char ** const errorP) { -/*---------------------------------------------------------------------------- - Set up the OpenSSL library to handle being called by multiple threads - concurrently. - - This setup is process-global, so this must be called exactly once in the - program (ergo a subroutine library cannot normally call this under the - covers; if a subroutine library want to use OpenSSL in a thread-safe - manner, it must depend upon its user to call this). - - This needs to be called as the program starts up, when it is only one - thread. - - (But this need not be called at all in a program that will never call - OpenSSL functions from multiple threads). ------------------------------------------------------------------------------*/ - maxLockCt = CRYPTO_num_locks(); - - MALLOCARRAY(opensslMutex, maxLockCt); - - if (!opensslMutex) - xmlrpc_asprintf(errorP, "Failed to allocate an array for %u " - "potential OpenSSL locks", maxLockCt); - else { - *errorP = NULL; - - unsigned int i; - - for (i = 0; i < maxLockCt; ++i) - pthread_mutex_init(&opensslMutex[i], NULL); - - CRYPTO_set_id_callback(id); - - CRYPTO_set_locking_callback(lock); - } -} - - - -void -xmlrpc_openssl_thread_cleanup() { -/*---------------------------------------------------------------------------- - Undo 'xmlrpc_openssl_thread_setup'. - - This should be called at the end of a program, when there is only one - thread left. - - (As a practical matter, there's really no need to call this at all; if the - program is just going to exit afterward, any cleanup we do is moot). ------------------------------------------------------------------------------*/ - CRYPTO_set_locking_callback(NULL); - - CRYPTO_set_id_callback(NULL); - - { - unsigned int i; - - for (i = 0; i < maxLockCt; ++i) - pthread_mutex_destroy(&opensslMutex[i]); - } - free(opensslMutex); -} - - diff --git a/trunk/lib/util/Makefile b/trunk/lib/util/Makefile deleted file mode 100644 index 0d406b6ef..000000000 --- a/trunk/lib/util/Makefile +++ /dev/null @@ -1,84 +0,0 @@ -############################################################################### -# This directory builds object modules that provide utility functions that -# programs can use. Not libraries, though -- just programs. The reason -# we don't want any library to use object modules in here is that they'll -# probably pollute the name space when users link those libraries to their -# programs. In fact, if more than one Xmlrpc-c library included one of these -# modules, the libraries would conflict with each other. -# -# So a utility function that is to be used by libraries (and, optionally, -# programs) should go in libxmlrpc_util. libxmlrpc_util is a prerequisite -# for many Xmlrpc-c libraries, gets included in a program link only once, -# and uses external symbol names that have the "xmlrpc_" prefix to avoid -# collision with users' code. -# -# If we knew a portable way to link multiple object modules into one and -# restrict the symbols exported by the whole, we could avoid this mess and -# just link utility object modules into each Xmlrpc-c library. -############################################################################## - -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - LIBDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/util - -default: all - -include $(BLDDIR)/config.mk - -OMIT_UTILS_RULE = Y - -include $(SRCDIR)/common.mk - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -LIBOBJS = \ - casprintf.o \ - cmdline_parser.o \ - getoptx.o \ - string_parser.o \ - stripcaseeq.o \ - -# If the overall build is not building C++ libraries, then it isn't building -# any tools that use them, and it's a good assumption that it isn't building -# any program written in C++. Since the main reason for not building C++ -# libraries is that your build system can't compile C++, it makes sense not to -# attempt to compile any C++ code if we're not building C++ libraries. Hence, -# we don't build any C++ code here if ENABLE_CPLUSPLUS is "no". - -ifeq ($(ENABLE_CPLUSPLUS),yes) - LIBOBJS += cmdline_parser_cpp.o -endif - -.PHONY: all -all: $(LIBOBJS) - -INCLUDES = -Isrcdir/$(SUBDIR)/include -I$(BLDDIR) - -%.o:%.c - $(CC) -c $(CFLAGS_ALL) $< - -%.o:%.cpp - $(CXX) -c $(CXXFLAGS_ALL) $< - -include depend.mk - -.PHONY: clean distclean -clean: clean-common - -distclean: clean distclean-common - -.PHONY: dep -dep: dep-common - -.PHONY: install -install: - -.PHONY: uninstall -uninstall: \ No newline at end of file diff --git a/trunk/lib/util/casprintf.c b/trunk/lib/util/casprintf.c deleted file mode 100644 index 5953f166c..000000000 --- a/trunk/lib/util/casprintf.c +++ /dev/null @@ -1,143 +0,0 @@ -#define _GNU_SOURCE /* But only when HAVE_ASPRINTF */ -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" /* For HAVE_ASPRINTF, __inline__ */ -#include "bool.h" -#include "casprintf.h" - - - -static __inline__ void -newVsnprintf(char * const buffer, - size_t const bufferSize, - const char * const fmt, - va_list varargs, - size_t * const formattedSizeP) { -/*---------------------------------------------------------------------------- - This is vsnprintf() with the new behavior, where not fitting in the buffer - is not a failure. - - Unfortunately, we can't practically return the size of the formatted string - if the C library has old vsnprintf() and the formatted string doesn't fit - in the buffer, so in that case we just return something larger than the - buffer. ------------------------------------------------------------------------------*/ - if (bufferSize > INT_MAX/2) { - /* There's a danger we won't be able to coerce the return value - of XMLRPC_VSNPRINTF to an integer (which we have to do because, - while for POSIX its return value is ssize_t, on Windows it is int), - or return double the buffer size. - */ - *formattedSizeP = 0; - } else { - int rc; - - rc = XMLRPC_VSNPRINTF(buffer, bufferSize, fmt, varargs); - - if (rc < 0) { - /* We have old vsnprintf() (or Windows) and the formatted value - doesn't fit in the buffer, but we don't know how big a buffer it - needs. - */ - *formattedSizeP = bufferSize * 2; - } else { - /* Either the string fits in the buffer or we have new vsnprintf() - which tells us how big the string is regardless. - */ - *formattedSizeP = rc; - } - } -} - - - -static __inline__ int -simpleVasprintf(char ** const resultP, - const char * const fmt, - va_list varargs) { -/*---------------------------------------------------------------------------- - This is a poor man's implementation of vasprintf(), of GNU fame. ------------------------------------------------------------------------------*/ - int retval; - char * buffer; - size_t bufferSize; - bool outOfMemory; - - for (buffer = NULL, bufferSize = 4096, outOfMemory = false; - !buffer && !outOfMemory; - ) { - - buffer = malloc(bufferSize); - if (!buffer) - outOfMemory = true; - else { - size_t bytesNeeded; - newVsnprintf(buffer, bufferSize, fmt, varargs, &bytesNeeded); - if (bytesNeeded > bufferSize) { - free(buffer); - buffer = NULL; - bufferSize = bytesNeeded; - } - } - } - if (outOfMemory) - retval = -1; - else { - retval = strlen(buffer); - *resultP = buffer; - } - return retval; -} - - - -const char * const strsol = "[Insufficient memory to build string]"; - - - -void -cvasprintf(const char ** const retvalP, - const char * const fmt, - va_list varargs) { - - char * string; - int rc; - -#if HAVE_ASPRINTF - rc = vasprintf(&string, fmt, varargs); -#else - rc = simpleVasprintf(&string, fmt, varargs); -#endif - - if (rc < 0) - *retvalP = strsol; - else - *retvalP = string; -} - - - -void GNU_PRINTF_ATTR(2,3) -casprintf(const char ** const retvalP, const char * const fmt, ...) { - - va_list varargs; /* mysterious structure used by variable arg facility */ - - va_start(varargs, fmt); /* start up the mysterious variable arg facility */ - - cvasprintf(retvalP, fmt, varargs); - - va_end(varargs); -} - - - -void -strfree(const char * const string) { - - if (string != strsol) - free((void *)string); -} diff --git a/trunk/lib/util/cmdline_parser.c b/trunk/lib/util/cmdline_parser.c deleted file mode 100644 index d8f127cde..000000000 --- a/trunk/lib/util/cmdline_parser.c +++ /dev/null @@ -1,589 +0,0 @@ -#define _XOPEN_SOURCE 600 /* Make sure has strdup() */ - -#include "xmlrpc_config.h" /* prereq for mallocvar.h -- defines __inline__ */ - -#include -#include -#include -#include -#include - -#include "bool.h" -#include "int.h" -#include "mallocvar.h" -#include "casprintf.h" -#include "getoptx.h" -#include "string_parser.h" - -#include "cmdline_parser.h" - -#define MAXOPTS 100 - -struct optionDesc { - const char * name; - enum optiontype type; - bool present; - union { - unsigned int u; - int i; - const char * s; - uint64_t llu; - double d; - } value; -}; - - - -struct cmdlineParserCtl { - struct optionDesc * optionDescArray; - unsigned int numOptions; - const char ** argumentArray; - unsigned int numArguments; -}; - - - -static struct optionx * -createLongOptsArray(struct optionDesc * const optionDescArray, - unsigned int const numOptions) { - - struct optionx * longopts; - - MALLOCARRAY(longopts, numOptions+1); - if (longopts != NULL) { - unsigned int i; - - for (i = 0; i < numOptions; ++i) { - longopts[i].name = optionDescArray[i].name; - /* If the option takes a value, we say it is optional even - though it never is. That's because if we say it is - mandatory, getopt_long_only() pretends it doesn't even - recognize the option if the user doesn't give a value. - We prefer to generate a meaningful error message when - the user omits a required option value. - */ - longopts[i].has_arg = - optionDescArray[i].type == OPTTYPE_FLAG ? - no_argument : optional_argument; - longopts[i].flag = NULL; - longopts[i].val = i; - } - longopts[numOptions].name = 0; - longopts[numOptions].has_arg = 0; - longopts[numOptions].flag = 0; - longopts[numOptions].val = 0; - } - return longopts; -} - - - -static void -parseInt(enum optiontype const type, - const char * const optarg, - unsigned int * const valueUintP, - int * const valueIntP, - const char ** const errorP) { - - if (optarg == NULL) - casprintf(errorP, "Option requires a value"); - else if (strlen(optarg) == 0) - casprintf(errorP, "Numeric option value is null string"); - else { - char * tailptr; - long const longvalue = strtol(optarg, &tailptr, 10); - - if (*tailptr != '\0') - casprintf(errorP, "Non-numeric value " - "for numeric option value: '%s'", optarg); - else if (errno == ERANGE || longvalue > INT_MAX) - casprintf(errorP, "Numeric value out of range: %s", optarg); - else { - if (type == OPTTYPE_UINT) { - if (longvalue < 0) - casprintf(errorP, "Unsigned numeric value is " - "negative: %ld", longvalue); - else { - *errorP = NULL; - *valueUintP = (unsigned int) longvalue; - } - } else { - *errorP = NULL; - *valueIntP = (int) longvalue; - } - } - } -} - - - -static void -parseBinUint(const char * const optarg, - uint64_t * const valueP, - const char ** const errorP) { - - if (optarg == NULL) - casprintf(errorP, "Option requires a value"); - else if (strlen(optarg) == 0) - casprintf(errorP, "Numeric option value is null string"); - else { - const char * error; - interpretBinUint(optarg, valueP, &error); - - if (error) { - casprintf(errorP, "Invalid numeric option value '%s'. %s", - optarg, error); - strfree(error); - } - } -} - - - -static void -parseFloat(const char * const optarg, - double * const valueP, - const char ** const errorP) { - - if (optarg == NULL) - casprintf(errorP, "Option requires a value"); - else if (strlen(optarg) == 0) - casprintf(errorP, "Numeric option value is null string"); - else { - char * tailptr; - double const doublevalue = strtod(optarg, &tailptr); - - if (*tailptr != '\0') - casprintf(errorP, "Non-numeric value " - "for numeric option value: '%s'", optarg); - else if (errno == ERANGE) - casprintf(errorP, "Numeric value out of range: %s", optarg); - else { - *errorP = NULL; - *valueP = doublevalue; - } - } -} - - - -static void -parseOptionValue(const char * const optarg, - struct optionDesc * const optionP, - const char ** const errorP) { - - switch (optionP->type) { - case OPTTYPE_FLAG: - *errorP = NULL; - break; - case OPTTYPE_INT: - case OPTTYPE_UINT: - parseInt(optionP->type, optarg, &optionP->value.u, &optionP->value.i, - errorP); - break; - case OPTTYPE_STRING: - if (optarg == NULL) - casprintf(errorP, "Option requires a value"); - else { - *errorP = NULL; - optionP->value.s = strdup(optarg); - } - break; - case OPTTYPE_BINUINT: - parseBinUint(optarg, &optionP->value.llu, errorP); - break; - case OPTTYPE_FLOAT: - parseFloat(optarg, &optionP->value.d, errorP); - break; - } -} - - - -static void -processOption(struct optionDesc * const optionP, - const char * const optarg, - const char ** const errorP) { - - const char * error; - - parseOptionValue(optarg, optionP, &error); - if (error) - casprintf(errorP, "Error in '%s' option: %s", optionP->name, error); - else - optionP->present = true; -} - - - -static void -extractArguments(struct cmdlineParserCtl * const cpP, - unsigned int const argc, - const char ** const argv) { - - cpP->numArguments = argc - getopt_argstart(); - MALLOCARRAY(cpP->argumentArray, cpP->numArguments); - - if (cpP->argumentArray == NULL) { - fprintf(stderr, "Unable to allocate memory for argument array " - "(%u arguments)\n", cpP->numArguments); - abort(); - } else { - unsigned int i; - - for (i = 0; i < cpP->numArguments; ++i) { - cpP->argumentArray[i] = strdup(argv[getopt_argstart() + i]); - if (cpP->argumentArray[i] == NULL) { - fprintf(stderr, "Unable to allocate memory for Argument %u\n", - i); - abort(); - } - } - } -} - - - -void -cmd_processOptions(cmdlineParser const cpP, - int const argc, - const char ** const argv, - const char ** const errorP) { - - struct optionx * longopts; - - longopts = createLongOptsArray(cpP->optionDescArray, cpP->numOptions); - - if (longopts == NULL) - casprintf(errorP, "Unable to get memory for longopts array"); - else { - int endOfOptions; - unsigned int i; - - *errorP = NULL; - - /* Set up initial assumption: No options present */ - - for (i = 0; i < cpP->numOptions; ++i) - cpP->optionDescArray[i].present = false; - - endOfOptions = false; /* initial value */ - - while (!endOfOptions && !*errorP) { - int const opterr0 = 0; - /* Don't let getopt_long_only() print an error message */ - unsigned int longoptsIndex; - const char * unrecognizedOption; - const char * optarg; - - getopt_long_onlyx(argc, (char**) argv, "", longopts, - &longoptsIndex, opterr0, - &endOfOptions, &optarg, &unrecognizedOption); - - if (unrecognizedOption) - casprintf(errorP, "Unrecognized option: '%s'", - unrecognizedOption); - else { - if (!endOfOptions) - processOption(&cpP->optionDescArray[longoptsIndex], optarg, - errorP); - } - } - if (!*errorP) - extractArguments(cpP, argc, argv); - - free(longopts); - } -} - - - -cmdlineParser -cmd_createOptionParser(void) { - - struct cmdlineParserCtl * cpP; - - MALLOCVAR(cpP); - - if (cpP != NULL) { - struct optionDesc * optionDescArray; - - cpP->numOptions = 0; - MALLOCARRAY(optionDescArray, MAXOPTS); - if (optionDescArray == NULL) { - free(cpP); - cpP = NULL; - } else - cpP->optionDescArray = optionDescArray; - } - return cpP; -} - - - -void -cmd_destroyOptionParser(cmdlineParser const cpP) { - - unsigned int i; - - for (i = 0; i < cpP->numOptions; ++i) { - struct optionDesc const option = cpP->optionDescArray[i]; - if (option.type == OPTTYPE_STRING && option.present) - strfree(option.value.s); - strfree(option.name); - } - - for (i = 0; i < cpP->numArguments; ++i) - strfree(cpP->argumentArray[i]); - - free(cpP->optionDescArray); - free(cpP); -} - - - -void -cmd_defineOption(cmdlineParser const cpP, - const char * const name, - enum optiontype const type) { - - if (cpP->numOptions < MAXOPTS) { - cpP->optionDescArray[cpP->numOptions].name = strdup(name); - cpP->optionDescArray[cpP->numOptions].type = type; - - ++cpP->numOptions; - } -} - - - -static struct optionDesc * -findOptionDesc(struct cmdlineParserCtl * const cpP, - const char * const name) { - - struct optionDesc * retval; - unsigned int i; - - retval = NULL; - - for (i = 0; i < cpP->numOptions && !retval; ++i) - if (strcmp(cpP->optionDescArray[i].name, name) == 0) - retval = &cpP->optionDescArray[i]; - - return retval; -} - - - -int -cmd_optionIsPresent(cmdlineParser const cpP, - const char * const name) { - - struct optionDesc * const optionDescP = findOptionDesc(cpP, name); - - bool present; - - if (!optionDescP) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "optionIsPresent() called for undefined option '%s'\n", - name); - abort(); - } else - present = optionDescP->present; - - return present; -} - - - -unsigned int -cmd_getOptionValueUint(cmdlineParser const cpP, - const char * const name) { - - struct optionDesc * const optionDescP = findOptionDesc(cpP, name); - - unsigned int retval; - - if (!optionDescP) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueUint() called for undefined option '%s'\n", - name); - abort(); - } else { - if (optionDescP->type != OPTTYPE_UINT) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueUint() called for non-unsigned integer " - "option '%s'\n", optionDescP->name); - abort(); - } else { - if (optionDescP->present) - retval = optionDescP->value.u; - else - retval = 0; - } - } - return retval; -} - - - -int -cmd_getOptionValueInt(cmdlineParser const cpP, - const char * const name) { - - struct optionDesc * const optionDescP = findOptionDesc(cpP, name); - - int retval; - - if (!optionDescP) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueInt() called for undefined option '%s'\n", - name); - abort(); - } else { - if (optionDescP->type != OPTTYPE_INT) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueInt() called for non-integer " - "option '%s'\n", optionDescP->name); - abort(); - } else { - if (optionDescP->present) - retval = optionDescP->value.i; - else - retval = 0; - } - } - - return retval; -} - - - -const char * -cmd_getOptionValueString(cmdlineParser const cpP, - const char * const name) { - - struct optionDesc * const optionDescP = findOptionDesc(cpP, name); - - const char * retval; - - if (!optionDescP) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueString() called for " - "undefined option '%s'\n", - name); - abort(); - } else { - if (optionDescP->type != OPTTYPE_STRING) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "getOptionValueString() called for non-string " - "option '%s'\n", optionDescP->name); - abort(); - } else { - if (optionDescP->present) { - retval = strdup(optionDescP->value.s); - if (retval == NULL) { - fprintf(stderr, - "out of memory in cmd_getOptionValueString()\n"); - abort(); - } - } else - retval = NULL; - } - } - return retval; -} - - - -uint64_t -cmd_getOptionValueBinUint(cmdlineParser const cpP, - const char * const name) { - - struct optionDesc * const optionDescP = findOptionDesc(cpP, name); - - uint64_t retval; - - if (!optionDescP) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueUint() called for undefined option '%s'\n", - name); - abort(); - } else { - if (optionDescP->type != OPTTYPE_BINUINT) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueBinUint() called for " - "non-OPTTYPE_BINUINT " - "option '%s'\n", optionDescP->name); - abort(); - } else { - if (optionDescP->present) - retval = optionDescP->value.llu; - else - retval = 0; - } - } - return retval; -} - - - -double -cmd_getOptionValueFloat(cmdlineParser const cpP, - const char * const name) { - - struct optionDesc * const optionDescP = findOptionDesc(cpP, name); - - double retval; - - if (!optionDescP) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueInt() called for undefined option '%s'\n", - name); - abort(); - } else { - if (optionDescP->type != OPTTYPE_FLOAT) { - fprintf(stderr, "cmdlineParser called incorrectly. " - "cmd_getOptionValueInt() called for non-float " - "option '%s'\n", optionDescP->name); - abort(); - } else { - if (optionDescP->present) - retval = optionDescP->value.d; - else - retval = 0.0; - } - } - return retval; -} - - - -unsigned int -cmd_argumentCount(cmdlineParser const cpP) { - - return cpP->numArguments; - -} - - - -const char * -cmd_getArgument(cmdlineParser const cpP, - unsigned int const argNumber) { - - const char * retval; - - if (argNumber >= cpP->numArguments) - retval = NULL; - else { - retval = strdup(cpP->argumentArray[argNumber]); - - if (retval == NULL) { - fprintf(stderr, - "out of memory in cmd_getArgument()\n"); - abort(); - } - } - return retval; -} diff --git a/trunk/lib/util/cmdline_parser_cpp.cpp b/trunk/lib/util/cmdline_parser_cpp.cpp deleted file mode 100644 index 0fc951eab..000000000 --- a/trunk/lib/util/cmdline_parser_cpp.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include -#include - -#include "girstring.h" -#include "casprintf.h" -#include "cmdline_parser.h" - -#include "cmdline_parser.hpp" - -using namespace std; - - - -static enum optiontype -optTypeConvert( - CmdlineParser::optType const arg) { - - enum optiontype retval; - - retval = OPTTYPE_FLAG; // defeat compiler warning - - switch (arg) { - case CmdlineParser::FLAG: retval = OPTTYPE_FLAG; break; - case CmdlineParser::INT: retval = OPTTYPE_INT; break; - case CmdlineParser::UINT: retval = OPTTYPE_UINT; break; - case CmdlineParser::STRING: retval = OPTTYPE_STRING; break; - case CmdlineParser::BINUINT: retval = OPTTYPE_BINUINT; break; - case CmdlineParser::FLOAT: retval = OPTTYPE_FLOAT; break; - } - return retval; -} - - - -CmdlineParser::CmdlineParser() { - - this->cp = cmd_createOptionParser(); -} - - - -CmdlineParser::~CmdlineParser() { - cmd_destroyOptionParser(this->cp); -} - - - -void -CmdlineParser::defineOption( - string const optionName, - optType const optionType) { - - cmd_defineOption(this->cp, optionName.c_str(), - optTypeConvert(optionType)); -} - - - -void -CmdlineParser::processOptions( - int const argc, - const char ** const argv) { - - const char * error; - - cmd_processOptions(this->cp, argc, argv, &error); - if (error) { - string const errorS(error); - strfree(error); - throw(runtime_error(errorS)); - } -} - - - -bool -CmdlineParser::optionIsPresent( - string const optionName) const { - - return (cmd_optionIsPresent(this->cp, optionName.c_str()) ? true : false); -} - - - -int -CmdlineParser::getOptionValueInt( - string const optionName) const { - - return cmd_getOptionValueInt(this->cp, optionName.c_str()); -} - - - -unsigned int -CmdlineParser::getOptionValueUint( - string const optionName) const { - - return cmd_getOptionValueUint(this->cp, optionName.c_str()); -} - - - -unsigned long long -CmdlineParser::getOptionValueBinUint( - string const optionName) const { - - return cmd_getOptionValueBinUint(this->cp, optionName.c_str()); -} - - - -double -CmdlineParser::getOptionValueFloat( - string const optionName) const { - - return cmd_getOptionValueFloat(this->cp, optionName.c_str()); -} - - - -string -CmdlineParser::getOptionValueString( - string const optionName) const { - - const char * const value = - cmd_getOptionValueString(this->cp, optionName.c_str()); - - string retval; - - if (value) { - retval = string(value); - strfree(value); - } else - retval = ""; - - return retval; -} - - - -unsigned int -CmdlineParser::argumentCount() const { - - return cmd_argumentCount(this->cp); -} - - - -string -CmdlineParser::getArgument( - unsigned int const argNumber) const { - - const char * const value = cmd_getArgument(this->cp, argNumber); - string const retval(value); - strfree(value); - return retval; -} diff --git a/trunk/lib/util/getoptx.c b/trunk/lib/util/getoptx.c deleted file mode 100644 index 114bacc9f..000000000 --- a/trunk/lib/util/getoptx.c +++ /dev/null @@ -1,466 +0,0 @@ -/* This version of `getopt' appears to the caller like standard Unix getopt() - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As getopt() works, it permutes the elements of `argv' so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable _POSIX_OPTION_ORDER disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. -*/ - -#include -#include -#include - -#include "getoptx.h" - -/* Note that on some systems, the header files above declare variables - for use with their native getopt facilities, and those variables have - the same names as we'd like to use. So we use things like optargx - instead of optarg to avoid the collision. -*/ - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. -*/ -static char *optargx = 0; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to getoptx(). - - On entry to getoptx(), zero means this is the first call; initialize. - - When getoptx() returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optindx' communicates from one call to the next - how much of ARGV has been scanned so far. -*/ - -static int optindx = 0; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. -*/ - -static int opterrx; - -/* Index in _GETOPT_LONG_OPTIONS of the long-named option actually found. - Only valid when a long-named option was found. */ - -static int option_index; - -struct optionx * _getopt_long_options; - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optindx), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -static void -exchange(char ** const argv) { - unsigned int const nonopts_size = - (last_nonopt - first_nonopt) * sizeof (char *); - char **temp = (char **) malloc (nonopts_size); - - if (temp == NULL) - abort(); - - /* Interchange the two blocks of data in argv. */ - - memcpy (temp, &argv[first_nonopt], nonopts_size); - memcpy (&argv[first_nonopt], &argv[last_nonopt], - (optindx - last_nonopt) * sizeof (char *)); - memcpy (&argv[first_nonopt + optindx - last_nonopt], temp, - nonopts_size); - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optindx - last_nonopt); - last_nonopt = optindx; - - free(temp); -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If getoptx() - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If getoptx() finds another option character, it returns that character, - updating `optindx' and `nextchar' so that the next call to getoptx() can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, getoptx() returns `EOF'. - Then `optindx' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterrx' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optargx'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optargx', otherwise `optargx' is set to zero. - - If OPTSTRING starts with `-', it requests a different method of handling the - non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. - - Long-named options begin with `+' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - getoptx() returns 0 when it finds a long-named option. */ - -static int -getoptx(int const argc, - char ** const argv, - const char * const optstring) { - - optargx = 0; - - /* Initialize the internal data when the first call is made. - Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - if (optindx == 0) - { - first_nonopt = last_nonopt = optindx = 1; - - nextchar = 0; - - } - - if (nextchar == 0 || *nextchar == 0) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optindx) - exchange (argv); - else if (last_nonopt != optindx) - first_nonopt = optindx; - - /* Now skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optindx < argc - && (argv[optindx][0] != '-'|| argv[optindx][1] == 0) - && (argv[optindx][0] != '+'|| argv[optindx][1] == 0)) - optindx++; - last_nonopt = optindx; - - /* Special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optindx != argc && !strcmp (argv[optindx], "--")) - { - optindx++; - - if (first_nonopt != last_nonopt && last_nonopt != optindx) - exchange (argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optindx; - last_nonopt = argc; - - optindx = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optindx == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optindx = first_nonopt; - return EOF; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass - it by. - */ - - if ((argv[optindx][0] != '-' || argv[optindx][1] == 0) - && (argv[optindx][0] != '+' || argv[optindx][1] == 0)) - { - optargx = argv[optindx++]; - return 1; - } - - /* We have found another option-ARGV-element. - Start decoding its characters. */ - - nextchar = argv[optindx] + 1; - } - - if ((argv[optindx][0] == '+' || (argv[optindx][0] == '-')) - ) - { - struct optionx *p; - char *s = nextchar; - int exact = 0; - int ambig = 0; - struct optionx * pfound; - int indfound; - - while (*s && *s != '=') s++; - - indfound = 0; /* quite compiler warning */ - - /* Test all options for either exact match or abbreviated matches. */ - for (p = _getopt_long_options, option_index = 0, pfound = NULL; - p->name; - p++, option_index++) - if (!strncmp (p->name, nextchar, s - nextchar)) - { - if ((unsigned int)(s - nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (!pfound) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optindx]); - nextchar += strlen (nextchar); - return '?'; - } - - if (pfound) - { - option_index = indfound; - optindx++; - if (*s) - { - if (pfound->has_arg > 0) - optargx = s + 1; - else - { - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optindx - 1][0], pfound->name); - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg) - { - if (optindx < argc) - optargx = argv[optindx++]; - else if (pfound->has_arg != 2) - { - fprintf (stderr, "%s: option `%s' requires an argument\n", - argv[0], argv[optindx - 1]); - nextchar += strlen (nextchar); - return '?'; - } - } - nextchar += strlen (nextchar); - if (pfound->flag) - *(pfound->flag) = pfound->val; - return 0; - } - if (argv[optindx][0] == '+' || strchr (optstring, *nextchar) == 0) - { - if (opterrx != 0) - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optindx][0], nextchar); - nextchar += strlen (nextchar); - return '?'; - } - } - - /* Look at and handle the next option-character. */ - - { - char c = *nextchar++; - char *temp = strchr (optstring, c); - - /* Increment `optindx' when we start to process its last character. */ - if (*nextchar == 0) - optindx++; - - if (temp == 0 || c == ':') - { - if (opterrx != 0) - { - if (c < 040 || c >= 0177) - fprintf (stderr, "%s: unrecognized option, " - "character code 0%o\n", - argv[0], c); - else - fprintf (stderr, "%s: unrecognized option `-%c'\n", - argv[0], c); - } - return '?'; - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != 0) - { - optargx = nextchar; - optindx++; - } - else - optargx = 0; - nextchar = 0; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != 0) - { - optargx = nextchar; - /* If we end this ARGV-element by taking the rest - as an arg, we must advance to the next element - now. - */ - optindx++; - } - else if (optindx == argc) - { - if (opterrx != 0) - fprintf (stderr, - "%s: option `-%c' requires an argument\n", - argv[0], c); - c = '?'; - } - else - /* We already incremented `optindx' once; - increment it again when taking next ARGV-elt as - argument. - */ - optargx = argv[optindx++]; - nextchar = 0; - } - } - return c; - } -} - - - -void -getopt_long_onlyx(int const argc, - char ** const argv, - const char * const options, - struct optionx * const long_options, - unsigned int * const opt_index, - int const opterrArg, - int * const end_of_options, - const char ** const optarg_arg, - const char ** const unrecognized_option) { - - int rc; - - opterrx = opterrArg; - _getopt_long_options = long_options; - rc = getoptx(argc, argv, options); - if (rc == 0) - *opt_index = option_index; - - if (rc == '?') - *unrecognized_option = argv[optindx]; - else - *unrecognized_option = NULL; - - if (rc < 0) - *end_of_options = 1; - else - *end_of_options = 0; - - *optarg_arg = optargx; -} - - -unsigned int -getopt_argstart(void) { -/*---------------------------------------------------------------------------- - This is a replacement for what traditional getopt does with global - variables. - - You call this after getopt_long_onlyx() has returned "end of - options" ------------------------------------------------------------------------------*/ - return optindx; -} - - -/* Getopt for GNU. - Copyright (C) 1987, 1989 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ diff --git a/trunk/lib/util/getoptx.h b/trunk/lib/util/getoptx.h deleted file mode 100644 index c68833124..000000000 --- a/trunk/lib/util/getoptx.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Interface to getopt_long_onlyx() */ - - -enum argreq {no_argument, required_argument, optional_argument}; - -struct optionx { - /* This describes an option. If the field `flag' is nonzero, it - points to a variable that is to be set to the value given in - the field `val' when the option is found, but left unchanged if - the option is not found. - */ - const char * name; - enum argreq has_arg; - int * flag; - int val; -}; - -/* long_options[] is a list terminated by an element that contains - a NULL 'name' member. -*/ -void -getopt_long_onlyx(int const argc, - char ** const argv, - const char * const options, - struct optionx * const long_options, - unsigned int * const opt_index, - int const opterrArg, - int * const end_of_options, - const char ** const optarg_arg, - const char ** const unrecognized_option); - -unsigned int -getopt_argstart(void); - -/* - Copyright (C) 1989 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - diff --git a/trunk/lib/util/include/assertx.hpp b/trunk/lib/util/include/assertx.hpp deleted file mode 100644 index 64e57faf1..000000000 --- a/trunk/lib/util/include/assertx.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef ASSERTX_HPP_INCLUDED -#define ASSERTX_HPP_INCLUDED - -#include - -/* The compiler often warns you if you give a function formal parameter a - name, but don't use it. But because assert() disappears when doing an - optimized build, the compiler doesn't recognize your reference to the - parameter in the assert() argument. To avoid the bogus warning in - this case, we have ASSERT_ONLY_ARG(), which declares a name for a - formal parameter for purposes of assert() only. In cases where an - assert() would disappear, ASSERT_ONLY_ARG() disappears too. - - E.g. - - void foo(int const ASSERT_ONLY_ARG(arg1)) { - - assert(arg1 > 0); - } -*/ -#ifdef NDEBUG - #define ASSERT_ONLY_ARG(x) -#else - #define ASSERT_ONLY_ARG(x) x -#endif - -#endif diff --git a/trunk/lib/util/include/bool.h b/trunk/lib/util/include/bool.h deleted file mode 100644 index 312477c4c..000000000 --- a/trunk/lib/util/include/bool.h +++ /dev/null @@ -1,18 +0,0 @@ -/* This takes the place of C99 stdbool.h, which at least some Windows - compilers don't have. (October 2005). - - One must not also include , because it might cause a name - collision. -*/ - -#ifndef __cplusplus -/* At least the GNU compiler defines __bool_true_false_are_defined */ -#ifndef __bool_true_false_are_defined -#define __bool_true_false_are_defined -typedef enum { - false = 0, - true = 1 -} bool; -#endif -#endif - diff --git a/trunk/lib/util/include/c_util.h b/trunk/lib/util/include/c_util.h deleted file mode 100644 index 5386b1330..000000000 --- a/trunk/lib/util/include/c_util.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef C_UTIL_H_INCLUDED -#define C_UTIL_H_INCLUDED - -/* C language stuff. Doesn't involve any libraries that aren't part of - the compiler. -*/ - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - -/* GNU_PRINTF_ATTR lets the GNU compiler check printf-type - calls to be sure the arguments match the format string, thus preventing - runtime segmentation faults and incorrect messages. -*/ -#ifdef __GNUC__ -#define GNU_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b))) -#else -#define GNU_PRINTF_ATTR(a,b) -#endif -#endif diff --git a/trunk/lib/util/include/casprintf.h b/trunk/lib/util/include/casprintf.h deleted file mode 100644 index 61098dc34..000000000 --- a/trunk/lib/util/include/casprintf.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef CASPRINTF_H_INCLUDED -#define CASPRINTF_H_INCLUDED - -#include - -#include "c_util.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const char * const strsol; - -void -cvasprintf(const char ** const retvalP, - const char * const fmt, - va_list varargs); - -void GNU_PRINTF_ATTR(2,3) -casprintf(const char ** const retvalP, const char * const fmt, ...); - -void -strfree(const char * const string); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/lib/util/include/cmdline_parser.h b/trunk/lib/util/include/cmdline_parser.h deleted file mode 100644 index cc8762527..000000000 --- a/trunk/lib/util/include/cmdline_parser.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef CMDLINE_PARSER_H -#define CMDLINE_PARSER_H - -#ifdef __cplusplus -extern "C" { -#endif -#if 0 -} /* to fake out automatic code indenters */ -#endif - -#include "int.h" - -/* - - NOTE NOTE NOTE: cmd_getOptionValueString() and - cmd_getArgument() return malloc'ed memory (and abort the program if - out of memory). You must free it. - -*/ - -enum optiontype { - OPTTYPE_FLAG, - OPTTYPE_INT, - OPTTYPE_UINT, - OPTTYPE_STRING, - OPTTYPE_BINUINT, - OPTTYPE_FLOAT -}; - -struct cmdlineParserCtl; - -typedef struct cmdlineParserCtl * cmdlineParser; - -void -cmd_processOptions(cmdlineParser const cpP, - int const argc, - const char ** const argv, - const char ** const errorP); - -cmdlineParser -cmd_createOptionParser(void); - -void -cmd_destroyOptionParser(cmdlineParser const cpP); - -void -cmd_defineOption(cmdlineParser const cpP, - const char * const name, - enum optiontype const type); - -int -cmd_optionIsPresent(cmdlineParser const cpP, - const char * const name); - -int -cmd_getOptionValueInt(cmdlineParser const cpP, - const char * const name); - -unsigned int -cmd_getOptionValueUint(cmdlineParser const cpP, - const char * const name); - -const char * -cmd_getOptionValueString(cmdlineParser const cpP, - const char * const name); - -uint64_t -cmd_getOptionValueBinUint(cmdlineParser const cpP, - const char * const name); - -double -cmd_getOptionValueFloat(cmdlineParser const cpP, - const char * const name); - -unsigned int -cmd_argumentCount(cmdlineParser const cpP); - -const char * -cmd_getArgument(cmdlineParser const cpP, - unsigned int const argNumber); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/trunk/lib/util/include/cmdline_parser.hpp b/trunk/lib/util/include/cmdline_parser.hpp deleted file mode 100644 index af93487c4..000000000 --- a/trunk/lib/util/include/cmdline_parser.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef CMDLINE_PARSER_HPP_INCLUDED -#define CMDLINE_PARSER_HPP_INCLUDED - -#include - -struct cmdlineParserCtl; - -class CmdlineParser { -public: - CmdlineParser(); - - ~CmdlineParser(); - - enum optType {FLAG, INT, UINT, STRING, BINUINT, FLOAT}; - - void - defineOption(std::string const optionName, - optType const optionType); - - void - processOptions(int const argc, - const char ** const argv); - - bool - optionIsPresent(std::string const optionName) const; - - int - getOptionValueInt(std::string const optionName) const; - - unsigned int - getOptionValueUint(std::string const optionName) const; - - std::string - getOptionValueString(std::string const optionName) const; - - unsigned long long - getOptionValueBinUint(std::string const optionName) const; - - double - getOptionValueFloat(std::string const optionName) const; - - unsigned int - argumentCount() const; - - std::string - getArgument(unsigned int const argNumber) const; - -private: - struct cmdlineParserCtl * cp; - - // Make sure no one can copy this object, because if there are two - // copies, there will be two attempts to destroy *cp. - CmdlineParser(CmdlineParser const&) {}; - - CmdlineParser& - operator=(CmdlineParser const&) {return *this;} -}; - -#endif diff --git a/trunk/lib/util/include/girmath.h b/trunk/lib/util/include/girmath.h deleted file mode 100644 index 8b996ab6b..000000000 --- a/trunk/lib/util/include/girmath.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __GIRMATH_H -#define __GIRMATH_H - -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -#define SQR(a) ((a)*(a)) - -/* ROUNDUP(a,b) rounds a up to the next multiple of b. - ROUNDDN(a,b) rounds a down to the next multiple of b. - ROUND(a,b) rounds a to the nearest multiple of b. - - These are for signed integers. - - "down" means arithmetically less: -4.3 rounded down to the next unit - is -5. - - ROUNDUPU, etc. are the same for unsigned integers, but with no compiler - warning about a comparison that is always true. -*/ - -#define ROUNDUPU(a,b) (((a)+(b)-1)/(b)*(b)) -#define ROUNDDNU(a,b) ((a)/(b)*(b)) -#define ROUNDU(a,b) (((a)+((b)/2))/(b)*(b)) - -#define ROUNDUP(a,b) ((a) >= 0 ? ROUNDUPU(a,b) : -ROUNDDNU(-a,b)) -#define ROUNDDN(a,b) ((a) >= 0 ? ROUNDDNU(a,b) : -ROUNDUPU(-a,b)) -#define ROUND(a,b) ((a) >= 0 ? ROUNDU(a,b) : -ROUNDU(-a,b)) - -/* ROUNDUP_DIV gives the quotient rounded up to the next integer. - It works only on unsigned numbers -*/ - -#define ROUNDUP_DIV(dividend, divisor) ((dividend) + (divisor) - 1)/(divisor) - -#define IS_POWER_OF_TWO(n) ((((n)-1) & (n)) == 0x0) - -#endif - diff --git a/trunk/lib/util/include/girstring.h b/trunk/lib/util/include/girstring.h deleted file mode 100644 index 2728a5d2f..000000000 --- a/trunk/lib/util/include/girstring.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef GIRSTRING_H_INCLUDED -#define GIRSTRING_H_INCLUDED - -#include - -#include "xmlrpc_config.h" -#include "bool.h" - -bool -stripcaseeq(const char * const comparand, - const char * const comparator); - -static __inline__ bool -streq(const char * const comparator, - const char * const comparand) { - - return (strcmp(comparand, comparator) == 0); -} - -static __inline__ bool -memeq(const void * const comparator, - const void * const comparand, - size_t const size) { - - return (memcmp(comparator, comparand, size) == 0); -} - -#define MEMEQ(a,b,c) (memcmp(a, b, c) == 0) - -#define MEMSSET(a,b) (memset(a, b, sizeof(*a))) - -#define MEMSCPY(a,b) (memcpy(a, b, sizeof(*a))) - -#define MEMSZERO(a) (MEMSSET(a, 0)) - -static __inline__ const char * -sdup(const char * const input) { - return (const char *) strdup(input); -} - -/* Copy string pointed by B to array A with size checking. */ -#define STRSCPY(A,B) \ - (strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0') -#define STRSCMP(A,B) \ - (strncmp((A), (B), sizeof(A))) - -/* Concatenate string B onto string in array A with size checking */ -#define STRSCAT(A,B) \ - (strncat((A), (B), sizeof(A)-strlen(A)-1)) - -#endif diff --git a/trunk/lib/util/include/inline.h b/trunk/lib/util/include/inline.h deleted file mode 100644 index f90032b28..000000000 --- a/trunk/lib/util/include/inline.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef XMLRPC_INLINE_H_INCLUDED -#define XMLRPC_INLINE_H_INCLUDED - -/* Xmlrpc-c uses __inline__ to declare functions that should be - compiled as inline code. Some compilers, e.g. GNU, recognize the - __inline__ keyword. -*/ -#ifndef __GNUC__ -#ifndef __inline__ -#ifdef __sgi -#define __inline__ __inline -#else -#define __inline__ -#endif -#endif -#endif - - -#endif diff --git a/trunk/lib/util/include/int.h b/trunk/lib/util/include/int.h deleted file mode 100644 index 3c7b2163b..000000000 --- a/trunk/lib/util/include/int.h +++ /dev/null @@ -1,63 +0,0 @@ -/* This takes the place of C99 inttypes.h, which at least some Windows - compilers don't have. (October 2007). -*/ - -/* PRId64 is the printf-style format specifier for a long long type, as in - long long mynumber = 5; - printf("My number is %" PRId64 ".\n", mynumber); - - The LL/ULL macro is for 64 bit integer literals, like this: - - long long mask= ULL(1) << 33; -*/ - -/* 'uint' is quite convenient, but there's no simple way have it everywhere. - Some systems have it in the base system (e.g. GNU C library has it in - , and others (e.g. Solaris - 08.12.02) don't. Since we - can't define it unless we know it's not defined already, and we don't - want to burden the reader with a special Xmlrpc-c name such as xuint, - we just use standard "unsigned int" instead. -*/ - -#ifdef _MSC_VER -# define PRId64 "I64d" -# define PRIu64 "I64u" - -#ifndef int16_t -typedef short int16_t; -#endif -#ifndef uint16_t -typedef unsigned short uint16_t; -#endif -#ifndef int32_t -typedef int int32_t; -#endif -#ifndef uint32_t -typedef unsigned int uint32_t; -#endif -#ifndef int64_t -typedef __int64 int64_t; -#endif -#ifndef uint64_t -typedef unsigned __int64 uint64_t; -#endif -#ifndef uint8_t -typedef unsigned char uint8_t; -#endif - -/* Older Microsoft compilers don't know the standard ll/ull suffixes */ -#define LL(x) x ## i64 -#define ULL(x) x ## u64 - -#elif defined(__INTERIX) -# include -# define PRId64 "I64d" -# define PRIu64 "I64u" - -#else - /* Not Microsoft compiler */ - #include - #define LL(x) x ## ll - #define ULL(x) x ## ull -#endif - diff --git a/trunk/lib/util/include/linklist.h b/trunk/lib/util/include/linklist.h deleted file mode 100644 index f6f264129..000000000 --- a/trunk/lib/util/include/linklist.h +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef LINKLIST_H_INCLUDED -#define LINKLIST_H_INCLUDED - -#include "inline.h" - -struct list_head { -/*---------------------------------------------------------------------------- - This is a header for an element of a doubly linked list, or an anchor - for such a list. - - itemP == NULL means it's an anchor; otherwise it's a header. - - Initialize a list header with list_init_header(). You don't have to - do anything to terminate a list header. - - Initialize an anchor with list_make_emtpy(). You don't have to do anything - to terminate a list header. ------------------------------------------------------------------------------*/ - struct list_head * nextP; - /* For a header, this is the address of the list header for - the next element in the list. If there is no next element, - it points to the anchor. If the header is not in a list at - all, it is NULL. - - For an anchor, it is the address of the list header of the - first element. If the list is empty, it points to the - anchor itself. - */ - struct list_head * prevP; - /* For a header, this is the address of the list header for - the previous element in the list. If there is no previous element, - it points to the anchor. If the header is not in a list at - all, it is NULL. - - For an anchor, it is the address of the list header of the - last element. If the list is empty, it points to the - anchor itself. - */ - void * itemP; - /* For a header, this is the address of the list element to which it - belongs. For an anchor, this is NULL. - */ -}; - -static __inline__ void -list_init_header(struct list_head * const headerP, - void * const itemP) { - - headerP->prevP = NULL; - headerP->nextP = NULL; - headerP->itemP = itemP; -} - - - -static __inline__ int -list_is_linked(struct list_head * headerP) { - return headerP->prevP != NULL; -} - - - -static __inline__ int -list_is_empty(struct list_head * const anchorP) { - return anchorP->nextP == anchorP; -} - - - -static __inline__ unsigned int -list_count(struct list_head * const anchorP) { - unsigned int count; - - struct list_head * p; - - for (p = anchorP->nextP, count = 0; - p != anchorP; - p = p->nextP, ++count); - - return count; -} - - - -static __inline__ void -list_make_empty(struct list_head * const anchorP) { - anchorP->prevP = anchorP; - anchorP->nextP = anchorP; - anchorP->itemP = NULL; -} - -static __inline__ void -list_insert_after(struct list_head * const beforeHeaderP, - struct list_head * const newHeaderP) { - newHeaderP->prevP = beforeHeaderP; - newHeaderP->nextP = beforeHeaderP->nextP; - - beforeHeaderP->nextP = newHeaderP; - newHeaderP->nextP->prevP = newHeaderP; -} - - - -static __inline__ void -list_add_tail(struct list_head * const anchorP, - struct list_head * const headerP) { - list_insert_after(anchorP->prevP, headerP); -} - - - -static __inline__ void -list_add_head(struct list_head * const anchorP, - struct list_head * const headerP) { - list_insert_after(anchorP, headerP); -} - - - -static __inline__ void -list_remove(struct list_head * const headerP) { - headerP->prevP->nextP = headerP->nextP; - headerP->nextP->prevP = headerP->prevP; - headerP->prevP = NULL; - headerP->nextP = NULL; -} - - - -static __inline__ struct list_head * -list_remove_head(struct list_head * const anchorP) { - struct list_head * retval; - - if (list_is_empty(anchorP)) - retval = NULL; - else { - retval = anchorP->nextP; - list_remove(retval); - } - return retval; -} - - - -static __inline__ struct list_head * -list_remove_tail(struct list_head * const anchorP) { - struct list_head * retval; - - if (list_is_empty(anchorP)) - retval = NULL; - else { - retval = anchorP->prevP; - list_remove(retval); - } - return retval; -} - - - -static __inline__ void * -list_foreach(struct list_head * const anchorP, - void * functionP(struct list_head *, void *), - void * const context) { - - struct list_head * p; - struct list_head * nextP; - void * result; - - for (p = anchorP->nextP, nextP = p->nextP, result=NULL; - p != anchorP && result == NULL; - p = nextP, nextP = p->nextP) - result = (*functionP)(p, context); - - return result; -} - - - -static __inline__ void -list_append(struct list_head * const newAnchorP, - struct list_head * const baseAnchorP) { - - if (!list_is_empty(newAnchorP)) { - baseAnchorP->prevP->nextP = newAnchorP->nextP; - newAnchorP->nextP->prevP = baseAnchorP->prevP; - newAnchorP->prevP->nextP = baseAnchorP; - baseAnchorP->prevP = newAnchorP->prevP; - } -} - -#endif - - diff --git a/trunk/lib/util/include/mallocvar.h b/trunk/lib/util/include/mallocvar.h deleted file mode 100644 index 12ca9d92a..000000000 --- a/trunk/lib/util/include/mallocvar.h +++ /dev/null @@ -1,111 +0,0 @@ -/* These are some dynamic memory allocation facilities. They are essentially - an extension to C, as they do allocations with a cognizance of C - variables. You can use them to make C read more like a high level - language. - - Before including this, you must define an __inline__ macro if your - compiler doesn't recognize it as a keyword. -*/ - -#ifndef MALLOCVAR_INCLUDED -#define MALLOCVAR_INCLUDED - -#include "xmlrpc_config.h" - -#include -#include - -static __inline__ void -mallocProduct(void ** const resultP, - unsigned int const factor1, - size_t const factor2) { -/*---------------------------------------------------------------------------- - malloc a space whose size in bytes is the product of 'factor1' and - 'factor2'. But if that size cannot be represented as an unsigned int, - return NULL without allocating anything. Also return NULL if the malloc - fails. - - If either factor is zero, malloc a single byte. - - Note that malloc() actually takes a size_t size argument, so the - proper test would be whether the size can be represented by size_t, - not unsigned int. But there is no reliable indication available to - us, like UINT_MAX, of what the limitations of size_t are. We - assume size_t is at least as expressive as unsigned int and that - nobody really needs to allocate more than 4GB of memory. ------------------------------------------------------------------------------*/ - if (factor1 == 0 || factor2 == 0) - *resultP = malloc(1); - else { - if (UINT_MAX / factor2 < factor1) - *resultP = NULL; - else - *resultP = malloc(factor1 * factor2); - } -} - - - -static __inline__ void -reallocProduct(void ** const blockP, - unsigned int const factor1, - unsigned int const factor2) { - - void * const oldBlockP = *blockP; - - void * newBlockP; - - if (UINT_MAX / factor2 < factor1) - newBlockP = NULL; - else - newBlockP = realloc(oldBlockP, factor1 * factor2); - - if (newBlockP) - *blockP = newBlockP; - else { - free(oldBlockP); - *blockP = NULL; - } -} - - -/* IMPLEMENTATION NOTE: There are huge strict aliasing pitfalls here - if you cast pointers, e.g. (void **) -*/ - -#define MALLOCARRAY(arrayName, nElements) do { \ - void * array; \ - mallocProduct(&array, nElements, sizeof(arrayName[0])); \ - arrayName = array; \ -} while (0) - -#define REALLOCARRAY(arrayName, nElements) do { \ - void * array = arrayName; \ - reallocProduct(&array, nElements, sizeof(arrayName[0])); \ - arrayName = array; \ -} while (0) - - -#define MALLOCARRAY_NOFAIL(arrayName, nElements) \ -do { \ - MALLOCARRAY(arrayName, nElements); \ - if ((arrayName) == NULL) \ - abort(); \ -} while(0) - -#define REALLOCARRAY_NOFAIL(arrayName, nElements) \ -do { \ - REALLOCARRAY(arrayName, nElements); \ - if ((arrayName) == NULL) \ - abort(); \ -} while(0) - - -#define MALLOCVAR(varName) \ - varName = malloc(sizeof(*varName)) - -#define MALLOCVAR_NOFAIL(varName) \ - do {if ((varName = malloc(sizeof(*varName))) == NULL) abort();} while(0) - -#endif - diff --git a/trunk/lib/util/include/stdargx.h b/trunk/lib/util/include/stdargx.h deleted file mode 100644 index cd4f2ec41..000000000 --- a/trunk/lib/util/include/stdargx.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef STDARGX_H_INCLUDED -#define STDARGX_H_INCLUDED - -#include "xmlrpc_config.h" -#include -#include - -/*---------------------------------------------------------------------------- - We need a special version of va_list in order to pass around the - variable argument heap by reference, thus allowing a subroutine to - advance the heap's pointer. - - On some systems (e.g. Gcc for PPC or AMD64), va_list is an array. - That invites the scourge of array-to-pointer degeneration if you try - to take its address. Burying it inside a struct as we do with our - va_listx type makes it immune. - - Example of what would happen if we used va_list instead of va_listx, - on a system where va_list is an array: - - void sub2(va_list * argsP) [ - ... - } - - void sub1(va_list args) { - sub2(&args); - } - - This doesn't work. '&args' is the same thing as 'args', so is - va_list, not va_list *. The compiler will even warn you about the - pointer type mismatch. - - To use va_listx: - - void sub1_va(char * format, va_list args) { - va_listx argsx; - init_va_listx(&argsx, args); - sub2(format, &argsx); - } - ------------------------------------------------------------------------------*/ - - -typedef struct { -/*---------------------------------------------------------------------------- - Same thing as va_list, but in a form that works everywhere. See above. ------------------------------------------------------------------------------*/ - va_list v; -} va_listx; - - - -static __inline__ void -init_va_listx(va_listx * const argsxP, - va_list const args) { -#if VA_LIST_IS_ARRAY - /* 'args' is NOT a va_list. It is a pointer to the first element of a - 'va_list', which is the same address as a pointer to the va_list - itself. (That's what happens when you pass an array in C). - */ - memcpy(&argsxP->v, args, sizeof(argsxP->v)); -#else - argsxP->v = args; -#endif -} - -#endif diff --git a/trunk/lib/util/include/string_parser.h b/trunk/lib/util/include/string_parser.h deleted file mode 100644 index 290d749bd..000000000 --- a/trunk/lib/util/include/string_parser.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef STRING_PARSER_H_INCLUDED -#define STRING_PARSER_H_INCLUDED - -#include "int.h" - -void -interpretUll(const char * const string, - uint64_t * const ullP, - const char ** const errorP); - -void -interpretLl(const char * const string, - int64_t * const llP, - const char ** const errorP); - -void -interpretUint(const char * const string, - unsigned int * const uintP, - const char ** const errorP); - -void -interpretInt(const char * const string, - int * const uintP, - const char ** const errorP); - -void -interpretBinUint(const char * const string, - uint64_t * const valueP, - const char ** const errorP); - -#endif diff --git a/trunk/lib/util/include/unistdx.h b/trunk/lib/util/include/unistdx.h deleted file mode 100644 index 69f1f6bb7..000000000 --- a/trunk/lib/util/include/unistdx.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UNISTDX_H_INCLUDED -#define UNISTDX_H_INCLUDED - -/* Xmlrpc-c code #includes "unistdx.h" instead of because - does not exist on WIN32. -*/ - -#ifndef WIN32 -# include -#else - -#endif /* WIN32 */ - -#endif diff --git a/trunk/lib/util/string_parser.c b/trunk/lib/util/string_parser.c deleted file mode 100644 index 3c1fdf591..000000000 --- a/trunk/lib/util/string_parser.c +++ /dev/null @@ -1,226 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "int.h" -#include "girstring.h" -#include "casprintf.h" - -#include "string_parser.h" - -static const char * -strippedSubstring(const char * const string) { - - const char * p; - - for (p = &string[0]; isspace(*p); ++p); - - return p; -} - - - -void -interpretUll(const char * const string, - uint64_t * const ullP, - const char ** const errorP) { - - /* strtoull() has the same disappointing weaknesses of strtoul(). - See interpretUint(). - */ - - const char * const strippedString = strippedSubstring(string); - - if (strippedString[0] == '\0') - casprintf(errorP, "Null (or all whitespace) string."); - else if (!isdigit(strippedString[0])) - casprintf(errorP, "First non-blank character is '%c', not a digit.", - strippedString[0]); - else { - /* strtoull() does a bizarre thing where if the number is out - of range, it returns a clamped value but tells you about it - by setting errno = ERANGE. If it is not out of range, - strtoull() leaves errno alone. - */ - char * tail; - - errno = 0; /* So we can tell if strtoull() overflowed */ - - *ullP = XMLRPC_STRTOULL(strippedString, &tail, 10); - - if (tail[0] != '\0') - casprintf(errorP, "Non-digit stuff in string: %s", tail); - else if (errno == ERANGE) - casprintf(errorP, "Number too large"); - else - *errorP = NULL; - } -} - - - -void -interpretLl(const char * const string, - int64_t * const llP, - const char ** const errorP) { - - if (string[0] == '\0') - casprintf(errorP, "Null string."); - else { - /* strtoll() does a bizarre thing where if the number is out - of range, it returns a clamped value but tells you about it - by setting errno = ERANGE. If it is not out of range, - strtoll() leaves errno alone. - */ - char * tail; - - errno = 0; /* So we can tell if strtoll() overflowed */ - - *llP = XMLRPC_STRTOLL(string, &tail, 10); - - if (tail[0] != '\0') - casprintf(errorP, "Non-digit stuff in string: %s", tail); - else if (errno == ERANGE) - casprintf(errorP, "Number too large"); - else - *errorP = NULL; - } -} - - - -void -interpretUint(const char * const string, - unsigned int * const uintP, - const char ** const errorP) { - - /* strtoul() does a lousy job of dealing with invalid numbers. A null - string is just zero; a negative number is a large positive one; a - positive (cf unsigned) number is accepted. strtoul is inconsistent - in its treatment of the tail; if there is no valid number at all, - it returns the entire string as the tail, including leading white - space and sign, which are not themselves invalid. - */ - - const char * const strippedString = strippedSubstring(string); - - if (strippedString[0] == '\0') - casprintf(errorP, "Null (or all whitespace) string."); - else if (!isdigit(strippedString[0])) - casprintf(errorP, "First non-blank character is '%c', not a digit.", - strippedString[0]); - else { - /* strtoul() does a bizarre thing where if the number is out - of range, it returns a clamped value but tells you about it - by setting errno = ERANGE. If it is not out of range, - strtoul() leaves errno alone. - */ - char * tail; - unsigned long ulongValue; - - errno = 0; /* So we can tell if strtoul() overflowed */ - - ulongValue = strtoul(strippedString, &tail, 10); - - if (tail[0] != '\0') - casprintf(errorP, "Non-digit stuff in string: %s", tail); - else if (errno == ERANGE) - casprintf(errorP, "Number too large"); - else if (ulongValue > UINT_MAX) - casprintf(errorP, "Number too large"); - else { - *uintP = ulongValue; - *errorP = NULL; - } - } -} - - - -void -interpretInt(const char * const string, - int * const intP, - const char ** const errorP) { - - if (string[0] == '\0') - casprintf(errorP, "Null string."); - else { - /* strtol() does a bizarre thing where if the number is out - of range, it returns a clamped value but tells you about it - by setting errno = ERANGE. If it is not out of range, - strtol() leaves errno alone. - */ - char * tail; - long longValue; - - errno = 0; /* So we can tell if strtol() overflowed */ - - longValue = strtol(string, &tail, 10); - - if (tail[0] != '\0') - casprintf(errorP, "Non-digit stuff in string: %s", tail); - else if (errno == ERANGE) - casprintf(errorP, "Number too large"); - else if (longValue > INT_MAX) - casprintf(errorP, "Number too large"); - else if (longValue < INT_MIN) - casprintf(errorP, "Number too negative"); - else { - *intP = longValue; - *errorP = NULL; - } - } -} - - - -void -interpretBinUint(const char * const string, - uint64_t * const valueP, - const char ** const errorP) { - - char * tailptr; - long const mantissa_long = strtol(string, &tailptr, 10); - - if (errno == ERANGE) - casprintf(errorP, - "Numeric value out of range for computation: '%s'. " - "Try a smaller number with a K, M, G, etc. suffix.", - string); - else { - int64_t const mantissa = mantissa_long; - - int64_t argNumber; - - *errorP = NULL; /* initial assumption */ - - if (*tailptr == '\0') - /* There's no suffix. A pure number */ - argNumber = mantissa * 1; - else if (stripcaseeq(tailptr, "K")) - argNumber = mantissa * 1024; - else if (stripcaseeq(tailptr, "M")) - argNumber = mantissa * 1024 * 1024; - else if (stripcaseeq(tailptr, "G")) - argNumber = mantissa * 1024 * 1024 * 1024; - else if (stripcaseeq(tailptr, "T")) - argNumber = mantissa * 1024 * 1024 * 1024 * 1024; - else if (stripcaseeq(tailptr, "P")) - argNumber = mantissa * 1024 * 1024 * 1024 * 1024 * 1024; - else { - argNumber = 0; /* quiet compiler warning */ - casprintf(errorP, "Garbage suffix '%s' on number", tailptr); - } - if (!*errorP) { - if (argNumber < 0) - casprintf(errorP, "Unsigned numeric value is " - "negative: %" PRId64, argNumber); - else - *valueP = (uint64_t) argNumber; - } - } -} diff --git a/trunk/lib/util/stripcaseeq.c b/trunk/lib/util/stripcaseeq.c deleted file mode 100644 index 861da1084..000000000 --- a/trunk/lib/util/stripcaseeq.c +++ /dev/null @@ -1,68 +0,0 @@ -#include - -#include "bool.h" -#include "girstring.h" - - - -bool -stripcaseeq(const char * const comparand, - const char * const comparator) { -/*---------------------------------------------------------------------------- - Compare two strings, ignoring leading and trailing blanks and case. - - Return true if the strings are identical, false otherwise. ------------------------------------------------------------------------------*/ - const char *p, *q, *px, *qx; - bool equal; - - /* Make p and q point to the first non-blank character in each string. - If there are no non-blank characters, make them point to the terminating - NULL. - */ - - p = &comparand[0]; - while (*p == ' ') - ++p; - q = &comparator[0]; - while (*q == ' ') - ++q; - - /* Make px and qx point to the last non-blank character in each string. - If there are no nonblank characters (which implies the string is - null), make them point to the terminating NULL. - */ - - if (*p == '\0') - px = p; - else { - px = p + strlen(p) - 1; - while (*px == ' ') - --px; - } - - if (*q == '\0') - qx = q; - else { - qx = q + strlen(q) - 1; - while (*qx == ' ') - --qx; - } - - equal = true; /* initial assumption */ - - /* If the stripped strings aren't the same length, - we know they aren't equal - */ - if (px - p != qx - q) - equal = false; - - - while (p <= px) { - if (toupper(*p) != toupper(*q)) - equal = false; - ++p; ++q; - } - return equal; -} - diff --git a/trunk/lib/wininet_transport/Makefile b/trunk/lib/wininet_transport/Makefile deleted file mode 100644 index 9ee33f46e..000000000 --- a/trunk/lib/wininet_transport/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - LIBDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(LIBDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := lib/wininet_transport - -include $(BLDDIR)/config.mk - -default: all - -.PHONY: all -all: xmlrpc_wininet_transport.o xmlrpc_wininet_transport.osh - -# Rules for the above dependencies are in common.mk, -# courtesy of TARGET_MODS. - -TARGET_MODS = xmlrpc_wininet_transport - -OMIT_WININET_TRANSPORT_RULE=Y - -include $(SRCDIR)/common.mk - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -INCLUDES = \ - -I$(BLDDIR) \ - -I$(BLDDIR)/include \ - -Isrcdir/include \ - -Isrcdir/lib/util/include \ - -.PHONY: clean -clean: clean-common - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: tags -tags: TAGS - -.PHONY: distdir -distdir: - -.PHONY: install -install: - -.PHONY: uninstall -uninstall: - -.PHONY: dep -dep: dep-common - -include depend.mk - -# Need this dependency for those who don't use depend.mk. -# Without it, version.h doesn't get created. -xmlrpc_wininet_transport.o xmlrpc_wininet_transport.osh: version.h diff --git a/trunk/lib/wininet_transport/pthreadx.h b/trunk/lib/wininet_transport/pthreadx.h deleted file mode 100644 index 23ebabdc7..000000000 --- a/trunk/lib/wininet_transport/pthreadx.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#ifndef PTHREADX_H_INCLUDED -#define PTHREADX_H_INCLUDED - -#include "xmlrpc_config.h" - -#if HAVE_PTHREAD -# define _REENTRANT -# include -#elif HAVE_WINDOWS_THREAD -/* We define WIN32_WIN_LEAN_AND_MEAN to make contain less - junk; nothing in Xmlrpc-c needs that stuff. One significant thing it cuts - out is , which would conflict with the that our - includer might use. -*/ -#define WIN32_WIN_LEAN_AND_MEAN -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef HANDLE pthread_t; - -typedef -struct { - int attrs; /* currently unused. placeholder. */ -} pthread_attr_t; - -typedef void * pthread_func(void *); - -extern int pthread_create(pthread_t * const new_thread_ID, - const pthread_attr_t * const attr, - pthread_func * start_func, - void * const arg); -extern int pthread_cancel(pthread_t target_thread); -extern int pthread_join(pthread_t target_thread, void **status); -extern int pthread_detach(pthread_t target_thread); - -#ifdef __cplusplus -} -#endif -#else /* HAVE_WINDOWS_THREAD */ - #error "You don't have any thread facility. (According to " - #error "HAVE_PTHREAD and HAVE_WINDOWS_THREAD macros defined in " - #error "xmlrpc_config.h)" -#endif - -#endif diff --git a/trunk/lib/wininet_transport/pthreadx_win32.c b/trunk/lib/wininet_transport/pthreadx_win32.c deleted file mode 100644 index 4055dcca8..000000000 --- a/trunk/lib/wininet_transport/pthreadx_win32.c +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include - -#include "mallocvar.h" - -#include "pthreadx.h" - -#undef PACKAGE -#undef VERSION - -struct winStartArg { - pthread_func * func; - void * arg; -}; - - - -static unsigned int __stdcall -winThreadStart(void * const arg) { -/*---------------------------------------------------------------------------- - This is a thread start/root function for the Windows threading facility - (i.e. this can be an argument to _beginthreadex()). - - All we do is call the real start/root function, which expects to be - called in the pthread format. ------------------------------------------------------------------------------*/ - struct winStartArg * const winStartArgP = arg; - - winStartArgP->func(winStartArgP->arg); - - free(winStartArgP); - - return 0; -} - - - -int -pthread_create(pthread_t * const newThreadIdP, - const pthread_attr_t * const attr, - pthread_func * func, - void * const arg) { - - HANDLE hThread; - DWORD dwThreadID; - struct winStartArg * winStartArgP; - - MALLOCVAR_NOFAIL(winStartArgP); - - winStartArgP->func = func; - winStartArgP->arg = arg; - - hThread = (HANDLE) _beginthreadex( - NULL, 0, &winThreadStart, (LPVOID)winStartArgP, CREATE_SUSPENDED, - &dwThreadID); - - SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL); - ResumeThread(hThread); - - *newThreadIdP = hThread; - - return hThread ? 0 : -1; -} - - - -/* Just kill it. */ -int -pthread_cancel(pthread_t const target_thread) { - - CloseHandle(target_thread); - return 0; -} - - - -/* Waits for the thread to exit before continuing. */ -int -pthread_join(pthread_t const target_thread, - void ** const statusP) { - - DWORD dwResult = WaitForSingleObject(target_thread, INFINITE); - *statusP = (void *)dwResult; - return 0; -} - - - -int -pthread_detach(pthread_t const target_thread) { - return 0; -} - - - diff --git a/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c b/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c deleted file mode 100644 index 858a7b461..000000000 --- a/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c +++ /dev/null @@ -1,1001 +0,0 @@ -/*============================================================================= - xmlrpc_wininet_transport -=============================================================================== - WinInet-based client transport for Xmlrpc-c. Copyright information at - the bottom of this file. - -=============================================================================*/ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#define WIN32_LEAN_AND_MEAN -#include -#include - -#include "bool.h" -#include "mallocvar.h" -#include "linklist.h" -#include "casprintf.h" -#include "pthreadx.h" - -#include "xmlrpc-c/lock.h" -#include "xmlrpc-c/lock_platform.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/client_int.h" -#include "xmlrpc-c/transport.h" - -#if defined(_DEBUG) -# include -# define new DEBUG_NEW -# define malloc(size) _malloc_dbg( size, _NORMAL_BLOCK, __FILE__, __LINE__) -# undef THIS_FILE - static char THIS_FILE[] = __FILE__; -#endif - - -static HINTERNET hSyncInternetSession = NULL; - -/* Declare WinInet status callback. */ -void CALLBACK -statusCallback(HINTERNET const hInternet, - unsigned long const dwContext, - unsigned long const dwInternetStatus, - void * const lpvStatusInformation, - unsigned long const dwStatusInformationLength); - - -struct xmlrpc_client_transport { - struct lock * listLockP; - struct list_head rpcList; - /* List of all RPCs that exist for this transport. An RPC exists - from the time the user requests it until the time the user - acknowledges it is done. - */ - int allowInvalidSSLCerts; - /* Flag to specify if we ignore invalid SSL Certificates. If this - is set to zero, calling a XMLRPC server with an invalid SSL - certificate will fail. This is the default behavior of the other - transports, but invalid certificates were allowed in pre 1.2 - wininet xmlrpc-c transports. - */ -}; - -typedef struct { - unsigned long http_status; - HINTERNET hHttpRequest; - HINTERNET hURL; - INTERNET_PORT nPort; - char szHostName[255]; - char szUrlPath[255]; - BOOL bUseSSL; - char * headerList; - BYTE * pSendData; - xmlrpc_mem_block * pResponseData; -} winInetTransaction; - -typedef struct { - struct list_head link; /* link in transport's list of RPCs */ - winInetTransaction * winInetTransactionP; - /* The object which does the HTTP transaction, with no knowledge - of XML-RPC or Xmlrpc-c. - */ - xmlrpc_mem_block * responseXmlP; - xmlrpc_bool threadExists; - pthread_t thread; - xmlrpc_transport_asynch_complete complete; - /* Routine to call to complete the RPC after it is complete HTTP-wise. - NULL if none. - */ - struct xmlrpc_call_info * callInfoP; - /* User's identifier for this RPC */ - struct xmlrpc_client_transport * clientTransportP; -} rpc; - - - -static void -createWinInetHeaderList(xmlrpc_env * const envP, - const xmlrpc_server_info * const serverP, - char ** const headerListP) { - - const char * const szContentType = "Content-Type: text/xml\r\n"; - - char * szHeaderList; - - /* Send an authorization header if we need one. */ - if (serverP->allowedAuth.basic) { - /* Make the header with content type and authorization */ - /* NOTE: A newline is required between each added header */ - szHeaderList = malloc(strlen(szContentType) + 17 + - strlen(serverP->basicAuthHdrValue) + 1); - - if (szHeaderList == NULL) - xmlrpc_faultf(envP, - "Couldn't allocate memory for authorization header"); - else { - memcpy(szHeaderList, szContentType, strlen(szContentType)); - memcpy(szHeaderList + strlen(szContentType),"\r\nAuthorization: ", - 17); - memcpy(szHeaderList + strlen(szContentType) + 17, - serverP->basicAuthHdrValue, - strlen(serverP->basicAuthHdrValue) + 1); - } - } else { - /* Just the content type header is needed */ - szHeaderList = malloc(strlen(szContentType) + 1); - - if (szHeaderList == NULL) - xmlrpc_faultf(envP, - "Couldn't allocate memory for standard header"); - else - memcpy(szHeaderList, szContentType, strlen(szContentType) + 1); - } - *headerListP = szHeaderList; -} - - - -static void -createWinInetTransaction(xmlrpc_env * const envP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block * const responseXmlP, - winInetTransaction ** const winInetTranPP) { - - winInetTransaction * winInetTransactionP; - - MALLOCVAR(winInetTransactionP); - if (winInetTransactionP == NULL) - xmlrpc_faultf(envP, "No memory to create WinInet transaction."); - else { - char szExtraInfo[255]; - char szScheme[100]; - URL_COMPONENTS uc; - BOOL succeeded; - - /* Init to defaults */ - winInetTransactionP->http_status = 0; - winInetTransactionP->hHttpRequest = NULL; - winInetTransactionP->hURL = NULL; - winInetTransactionP->headerList = NULL; - winInetTransactionP->pSendData = NULL; - winInetTransactionP->pResponseData = responseXmlP; - - /* Parse the URL and store results into the winInetTransaction */ - - memset(&uc, 0, sizeof(uc)); - uc.dwStructSize = sizeof (uc); - uc.lpszScheme = szScheme; - uc.dwSchemeLength = 100; - uc.lpszHostName = winInetTransactionP->szHostName; - uc.dwHostNameLength = 255; - uc.lpszUrlPath = winInetTransactionP->szUrlPath; - uc.dwUrlPathLength = 255; - uc.lpszExtraInfo = szExtraInfo; - uc.dwExtraInfoLength = 255; - succeeded = InternetCrackUrl(serverP->serverUrl, - strlen(serverP->serverUrl), - ICU_ESCAPE, &uc); - if (!succeeded) - xmlrpc_faultf(envP, "Unable to parse the server URL."); - else { - winInetTransactionP->nPort = - uc.nPort ? uc.nPort : INTERNET_DEFAULT_HTTP_PORT; - if (_strnicmp(uc.lpszScheme, "https", 5) == 0) - winInetTransactionP->bUseSSL=TRUE; - else - winInetTransactionP->bUseSSL=FALSE; - createWinInetHeaderList(envP, serverP, - &winInetTransactionP->headerList); - - XMLRPC_MEMBLOCK_APPEND(char, envP, callXmlP, "\0", 1); - if (!envP->fault_occurred) { - winInetTransactionP->pSendData = - XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP); - } - } - - if (envP->fault_occurred) - free(winInetTransactionP); - } - *winInetTranPP = winInetTransactionP; -} - - - -static void -destroyWinInetTransaction(winInetTransaction * const winInetTransactionP) { - - XMLRPC_ASSERT_PTR_OK(winInetTransactionP); - - if (winInetTransactionP->hHttpRequest) - InternetCloseHandle(winInetTransactionP->hHttpRequest); - - if (winInetTransactionP->hURL) - InternetCloseHandle(winInetTransactionP->hURL); - - if (winInetTransactionP->headerList) - free(winInetTransactionP->headerList); - - free(winInetTransactionP); -} - - - -static void -get_wininet_response(xmlrpc_env * const envP, - winInetTransaction * const winInetTransactionP) { - - unsigned long dwLen; - INTERNET_BUFFERS inetBuffer; - unsigned long dwFlags; - unsigned long dwErr; - unsigned long nExpected; - void * body; - BOOL bOK; - PVOID pMsgMem; - - pMsgMem = NULL; /* initial value */ - dwErr = 0; /* initial value */ - body = NULL; /* initial value */ - dwLen = sizeof(unsigned long); /* initial value */ - - inetBuffer.dwStructSize = sizeof (INTERNET_BUFFERS); - inetBuffer.Next = NULL; - inetBuffer.lpcszHeader = NULL; - inetBuffer.dwHeadersTotal = 0; - inetBuffer.dwHeadersLength = 0; - inetBuffer.dwOffsetHigh = 0; - inetBuffer.dwOffsetLow = 0; - inetBuffer.dwBufferLength = 0; - - /* Note that while Content-Length is optional in HTTP 1.1, it is - required by XML-RPC. Following fails if server didn't send it. - */ - - bOK = HttpQueryInfo(winInetTransactionP->hHttpRequest, - HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, - &inetBuffer.dwBufferTotal, &dwLen, NULL); - if (!bOK) { - LPTSTR pMsg; - dwErr = GetLastError (); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dwErr, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &pMsgMem, - 1024,NULL); - - pMsg = pMsgMem ? (LPTSTR)pMsgMem : "Sync HttpQueryInfo failed."; - XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); - } - - if (inetBuffer.dwBufferTotal == 0) - XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, "WinInet returned no data"); - - inetBuffer.lpvBuffer = calloc(inetBuffer.dwBufferTotal, sizeof(TCHAR)); - body = inetBuffer.lpvBuffer; - dwFlags = IRF_SYNC; - nExpected = inetBuffer.dwBufferTotal; - inetBuffer.dwBufferLength = nExpected; - InternetQueryDataAvailable(winInetTransactionP->hHttpRequest, - &inetBuffer.dwBufferLength, 0, 0); - - /* Read Response from InternetFile */ - do { - if (inetBuffer.dwBufferLength != 0) - bOK = InternetReadFileEx(winInetTransactionP->hHttpRequest, - &inetBuffer, dwFlags, 1); - - if (!bOK) - dwErr = GetLastError(); - - if (dwErr) { - if (dwErr == WSAEWOULDBLOCK || dwErr == ERROR_IO_PENDING) { - /* Non-block socket operation wait 10 msecs */ - SleepEx(10, TRUE); - /* Reset dwErr to zero for next pass */ - dwErr = 0; - } else { - LPTSTR pMsg; - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dwErr, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &pMsgMem, - 1024,NULL); - pMsg = pMsgMem ? - (LPTSTR)pMsgMem : "ASync InternetReadFileEx failed."; - XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); - } - } - - if (inetBuffer.dwBufferLength) { - TCHAR * const oldBufptr = inetBuffer.lpvBuffer; - - inetBuffer.lpvBuffer = oldBufptr + inetBuffer.dwBufferLength; - nExpected -= inetBuffer.dwBufferLength; - /* Adjust inetBuffer.dwBufferLength when it is greater than the */ - /* expected end of file */ - if (inetBuffer.dwBufferLength > nExpected) - inetBuffer.dwBufferLength = nExpected; - - } else - inetBuffer.dwBufferLength = nExpected; - dwErr = 0; - } while (nExpected != 0); - - /* Add to the response buffer. */ - xmlrpc_mem_block_append(envP, winInetTransactionP->pResponseData, body, - inetBuffer.dwBufferTotal); - XMLRPC_FAIL_IF_FAULT(envP); - - cleanup: - /* Since the XMLRPC_FAIL calls goto cleanup, we must handle */ - /* the free'ing of the memory here. */ - if (pMsgMem != NULL) - LocalFree(pMsgMem); - - if (body) - free(body); -} - - - -static void -performWinInetTransaction( - xmlrpc_env * const envP, - winInetTransaction * const winInetTransactionP, - struct xmlrpc_client_transport * const clientTransportP) { - - const char * const acceptTypes[] = {"text/xml", NULL}; - - unsigned long queryLen; - LPVOID pMsgMem; - BOOL succeeded; - - unsigned long lastErr; - unsigned long reqFlags; - - pMsgMem = NULL; /* initial value */ - - reqFlags = INTERNET_FLAG_NO_UI; /* initial value */ - - winInetTransactionP->hURL = - InternetConnect(hSyncInternetSession, - winInetTransactionP->szHostName, - winInetTransactionP->nPort, - NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); - - /* Start our request running. */ - if (winInetTransactionP->bUseSSL == TRUE) - reqFlags |= - INTERNET_FLAG_SECURE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID; - - winInetTransactionP->hHttpRequest = - HttpOpenRequest(winInetTransactionP->hURL, "POST", - winInetTransactionP->szUrlPath, "HTTP/1.1", NULL, - (const char **)&acceptTypes, - reqFlags, 1); - - XMLRPC_FAIL_IF_NULL(winInetTransactionP->hHttpRequest, envP, - XMLRPC_INTERNAL_ERROR, - "Unable to open the requested URL."); - - succeeded = - HttpAddRequestHeaders(winInetTransactionP->hHttpRequest, - winInetTransactionP->headerList, - strlen (winInetTransactionP->headerList), - HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); - - if (!succeeded) - XMLRPC_FAIL(envP, XMLRPC_INTERNAL_ERROR, - "Could not set Content-Type."); - - { - /* By default, a request times out after 30 seconds. We don't want - it to timeout at all, since we don't know what the user is doing. - */ - DWORD dwTimeOut = 0x7FFFFFFF; /* Approximation of infinity */ - InternetSetOption(winInetTransactionP->hHttpRequest, - INTERNET_OPTION_RECEIVE_TIMEOUT, - &dwTimeOut, sizeof(dwTimeOut)); - } -Again: - /* Send the requested XML remote procedure command */ - succeeded = HttpSendRequest(winInetTransactionP->hHttpRequest, NULL, 0, - winInetTransactionP->pSendData, - strlen(winInetTransactionP->pSendData)); - if (!succeeded) { - LPTSTR pMsg; - - lastErr = GetLastError(); - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErr, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &pMsgMem, - 0, NULL); - - if (pMsgMem == NULL) { - switch (lastErr) { - case ERROR_INTERNET_CANNOT_CONNECT: - pMsg = "Sync HttpSendRequest failed: Connection refused."; - break; - case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED: - pMsg = "Sync HttpSendRequest failed: " - "Client authorization certificate needed."; - break; - - /* The following conditions are recommendations that microsoft */ - /* provides in their knowledge base. */ - - /* HOWTO: Handle Invalid Certificate Authority Error with - WinInet (Q182888) - */ - case ERROR_INTERNET_INVALID_CA: - if (clientTransportP->allowInvalidSSLCerts){ - OutputDebugString( - "Sync HttpSendRequest failed: " - "The function is unfamiliar with the certificate " - "authority that generated the server's certificate. "); - reqFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; - - InternetSetOption(winInetTransactionP->hHttpRequest, - INTERNET_OPTION_SECURITY_FLAGS, - &reqFlags, sizeof(reqFlags)); - - goto Again; - } else - pMsg = "Invalid or unknown/untrusted " - "SSL Certificate Authority."; - break; - - /* HOWTO: Make SSL Requests Using WinInet (Q168151) */ - case ERROR_INTERNET_SEC_CERT_CN_INVALID: - if (clientTransportP->allowInvalidSSLCerts) { - OutputDebugString( - "Sync HttpSendRequest failed: " - "The SSL certificate common name (host name field) " - "is incorrect\r\n " - "for example, if you entered www.server.com " - "and the common name " - "on the certificate says www.different.com. "); - - reqFlags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID; - - InternetSetOption(winInetTransactionP->hHttpRequest, - INTERNET_OPTION_SECURITY_FLAGS, - &reqFlags, sizeof(reqFlags)); - - goto Again; - } else - pMsg = "The SSL certificate common name " - "(host name field) is incorrect."; - break; - - case ERROR_INTERNET_SEC_CERT_DATE_INVALID: - if (clientTransportP->allowInvalidSSLCerts) { - OutputDebugString( - "Sync HttpSendRequest failed: " - "The SSL certificate date that was received " - "from the server is " - "bad. The certificate is expired. "); - - reqFlags |= INTERNET_FLAG_IGNORE_CERT_DATE_INVALID; - - InternetSetOption(winInetTransactionP->hHttpRequest, - INTERNET_OPTION_SECURITY_FLAGS, - &reqFlags, sizeof(reqFlags)); - - goto Again; - } else - pMsg = "The SSL certificate date that was received " - "from the server is invalid."; - break; - - case ERROR_INTERNET_SEC_CERT_REV_FAILED: - if (clientTransportP->allowInvalidSSLCerts) { - OutputDebugString( - "Sync HttpSendRequest failed: " - "Check for revocation of the SSL certificate " - "failed. "); - - reqFlags |= SECURITY_FLAG_IGNORE_REVOCATION; - - InternetSetOption(winInetTransactionP->hHttpRequest, - INTERNET_OPTION_SECURITY_FLAGS, - &reqFlags, sizeof(reqFlags)); - - goto Again; - } else - pMsg = "Check for revocation of the SSL certificate " - "failed."; - break; - - default: - pMsg = (LPTSTR)pMsgMem = LocalAlloc(LPTR, MAX_PATH); - sprintf(pMsg, "Sync HttpSendRequest failed: " - "GetLastError (%d)", lastErr); - break; - - } - } else - pMsg = (LPTSTR)pMsgMem; - - XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); - } - - queryLen = sizeof(unsigned long); /* initial value */ - - succeeded = HttpQueryInfo(winInetTransactionP->hHttpRequest, - HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, - &winInetTransactionP->http_status, - &queryLen, NULL); - if (!succeeded) { - LPTSTR pMsg; - - lastErr = GetLastError(); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - lastErr, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &pMsgMem, - 1024, NULL); - - pMsg = pMsgMem ? (LPTSTR)pMsgMem : "Sync HttpQueryInfo failed."; - XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); - } - - /* Make sure we got a "200 OK" message from the remote server. */ - if (winInetTransactionP->http_status != 200) { - unsigned long msgLen; - char errMsg[1024]; - errMsg[0] = '\0'; - msgLen = 1024; /* initial value */ - - HttpQueryInfo(winInetTransactionP->hHttpRequest, - HTTP_QUERY_STATUS_TEXT, errMsg, &msgLen, NULL); - - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NETWORK_ERROR, - "HTTP error #%d occurred\n %s", - winInetTransactionP->http_status, errMsg); - goto cleanup; - } - /* Read the response. */ - get_wininet_response(envP, winInetTransactionP); - XMLRPC_FAIL_IF_FAULT(envP); - - cleanup: - /* Since the XMLRPC_FAIL calls goto cleanup, we must handle */ - /* the free'ing of the memory here. */ - if (pMsgMem) - LocalFree(pMsgMem); -} - - - -static void * -doAsyncRpc(void * const arg) { - - rpc * const rpcP = arg; - - xmlrpc_env env; - xmlrpc_env_init(&env); - - performWinInetTransaction(&env, rpcP->winInetTransactionP, - rpcP->clientTransportP ); - - rpcP->complete(rpcP->callInfoP, rpcP->responseXmlP, env); - - xmlrpc_env_clean(&env); - - return NULL; -} - - - -static void -createRpcThread(xmlrpc_env * const envP, - rpc * const rpcP, - pthread_t * const threadP) { - - int rc; - - rc = pthread_create(threadP, NULL, doAsyncRpc, rpcP); - switch (rc) { - case 0: - break; - case EAGAIN: - xmlrpc_faultf(envP, "pthread_create() failed: " - "System Resources exceeded."); - break; - case EINVAL: - xmlrpc_faultf(envP, "pthread_create() failed: " - "Param Error for attr."); - break; - case ENOMEM: - xmlrpc_faultf(envP, "pthread_create() failed: " - "No memory for new thread."); - break; - default: - xmlrpc_faultf(envP, "pthread_create() failed: " - "Unrecognized error code %d.", rc); - break; - } -} - - - -static void -rpcCreate(xmlrpc_env * const envP, - struct xmlrpc_client_transport * const clientTransportP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block * const responseXmlP, - xmlrpc_transport_asynch_complete complete, - struct xmlrpc_call_info * const callInfoP, - rpc ** const rpcPP) { - - rpc * rpcP; - - MALLOCVAR(rpcP); - if (rpcP == NULL) - xmlrpc_faultf(envP, "Couldn't allocate memory for rpc object"); - else { - rpcP->callInfoP = callInfoP; - rpcP->complete = complete; - rpcP->responseXmlP = responseXmlP; - rpcP->threadExists = FALSE; - - createWinInetTransaction(envP, serverP, callXmlP, responseXmlP, - &rpcP->winInetTransactionP); - if (!envP->fault_occurred) { - if (complete) { - createRpcThread(envP, rpcP, &rpcP->thread); - if (!envP->fault_occurred) - rpcP->threadExists = TRUE; - } - if (!envP->fault_occurred) { - list_init_header(&rpcP->link, rpcP); - clientTransportP->listLockP->acquire( - clientTransportP->listLockP); - list_add_head(&clientTransportP->rpcList, &rpcP->link); - clientTransportP->listLockP->release( - clientTransportP->listLockP); - } - if (envP->fault_occurred) - destroyWinInetTransaction(rpcP->winInetTransactionP); - } - if (envP->fault_occurred) - free(rpcP); - } - *rpcPP = rpcP; -} - - - -static void -rpcDestroy(rpc * const rpcP) { - - XMLRPC_ASSERT_PTR_OK(rpcP); - XMLRPC_ASSERT(!rpcP->threadExists); - - destroyWinInetTransaction(rpcP->winInetTransactionP); - - list_remove(&rpcP->link); - - free(rpcP); -} - - - -static void * -finishRpc(struct list_head * const headerP, - void * const context ATTR_UNUSED) { - - rpc * const rpcP = headerP->itemP; - - if (rpcP->threadExists) { - void * status; - int result; - - result = pthread_join(rpcP->thread, &status); - - rpcP->threadExists = FALSE; - } - - XMLRPC_MEMBLOCK_FREE(char, rpcP->responseXmlP); - - rpcDestroy(rpcP); - - return NULL; -} - - -/* Used for debugging purposes to track the status of - your request. -*/ -void CALLBACK -statusCallback (HINTERNET const hInternet, - unsigned long const dwContext, - unsigned long const dwInternetStatus, - void * const lpvStatusInformation, - unsigned long const dwStatusInformationLength) { - - switch (dwInternetStatus) { - case INTERNET_STATUS_RESOLVING_NAME: - OutputDebugString("INTERNET_STATUS_RESOLVING_NAME\r\n"); - break; - - case INTERNET_STATUS_NAME_RESOLVED: - OutputDebugString("INTERNET_STATUS_NAME_RESOLVED\r\n"); - break; - - case INTERNET_STATUS_HANDLE_CREATED: - OutputDebugString("INTERNET_STATUS_HANDLE_CREATED\r\n"); - break; - - case INTERNET_STATUS_CONNECTING_TO_SERVER: - OutputDebugString("INTERNET_STATUS_CONNECTING_TO_SERVER\r\n"); - break; - - case INTERNET_STATUS_REQUEST_SENT: - OutputDebugString("INTERNET_STATUS_REQUEST_SENT\r\n"); - break; - - case INTERNET_STATUS_SENDING_REQUEST: - OutputDebugString("INTERNET_STATUS_SENDING_REQUEST\r\n"); - break; - - case INTERNET_STATUS_CONNECTED_TO_SERVER: - OutputDebugString("INTERNET_STATUS_CONNECTED_TO_SERVER\r\n"); - break; - - case INTERNET_STATUS_RECEIVING_RESPONSE: - OutputDebugString("INTERNET_STATUS_RECEIVING_RESPONSE\r\n"); - break; - - case INTERNET_STATUS_RESPONSE_RECEIVED: - OutputDebugString("INTERNET_STATUS_RESPONSE_RECEIVED\r\n"); - break; - - case INTERNET_STATUS_CLOSING_CONNECTION: - OutputDebugString("INTERNET_STATUS_CLOSING_CONNECTION\r\n"); - break; - - case INTERNET_STATUS_CONNECTION_CLOSED: - OutputDebugString("INTERNET_STATUS_CONNECTION_CLOSED\r\n"); - break; - - case INTERNET_STATUS_HANDLE_CLOSING: - OutputDebugString("INTERNET_STATUS_HANDLE_CLOSING\r\n"); - break; - - case INTERNET_STATUS_CTL_RESPONSE_RECEIVED: - OutputDebugString("INTERNET_STATUS_CTL_RESPONSE_RECEIVED\r\n"); - break; - - case INTERNET_STATUS_REDIRECT: - OutputDebugString("INTERNET_STATUS_REDIRECT\r\n"); - break; - - case INTERNET_STATUS_REQUEST_COMPLETE: - /* This indicates the data is ready. */ - OutputDebugString("INTERNET_STATUS_REQUEST_COMPLETE\r\n"); - break; - - default: - OutputDebugString("statusCallback, default case!\r\n"); - break; - } -} - - - -static void -create(xmlrpc_env * const envP, - int const flags ATTR_UNUSED, - const char * const appname ATTR_UNUSED, - const char * const appversion ATTR_UNUSED, - const void * const transportparmsP, - size_t const parm_size, - struct xmlrpc_client_transport ** const handlePP) { -/*---------------------------------------------------------------------------- - This does the 'create' operation for a WinInet client transport. ------------------------------------------------------------------------------*/ - const struct xmlrpc_wininet_xportparms * const wininetXportParmsP = - transportparmsP; - - struct xmlrpc_client_transport * transportP; - - MALLOCVAR(transportP); - if (transportP == NULL) - xmlrpc_faultf(envP, "Unable to allocate transport descriptor."); - else { - transportP->listLockP = xmlrpc_lock_create(); - - list_make_empty(&transportP->rpcList); - - if (hSyncInternetSession == NULL) - hSyncInternetSession = - InternetOpen("xmlrpc-c wininet transport", - INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); - - if (!wininetXportParmsP || - parm_size < XMLRPC_WXPSIZE(allowInvalidSSLCerts)) - transportP->allowInvalidSSLCerts = 0; - else - transportP->allowInvalidSSLCerts = - wininetXportParmsP->allowInvalidSSLCerts; - - *handlePP = transportP; - } -} - - - -static void -destroy(struct xmlrpc_client_transport * const clientTransportP) { -/*---------------------------------------------------------------------------- - This does the 'destroy' operation for a WinInet client transport. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(clientTransportP != NULL); - - XMLRPC_ASSERT(list_is_empty(&clientTransportP->rpcList)); - - if (hSyncInternetSession) - InternetCloseHandle(hSyncInternetSession); - hSyncInternetSession = NULL; - - clientTransportP->listLockP->destroy(clientTransportP->listLockP); - - free(clientTransportP); -} - - - -static void -sendRequest(xmlrpc_env * const envP, - struct xmlrpc_client_transport * const clientTransportP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_transport_asynch_complete complete, - xmlrpc_transport_progress progress, - struct xmlrpc_call_info * const callInfoP) { -/*---------------------------------------------------------------------------- - Initiate an XML-RPC rpc asynchronously. Don't wait for it to go to - the server. - - Unless we return failure, we arrange to have complete() called when - the rpc completes. - - This does the 'send_request' operation for a WinInet client transport. ------------------------------------------------------------------------------*/ - rpc * rpcP; - xmlrpc_mem_block * responseXmlP; - - responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - rpcCreate(envP, clientTransportP, serverP, callXmlP, responseXmlP, - complete, callInfoP, - &rpcP); - - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, responseXmlP); - } - /* The user's eventual finish_asynch call will destroy this RPC - and response buffer - */ -} - - - -static void -finishAsynch(struct xmlrpc_client_transport * const clientTransportP, - xmlrpc_timeoutType const timeoutType ATTR_UNUSED, - xmlrpc_timeout const timeout ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - Wait for the threads of all outstanding RPCs to exit and destroy those - RPCs. - - This does the 'finish_asynch' operation for a WinInet client transport. ------------------------------------------------------------------------------*/ - /* We ignore any timeout request. Some day, we should figure out how - to set an alarm and interrupt running threads. - */ - - clientTransportP->listLockP->acquire(clientTransportP->listLockP); - - list_foreach(&clientTransportP->rpcList, finishRpc, NULL); - - clientTransportP->listLockP->release(clientTransportP->listLockP); -} - - - -static void -call(xmlrpc_env * const envP, - struct xmlrpc_client_transport * const clientTransportP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block ** const responsePP) { - - xmlrpc_mem_block * responseXmlP; - rpc * rpcP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(callXmlP); - XMLRPC_ASSERT_PTR_OK(responsePP); - - responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - rpcCreate(envP, clientTransportP, serverP, callXmlP, responseXmlP, - NULL, NULL, &rpcP); - if (!envP->fault_occurred) { - performWinInetTransaction(envP, rpcP->winInetTransactionP, - clientTransportP); - - *responsePP = responseXmlP; - - rpcDestroy(rpcP); - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, responseXmlP); - } -} - - - -struct xmlrpc_client_transport_ops xmlrpc_wininet_transport_ops = { - NULL, - NULL, - &create, - &destroy, - &sendRequest, - &call, - &finishAsynch, - NULL, -}; - - - -/* 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. */ diff --git a/trunk/missing b/trunk/missing deleted file mode 100755 index 7789652e8..000000000 --- a/trunk/missing +++ /dev/null @@ -1,190 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. -# Copyright (C) 1996, 1997 Free Software Foundation, Inc. -# Franc,ois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -case "$1" in - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - yacc create \`y.tab.[ch]', if possible, from existing .[ch]" - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing - GNU libit 0.0" - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - - aclocal) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acinclude.m4' or \`configure.in'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`configure.in'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acconfig.h' or \`configure.in'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case "$f" in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if [ ! -f y.tab.h ]; then - echo >y.tab.h - fi - if [ ! -f y.tab.c ]; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if [ ! -f lex.yy.c ]; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - makeinfo) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` - fi - touch $file - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequirements for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 diff --git a/trunk/mkinstalldirs b/trunk/mkinstalldirs deleted file mode 100755 index 4f58503ea..000000000 --- a/trunk/mkinstalldirs +++ /dev/null @@ -1,40 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Public domain - -# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ - -errstatus=0 - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d - do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# mkinstalldirs ends here diff --git a/trunk/src/Makefile b/trunk/src/Makefile deleted file mode 100644 index 1cdf8b021..000000000 --- a/trunk/src/Makefile +++ /dev/null @@ -1,421 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - SRCDIR := $(call updir,$(CURDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := src - -include $(BLDDIR)/config.mk - -default: all - -SUBDIRS = - -ifeq ($(ENABLE_CPLUSPLUS),yes) - SUBDIRS += cpp -endif - -TARGET_LIBRARY_NAMES := libxmlrpc libxmlrpc_server - -# We cannot build libxmlrpc_server_abyss if we can't also build Abyss, -# because we need libxmlrpc_abyss in order to build the proper runtime -# dependencies into libxmlrpc_server_abyss. - -ifeq ($(ENABLE_ABYSS_SERVER),yes) - TARGET_LIBRARY_NAMES += libxmlrpc_server_abyss -endif - -ifeq ($(MUST_BUILD_CLIENT),yes) - TARGET_LIBRARY_NAMES += libxmlrpc_client -endif - -ifeq ($(ENABLE_CGI_SERVER),yes) - TARGET_LIBRARY_NAMES += libxmlrpc_server_cgi -endif - -STATIC_LIBRARIES_TO_INSTALL = $(TARGET_STATIC_LIBRARIES) - -SHARED_LIBS_TO_BUILD := $(TARGET_LIBRARY_NAMES) -SHARED_LIBS_TO_INSTALL := $(TARGET_LIBRARY_NAMES) - -# TRANSPORT_MODS is the list of modules that have to go into the client -# library to provide the client XML transport functions. - -# TRANSPORT_LIBDEP is linker -l options to declare what libraries contain -# things to which the transport objects refer. (like LIBxxx_LIBDEP -- -# see below) - -TRANSPORT_MODS = -TRANSPORT_LIBDEP = -TRANSPORT_INCLUDES = -ifeq ($(MUST_BUILD_WININET_CLIENT),yes) - TRANSPORT_MODS += $(BLDDIR)/lib/wininet_transport/xmlrpc_wininet_transport - TRANSPORT_LIBDEP += $(shell wininet-config --libs) - TRANSPORT_INCLUDES += -Isrcdir/lib/wininet_transport -endif -ifeq ($(MUST_BUILD_CURL_CLIENT),yes) - TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport - TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curltransaction - TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curlmulti - TRANSPORT_LIBDEP += $(shell $CURL_CONFIG --libs) - TRANSPORT_INCLUDES += -Isrcdir/lib/curl_transport -endif -ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) - TRANSPORT_MODS += $(BLDDIR)/lib/libwww_transport/xmlrpc_libwww_transport - TRANSPORT_LIBDEP += $(shell libwww-config --libs) - TRANSPORT_INCLUDES += -Isrcdir/lib/libwww_transport -endif - -ifeq ($(ENABLE_LIBXML2_BACKEND),yes) - XMLRPC_XML_PARSER = xmlrpc_libxml2 - XML_PARSER_LIBDEP = $(shell xml2-config --libs) - XML_PARSER_LIBDEP_DEP = - XML_PKGCONFIG_REQ = libxml-2.0 -else - XMLRPC_XML_PARSER = xmlrpc_expat - XML_PARSER_LIBDEP = \ - -Lblddir/lib/expat/xmlparse -lxmlrpc_xmlparse \ - -Lblddir/lib/expat/xmltok -lxmlrpc_xmltok - XML_PARSER_LIBDEP_DEP = $(LIBXMLRPC_XMLPARSE) $(LIBXMLRPC_XMLTOK) - XML_PKGCONFIG_REQ = xmlrpc_expat -endif - -# LIBxxx_OBJS is the list of object files that make up library libxxx. - -LIBXMLRPC_MODS = \ - base_global \ - double \ - json \ - parse_datetime \ - parse_value \ - resource \ - trace \ - version \ - xmlrpc_data \ - xmlrpc_datetime \ - xmlrpc_string \ - xmlrpc_array \ - xmlrpc_struct \ - xmlrpc_build \ - xmlrpc_decompose \ - $(XMLRPC_XML_PARSER) \ - xmlrpc_parse \ - xmlrpc_serialize \ - xmlrpc_authcookie \ - -LIBXMLRPC_CLIENT_MODS = xmlrpc_client xmlrpc_client_global xmlrpc_server_info - -LIBXMLRPC_SERVER_MODS = registry method system_method - -LIBXMLRPC_SERVER_ABYSS_MODS = xmlrpc_server_abyss abyss_handler - -LIBXMLRPC_SERVER_CGI_MODS = xmlrpc_server_cgi - -TARGET_MODS = \ - $(LIBXMLRPC_MODS) \ - $(LIBXMLRPC_SERVER_MODS) \ - $(LIBXMLRPC_SERVER_ABYSS_MODS) \ - $(LIBXMLRPC_SERVER_CGI_MODS) \ - $(LIBXMLRPC_CLIENT_MODS) \ - -PKGCONFIG_FILES_TO_INSTALL := \ - xmlrpc.pc \ - xmlrpc_client.pc \ - xmlrpc_server.pc \ - xmlrpc_server_abyss.pc \ - xmlrpc_server_cgi.pc \ - -OMIT_XMLRPC_LIB_RULE=Y -MAJ=3 - # Major number of shared libraries in this directory - -include $(SRCDIR)/common.mk - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -# TARGET_STATIC_LIBRARIES, etc. are set by common.mk, based on -# TARGET_LIBRARY_NAMES. - - -all: \ - $(TARGET_STATIC_LIBRARIES) \ - $(TARGET_SHARED_LIBRARIES) \ - $(TARGET_SHARED_LE_LIBS) \ - $(PKGCONFIG_FILES_TO_INSTALL) \ - $(SUBDIRS:%=%/all) \ - -# Extra dependencies to make parallel make work in spite of all the submakes -# (See top level make file for details) - -cpp/all: $(TARGET_SHARED_LE_LIBS) - -ifeq ($MUST_BUILD_CLIENT),yes) - cpp/all: $(BLDDIR)/transport_config.h -endif - -#----------------------------------------------------------------------------- -# RULES TO LINK LIBRARIES -#----------------------------------------------------------------------------- - -# Rules for these are in common.mk, courtesy of TARGET_LIBRARY_NAMES: - -# shlibfn generates e.g. libxmlrpc.so.3.1 -# shliblefn generates e.g. libxmlrpc.so - -LIBXMLRPC = $(call shlibfn, libxmlrpc) - -$(LIBXMLRPC): $(LIBXMLRPC_MODS:%=%.osh) \ - $(LIBXMLRPC_UTIL) \ - $(XML_PARSER_LIBDEP_DEP) -$(LIBXMLRPC): LIBOBJECTS = $(LIBXMLRPC_MODS:%=%.osh) -$(LIBXMLRPC): LIBDEP = \ - $(LIBXMLRPC_UTIL_LIBDEP) \ - $(XML_PARSER_LIBDEP) - -LIBXMLRPC_SERVER = $(call shlibfn, libxmlrpc_server) - -$(LIBXMLRPC_SERVER): \ - $(LIBXMLRPC_SERVER_MODS:%=%.osh) \ - $(LIBXMLRPC_UTIL) \ - $(call shliblefn, libxmlrpc) -$(LIBXMLRPC_SERVER): LIBOBJECTS = $(LIBXMLRPC_SERVER_MODS:%=%.osh) -$(LIBXMLRPC_SERVER): LIBDEP = \ - -L. -lxmlrpc $(XML_PARSER_LIBDEP) $(LIBXMLRPC_UTIL_LIBDEP) - -LIBXMLRPC_SERVER_ABYSS = $(call shlibfn, libxmlrpc_server_abyss) - -$(LIBXMLRPC_SERVER_ABYSS): \ - $(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.osh) \ - $(LIBXMLRPC_UTIL) \ - $(LIBXMLRPC_ABYSS) \ - $(call shliblefn, libxmlrpc_server) \ - $(call shliblefn, libxmlrpc) -$(LIBXMLRPC_SERVER_ABYSS): LIBOBJECTS = $(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.osh) -$(LIBXMLRPC_SERVER_ABYSS): LIBDEP = \ - -L. -lxmlrpc_server \ - -L$(LIBXMLRPC_ABYSS_DIR) -lxmlrpc_abyss \ - -L. -lxmlrpc $(XML_PARSER_LIBDEP) $(LIBXMLRPC_UTIL_LIBDEP) -ifeq ($(MSVCRT),yes) - $(LIBXMLRPC_SERVER_ABYSS): LIBDEP += -lws2_32 -lwsock32 -endif - -LIBXMLRPC_SERVER_CGI = $(call shlibfn, libxmlrpc_server_cgi) - -$(LIBXMLRPC_SERVER_CGI): \ - $(LIBXMLRPC_SERVER_CGI_MODS:%=%.osh) \ - $(LIBXMRPC_UTIL) \ - $(call shliblefn, libxmlrpc_server) \ - $(call shliblefn, libxmlrpc) -$(LIBXMLRPC_SERVER_CGI): LIBOBJECTS = $(LIBXMLRPC_SERVER_CGI_MODS:%=%.osh) -$(LIBXMLRPC_SERVER_CGI): LIBDEP = \ - -L. -lxmlrpc_server \ - -L. -lxmlrpc $(XML_PARSER_LIBDEP) $(LIBXMLRPC_UTIL_LIBDEP) - -LIBXMLRPC_CLIENT = $(call shlibfn, libxmlrpc_client) - -$(LIBXMLRPC_CLIENT): \ - $(LIBXMLRPC_CLIENT_MODS:%=%.osh) \ - $(TRANSPORT_MODS:%=%.osh) \ - $(LIBXMLRPC_UTIL) \ - $(call shliblefn, libxmlrpc) -$(LIBXMLRPC_CLIENT): LIBOBJECTS = \ - $(LIBXMLRPC_CLIENT_MODS:%=%.osh) \ - $(TRANSPORT_MODS:%=%.osh) - -# We try to get Xmlrpc-c directories early in the link library search -# path to avert problems with other versions of Xmlrpc-c being in more -# general directories (such as /usr/local/lib) that are added to the -# search path by curl-config, etc. That's why we separate the -L from -# the corresponding -l. -# -# Note that in a properly configured system, curl-config, etc. do not -# generate -L options for general directories. - -LIBXMLRPC_CLIENT_LIBDEP = \ - -Lblddir/src -Lblddir/lib/libutil \ - -lxmlrpc -lxmlrpc_util \ - $(XML_PARSER_LIBDEP) \ - $(TRANSPORT_LIBDEP) \ - -$(LIBXMLRPC_CLIENT): LIBDEP = \ - $(LIBXMLRPC_CLIENT_LIBDEP) \ - $(SOCKETLIBOPT) \ - $(THREAD_LIBS) \ - -libxmlrpc.a: $(LIBXMLRPC_MODS:%=%.o) -libxmlrpc.a: LIBOBJECTS = $(LIBXMLRPC_MODS:%=%.o) - -libxmlrpc_server.a: $(LIBXMLRPC_SERVER_MODS:%=%.o) -libxmlrpc_server.a: LIBOBJECTS = $(LIBXMLRPC_SERVER_MODS:%=%.o) - -libxmlrpc_server_abyss.a: $(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.o) -libxmlrpc_server_abyss.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.o) - -libxmlrpc_server_cgi.a: $(LIBXMLRPC_SERVER_CGI_MODS:%=%.o) -libxmlrpc_server_cgi.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_CGI_MODS:%=%.o) - -libxmlrpc_client.a: $(LIBXMLRPC_CLIENT_MODS:%=%.o) $(TRANSPORT_MODS:%=%.o) -libxmlrpc_client.a: LIBOBJECTS = \ - $(LIBXMLRPC_CLIENT_MODS:%=%.o) \ - $(TRANSPORT_MODS:%=%.o) - - -#----------------------------------------------------------------------------- -# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES -#----------------------------------------------------------------------------- - -# Rules for these are in common.mk, courtesy of TARGET_MODS: - -BASIC_INCLUDES = \ - -Iblddir \ - -Iblddir/include \ - -Isrcdir/include \ - -Isrcdir/lib/util/include \ - -ifeq ($(ENABLE_LIBXML2_BACKEND),yes) - LIBXML_INCLUDES = $(shell xml2-config --cflags) -else - LIBXML_INCLUDES = -Isrcdir/lib/expat/xmlparse -endif - -$(LIBXMLRPC_MODS:%=%.o) \ -$(LIBXMLRPC_MODS:%=%.osh): \ - INCLUDES = $(BASIC_INCLUDES) $(LIBXML_INCLUDES) - -$(LIBXMLRPC_CLIENT_MODS:%=%.o) \ -$(LIBXMLRPC_CLIENT_MODS:%=%.osh): \ - INCLUDES = $(BASIC_INCLUDES) $(TRANSPORT_INCLUDES) - -$(LIBXMLRPC_SERVER_MODS:%=%.o) \ -$(LIBXMLRPC_SERVER_MODS:%=%.osh): \ - INCLUDES = $(BASIC_INCLUDES) - -$(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.o) \ -$(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.osh): \ - INCLUDES = $(BASIC_INCLUDES) -Isrcdir/lib/abyss/src - -$(LIBXMLRPC_SERVER_CGI_MODS:%=%.o) \ -$(LIBXMLRPC_SERVER_CGI_MODS:%=%.osh): \ - INCLUDES = $(BASIC_INCLUDES) - -#----------------------------------------------------------------------------- -# RULES TO MAKE CFLAGS/LDFLAGS FILES -# -# These are for builds in other directories of things that use libraries in -# this directory. E.g. when you build libxmlrpc_client++, it depends upon -# libxmlrpc_client from this directory. So the link of libxmlrpc_client++ -# must specify a dependency upon libxmlrpc_client and any library upon which -# libxmlrpc_client depends, so the link command for libxmlrpc_client++ -# should include $(shell cat libxmlrpc_client.ldflags). -# -# Note that some systems don't need this because there is information in -# libxmlrpc_client that tells libxmlrpc_client's dependencies, so you need -# only find libxmlrpc_client to generate libxmlrpc_client++. -#----------------------------------------------------------------------------- - -libxmlrpc_client.cflags: - echo "$(TRANSPORT_INCLUDES)" >$@ - -libxmlrpc_client.ldflags: - echo "-Lblddir/src -lxmlrpc_client $(LIBXMLRPC_CLIENT_LIBDEP)" >$@ - - -#----------------------------------------------------------------------------- -# RULES TO MAKE PKGCONFIG FILES -# -# (These are files used by the 'pkg-config' program to get information about -# using the libraries we build) -#----------------------------------------------------------------------------- - -xmlrpc.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc" >>$@ - @echo "Description: Xmlrpc-c basic XML-RPC library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc_util $(XML_PKGCONFIG_REQ)" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -xmlrpc_client.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_client" >>$@ - @echo "Description: Xmlrpc-c XML-RPC client library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_client" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -xmlrpc_server.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_server" >>$@ - @echo "Description: Xmlrpc-c XML-RPC server library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -xmlrpc_server_abyss.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_server_abyss" >>$@ - @echo "Description: Xmlrpc-c Abyss XML-RPC server library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc xmlrpc_server xmlrpc_abyss xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server_abyss" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -xmlrpc_server_cgi.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_server_cgi" >>$@ - @echo "Description: Xmlrpc-c CGI XML-RPC server library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc xmlrpc_server xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server_cgi" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -.PHONY: check -check: - -.PHONY: install -install: install-common $(SUBDIRS:%=%/install) - -.PHONY: uninstall -uninstall: uninstall-common $(SUBDIRS:%=%/uninstall) - -.PHONY: clean clean-local distclean distclean-local -clean: $(SUBDIRS:%=%/clean) clean-common clean-local -clean-local: - -distclean: $(SUBDIRS:%=%/distclean) \ - clean-common \ - clean-local \ - distclean-local \ - distclean-common \ - -distclean-local: - rm -f *.cflags *.ldflags - -.PHONY: dep -dep: $(SUBDIRS:%=%/dep) $(BLDDIR)/transport_config.h dep-common - -dep-common: - INCLUDES = $(BASIC_INCLUDES) $(TRANSPORT_INCLUDES) $(LIBXML_INCLUDES) - -xmlrpc_client.o xmlrpc_client.osh: $(BLDDIR)/transport_config.h -xmlrpc_client.o xmlrpc_client.osh: $(BLDDIR)/version.h -registry.o registry.osh: $(BLDDIR)/version.h -version.o version.osh: $(BLDDIR)/version.h - -include depend.mk diff --git a/trunk/src/abyss_handler.c b/trunk/src/abyss_handler.c deleted file mode 100644 index 7698703bb..000000000 --- a/trunk/src/abyss_handler.c +++ /dev/null @@ -1,642 +0,0 @@ -#include "xmlrpc_config.h" - -#define _XOPEN_SOURCE 600 /* For strdup(), sigaction */ -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ - -#include -#include -#include -#include -#include -#include -#include - -#include "bool.h" -#include "int.h" -#include "mallocvar.h" -#include "xmlrpc-c/abyss.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" - -#include "abyss_handler.h" - - - -static const char * trace_abyss; - - -void -xmlrpc_abyss_handler_trace(const char * const trace) { - - trace_abyss = trace; -} - - -static void -addAuthCookie(xmlrpc_env * const envP, - TSession * const abyssSessionP, - const char * const authCookie) { - - const char * cookieResponse; - - xmlrpc_asprintf(&cookieResponse, "auth=%s", authCookie); - - if (xmlrpc_strnomem(cookieResponse)) - xmlrpc_faultf(envP, "Insufficient memory to generate cookie " - "response header."); - else { - ResponseAddField(abyssSessionP, "Set-Cookie", cookieResponse); - - xmlrpc_strfree(cookieResponse); - } -} - - - -static void -sendResponse(xmlrpc_env * const envP, - TSession * const abyssSessionP, - const char * const body, - size_t const len, - bool const chunked, - ResponseAccessCtl const accessControl) { -/*---------------------------------------------------------------------------- - Generate an HTTP response containing body 'body' of length 'len' - characters. - - This is meant to run in the context of an Abyss URI handler for - Abyss session 'abyssSessionP'. - - 'chunked' means to make it a chunked response if possible. ------------------------------------------------------------------------------*/ - const char * http_cookie = NULL; - /* This used to set http_cookie to getenv("HTTP_COOKIE"), but - that doesn't make any sense -- environment variables are not - appropriate for this. So for now, cookie code is disabled. - - Bryan 2004.10.03. - */ - - /* Various bugs before Xmlrpc-c 1.05 caused the response to be not - chunked in the most basic case, but chunked if the client explicitly - requested keepalive. I think it's better not to chunk, because - it's simpler, so I removed this in 1.05. I don't know what the - purpose of chunking would be, and an original comment suggests - the author wasn't sure chunking was a good idea. - - In 1.06 we added the user option to chunk. - */ - if (chunked) - ResponseChunked(abyssSessionP); - - ResponseStatus(abyssSessionP, 200); - - if (http_cookie) - /* There's an auth cookie, so pass it back in the response. */ - addAuthCookie(envP, abyssSessionP, http_cookie); - - if ((size_t)(uint32_t)len != len) - xmlrpc_faultf(envP, "XML-RPC method generated a response too " - "large for Abyss to send"); - else { - uint32_t const abyssLen = (uint32_t)len; - - /* See discussion below of quotes around "utf-8" */ - ResponseContentType(abyssSessionP, "text/xml; charset=utf-8"); - ResponseContentLength(abyssSessionP, abyssLen); - ResponseAccessControl(abyssSessionP, accessControl); - - ResponseWriteStart(abyssSessionP); - ResponseWriteBody(abyssSessionP, body, abyssLen); - ResponseWriteEnd(abyssSessionP); - } -} - - - -/* From 0.9.10 (May 2001) through 1.17 (December 2008), the content-type - header said charset="utf-8" (i.e. with the value of 'charset' an HTTP quoted - string). Before 0.9.10, the header didn't have charset at all. - - We got a complaint in January 2009 that some client didn't understand that, - saying - - apache2: XML-RPC: xmlrpcmsg::parseResponse: invalid charset encoding of - received response: "UTF-8" - - And that removing the quotation marks fixes this. - - From what I can tell, the module is wrong to distinguish between the - two, but I don't think it hurts anything to use a basic HTTP token instead - of an HTTP quoted string here, so starting in 1.18, we do. */ - - -static void -sendError(TSession * const abyssSessionP, - unsigned int const status, - const char * const explanation) { -/*---------------------------------------------------------------------------- - Send an error response back to the client. ------------------------------------------------------------------------------*/ - ResponseStatus(abyssSessionP, (uint16_t) status); - ResponseError2(abyssSessionP, explanation); -} - - - -static void -traceChunkRead(TSession * const abyssSessionP) { - - fprintf(stderr, "XML-RPC handler got a chunk of %u bytes\n", - (unsigned int)SessionReadDataAvail(abyssSessionP)); -} - - - -static void -refillBufferFromConnection(xmlrpc_env * const envP, - TSession * const abyssSessionP, - const char * const trace) { -/*---------------------------------------------------------------------------- - Get the next chunk of data from the connection into the buffer. ------------------------------------------------------------------------------*/ - bool succeeded; - - succeeded = SessionRefillBuffer(abyssSessionP); - - if (!succeeded) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TIMEOUT_ERROR, "Timed out waiting for " - "client to send its POST data"); - else { - if (trace) - traceChunkRead(abyssSessionP); - } -} - - - -static void -getBody(xmlrpc_env * const envP, - TSession * const abyssSessionP, - size_t const contentSize, - const char * const trace, - xmlrpc_mem_block ** const bodyP) { -/*---------------------------------------------------------------------------- - Get the entire body, which is of size 'contentSize' bytes, from the - Abyss session and return it as the new memblock *bodyP. - - The first chunk of the body may already be in Abyss's buffer. We - retrieve that before reading more. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * body; - - if (trace) - fprintf(stderr, "XML-RPC handler processing body. " - "Content Size = %u bytes\n", (unsigned)contentSize); - - body = xmlrpc_mem_block_new(envP, 0); - if (!envP->fault_occurred) { - size_t bytesRead; - - bytesRead = 0; - - while (!envP->fault_occurred && bytesRead < contentSize) { - const char * chunkPtr; - size_t chunkLen; - - SessionGetReadData(abyssSessionP, contentSize - bytesRead, - &chunkPtr, &chunkLen); - bytesRead += chunkLen; - - assert(bytesRead <= contentSize); - - XMLRPC_MEMBLOCK_APPEND(char, envP, body, chunkPtr, chunkLen); - if (bytesRead < contentSize) - refillBufferFromConnection(envP, abyssSessionP, trace); - } - if (envP->fault_occurred) - xmlrpc_mem_block_free(body); - } - *bodyP = body; -} - - - -static void -storeCookies(TSession * const httpRequestP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Get the cookie settings from the HTTP headers and remember them for - use in responses. ------------------------------------------------------------------------------*/ - const char * const cookie = RequestHeaderValue(httpRequestP, "cookie"); - if (cookie) { - /* - Setting the value in an environment variable doesn't make - any sense. So for now, cookie code is disabled. - -Bryan 04.10.03. - - setenv("HTTP_COOKIE", cookie, 1); - */ - } - /* TODO: parse HTTP_COOKIE to find auth pair, if there is one */ - - *errorP = NULL; -} - - - - -static void -processContentLength(TSession * const httpRequestP, - size_t * const inputLenP, - bool * const missingP, - const char ** const errorP) { -/*---------------------------------------------------------------------------- - Make sure the content length is present and non-zero. This is - technically required by XML-RPC, but we only enforce it because we - don't want to figure out how to safely handle HTTP < 1.1 requests - without it. ------------------------------------------------------------------------------*/ - const char * const content_length = - RequestHeaderValue(httpRequestP, "content-length"); - - if (content_length == NULL) { - *missingP = true; - *errorP = NULL; - } else { - *missingP = false; - *inputLenP = 0; /* quiet compiler warning */ - if (content_length[0] == '\0') - xmlrpc_asprintf(errorP, "The value in your content-length " - "HTTP header value is a null string"); - else { - unsigned long contentLengthValue; - char * tail; - - contentLengthValue = strtoul(content_length, &tail, 10); - - if (*tail != '\0') - xmlrpc_asprintf(errorP, "There's non-numeric crap in " - "the value of your content-length " - "HTTP header: '%s'", tail); - else if (contentLengthValue < 1) - xmlrpc_asprintf(errorP, "According to your content-length " - "HTTP header, your request is empty (zero " - "length)"); - else if ((unsigned long)(size_t)contentLengthValue - != contentLengthValue) - xmlrpc_asprintf(errorP, "According to your content-length " - "HTTP header, your request is too big to " - "process; we can't even do arithmetic on its " - "size: %s bytes", content_length); - else { - *errorP = NULL; - *inputLenP = (size_t)contentLengthValue; - } - } - } -} - - - -static void -traceHandlerCalled(TSession * const abyssSessionP) { - - const char * methodDesc; - const TRequestInfo * requestInfoP; - - fprintf(stderr, "xmlrpc_server_abyss URI path handler called.\n"); - - SessionGetRequestInfo(abyssSessionP, &requestInfoP); - - fprintf(stderr, "URI = '%s'\n", requestInfoP->uri); - - switch (requestInfoP->method) { - case m_unknown: methodDesc = "unknown"; break; - case m_get: methodDesc = "get"; break; - case m_put: methodDesc = "put"; break; - case m_head: methodDesc = "head"; break; - case m_post: methodDesc = "post"; break; - case m_delete: methodDesc = "delete"; break; - case m_trace: methodDesc = "trace"; break; - case m_options: methodDesc = "m_options"; break; - default: methodDesc = "?"; - } - fprintf(stderr, "HTTP method = '%s'\n", methodDesc); - - if (requestInfoP->query) - fprintf(stderr, "query (component of URL)='%s'\n", - requestInfoP->query); - else - fprintf(stderr, "URL has no query component\n"); -} - - - -static void -processCall(TSession * const abyssSessionP, - size_t const contentSize, - xmlrpc_call_processor xmlProcessor, - void * const xmlProcessorArg, - bool const wantChunk, - ResponseAccessCtl const accessControl, - const char * const trace) { -/*---------------------------------------------------------------------------- - Handle an RPC request. This is an HTTP request that has the proper form - to be an XML-RPC call. - - We get the body of the request, which is the text of the call, - via the Abyss session 'abyssSessionP'. - - Its content length is 'contentSize' bytes. - - We send the response to the request (which may contain the RPC response, - but may be an error indication) via the Abyss session 'abyssSessionP'. - - We use 'xmlProcessor', with argument 'xmlProcessorArg' to execute the - RPC, i.e. turn the XML-RPC call into an XML-RPC response. - - 'wantChunk' means Caller wants the HTTP reponse chunked. - - We use the Abyss session's memory pool for some memory allocations - - essentially those that aren't predictable because they depend upon the data - from the client. We do this because the session's memory pool has a size - limit designed to keep the client from monopolizing the server's memory. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - - if (trace) - fprintf(stderr, - "xmlrpc_server_abyss URI path handler processing RPC.\n"); - - xmlrpc_env_init(&env); - - if (contentSize > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_LIMIT_EXCEEDED_ERROR, - "XML-RPC request too large (%u bytes)", (unsigned)contentSize); - else { - xmlrpc_mem_block * body; - /* Read XML data off the wire. */ - getBody(&env, abyssSessionP, contentSize, trace, &body); - if (!env.fault_occurred) { - xmlrpc_mem_block * output; - - /* Process the RPC. */ - xmlProcessor( - &env, xmlProcessorArg, - XMLRPC_MEMBLOCK_CONTENTS(char, body), - XMLRPC_MEMBLOCK_SIZE(char, body), - abyssSessionP, - &output); - if (!env.fault_occurred) { - /* Send out the result. */ - sendResponse(&env, abyssSessionP, - XMLRPC_MEMBLOCK_CONTENTS(char, output), - XMLRPC_MEMBLOCK_SIZE(char, output), - wantChunk, accessControl); - - XMLRPC_MEMBLOCK_FREE(char, output); - } - XMLRPC_MEMBLOCK_FREE(char, body); - } - } - if (env.fault_occurred) { - uint16_t httpResponseStatus; - if (env.fault_code == XMLRPC_TIMEOUT_ERROR) - httpResponseStatus = 408; /* Request Timeout */ - else - httpResponseStatus = 500; /* Internal Server Error */ - - sendError(abyssSessionP, httpResponseStatus, env.fault_string); - } - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_initAccessCtl(ResponseAccessCtl * const accessCtlP, - const char * const allowOrigin, - bool const expires, - unsigned int const maxAge) { -/*---------------------------------------------------------------------------- - Set up *accessCtlP to reflect the HTTP access control parameters - 'allowOrigin', 'expires', and 'maxAge'. - - Note that 'maxAge' is irrelevant when 'expires' is false. ------------------------------------------------------------------------------*/ - accessCtlP->allowOrigin = - allowOrigin ? xmlrpc_strdupsol(allowOrigin) : NULL; - accessCtlP->expires = expires; - accessCtlP->maxAge = maxAge; -} - - - -void -xmlrpc_termAccessControl(ResponseAccessCtl * const accessCtlP) { - - xmlrpc_strfreenull(accessCtlP->allowOrigin); -} - - - -void -xmlrpc_termUriHandler(void * const arg) { - - struct uriHandlerXmlrpc * const uriHandlerXmlrpcP = arg; - - xmlrpc_strfree(uriHandlerXmlrpcP->uriPath); - xmlrpc_termAccessControl(&uriHandlerXmlrpcP->accessControl); - free(uriHandlerXmlrpcP); -} - - - -static void -handleXmlRpcCallReq(TSession * const abyssSessionP, - const TRequestInfo * const requestInfoP ATTR_UNUSED, - xmlrpc_call_processor xmlProcessor, - void * const xmlProcessorArg, - bool const wantChunk, - ResponseAccessCtl const accessControl) { -/*---------------------------------------------------------------------------- - Handle the HTTP request described by *requestInfoP, which arrived over - Abyss HTTP session *abyssSessionP, which is an XML-RPC call - (i.e. a POST request to /RPC2 or whatever other URI our server is - supposed to handle). - - Handle it by feeding the XML which is its content to 'xmlProcessor' - along with argument 'xmlProcessorArg'. - - (There doesn't seem to be any way 'xmlProcessor' could ever be anything but - 'processXmlrpcCall' in xmlrpc_server_abyss.c (with 'xmlProcessorArg' being - the handle of a method registry), so I'm not sure why we didn't just put - that in this module and call it explicitly). ------------------------------------------------------------------------------*/ - /* We used to reject the call if content-type was not present and - text/xml, on some security theory (a firewall may block text/xml with - the intent of blocking XML-RPC). Now, we believe that is silly, and we - have seen an incorrectly implemented client that says text/plain. - */ - const char * error; - - assert(requestInfoP->method == m_post); - - storeCookies(abyssSessionP, &error); - if (error) { - sendError(abyssSessionP, 400, error); - xmlrpc_strfree(error); - } else { - const char * error; - bool missing; - size_t contentSize; - - processContentLength(abyssSessionP, - &contentSize, &missing, &error); - if (error) { - sendError(abyssSessionP, 400, error); - xmlrpc_strfree(error); - } else { - if (missing) - sendError(abyssSessionP, 411, "You must send a " - "content-length HTTP header in an " - "XML-RPC call."); - else - processCall(abyssSessionP, contentSize, - xmlProcessor, xmlProcessorArg, - wantChunk, accessControl, - trace_abyss); - } - } -} - - - -static void -handleXmlRpcOptionsReq(TSession * const abyssSessionP, - ResponseAccessCtl const accessControl) { - - ResponseAddField(abyssSessionP, "Allow", "POST"); - - ResponseAccessControl(abyssSessionP, accessControl); - ResponseContentLength(abyssSessionP, 0); - ResponseStatus(abyssSessionP, 200); - ResponseWriteStart(abyssSessionP); - ResponseWriteEnd(abyssSessionP); -} - - - -void -xmlrpc_handleIfXmlrpcReq(void * const handlerArg, - TSession * const abyssSessionP, - abyss_bool * const handledP) { -/*---------------------------------------------------------------------------- - Our job is to look at this HTTP request that the Abyss server is - trying to process and see if we can handle it. If it's an XML-RPC - call for this XML-RPC server, we handle it. If it's not, we refuse - it and Abyss can try some other handler. - - We return *handledP true to mean we handled it; false to mean we didn't. - - Note that failing the request counts as handling it, and not handling - it does not mean we failed it. - - This is an Abyss HTTP Request handler -- type handleReqFn3. ------------------------------------------------------------------------------*/ - struct uriHandlerXmlrpc * const uriHandlerXmlrpcP = handlerArg; - - const TRequestInfo * requestInfoP; - - if (trace_abyss) - traceHandlerCalled(abyssSessionP); - - SessionGetRequestInfo(abyssSessionP, &requestInfoP); - - /* Note that requestInfoP->uri is not the whole URI. It is just - the "file name" part of it. - */ - if (!xmlrpc_streq(requestInfoP->uri, uriHandlerXmlrpcP->uriPath)) - /* It's not for the path (e.g. "/RPC2") that we're supposed to - handle. - */ - *handledP = false; - else { - *handledP = true; - - switch (requestInfoP->method) { - case m_post: - handleXmlRpcCallReq(abyssSessionP, requestInfoP, - uriHandlerXmlrpcP->xmlProcessor, - uriHandlerXmlrpcP->xmlProcessorArg, - uriHandlerXmlrpcP->chunkResponse, - uriHandlerXmlrpcP->accessControl); - break; - case m_options: - handleXmlRpcOptionsReq(abyssSessionP, - uriHandlerXmlrpcP->accessControl); - break; - default: - sendError(abyssSessionP, 405, - "POST is the only HTTP method this server understands"); - /* 405 = Method Not Allowed */ - } - } - if (trace_abyss) - fprintf(stderr, "xmlrpc_server_abyss URI path handler returning.\n"); -} - - - -unsigned int -xmlrpc_abyss_handler_stacksize() { -/*---------------------------------------------------------------------------- - The maximum number of bytes an HTTP request handler in this file might - place on the stack. - - This doesn't include what the user's method function requires. ------------------------------------------------------------------------------*/ - return 1024; -} - - - -abyss_bool -xmlrpc_serverAbyssDefaultUriHandler(TSession * const sessionP) { -/*---------------------------------------------------------------------------- - This is an Abyss default handler. It return a 404 Not Found for all - requests. ------------------------------------------------------------------------------*/ - const TRequestInfo * requestInfoP; - - const char * explanation; - - if (trace_abyss) - fprintf(stderr, "xmlrpc_server_abyss default handler called.\n"); - - SessionGetRequestInfo(sessionP, &requestInfoP); - - xmlrpc_asprintf( - &explanation, - "This XML-RPC For C/C++ Abyss XML-RPC server " - "responds to only one URI path. " - "I don't know what URI path that is, " - "but it's not the one you requested: '%s'. (Typically, it's " - "'/RPC2')", requestInfoP->uri); - - sendError(sessionP, 404, explanation); - - xmlrpc_strfree(explanation); - - return true; -} - - - diff --git a/trunk/src/abyss_handler.h b/trunk/src/abyss_handler.h deleted file mode 100644 index 363f1ed6a..000000000 --- a/trunk/src/abyss_handler.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef ABYSS_HANDER_H_INCLUDED -#define ABYSS_HANDER_H_INCLUDED - -#include "xmlrpc-c/abyss.h" -#include "xmlrpc-c/server.h" -#include "xmlrpc-c/server_abyss.h" - -struct uriHandlerXmlrpc { -/*---------------------------------------------------------------------------- - This is the part of an Abyss HTTP request handler (aka URI handler) - that is specific to the Xmlrpc-c handler. ------------------------------------------------------------------------------*/ - xmlrpc_registry * registryP; - const char * uriPath; /* malloc'ed */ - bool chunkResponse; - /* The handler should chunk its response whenever possible */ - xmlrpc_call_processor * xmlProcessor; - void * xmlProcessorArg; - ResponseAccessCtl accessControl; -}; - - -void -xmlrpc_termUriHandler(void * const arg); - -void -xmlrpc_handleIfXmlrpcReq(void * const handlerArg, - TSession * const abyssSessionP, - abyss_bool * const handledP); - -abyss_bool -xmlrpc_serverAbyssDefaultUriHandler(TSession * const sessionP); - -void -xmlrpc_initAccessCtl(ResponseAccessCtl * const accessCtlP, - const char * const allowOrigin, - bool const expires, - unsigned int const maxAge); - -void -xmlrpc_termAccessControl(ResponseAccessCtl * const accessCtlP); - -void -xmlrpc_abyss_handler_trace(const char * const trace); - -unsigned int -xmlrpc_abyss_handler_stacksize(void); - -#endif diff --git a/trunk/src/base_global.c b/trunk/src/base_global.c deleted file mode 100644 index 1c34a763f..000000000 --- a/trunk/src/base_global.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "xmlrpc-c/base.h" -#include "xmlparser.h" - - - -static unsigned int globallyInitialized = 0; - /* Initialization count */ - - -/* It ought to be a requirement for any user of libxmlrpc to call - xmlrpc_init(), but for ten years it wasn't, so we can't start requiring it - now except for new services. - - One thing we know requires it (and always did, but didn't show up as a - problem until 2012) is libxml2. Without a call to xmlrpc_init(), - if libxmlrpc was built to use libxml2, the program leaks lots of memory. -*/ - -void -xmlrpc_init(xmlrpc_env * const envP) { - - /* Note that this is specified as not thread safe; user calls it at - the beginning of his program, when it is only one thread. - */ - - XMLRPC_ASSERT_ENV_OK(envP); - - if (globallyInitialized == 0) { - xml_init(envP); /* Initialize the XML parser library */ - } - ++globallyInitialized; -} - - - -void -xmlrpc_term(void) { - - /* Note that this is specified as not thread safe; user calls it at - the end of his program, when it is only one thread. - */ - - XMLRPC_ASSERT(globallyInitialized > 0); - - --globallyInitialized; - - if (globallyInitialized == 0) { - xml_term(); - } -} - - diff --git a/trunk/src/cpp/Makefile b/trunk/src/cpp/Makefile deleted file mode 100644 index cc654a0ac..000000000 --- a/trunk/src/cpp/Makefile +++ /dev/null @@ -1,432 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - srcDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(srcDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := src/cpp - -include $(BLDDIR)/config.mk - -default: all - -# libxmlrpc_cpp is the legacy C++ wrapper library. The others are the -# more elaborate replacements. - -TARGET_LIB_NAMES_PP = \ - libxmlrpc_cpp \ - lib$(LIBXMLRPCPP_NAME) \ - libxmlrpc_server++ \ - libxmlrpc_server_cgi++ \ - libxmlrpc_server_pstream++ \ - libxmlrpc_packetsocket \ - -ifeq ($(ENABLE_ABYSS_SERVER),yes) - TARGET_LIB_NAMES_PP += libxmlrpc_server_abyss++ -endif - -ifeq ($(MUST_BUILD_CLIENT),yes) - TARGET_LIB_NAMES_PP += libxmlrpc_client++ -endif - -STATIC_LIBRARIES_TO_INSTALL = $(TARGET_STATIC_LIBRARIES) - -SHARED_LIBS_TO_BUILD = $(TARGET_LIB_NAMES_PP) -SHARED_LIBS_TO_INSTALL = $(TARGET_LIB_NAMES_PP) - -# INCLUDES and DEP_SOURCES are used by dep-common target -INCLUDES = $(BASIC_INCLUDES) $(LIBXML_INCLUDES) \ - $(shell cat blddir/src/libxmlrpc_client.cflags) -DEP_SOURCES = *.cpp - -ifeq ($(ENABLE_LIBXML2_BACKEND),yes) - LIBXML_INCLUDES = $(LIBXML2_CFLAGS) -else - LIBXML_INCLUDES = -Isrcdir/lib/expat/xmlparse -endif - -ifeq ($(ENABLE_LIBXML2_BACKEND),yes) - XML_PARSER_LIBDEP = $(shell xml2-config --libs) -else - XML_PARSER_LIBDEP = \ - -L$(BLDDIR)/lib/expat/xmlparse -lxmlrpc_xmlparse \ - -L$(BLDDIR)/lib/expat/xmltok -lxmlrpc_xmltok -endif - -LIBXMLRPCPP_MODS = fault global outcome param_list value xml -LIBXMLRPC_SERVERPP_MODS = registry -LIBXMLRPC_SERVER_ABYSSPP_MODS = server_abyss abyss_reqhandler_xmlrpc -LIBXMLRPC_SERVER_CGIPP_MODS = server_cgi -LIBXMLRPC_SERVER_PSTREAMPP_MODS = server_pstream_conn server_pstream -LIBXMLRPC_CLIENTPP_MODS = client client_simple curl libwww wininet pstream -LIBXMLRPC_PACKETSOCKET_MODS = packetsocket - -TARGET_MODS_PP = \ - XmlRpcCpp \ - $(LIBXMLRPCPP_MODS) \ - $(LIBXMLRPC_SERVERPP_MODS) \ - $(LIBXMLRPC_SERVER_ABYSSPP_MODS) \ - $(LIBXMLRPC_SERVER_CGIPP_MODS) \ - $(LIBXMLRPC_SERVER_PSTREAMPP_MODS) \ - $(LIBXMLRPC_CLIENTPP_MODS) \ - $(LIBXMLRPC_PACKETSOCKET_MODS) \ - -PKGCONFIG_FILES_TO_INSTALL := \ - xmlrpc++.pc \ - xmlrpc_client++.pc \ - xmlrpc_server++.pc \ - xmlrpc_server_pstream++.pc \ - -OMIT_CPP_LIB_RULES = Y -MAJ = 8 - # Major number of shared libraries in this directory - -include $(SRCDIR)/common.mk - - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -BASIC_INCLUDES = \ - -Iblddir/include \ - -Isrcdir/include \ - -Iblddir \ - -Isrcdir/lib/util/include - - -# TARGET_STATIC_LIBARIES, etc. are set by common.mk, based on -# TARGET_LIB_NAMES_PP. - -all: \ - $(TARGET_STATIC_LIBRARIES) \ - $(TARGET_SHARED_LIBS_PP) \ - $(TARGET_SHARED_LE_LIBS) \ - $(PKGCONFIG_FILES_TO_INSTALL) \ - - -#----------------------------------------------------------------------------- -# RULES TO LINK LIBRARIES -#----------------------------------------------------------------------------- - -# Rules for these are in common.mk, courtesy of TARGET_LIB_NAMES_PP: - -# shlibfn generates e.g. libxmlrpc.so.3.1 -# shliblefn generates e.g. libxmlrpc.so - -LIBXMLRPC_CPP_SH = $(call shlibfn, libxmlrpc_cpp) - -# Sometimes -lpthread is necessary when link-editing a shared library that -# uses pthread services, and sometimes it is not. We've seen links on -# Windows and AIX fail without it. It seems to be a good idea in all cases, -# as it declares an actual dependency of the shared library. - -$(LIBXMLRPC_CPP_SH): XmlRpcCpp.osh \ - $(LIBXMLRPC_UTIL) \ - $(LIBXMLRPC) \ - $(LIBXMLRPC_SERVER) \ - $(LIBXMLRPC_UTIL) \ - -$(LIBXMLRPC_CPP_SH): LIBOBJECTS = XmlRpcCpp.osh -$(LIBXMLRPC_CPP_SH): LIBDEP = \ - -Lblddir/src -lxmlrpc_server -lxmlrpc \ - $(XML_PARSER_LIBDEP) \ - $(LIBXMLRPC_UTIL_LIBDEP) \ - -LIBXMLRPCPP_SH = $(call shlibfn, lib$(LIBXMLRPCPP_NAME)) - -$(LIBXMLRPCPP_SH): $(LIBXMLRPCPP_MODS:%=%.osh) \ - $(LIBXMLRPC) \ - $(LIBXMLRPC_UTILPP) \ - $(LIBXMLRPC_UTIL) \ - -$(LIBXMLRPCPP_SH): LIBOBJECTS = $(LIBXMLRPCPP_MODS:%=%.osh) -$(LIBXMLRPCPP_SH): LIBDEP = \ - -Lblddir/src -lxmlrpc \ - $(XML_PARSER_LIBDEP) \ - -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ - -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ - $(THREAD_LIBS) \ - -LIBXMLRPC_SERVERPP_SH = $(call shlibfn, libxmlrpc_server++) - -$(LIBXMLRPC_SERVERPP_SH): $(LIBXMLRPC_SERVERPP_MODS:%=%.osh) \ - $(LIBXMLRPC_SERVER) \ - $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ - $(LIBXMLRPC_UTILPP) \ - $(LIBXMLRPC_UTIL) \ - $(LIBXMLRPC) \ - -$(LIBXMLRPC_SERVERPP_SH): LIBOBJECTS = $(LIBXMLRPC_SERVERPP_MODS:%=%.osh) -$(LIBXMLRPC_SERVERPP_SH): LIBDEP = \ - -L. -l$(LIBXMLRPCPP_NAME) \ - -Lblddir/src -lxmlrpc_server -lxmlrpc \ - $(XML_PARSER_LIBDEP) \ - -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ - -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ - $(THREAD_LIBS) \ - -LIBXMLRPC_SERVER_ABYSSPP_SH = $(call shlibfn, libxmlrpc_server_abyss++) - -$(LIBXMLRPC_SERVER_ABYSSPP_SH): $(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.osh) \ - $(LIBXMLRPC_ABYSSPP) \ - $(LIBXMLRPC_ABYSS) \ - $(LIBXMLRPC_SERVER_ABYSS) \ - $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ - $(call shliblefn, libxmlrpc_server++) \ - $(LIBXMLRPC_UTILPP) \ - $(LIBXMLRPC_UTIL) \ - $(LIBXMLRPC) \ - -$(LIBXMLRPC_SERVER_ABYSSPP_SH): LIBOBJECTS = $(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.osh) -$(LIBXMLRPC_SERVER_ABYSSPP_SH): LIBDEP = \ - -L. -lxmlrpc_server++ -l$(LIBXMLRPCPP_NAME) \ - -Lblddir/src -lxmlrpc_server_abyss -lxmlrpc_server -lxmlrpc \ - $(XML_PARSER_LIBDEP) \ - -L$(LIBXMLRPC_ABYSSPP_DIR) -lxmlrpc_abyss++ \ - -L$(LIBXMLRPC_ABYSS_DIR) -lxmlrpc_abyss \ - -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ - -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ - $(SOCKETLIBOBT) \ - $(THREAD_LIBS) \ - -LIBXMLRPC_SERVER_CGIPP_SH = $(call shlibfn, libxmlrpc_server_cgi++) - -$(LIBXMLRPC_SERVER_CGIPP_SH): $(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.osh) \ - $(call shliblefn, libxmlrpc_server++) \ - $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ - $(LIBXMLRPC_UTILPP) \ - $(LIBXMLRPC_UTIL) \ - $(LIBXMLRPC) \ - -$(LIBXMLRPC_SERVER_CGIPP_SH): LIBOBJECTS = $(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.osh) -$(LIBXMLRPC_SERVER_CGIPP_SH): LIBDEP = \ - -L. -lxmlrpc_server++ -l$(LIBXMLRPCPP_NAME) \ - -Lblddir/src -lxmlrpc_server -lxmlrpc \ - $(XML_PARSER_LIBDEP) \ - -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ - -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ - $(THREAD_LIBS) \ - -LIBXMLRPC_SERVER_PSTREAMPP_SH = $(call shlibfn, libxmlrpc_server_pstream++) - -$(LIBXMLRPC_SERVER_PSTREAMPP_SH): $(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.osh) \ - $(LIBXMLRPC_SERVER) \ - $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ - $(call shliblefn, libxmlrpc_packetsocket) \ - $(call shliblefn, libxmlrpc_server++) \ - $(LIBXMLRPC_UTILPP) \ - $(LIBXMLRPC_UTIL) \ - -$(LIBXMLRPC_SERVER_PSTREAMPP_SH): LIBOBJECTS = $(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.osh) -$(LIBXMLRPC_SERVER_PSTREAMPP_SH): LIBDEP = \ - -L. -lxmlrpc_server++ -l$(LIBXMLRPCPP_NAME) -lxmlrpc_packetsocket \ - -Lblddir/src -lxmlrpc_server -lxmlrpc \ - $(XML_PARSER_LIBDEP) \ - -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ - -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ - $(SOCKETLIBOPT) \ - $(THREAD_LIBS) \ - -LIBXMLRPC_CLIENTPP_SH = $(call shlibfn, libxmlrpc_client++) - -$(LIBXMLRPC_CLIENTPP_SH): $(LIBXMLRPC_CLIENTPP_MODS:%=%.osh) \ - $(LIBXMLRPC_UTILPP) \ - $(LIBXMLRPC_UTIL) \ - $(call shliblefn, libxmlrpc_packetsocket) \ - $(LIBXMLRPC) \ - $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ - $(LIBXMLRPC_CLIENT) \ - $(BLDDIR)/src/libxmlrpc_client.ldflags \ - -$(LIBXMLRPC_CLIENTPP_SH): LIBOBJECTS = $(LIBXMLRPC_CLIENTPP_MODS:%=%.osh) -$(LIBXMLRPC_CLIENTPP_SH): LIBDEP = \ - -L. -l$(LIBXMLRPCPP_NAME) -lxmlrpc_packetsocket \ - $(shell cat blddir/src/libxmlrpc_client.ldflags) \ - -Lblddir/src -lxmlrpc_client -lxmlrpc \ - $(XML_PARSER_LIBDEP) \ - -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ - -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ - $(SOCKETLIBOPT) \ - $(THREAD_LIBS) \ - -LIBXMLRPC_PACKETSOCKET_SH = $(call shlibfn, libxmlrpc_packetsocket) - -$(LIBXMLRPC_PACKETSOCKET_SH): $(LIBXMLRPC_PACKETSOCKET_MODS:%=%.osh) \ - $(LIBXMLRPC_UTILPP) \ - $(LIBXMLRPC_UTIL) \ - $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ - -$(LIBXMLRPC_PACKETSOCKET_SH): LIBOBJECTS = $(LIBXMLRPC_PACKETSOCKET_MODS:%=%.osh) -$(LIBXMLRPC_PACKETSOCKET_SH): LIBDEP = \ - -L. -l$(LIBXMLRPCPP_NAME) \ - -Lblddir/src -lxmlrpc \ - $(XML_PARSER_LIBDEP) \ - -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ - -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ - $(SOCKETLIBOPT) \ - $(THREAD_LIBS) \ - -libxmlrpc_cpp.a: XmlRpcCpp.o -libxmlrpc_cpp.a: LIBOBJECTS = XmlRpcCpp.o - -lib$(LIBXMLRPCPP_NAME).a: $(LIBXMLRPCPP_MODS:%=%.o) -lib$(LIBXMLRPCPP_NAME).a: LIBOBJECTS = $(LIBXMLRPCPP_MODS:%=%.o) - -libxmlrpc_server++.a: $(LIBXMLRPC_SERVERPP_MODS:%=%.o) -libxmlrpc_server++.a: LIBOBJECTS = $(LIBXMLRPC_SERVERPP_MODS:%=%.o) - -libxmlrpc_server_abyss++.a: $(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.o) -libxmlrpc_server_abyss++.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.o) - -libxmlrpc_server_cgi++.a: $(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.o) -libxmlrpc_server_cgi++.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.o) - -libxmlrpc_server_pstream++.a: $(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.o) -libxmlrpc_server_pstream++.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.o) - -libxmlrpc_client++.a: $(LIBXMLRPC_CLIENTPP_MODS:%=%.o) -libxmlrpc_client++.a: LIBOBJECTS = $(LIBXMLRPC_CLIENTPP_MODS:%=%.o) - -libxmlrpc_packetsocket.a: $(LIBXMLRPC_PACKETSOCKET_MODS:%=%.o) -libxmlrpc_packetsocket.a: LIBOBJECTS = $(LIBXMLRPC_PACKETSOCKET_MODS:%=%.o) - -#----------------------------------------------------------------------------- -# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES -#----------------------------------------------------------------------------- - -# Rules for these are in common.mk, courtesy of TARGET_MODS_PP: - -XmlRpcCpp.o% XmlrpcCpp.osh: \ - INCLUDES = $(BASIC_INCLUDES) - -$(LIBXMLRPCPP_MODS:%=%.o) \ -$(LIBXMLRPCPP_MODS:%=%.osh): \ - INCLUDES = $(BASIC_INCLUDES) - -SERVER_INCLUDES = $(BASIC_INCLUDES) $(LIBXML_INCLUDES) - -$(LIBXMLRPC_SERVERPP_MODS:%=%.o) \ -$(LIBXMLRPC_SERVERPP_MODS:%=%.osh): \ - INCLUDES = $(SERVER_INCLUDES) - -$(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.o) \ -$(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.osh): \ - INCLUDES = $(SERVER_INCLUDES) - -$(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.o) \ -$(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.osh): \ - INCLUDES = $(SERVER_INCLUDES) - -$(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.o) \ -$(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.osh): \ - INCLUDES = $(SERVER_INCLUDES) - -$(LIBXMLRPC_CLIENTPP_MODS:%=%.o) \ -$(LIBXMLRPC_CLIENTPP_MODS:%=%.osh): $(BLDDIR)/src/libxmlrpc_client.cflags - -$(LIBXMLRPC_CLIENTPP_MODS:%=%.o) \ -$(LIBXMLRPC_CLIENTPP_MODS:%=%.osh): \ - INCLUDES = $(BASIC_INCLUDES) $(LIBXML_INCLUDES) \ - $(shell cat blddir/src/libxmlrpc_client.cflags) - -$(LIBXMLRPC_PACKETSOCKET_MODS:%=%.o) \ -$(LIBXMLRPC_PACKETSOCKET_MODS:%=%.osh): \ - INCLUDES = $(BASIC_INCLUDES) - -# in Glibc 2.2 has some failed inlines, so we disable that warning: -$(LIBXMLRPC_PACKETSOCKET_MODS:%=%.o) \ -$(LIBXMLRPC_PACKETSOCKET_MODS:%=%.osh): \ - CFLAGS_LOCAL = $(CFLAGS_NO_INLINE_WARNING) - -TRANSPORT_CONFIG_USERS = client curl libwww wininet - -$(TRANSPORT_CONFIG_USERS:%=%.o) $(TRANSPORT_CONFIG_USERS:%=%.osh): \ - $(BLDDIR)/transport_config.h - -#----------------------------------------------------------------------------- -# RULES TO MAKE PKGCONFIG FILES -# -# (These are files used by the 'pkg-config' program to get information about -# using the libraries we build) -#----------------------------------------------------------------------------- - -xmlrpc++.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc++" >>$@ - @echo "Description: Xmlrpc-c basic XML-RPC C++ library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc++" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -xmlrpc_client++.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_client++" >>$@ - @echo "Description: Xmlrpc-c XML-RPC client C++ library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc++ xmlrpc_client xmlrpc_util++ xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_client++" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -xmlrpc_server++.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_server++" >>$@ - @echo "Description: Xmlrpc-c XML-RPC server C++ library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc++ xmlrpc xmlrpc_server xmlrpc_util++ xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server++" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -xmlrpc_server_abyss++.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_server_abyss++" >>$@ - @echo "Description: Xmlrpc-c Abyss XML-RPC server C++ library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc++ xmlrpc xmlrpc_server++ xmlrpc_abyss xmlrpc_util++ xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server_abyss" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -xmlrpc_server_pstream++.pc: - rm -f $@ - @echo "Echoes to '$@' suppressed here ..." - @echo "Name: xmlrpc_server_pstream" >>$@ - @echo "Description: Xmlrpc-c packet stream XML-RPC server library" >>$@ - @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ - @echo >>$@ - @echo "Requires: xmlrpc++ xmlrpc xmlrpc_server++ xmlrpc_util++ xmlrpc_util" >>$@ - @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server_pstream++ -lxmlrpc_packetsocket" >>$@ - @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ - -#----------------------------------------------------------------------------- -# MISCELLANEOUS RULES -#----------------------------------------------------------------------------- - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean clean-local distclean distclean-local -clean: clean-common clean-local -clean-local: - -distclean: clean distclean-local distclean-common - -distclean-local: - -.PHONY: dep -dep: dep-common $(BLDDIR)/transport_config.h -dep-common: $(BLDDIR)/src/libxmlrpc_client.cflags - -include depend.mk diff --git a/trunk/src/cpp/XmlRpcCpp.cpp b/trunk/src/cpp/XmlRpcCpp.cpp deleted file mode 100644 index 2270ee917..000000000 --- a/trunk/src/cpp/XmlRpcCpp.cpp +++ /dev/null @@ -1,397 +0,0 @@ -// Copyright (C) 2001 by Eric Kidd. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// 3. The name of the author may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -// SUCH DAMAGE. - - -#include -#include - -#include "xmlrpc-c/util_int.h" - -#include "xmlrpc-c/oldcppwrapper.hpp" - -using std::string; - -//========================================================================= -// XmlRpcFault Methods -//========================================================================= - -XmlRpcFault::XmlRpcFault (const XmlRpcFault &fault) { - xmlrpc_env_init(&mFault); - xmlrpc_env_set_fault(&mFault, - fault.mFault.fault_code, - fault.mFault.fault_string); -} - -XmlRpcFault::XmlRpcFault (const int faultCode, const string faultString) { - xmlrpc_env_init(&mFault); - xmlrpc_env_set_fault(&mFault, faultCode, - const_cast(faultString.c_str())); -} - -XmlRpcFault::XmlRpcFault (const xmlrpc_env *env) { - if (!env->fault_string) - throw XmlRpcFault(XMLRPC_INTERNAL_ERROR, - "Tried to create empty fault"); - xmlrpc_env_init(&mFault); - xmlrpc_env_set_fault(&mFault, env->fault_code, - const_cast(env->fault_string)); -} - -XmlRpcFault::~XmlRpcFault (void) { - xmlrpc_env_clean(&mFault); -} - -string XmlRpcFault::getFaultString (void) const { - XMLRPC_ASSERT(mFault.fault_occurred); - return string(mFault.fault_string); -} - - -//========================================================================= -// XmlRpcEnv Methods -//========================================================================= - -XmlRpcEnv::XmlRpcEnv (const XmlRpcEnv &env) { - xmlrpc_env_init(&mEnv); - if (env.hasFaultOccurred()) - xmlrpc_env_set_fault(&mEnv, - env.mEnv.fault_code, - env.mEnv.fault_string); -} - -XmlRpcFault XmlRpcEnv::getFault (void) const { - return XmlRpcFault(&mEnv); -} - -void XmlRpcEnv::throwMe (void) const { - throw XmlRpcFault(&mEnv); -} - - -//========================================================================= -// XmlRpcValue Methods -//========================================================================= - -// If the user doesn't tell us what kind of value to create, use -// a false boolean value as the default. -XmlRpcValue::XmlRpcValue (void) { - XmlRpcEnv env; - mValue = xmlrpc_build_value(env, "b", (xmlrpc_bool) 0); - env.throwIfFaultOccurred(); -} - -XmlRpcValue XmlRpcValue::makeInt (const XmlRpcValue::int32 i) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "i", i); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeBool (const bool b) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "b", (xmlrpc_bool) b); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeDouble (const double d) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "d", d); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeDateTime (const string& dateTime) { - XmlRpcEnv env; - xmlrpc_value *value; - const char *data = dateTime.c_str(); // Make sure we're not using wchar_t. - value = xmlrpc_build_value(env, "8", data); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeString (const string& str) { - XmlRpcEnv env; - const char *data = str.data(); // Make sure we're not using wchar_t. - size_t size = str.size(); - xmlrpc_value *value = xmlrpc_build_value(env, "s#", data, size); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeString (const char *const str) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "s", str); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeString (const char *const str, size_t len) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "s#", str, len); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeArray (void) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "()"); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeStruct (void) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_struct_new(env); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeBase64 (const unsigned char *const data, - size_t len) -{ - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "6", data, len); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue::int32 XmlRpcValue::getInt (void) const { - XmlRpcEnv env; - XmlRpcValue::int32 result; - xmlrpc_parse_value(env, mValue, "i", &result); - env.throwIfFaultOccurred(); - return result; -} - -bool XmlRpcValue::getBool (void) const { - XmlRpcEnv env; - xmlrpc_bool result; - xmlrpc_parse_value(env, mValue, "b", &result); - env.throwIfFaultOccurred(); - return (result != 0); -} - -double XmlRpcValue::getDouble (void) const { - XmlRpcEnv env; - double result; - xmlrpc_parse_value(env, mValue, "d", &result); - env.throwIfFaultOccurred(); - return result; -} - -string XmlRpcValue::getRawDateTime (void) const { - XmlRpcEnv env; - char *result; - xmlrpc_parse_value(env, mValue, "8", &result); - env.throwIfFaultOccurred(); - return string(result); -} - -string XmlRpcValue::getString (void) const { - XmlRpcEnv env; - char *result; - size_t result_len; - xmlrpc_parse_value(env, mValue, "s#", &result, &result_len); - env.throwIfFaultOccurred(); - return string(result, result_len); - -} - -XmlRpcValue XmlRpcValue::getArray (void) const { - XmlRpcEnv env; - xmlrpc_value *result; - xmlrpc_parse_value(env, mValue, "A", &result); - env.throwIfFaultOccurred(); - return XmlRpcValue(result); -} - -XmlRpcValue XmlRpcValue::getStruct (void) const { - XmlRpcEnv env; - xmlrpc_value *result; - xmlrpc_parse_value(env, mValue, "S", &result); - env.throwIfFaultOccurred(); - return XmlRpcValue(result); -} - -void XmlRpcValue::getBase64 (const unsigned char *& out_data, - size_t& out_len) const -{ - XmlRpcEnv env; - xmlrpc_parse_value(env, mValue, "6", &out_data, &out_len); - env.throwIfFaultOccurred(); -} - -size_t XmlRpcValue::arraySize (void) const { - XmlRpcEnv env; - size_t result = xmlrpc_array_size(env, mValue); - env.throwIfFaultOccurred(); - return result; -} - -void XmlRpcValue::arrayAppendItem (const XmlRpcValue& value) { - XmlRpcEnv env; - xmlrpc_array_append_item(env, mValue, value.borrowReference()); - env.throwIfFaultOccurred(); -} - -XmlRpcValue XmlRpcValue::arrayGetItem (int index) const { - XmlRpcEnv env; - xmlrpc_value *result = xmlrpc_array_get_item(env, mValue, index); - env.throwIfFaultOccurred(); - return XmlRpcValue(result); -} - -size_t XmlRpcValue::structSize (void) const { - XmlRpcEnv env; - size_t result = xmlrpc_struct_size(env, mValue); - env.throwIfFaultOccurred(); - return result; -} - -bool XmlRpcValue::structHasKey (const string& key) const { - XmlRpcEnv env; - const char *keystr = key.data(); - size_t keylen = key.size(); - int result = xmlrpc_struct_has_key_n(env, mValue, - const_cast(keystr), keylen); - env.throwIfFaultOccurred(); - return (result != 0); -} - -XmlRpcValue XmlRpcValue::structGetValue (const string& key) const { - XmlRpcEnv env; - const char *keystr = key.data(); - size_t keylen = key.size(); - xmlrpc_value *result = - xmlrpc_struct_get_value_n(env, mValue, - const_cast(keystr), keylen); - env.throwIfFaultOccurred(); - return XmlRpcValue(result); -} - -void XmlRpcValue::structSetValue (const string& key, const XmlRpcValue& value) -{ - XmlRpcEnv env; - const char *keystr = key.data(); - size_t keylen = key.size(); - xmlrpc_struct_set_value_n(env, mValue, (char*) keystr, keylen, - value.borrowReference()); - env.throwIfFaultOccurred(); -} - -void XmlRpcValue::structGetKeyAndValue (const int index, - string& out_key, - XmlRpcValue& out_value) const -{ - XmlRpcEnv env; - - xmlrpc_value *key, *value; - xmlrpc_struct_get_key_and_value(env, mValue, index, &key, &value); - env.throwIfFaultOccurred(); - - out_key = XmlRpcValue(key).getString(); - out_value = XmlRpcValue(value); -} - -XmlRpcGenSrv& XmlRpcGenSrv::addMethod (const string& name, - xmlrpc_method method, - void *data) -{ - XmlRpcEnv env; - - xmlrpc_registry_add_method (env, mRegistry, NULL, - name.c_str (), - method, data); - - env.throwIfFaultOccurred (); - return (*this); -} - -XmlRpcGenSrv& XmlRpcGenSrv::addMethod (const string& name, - xmlrpc_method method, - void* data, - const string& signature, - const string& help) -{ - XmlRpcEnv env; - - xmlrpc_registry_add_method_w_doc (env, mRegistry, NULL, - name.c_str (), - method, data, - signature.c_str (), - help.c_str ()); - - env.throwIfFaultOccurred (); - return (*this); -} - -xmlrpc_mem_block* XmlRpcGenSrv::alloc (XmlRpcEnv& env, const string& body) const -{ - xmlrpc_mem_block* result = NULL; - char* contents; - - result = xmlrpc_mem_block_new (env, body.length ()); - env.throwIfFaultOccurred (); - - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, result); - - memcpy (contents, body.c_str (), body.length ()); - return result; -} - -string XmlRpcGenSrv::handle (const string& body) const -{ - XmlRpcEnv env; - string result; - xmlrpc_mem_block* input = NULL, * output = NULL; - char* input_data, * output_data; - size_t input_size, output_size; - - if (body.length () > xmlrpc_limit_get (XMLRPC_XML_SIZE_LIMIT_ID)) - throw XmlRpcFault (XMLRPC_LIMIT_EXCEEDED_ERROR, "XML-RPC request too large"); - - input = alloc (env, body); - input_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, input); - input_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, input); - - output = xmlrpc_registry_process_call (env, mRegistry, NULL, - input_data, input_size); - - if (output) - { - output_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output); - output_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); - - result.assign (output_data, output_size); - xmlrpc_mem_block_free (output); - } - - xmlrpc_mem_block_free (input); - if (!result.length ()) - throw XmlRpcFault (env); - - return result; -} diff --git a/trunk/src/cpp/abyss_reqhandler_xmlrpc.cpp b/trunk/src/cpp/abyss_reqhandler_xmlrpc.cpp deleted file mode 100644 index 2565b8143..000000000 --- a/trunk/src/cpp/abyss_reqhandler_xmlrpc.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include - -using namespace std; - -#include "xmlrpc-c/AbyssServer.hpp" -using xmlrpc_c::AbyssServer; -#include "xmlrpc-c/registry.hpp" - -#include "xmlrpc-c/abyss_reqhandler_xmlrpc.hpp" - - -namespace xmlrpc_c { - -abyssReqhandlerXmlrpc::abyssReqhandlerXmlrpc( - xmlrpc_c::registryPtr const& registryP) : - registryP(registryP) -{} - - - -static void -handleXmlRpc(AbyssServer::Session * const sessionP, - xmlrpc_c::registry * const registryP, - bool * const responseStartedP) { - - string const callXml(sessionP->body()); - string responseXml; - - registryP->processCall(callXml, &responseXml); - - sessionP->setRespStatus(200); - - sessionP->setRespContentType("text/xml charset=utf-8"); - - sessionP->setRespContentLength(responseXml.size()); - - *responseStartedP = true; - - sessionP->writeResponse(responseXml); -} - - - -void -abyssReqhandlerXmlrpc::abortRequest( - AbyssServer::Session * const sessionP, - bool const responseStarted, - AbyssServer::Exception const& e) { - - if (responseStarted) { - // We can't send an error response because we failed - // partway through sending a non-error response. All we can - // do is perhaps log the error and then close the connection. - this->handleUnreportableFailure(e); - } else - sessionP->sendErrorResponse(e); -} - - - -void -abyssReqhandlerXmlrpc::handleRequest( - AbyssServer::Session * const sessionP, - bool * const handledP) { - - bool responseStarted; - // We have at least started to send an HTTP response. (This is - // important in error handling, because it means it is too late to - // send an error response). - - responseStarted = false; - - try { - switch (sessionP->method()) { - case AbyssServer::Session::METHOD_POST: { - if (sessionP->uriPathName() == "/RPC2") { - - handleXmlRpc(sessionP, this->registryP.get(), - &responseStarted); - *handledP = true; - } else - *handledP = false; - } break; - default: - *handledP = false; - } - } catch (AbyssServer::Exception const& e) { - this->abortRequest(sessionP, responseStarted, e); - *handledP = true; - } catch (exception const& e) { - this->abortRequest(sessionP, responseStarted, - AbyssServer::Exception(500, e.what())); - *handledP = true; - } -} - - - -void -abyssReqhandlerXmlrpc::handleUnreportableFailure( - AbyssServer::Exception const& ) { -/*----------------------------------------------------------------------------- - This is the default implementation of the virtual method. ------------------------------------------------------------------------------*/ -} - - - -} // namespace diff --git a/trunk/src/cpp/client.cpp b/trunk/src/cpp/client.cpp deleted file mode 100644 index 0e8184c14..000000000 --- a/trunk/src/cpp/client.cpp +++ /dev/null @@ -1,1279 +0,0 @@ -/*============================================================================= - client.cpp -=============================================================================== - This is the C++ XML-RPC client library for Xmlrpc-c. - - Note that unlike most of Xmlprc-c's C++ API, this is _not_ based on the - C client library. This code is independent of the C client library, and - is based directly on the client XML transport libraries (with a little - help from internal C utility libraries). -=============================================================================*/ - -#include -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/girmem.hpp" -using girmem::autoObjectPtr; -using girmem::autoObject; -#include "xmlrpc-c/env_wrap.hpp" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/transport.h" -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/xml.hpp" -#include "xmlrpc-c/timeout.hpp" -#include "xmlrpc-c/client.hpp" -#include "transport_config.h" - -using namespace std; -using namespace xmlrpc_c; - - -namespace { - -void -throwIfError(env_wrap const& env) { - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -class memblockStringWrapper { - -public: - memblockStringWrapper(string const value) { - - env_wrap env; - - this->memblockP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); - throwIfError(env); - - XMLRPC_MEMBLOCK_APPEND(char, &env.env_c, this->memblockP, - value.c_str(), value.size()); - throwIfError(env); - } - - memblockStringWrapper(xmlrpc_mem_block * const memblockP) : - memblockP(memblockP) {}; - - ~memblockStringWrapper() { - XMLRPC_MEMBLOCK_FREE(char, this->memblockP); - } - - xmlrpc_mem_block * memblockP; -}; - -} // namespace - -namespace xmlrpc_c { - -struct client_xml_impl { - /* We have both kinds of pointers to give the user flexibility -- we - have constructors that take both. But the simple pointer - 'transportP' is valid in both cases. - */ - clientXmlTransport * transportP; - clientXmlTransportPtr transportPtr; - xmlrpc_dialect dialect; - - client_xml_impl(clientXmlTransport * const transportP, - xmlrpc_dialect const dialect = xmlrpc_dialect_i8) : - transportP(transportP), - dialect(dialect) {} - - client_xml_impl(clientXmlTransportPtr const transportPtr, - clientXmlTransport * const transportP, - xmlrpc_dialect const dialect = xmlrpc_dialect_i8) : - transportP(transportP), - transportPtr(transportPtr), - dialect(dialect) {} -}; - - - -carriageParm::carriageParm() {} - - - -carriageParm::~carriageParm() {} - - - -carriageParmPtr::carriageParmPtr() { - // Base class constructor will construct pointer that points to nothing -} - - - -carriageParmPtr::carriageParmPtr( -carriageParm * const carriageParmP) : autoObjectPtr(carriageParmP) {} - - - -carriageParm * -carriageParmPtr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -carriageParm * -carriageParmPtr::get() const { - return dynamic_cast(this->objectP); -} - - - -carriageParm_http0::carriageParm_http0() : - c_serverInfoP(NULL) {} - - - -carriageParm_http0::carriageParm_http0(string const serverUrl) { - this->c_serverInfoP = NULL; - - this->instantiate(serverUrl); -} - - - -carriageParm_http0::~carriageParm_http0() { - - if (this->c_serverInfoP) - xmlrpc_server_info_free(this->c_serverInfoP); -} - - - -void -carriageParm_http0::instantiate(string const serverUrl) { - - if (c_serverInfoP) - throw(error("object already instantiated")); - - env_wrap env; - - this->c_serverInfoP = - xmlrpc_server_info_new(&env.env_c, serverUrl.c_str()); - throwIfError(env); -} - - - -void -carriageParm_http0::setUser(string const userid, - string const password) { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_set_user( - &env.env_c, this->c_serverInfoP, userid.c_str(), password.c_str()); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -carriageParm_http0::allowAuthBasic() { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_allow_auth_basic(&env.env_c, this->c_serverInfoP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -carriageParm_http0::disallowAuthBasic() { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_disallow_auth_basic(&env.env_c, this->c_serverInfoP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -carriageParm_http0::allowAuthDigest() { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_allow_auth_digest(&env.env_c, this->c_serverInfoP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -carriageParm_http0::disallowAuthDigest() { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_disallow_auth_digest(&env.env_c, this->c_serverInfoP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -carriageParm_http0::allowAuthNegotiate() { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_allow_auth_negotiate(&env.env_c, this->c_serverInfoP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -carriageParm_http0::disallowAuthNegotiate() { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_disallow_auth_negotiate( - &env.env_c, this->c_serverInfoP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -carriageParm_http0::allowAuthNtlm() { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_allow_auth_ntlm(&env.env_c, this->c_serverInfoP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -carriageParm_http0::disallowAuthNtlm() { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_disallow_auth_ntlm(&env.env_c, this->c_serverInfoP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -carriageParm_http0::setBasicAuth(string const username, - string const password) { - - if (!this->c_serverInfoP) - throw(error("object not instantiated")); - - env_wrap env; - - xmlrpc_server_info_set_basic_auth( - &env.env_c, this->c_serverInfoP, username.c_str(), password.c_str()); - throwIfError(env); -} - - - -carriageParm_http0Ptr::carriageParm_http0Ptr() { - // Base class constructor will construct pointer that points to nothing -} - - - -carriageParm_http0Ptr::carriageParm_http0Ptr( - carriageParm_http0 * const carriageParmP) : - carriageParmPtr(carriageParmP) {} - - - -carriageParm_http0 * -carriageParm_http0Ptr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -xmlTransaction::xmlTransaction() {} - - - -void -xmlTransaction::finish(string const& responseXml) const { - - xml::trace("XML-RPC RESPONSE", responseXml); -} - - - -void -xmlTransaction::finishErr(error const&) const { - -} - - - -void -xmlTransaction::progress(struct xmlrpc_progress_data const&) const { - - // This is just the base class method. A derived class may override - // this with something substantial. -} - - - -xmlTransactionPtr::xmlTransactionPtr() {} - - - -xmlTransactionPtr::xmlTransactionPtr(xmlTransaction * xmlTransP) : - autoObjectPtr(xmlTransP) {} - - - -xmlTransaction * -xmlTransactionPtr::operator->() const { - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -struct xmlTranCtl { -/*---------------------------------------------------------------------------- - This contains information needed to conduct a transaction. You - construct it as you start the transaction and destroy it after the - work is done. You need this only for an asynchronous one, because - where the user starts and finishes the RPC in the same - libxmlrpc_client call, you can just keep this information in - various stack variables, and it's faster and easier to understand - that way. - - The C transport is designed to take a xmlrpc_call_info argument for - similar stuff needed by the the C client object. But it's really - opaque to the transport, so we just let xmlTranCtl masquerade as - xmlprc_call_info in our call to the C transport. ------------------------------------------------------------------------------*/ - xmlTranCtl(xmlTransactionPtr const& xmlTranP, - string const& callXml) : - - xmlTranP(xmlTranP) { - - env_wrap env; - - this->callXmlP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); - throwIfError(env); - - XMLRPC_MEMBLOCK_APPEND(char, &env.env_c, this->callXmlP, - callXml.c_str(), callXml.size()); - throwIfError(env); - } - - ~xmlTranCtl() { - XMLRPC_MEMBLOCK_FREE(char, this->callXmlP); - } - - xmlTransactionPtr const xmlTranP; - // The transaction we're controlling. Most notable use of this is - // that this object we inform when the transaction is done. This - // is where the response XML and other transaction results go. - - xmlrpc_mem_block * callXmlP; - // The XML of the call. This is what the transport transports. -}; - - - -clientXmlTransport::~clientXmlTransport() {} - - - -void -clientXmlTransport::start(carriageParm * const carriageParmP, - string const& callXml, - xmlTransactionPtr const& xmlTranP) { - - // Note: derived class clientXmlTransport_http overrides this, - // so it doesn't normally get used. - - string responseXml; - - this->call(carriageParmP, callXml, &responseXml); - - xmlTranP->finish(responseXml); -} - - - -void -clientXmlTransport::finishAsync(xmlrpc_c::timeout) { - - // Since our start() does the whole thing, there's nothing for - // us to do. - - // A derived class that overrides start() with something properly - // asynchronous had better also override finishAsync() with something - // substantial. -} - - - -void -clientXmlTransport::asyncComplete( - struct xmlrpc_call_info * const callInfoP, - xmlrpc_mem_block * const responseXmlMP, - xmlrpc_env const transportEnv) { - - xmlTranCtl * const xmlTranCtlP = reinterpret_cast(callInfoP); - - try { - if (transportEnv.fault_occurred) { - xmlTranCtlP->xmlTranP->finishErr(error(transportEnv.fault_string)); - } else { - string const responseXml( - XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlMP), - XMLRPC_MEMBLOCK_SIZE(char, responseXmlMP)); - xmlTranCtlP->xmlTranP->finish(responseXml); - } - } catch(exception const&) { - /* We can't throw an error back to C code, and the async_complete - interface does not provide for failure, so we define ->finish() - as not being capable of throwing an error. - */ - assert(false); - } - delete(xmlTranCtlP); - - /* Ordinarily, *xmlTranCtlP is the last reference to - xmlTranCtlP->xmlTranP, so that will get destroyed too. But - ->finish() could conceivably create a new reference to - xmlTranCtlP->xmlTranP, and then it would keep living. - */ -} - - - -void -clientXmlTransport::progress( - struct xmlrpc_call_info * const callInfoP, - struct xmlrpc_progress_data const progressData) { - - xmlTranCtl * const xmlTranCtlP = reinterpret_cast(callInfoP); - - xmlTranCtlP->xmlTranP->progress(progressData); -} - - - -void -clientXmlTransport::setInterrupt(int *) { - - throwf("The client XML transport is not interruptible"); -} - - - -clientXmlTransportPtr::clientXmlTransportPtr() { - // Base class constructor will construct pointer that points to nothing -} - - - -clientXmlTransportPtr::clientXmlTransportPtr( - clientXmlTransport * const transportP) : autoObjectPtr(transportP) {} - - - -clientXmlTransport * -clientXmlTransportPtr::get() const { - return dynamic_cast(objectP); -} - - - -clientXmlTransport * -clientXmlTransportPtr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -clientXmlTransport_http::~clientXmlTransport_http() {} - - - -void -clientXmlTransport_http::call( - carriageParm * const carriageParmP, - string const& callXml, - string * const responseXmlP) { - - carriageParm_http0 * const carriageParmHttpP = - dynamic_cast(carriageParmP); - - if (carriageParmHttpP == NULL) - throw(error("HTTP client XML transport called with carriage " - "parameter object not of class carriageParm_http")); - - memblockStringWrapper callXmlM(callXml); - - xmlrpc_mem_block * responseXmlMP; - - env_wrap env; - - this->c_transportOpsP->call(&env.env_c, - this->c_transportP, - carriageParmHttpP->c_serverInfoP, - callXmlM.memblockP, - &responseXmlMP); - - throwIfError(env); - - memblockStringWrapper responseHolder(responseXmlMP); - // Makes responseXmlMP get freed at end of scope - - *responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlMP), - XMLRPC_MEMBLOCK_SIZE(char, responseXmlMP)); -} - - - -void -clientXmlTransport_http::start( - carriageParm * const carriageParmP, - string const& callXml, - xmlTransactionPtr const& xmlTranP) { - - env_wrap env; - - carriageParm_http0 * const carriageParmHttpP = - dynamic_cast(carriageParmP); - - if (carriageParmHttpP == NULL) - throw(error("HTTP client XML transport called with carriage " - "parameter object not of type carriageParm_http")); - - xmlTranCtl * const tranCtlP(new xmlTranCtl(xmlTranP, callXml)); - - try { - this->c_transportOpsP->send_request( - &env.env_c, - this->c_transportP, - carriageParmHttpP->c_serverInfoP, - tranCtlP->callXmlP, - &this->asyncComplete, &this->progress, - reinterpret_cast(tranCtlP)); - - throwIfError(env); - } catch (...) { - delete tranCtlP; - throw; - } -} - - - -void -clientXmlTransport_http::finishAsync(xmlrpc_c::timeout const timeout) { - - xmlrpc_timeoutType const c_timeoutType( - timeout.finite ? timeout_yes : timeout_no); - xmlrpc_timeout const c_timeout(timeout.duration); - - this->c_transportOpsP->finish_asynch( - this->c_transportP, c_timeoutType, c_timeout); -} - - - -void -clientXmlTransport_http::setInterrupt(int * const interruptP) { - - if (this->c_transportOpsP->set_interrupt) - this->c_transportOpsP->set_interrupt(this->c_transportP, interruptP); -} - - - -bool const haveCurl( -#if MUST_BUILD_CURL_CLIENT -true -#else -false -#endif -); - -bool const haveLibwww( -#if MUST_BUILD_LIBWWW_CLIENT -true -#else -false -#endif -); - -bool const haveWininet( -#if MUST_BUILD_WININET_CLIENT -true -#else -false -#endif -); - - - -vector -clientXmlTransport_http::availableTypes() { - - vector retval; - - if (haveCurl) - retval.push_back("curl"); - - if (haveLibwww) - retval.push_back("libwww"); - - if (haveWininet) - retval.push_back("wininet"); - - return retval; -} - - - -clientXmlTransportPtr -clientXmlTransport_http::create() { -/*---------------------------------------------------------------------------- - Make an HTTP Client XML transport of any kind (Caller doesn't care). - - Caller can find out what kind he got by trying dynamic casts. - - Caller can use a carriageParm_http0 with the transport. ------------------------------------------------------------------------------*/ - if (haveCurl) - return clientXmlTransportPtr(new clientXmlTransport_curl()); - else if (haveLibwww) - return clientXmlTransportPtr(new clientXmlTransport_libwww()); - else if (haveWininet) - return clientXmlTransportPtr(new clientXmlTransport_wininet()); - else - throwf("This XML-RPC client library contains no HTTP XML transports"); -} - - - -clientTransaction::clientTransaction() {} - - - -clientTransactionPtr::clientTransactionPtr() {} - - - -clientTransactionPtr::clientTransactionPtr( - clientTransaction * const transP) : autoObjectPtr(transP) {} - - - -clientTransactionPtr::~clientTransactionPtr() {} - - - -clientTransaction * -clientTransactionPtr::operator->() const { - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -client::~client() {} - - - -void -client::start(carriageParm * const carriageParmP, - string const& methodName, - paramList const& paramList, - clientTransactionPtr const& tranP) { -/*---------------------------------------------------------------------------- - Start an RPC, wait for it to complete, and finish it. - - Usually, a derived class overrides this with something that does - not wait for the RPC to complete, but rather arranges for something - to finish the RPC later when the RPC does complete. ------------------------------------------------------------------------------*/ - rpcOutcome outcome; - - this->call(carriageParmP, methodName, paramList, &outcome); - - tranP->finish(outcome); -} - - - -void -client::finishAsync(xmlrpc_c::timeout) { - - // Since our start() does the whole thing, there's nothing for - // us to do. - - // A derived class that overrides start() with something properly - // asynchronous had better also override finishAsync() with something - // substantial. -} - - - -void -client::setInterrupt(int *) { - - throwf("Clients of this type are not interruptible"); -} - - - -clientPtr::clientPtr() { - // Base class constructor will construct pointer that points to nothing -} - - - -clientPtr::clientPtr( - client * const clientP) : autoObjectPtr(clientP) {} - - - -client * -clientPtr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -client * -clientPtr::get() const { - return dynamic_cast(objectP); -} - - - -client_xml::client_xml(clientXmlTransport * const transportP) { - - this->implP = new client_xml_impl(transportP); -} - - - -client_xml::client_xml(clientXmlTransportPtr const transportPtr) { - - this->implP = new client_xml_impl(transportPtr, transportPtr.get()); -} - - - -client_xml::client_xml(clientXmlTransport * const transportP, - xmlrpc_dialect const dialect) { - - this->implP = new client_xml_impl(transportP, dialect); -} - - - -client_xml::client_xml(clientXmlTransportPtr const transportPtr, - xmlrpc_dialect const dialect) { - - this->implP = new client_xml_impl(transportPtr, transportPtr.get(), - dialect); -} - - - -client_xml::~client_xml() { - - delete(this->implP); -} - - - -void -client_xml::call(carriageParm * const carriageParmP, - string const& methodName, - paramList const& paramList, - rpcOutcome * const outcomeP) { - - string callXml; - string responseXml; - - xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); - - xml::trace("XML-RPC CALL", callXml); - - try { - this->implP->transportP->call(carriageParmP, callXml, &responseXml); - } catch (exception const& e) { - throwf("Unable to transport XML to server and " - "get XML response back. %s", e.what()); - } - xml::trace("XML-RPC RESPONSE", responseXml); - - try { - xml::parseResponse(responseXml, outcomeP); - } catch (exception const& e) { - throwf("Response XML from server is not valid XML-RPC response. %s", - e.what()); - } -} - - - -void -client_xml::start(carriageParm * const carriageParmP, - string const& methodName, - paramList const& paramList, - clientTransactionPtr const& tranP) { - - string callXml; - - xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); - - xml::trace("XML-RPC CALL", callXml); - - xmlTransaction_clientPtr const xmlTranP(tranP); - - this->implP->transportP->start(carriageParmP, callXml, xmlTranP); -} - - - -void -client_xml::finishAsync(xmlrpc_c::timeout const timeout) { - - this->implP->transportP->finishAsync(timeout); -} - - - -void -client_xml::setInterrupt(int * const interruptP) { - - this->implP->transportP->setInterrupt(interruptP); -} - - - -serverAccessor::serverAccessor(clientPtr const clientP, - carriageParmPtr const carriageParmP) : - - clientP(clientP), carriageParmP(carriageParmP) {}; - - - -void -serverAccessor::call(std::string const& methodName, - xmlrpc_c::paramList const& paramList, - xmlrpc_c::rpcOutcome * const outcomeP) const { - - this->clientP->call(this->carriageParmP.get(), - methodName, - paramList, - outcomeP); -} - - - -serverAccessorPtr::serverAccessorPtr() { - // Base class constructor will construct pointer that points to nothing -} - - - -serverAccessorPtr::serverAccessorPtr( - serverAccessor * const serverAccessorParmP) : - autoObjectPtr(serverAccessorParmP) {} - - - -serverAccessor * -serverAccessorPtr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -serverAccessor * -serverAccessorPtr::get() const { - return dynamic_cast(objectP); -} - - - -connection::connection(client * const clientP, - carriageParm * const carriageParmP) : - clientP(clientP), carriageParmP(carriageParmP) {} - - - -connection::~connection() {} - - - -struct rpc_impl { - 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 - rpcOutcome outcome; - // Defined only in STATE_FAILED and STATE_SUCCEEDED - string methodName; - xmlrpc_c::paramList paramList; - - rpc_impl(string const& methodName, - xmlrpc_c::paramList const& paramList) : - state(STATE_UNFINISHED), - methodName(methodName), - paramList(paramList) {} -}; - - - -rpc::rpc(string const methodName, - paramList const& paramList) { - - this->implP = new rpc_impl(methodName, paramList); -} - - - -rpc::~rpc() { - - if (this->implP->state == rpc_impl::STATE_ERROR) - delete(this->implP->errorP); - - delete(this->implP); -} - - - -void -rpc::call(client * const clientP, - carriageParm * const carriageParmP) { - - if (this->implP->state != rpc_impl::STATE_UNFINISHED) - throw(error("Attempt to execute an RPC that has already been " - "executed")); - - clientP->call(carriageParmP, - this->implP->methodName, - this->implP->paramList, - &this->implP->outcome); - - this->implP->state = this->implP->outcome.succeeded() ? - rpc_impl::STATE_SUCCEEDED : rpc_impl::STATE_FAILED; -} - - - -void -rpc::call(connection const& connection) { - - this->call(connection.clientP, connection.carriageParmP); - -} - - - -void -rpc::start(client * const clientP, - carriageParm * const carriageParmP) { - - if (this->implP->state != rpc_impl::STATE_UNFINISHED) - throw(error("Attempt to execute an RPC that has already been " - "executed")); - - clientP->start(carriageParmP, - this->implP->methodName, - this->implP->paramList, - rpcPtr(this)); -} - - - -void -rpc::start(xmlrpc_c::connection const& connection) { - - this->start(connection.clientP, connection.carriageParmP); -} - - - -void -rpc::finish(rpcOutcome const& outcome) { - - this->implP->state = - outcome.succeeded() ? - rpc_impl::STATE_SUCCEEDED : rpc_impl::STATE_FAILED; - - this->implP->outcome = outcome; - - this->notifyComplete(); -} - - - -void -rpc::finishErr(error const& error) { - - this->implP->state = rpc_impl::STATE_ERROR; - this->implP->errorP = new girerr::error(error); - this->notifyComplete(); -} - - - -void -rpc::notifyComplete() { -/*---------------------------------------------------------------------------- - Anyone who does RPCs asynchronously and doesn't use polling will - want to make his own class derived from 'rpc' and override this - with a notifyFinish() that does something. - - Typically, notifyFinish() will queue the RPC so some other thread - will deal with the fact that the RPC is finished. - - - In the absence of the aforementioned queueing, the RPC becomes - unreferenced as soon as our Caller releases his reference, so the - RPC gets destroyed when we return. ------------------------------------------------------------------------------*/ - -} - - - -void -rpc::progress(struct xmlrpc_progress_data const&) const { -/*---------------------------------------------------------------------------- - If the user is interested in tracking the progress of the RPC, he will - derive a class from xmlrpc_c::rpc and override this with a progress() - that does something, such as display a progress bar. ------------------------------------------------------------------------------*/ - -} - - - -value -rpc::getResult() const { - - switch (this->implP->state) { - case rpc_impl::STATE_UNFINISHED: - throw(error("Attempt to get result of RPC that is not finished.")); - break; - case rpc_impl::STATE_ERROR: - throw(*this->implP->errorP); - break; - case rpc_impl::STATE_FAILED: - throw(error("RPC response indicates failure. " + - this->implP->outcome.getFault().getDescription())); - break; - case rpc_impl::STATE_SUCCEEDED: { - // All normal - } - } - - return this->implP->outcome.getResult(); -} - - - - -fault -rpc::getFault() const { - - switch (this->implP->state) { - case rpc_impl::STATE_UNFINISHED: - throw(error("Attempt to get fault from RPC that is not finished")); - break; - case rpc_impl::STATE_ERROR: - throw(*this->implP->errorP); - break; - case rpc_impl::STATE_SUCCEEDED: - throw(error("Attempt to get fault from an RPC that succeeded")); - break; - case rpc_impl::STATE_FAILED: { - // All normal - } - } - - return this->implP->outcome.getFault(); -} - - - -bool -rpc::isFinished() const { - return (this->implP->state != rpc_impl::STATE_UNFINISHED); -} - - - -bool -rpc::isSuccessful() const { - return (this->implP->state == rpc_impl::STATE_SUCCEEDED); -} - - - -rpcPtr::rpcPtr() {} - - - -rpcPtr::rpcPtr(rpc * const rpcP) : clientTransactionPtr(rpcP) {} - - - -rpcPtr::rpcPtr(string const methodName, - xmlrpc_c::paramList const& paramList) : - clientTransactionPtr(new rpc(methodName, paramList)) {} - - - -rpc * -rpcPtr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -xmlTransaction_client::xmlTransaction_client( - clientTransactionPtr const& tranP) : - tranP(tranP) {} - - - -void -xmlTransaction_client::finish(string const& responseXml) const { - - xml::trace("XML-RPC RESPONSE", responseXml); - - try { - rpcOutcome outcome; - - xml::parseResponse(responseXml, &outcome); - - this->tranP->finish(outcome); - } catch (error const& error) { - this->tranP->finishErr(error); - } -} - - - -void -xmlTransaction_client::finishErr(error const& error) const { - - this->tranP->finishErr(error); -} - - - -void -xmlTransaction_client::progress( - struct xmlrpc_progress_data const& progressData) const { - - this->tranP->progress(progressData); -} - - - -xmlTransaction_clientPtr::xmlTransaction_clientPtr() {} - - - -xmlTransaction_clientPtr::xmlTransaction_clientPtr( - clientTransactionPtr const& tranP) : - xmlTransactionPtr(new xmlTransaction_client(tranP)) {} - - - -xmlTransaction_client * -xmlTransaction_clientPtr::operator->() const { - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -} // namespace diff --git a/trunk/src/cpp/client_simple.cpp b/trunk/src/cpp/client_simple.cpp deleted file mode 100644 index abd198452..000000000 --- a/trunk/src/cpp/client_simple.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "xmlrpc-c/env_wrap.hpp" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/client.hpp" -#include - -#include "xmlrpc-c/client_simple.hpp" - -using namespace std; -using namespace xmlrpc_c; - -namespace xmlrpc_c { - - -namespace { - -class cValueWrapper { -/*---------------------------------------------------------------------------- - Use an object of this class to set up to remove a reference to an - xmlrpc_value object (a C object with manual reference management) - at then end of a scope -- even if the scope ends with a throw. ------------------------------------------------------------------------------*/ - xmlrpc_value * valueP; -public: - cValueWrapper(xmlrpc_value * valueP) : valueP(valueP) {} - ~cValueWrapper() { xmlrpc_DECREF(valueP); } -}; - -} // namespace - - - -clientSimple::clientSimple() { - - clientXmlTransportPtr const transportP(clientXmlTransport_http::create()); - - this->clientP = clientPtr(new client_xml(transportP)); -} - - - -void -clientSimple::call(string const serverUrl, - string const methodName, - value * const resultP) { - - carriageParm_http0 carriageParm(serverUrl); - - rpcPtr rpcPtr(methodName, paramList()); - - rpcPtr->call(this->clientP.get(), &carriageParm); - - *resultP = rpcPtr->getResult(); -} - - -namespace { - -void -makeParamArray(string const format, - xmlrpc_value ** const paramArrayPP, - va_list args) { - - env_wrap env; - - /* The format is a sequence of parameter specifications, such as - "iiii" for 4 integer parameters. We add parentheses to make it - an array of those parameters: "(iiii)". - */ - string const arrayFormat("(" + string(format) + ")"); - const char * tail; - - xmlrpc_build_value_va(&env.env_c, arrayFormat.c_str(), - args, paramArrayPP, &tail); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); - - if (strlen(tail) != 0) { - /* xmlrpc_build_value_va() parses off a single value specification - from its format string, and 'tail' points to whatever is after - it. Our format string should have been a single array value, - meaning tail is end-of-string. If it's not, that means - something closed our array early. - */ - xmlrpc_DECREF(*paramArrayPP); - throw(error("format string is invalid. It apparently has a " - "stray right parenthesis")); - } -} - -} // namespace - - -void -clientSimple::call(string const serverUrl, - string const methodName, - string const format, - value * const resultP, - ...) { - - carriageParm_http0 carriageParm(serverUrl); - - env_wrap env; - xmlrpc_value * paramArrayP; - - va_list args; - va_start(args, resultP); - makeParamArray(format, ¶mArrayP, args); - va_end(args); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); - else { - cValueWrapper paramArrayWrapper(paramArrayP); // ensure destruction - unsigned int const paramCount( - xmlrpc_array_size(&env.env_c, paramArrayP)); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); - - paramList paramList; - for (unsigned int i = 0; i < paramCount; ++i) { - xmlrpc_value * paramP; - xmlrpc_array_read_item(&env.env_c, paramArrayP, i, ¶mP); - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); - else { - cValueWrapper paramWrapper(paramP); // ensure destruction - paramList.add(value(paramP)); - } - } - rpcPtr rpcPtr(methodName, paramList); - rpcPtr->call(this->clientP.get(), &carriageParm); - *resultP = rpcPtr->getResult(); - } -} - - - -void -clientSimple::call(string const serverUrl, - string const methodName, - paramList const& paramList, - value * const resultP) { - - carriageParm_http0 carriageParm(serverUrl); - - rpcPtr rpcPtr(methodName, paramList); - - rpcPtr->call(this->clientP.get(), &carriageParm); - - *resultP = rpcPtr->getResult(); -} - -} // namespace diff --git a/trunk/src/cpp/curl.cpp b/trunk/src/cpp/curl.cpp deleted file mode 100644 index d69783d27..000000000 --- a/trunk/src/cpp/curl.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/*============================================================================= - curl.cpp -=============================================================================== - This is the Curl XML transport of the C++ XML-RPC client library for - Xmlrpc-c. - - Note that unlike most of Xmlprc-c's C++ API, this is _not_ based on the - C client library. This code is independent of the C client library, and - is based directly on the client XML transport libraries (with a little - help from internal C utility libraries). -=============================================================================*/ - -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/girmem.hpp" -using girmem::autoObjectPtr; -using girmem::autoObject; -#include "xmlrpc-c/env_wrap.hpp" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/transport.h" -#include "xmlrpc-c/base_int.h" - -/* transport_config.h defines MUST_BUILD_CURL_CLIENT */ -#include "transport_config.h" - -#include "xmlrpc-c/client_transport.hpp" - - -using namespace std; -using namespace xmlrpc_c; - - - -namespace { - -class globalConstant { -public: - globalConstant(); - ~globalConstant(); -}; - - - -globalConstant::globalConstant() { - - // Not thread safe - - xmlrpc_transport_setup setupFn; - -#if MUST_BUILD_CURL_CLIENT - setupFn = xmlrpc_curl_transport_ops.setup_global_const; -#else - setupFn = NULL; -#endif - if (setupFn) { - env_wrap env; - - setupFn(&env.env_c); // Not thread safe - - if (env.env_c.fault_occurred) - throwf("Failed to do global initialization " - "of Curl transport code. %s", env.env_c.fault_string); - } -} - - - -globalConstant::~globalConstant() { - - // Not thread safe - - xmlrpc_transport_teardown teardownFn; - -#if MUST_BUILD_CURL_CLIENT - teardownFn = xmlrpc_curl_transport_ops.teardown_global_const; -#else - teardownFn = NULL; -#endif - if (teardownFn) - teardownFn(); // not thread safe -} - -globalConstant globalConst; - // This object is never accessed. Its whole purpose to to be born and - // to die, which it does automatically as part of C++ program - // program initialization and termination. - -} // namespace - - -namespace xmlrpc_c { - -carriageParm_curl0::carriageParm_curl0( - string const serverUrl - ) { - - this->instantiate(serverUrl); -} - - - -carriageParm_curl0Ptr::carriageParm_curl0Ptr() { - // Base class constructor will construct pointer that points to nothing -} - - - -carriageParm_curl0Ptr::carriageParm_curl0Ptr( - carriageParm_curl0 * const carriageParmP) { - this->point(carriageParmP); -} - - - -carriageParm_curl0 * -carriageParm_curl0Ptr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -struct clientXmlTransport_curl::constrOpt_impl { - - constrOpt_impl(); - - struct { - std::string network_interface; - bool dont_advertise; - std::string user_agent; - std::string referer; - bool no_ssl_verifypeer; - bool no_ssl_verifyhost; - std::string ssl_cert; - std::string sslcerttype; - std::string sslcertpasswd; - std::string sslkey; - std::string sslkeytype; - std::string sslkeypasswd; - std::string sslengine; - bool sslengine_default; - xmlrpc_sslversion sslversion; - std::string cainfo; - std::string capath; - std::string randomfile; - std::string egdsocket; - std::string ssl_cipher_list; - unsigned int timeout; - std::string proxy; - unsigned int proxy_auth; - unsigned int proxy_port; - std::string proxy_userpwd; - xmlrpc_httpproxytype proxy_type; - bool gssapi_delegation; - unsigned int connect_timeout; - } value; - struct { - bool network_interface; - bool dont_advertise; - bool user_agent; - bool referer; - bool no_ssl_verifypeer; - bool no_ssl_verifyhost; - bool ssl_cert; - bool sslcerttype; - bool sslcertpasswd; - bool sslkey; - bool sslkeytype; - bool sslkeypasswd; - bool sslengine; - bool sslengine_default; - bool sslversion; - bool cainfo; - bool capath; - bool randomfile; - bool egdsocket; - bool ssl_cipher_list; - bool timeout; - bool proxy; - bool proxy_auth; - bool proxy_port; - bool proxy_userpwd; - bool proxy_type; - bool gssapi_delegation; - bool connect_timeout; - } present; -}; - -clientXmlTransport_curl::constrOpt_impl::constrOpt_impl() { - - present.network_interface = false; - present.dont_advertise = false; - present.user_agent = false; - present.referer = false; - present.no_ssl_verifypeer = false; - present.no_ssl_verifyhost = false; - present.ssl_cert = false; - present.sslcerttype = false; - present.sslcertpasswd = false; - present.sslkey = false; - present.sslkeytype = false; - present.sslkeypasswd = false; - present.sslengine = false; - present.sslengine_default = false; - present.sslversion = false; - present.cainfo = false; - present.capath = false; - present.randomfile = false; - present.egdsocket = false; - present.ssl_cipher_list = false; - present.timeout = false; - present.proxy = false; - present.proxy_port = false; - present.proxy_auth = false; - present.proxy_userpwd = false; - present.proxy_type = false; - present.gssapi_delegation = false; - present.connect_timeout = false; -} - - - -#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ -clientXmlTransport_curl::constrOpt & \ -clientXmlTransport_curl::constrOpt::OPTION_NAME(TYPE const& arg) { \ - this->implP->value.OPTION_NAME = arg; \ - this->implP->present.OPTION_NAME = true; \ - return *this; \ -} - -DEFINE_OPTION_SETTER(network_interface, string); -DEFINE_OPTION_SETTER(dont_advertise, bool); -DEFINE_OPTION_SETTER(referer, string); -DEFINE_OPTION_SETTER(user_agent, string); -DEFINE_OPTION_SETTER(no_ssl_verifypeer, bool); -DEFINE_OPTION_SETTER(no_ssl_verifyhost, bool); -DEFINE_OPTION_SETTER(ssl_cert, string); -DEFINE_OPTION_SETTER(sslcerttype, string); -DEFINE_OPTION_SETTER(sslcertpasswd, string); -DEFINE_OPTION_SETTER(sslkey, string); -DEFINE_OPTION_SETTER(sslkeytype, string); -DEFINE_OPTION_SETTER(sslkeypasswd, string); -DEFINE_OPTION_SETTER(sslengine, string); -DEFINE_OPTION_SETTER(sslengine_default, bool); -DEFINE_OPTION_SETTER(sslversion, xmlrpc_sslversion); -DEFINE_OPTION_SETTER(cainfo, string); -DEFINE_OPTION_SETTER(capath, string); -DEFINE_OPTION_SETTER(randomfile, string); -DEFINE_OPTION_SETTER(egdsocket, string); -DEFINE_OPTION_SETTER(ssl_cipher_list, string); -DEFINE_OPTION_SETTER(timeout, unsigned int); -DEFINE_OPTION_SETTER(proxy, string); -DEFINE_OPTION_SETTER(proxy_port, unsigned int); -DEFINE_OPTION_SETTER(proxy_auth, unsigned int); -DEFINE_OPTION_SETTER(proxy_userpwd, string); -DEFINE_OPTION_SETTER(proxy_type, xmlrpc_httpproxytype); -DEFINE_OPTION_SETTER(gssapi_delegation, bool); -DEFINE_OPTION_SETTER(connect_timeout, unsigned int); - -#undef DEFINE_OPTION_SETTER - -clientXmlTransport_curl::constrOpt::constrOpt() { - - this->implP = new clientXmlTransport_curl::constrOpt_impl(); -} - - - -clientXmlTransport_curl::constrOpt::~constrOpt() { - - delete(this->implP); -} - - - -clientXmlTransport_curl::constrOpt::constrOpt(constrOpt& arg) { - - this->implP = new constrOpt_impl(*arg.implP); -} - - - -#if MUST_BUILD_CURL_CLIENT - -void -clientXmlTransport_curl::initialize(constrOpt const& optExt) { - constrOpt_impl const opt(*optExt.implP); - - struct xmlrpc_curl_xportparms transportParms; - - transportParms.network_interface = opt.present.network_interface ? - opt.value.network_interface.c_str() : NULL; - transportParms.referer = opt.present.referer ? - opt.value.referer.c_str() : NULL; - transportParms.dont_advertise = opt.present.dont_advertise ? - opt.value.dont_advertise : false; - transportParms.user_agent = opt.present.user_agent ? - opt.value.user_agent.c_str() : NULL; - transportParms.no_ssl_verifypeer = opt.present.no_ssl_verifypeer ? - opt.value.no_ssl_verifypeer : false; - transportParms.no_ssl_verifyhost = opt.present.no_ssl_verifyhost ? - opt.value.no_ssl_verifyhost : false; - transportParms.ssl_cert = opt.present.ssl_cert ? - opt.value.ssl_cert.c_str() : NULL; - transportParms.sslcerttype = opt.present.sslcerttype ? - opt.value.sslcerttype.c_str() : NULL; - transportParms.sslcertpasswd = opt.present.sslcertpasswd ? - opt.value.sslcertpasswd.c_str() : NULL; - transportParms.sslkey = opt.present.sslkey ? - opt.value.sslkey.c_str() : NULL; - transportParms.sslkeytype = opt.present.sslkeytype ? - opt.value.sslkeytype.c_str() : NULL; - transportParms.sslkeypasswd = opt.present.sslkeypasswd ? - opt.value.sslkeypasswd.c_str() : NULL; - transportParms.sslengine = opt.present.sslengine ? - opt.value.sslengine.c_str() : NULL; - transportParms.sslengine_default = opt.present.sslengine_default ? - opt.value.sslengine_default : false; - transportParms.sslversion = opt.present.sslversion ? - opt.value.sslversion : XMLRPC_SSLVERSION_DEFAULT; - transportParms.cainfo = opt.present.cainfo ? - opt.value.cainfo.c_str() : NULL; - transportParms.capath = opt.present.capath ? - opt.value.capath.c_str() : NULL; - transportParms.randomfile = opt.present.randomfile ? - opt.value.randomfile.c_str() : NULL; - transportParms.egdsocket = opt.present.egdsocket ? - opt.value.egdsocket.c_str() : NULL; - transportParms.ssl_cipher_list = opt.present.ssl_cipher_list ? - opt.value.ssl_cipher_list.c_str() : NULL; - transportParms.timeout = opt.present.timeout ? - opt.value.timeout : 0; - transportParms.proxy = opt.present.proxy ? - opt.value.proxy.c_str() : NULL; - transportParms.proxy_port = opt.present.proxy_port ? - opt.value.proxy_port : 0; - transportParms.proxy_auth = opt.present.proxy_auth ? - opt.value.proxy_auth : XMLRPC_HTTPAUTH_NONE; - transportParms.proxy_userpwd = opt.present.proxy_userpwd ? - opt.value.proxy_userpwd.c_str() : NULL; - transportParms.proxy_type = opt.present.proxy_type ? - opt.value.proxy_type : XMLRPC_HTTPPROXY_HTTP; - transportParms.gssapi_delegation = opt.present.gssapi_delegation ? - opt.value.gssapi_delegation : false; - transportParms.connect_timeout = opt.present.connect_timeout ? - opt.value.connect_timeout : 0; - - this->c_transportOpsP = &xmlrpc_curl_transport_ops; - - env_wrap env; - - xmlrpc_curl_transport_ops.create( - &env.env_c, 0, "", "", - &transportParms, XMLRPC_CXPSIZE(gssapi_delegation), - &this->c_transportP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - -#else // MUST_BUILD_CURL_CLIENT - -void -clientXmlTransport_curl::initialize(constrOpt const& opt) { - - throw(error("There is no Curl client XML transport in this XML-RPC client " - "library")); -} - -#endif - -clientXmlTransport_curl::clientXmlTransport_curl(constrOpt const& opt) { - - this->initialize(opt); -} - - - -clientXmlTransport_curl::clientXmlTransport_curl( - string const networkInterface, - bool const noSslVerifyPeer, - bool const noSslVerifyHost, - string const userAgent) { - - clientXmlTransport_curl::constrOpt opt; - - if (networkInterface.size() > 0) - opt.network_interface(networkInterface); - opt.no_ssl_verifypeer(noSslVerifyPeer); - opt.no_ssl_verifyhost(noSslVerifyHost); - if (userAgent.size() > 0) - opt.user_agent(userAgent); - - this->initialize(opt); -} - - - -clientXmlTransport_curl::~clientXmlTransport_curl() { - - this->c_transportOpsP->destroy(this->c_transportP); -} - - -} // namespace diff --git a/trunk/src/cpp/fault.cpp b/trunk/src/cpp/fault.cpp deleted file mode 100644 index 4db6bc865..000000000 --- a/trunk/src/cpp/fault.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "xmlrpc-c/base.hpp" - -using namespace std; - -namespace xmlrpc_c { - -fault::fault() : valid(false) {}; - -fault::fault(string const _description, - xmlrpc_c::fault::code_t const _code - ) : - valid(true), - code(_code), - description(_description) - {} - -xmlrpc_c::fault::code_t -fault::getCode() const { - if (!valid) - throw(error("Attempt to access placeholder xmlrpc_c::fault object")); - return this->code; -} - -string -fault::getDescription() const { - if (!valid) - throw(error("Attempt to access placeholder xmlrpc_c::fault object")); - return this->description; -} - -} // namespace diff --git a/trunk/src/cpp/global.cpp b/trunk/src/cpp/global.cpp deleted file mode 100644 index 563681949..000000000 --- a/trunk/src/cpp/global.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include - -using namespace std; - -#include -using girerr::throwf; -#include - - -class LibxmlrpcGlobalState { - -public: - LibxmlrpcGlobalState() { - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_init(&env); - if (env.fault_occurred) { - string const fault(env.fault_string); - xmlrpc_env_clean(&env); - throwf("Failed to initailize libxmlrpc. %s", fault.c_str()); - } - } - - ~LibxmlrpcGlobalState() { - xmlrpc_term(); - } -}; - -static LibxmlrpcGlobalState libxmlrpcGlobalState; - diff --git a/trunk/src/cpp/libwww.cpp b/trunk/src/cpp/libwww.cpp deleted file mode 100644 index f7cf01122..000000000 --- a/trunk/src/cpp/libwww.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/*============================================================================= - libwww.cpp -=============================================================================== - This is the Libwww XML transport of the C++ XML-RPC client library for - Xmlrpc-c. -=============================================================================*/ - -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/girmem.hpp" -using girmem::autoObjectPtr; -using girmem::autoObject; -#include "xmlrpc-c/env_wrap.hpp" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/transport.h" -#include "xmlrpc-c/base_int.h" - -/* transport_config.h defines MUST_BUILD_LIBWWW_CLIENT */ -#include "transport_config.h" - -#include "xmlrpc-c/client_transport.hpp" - - -using namespace std; -using namespace xmlrpc_c; - - -namespace { - -class globalConstant { -public: - globalConstant(); - ~globalConstant(); -}; - - - -globalConstant::globalConstant() { - - // Not thread safe - - xmlrpc_transport_setup setupFn; - -#if MUST_BUILD_LIBWWW_CLIENT - setupFn = xmlrpc_libwww_transport_ops.setup_global_const; -#else - setupFn = NULL; -#endif - if (setupFn) { - env_wrap env; - - setupFn(&env.env_c); // Not thread safe - - if (env.env_c.fault_occurred) - throwf("Failed to do global initialization " - "of Libwww transport code. %s", env.env_c.fault_string); - } -} - - - -globalConstant::~globalConstant() { - - // Not thread safe - - xmlrpc_transport_teardown teardownFn; - -#if MUST_BUILD_LIBWWW_CLIENT - teardownFn = xmlrpc_libwww_transport_ops.teardown_global_const; -#else - teardownFn = NULL; -#endif - if (teardownFn) - teardownFn(); // not thread safe -} - - -globalConstant globalConst; - // This object is never accessed. Its whole purpose to to be born and - // to die, which it does automatically as part of C++ program - // program initialization and termination. - -} // namespace - - -namespace xmlrpc_c { - -carriageParm_libwww0::carriageParm_libwww0( - string const serverUrl - ) { - - this->instantiate(serverUrl); -} - - - -carriageParm_libwww0Ptr::carriageParm_libwww0Ptr() { - // Base class constructor will construct pointer that points to nothing -} - - - -carriageParm_libwww0Ptr::carriageParm_libwww0Ptr( - carriageParm_libwww0 * const carriageParmP) { - this->point(carriageParmP); -} - - - -carriageParm_libwww0 * -carriageParm_libwww0Ptr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -#if MUST_BUILD_LIBWWW_CLIENT - -clientXmlTransport_libwww::clientXmlTransport_libwww( - string const appname, - string const appversion) { - - this->c_transportOpsP = &xmlrpc_libwww_transport_ops; - - env_wrap env; - - xmlrpc_libwww_transport_ops.create( - &env.env_c, 0, appname.c_str(), appversion.c_str(), NULL, 0, - &this->c_transportP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - -#else // MUST_BUILD_LIBWWW_CLIENT - clientXmlTransport_libwww::clientXmlTransport_libwww(string const, - string const) { - - throw(error("There is no Libwww client XML transport " - "in this XML-RPC client library")); -} - -#endif - - -clientXmlTransport_libwww::~clientXmlTransport_libwww() { - - this->c_transportOpsP->destroy(this->c_transportP); -} - -} // namespace diff --git a/trunk/src/cpp/outcome.cpp b/trunk/src/cpp/outcome.cpp deleted file mode 100644 index e004ef880..000000000 --- a/trunk/src/cpp/outcome.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "xmlrpc-c/base.hpp" - -using namespace std; - -namespace xmlrpc_c { - -rpcOutcome::rpcOutcome() : valid(false) {} - -rpcOutcome::rpcOutcome(xmlrpc_c::value const result) : - valid(true), _succeeded(true), result(result) - {} - - - -rpcOutcome::rpcOutcome(xmlrpc_c::fault const fault) : - valid(true), _succeeded(false), fault(fault) - {} - - - -bool -rpcOutcome::succeeded() const { - if (!valid) - throw(error("Attempt to access rpcOutcome object before setting it")); - return _succeeded; -} - - - -fault -rpcOutcome::getFault() const { - - if (!valid) - throw(error("Attempt to access rpcOutcome object before setting it")); - if (_succeeded) - throw(error("Attempt to get fault description from a non-failure " - "RPC outcome")); - return fault; -} - - - -value -rpcOutcome::getResult() const { - - if (!valid) - throw(error("Attempt to access rpcOutcome object before setting it")); - if (!_succeeded) - throw(error("Attempt to get result from an unsuccessful RPC outcome")); - return result; -} - - -} // namespace - diff --git a/trunk/src/cpp/packetsocket.cpp b/trunk/src/cpp/packetsocket.cpp deleted file mode 100644 index 3719357a2..000000000 --- a/trunk/src/cpp/packetsocket.cpp +++ /dev/null @@ -1,1106 +0,0 @@ -/*============================================================================ - packetsocket -============================================================================== - - This is a facility for communicating socket-style, with defined - packets like a datagram socket but with reliable delivery like a - stream socket. It's like a POSIX "sequential packet" socket, except - it is built on top of a stream socket, so it is usable on the many - systems that have stream sockets but not sequential packet sockets. - - By Bryan Henderson 2007.05.12 - - Contributed to the public domain by its author. -============================================================================*/ - - -/*============================================================================ - The protocol for carrying packets on a character stream: - - The protocol consists of the actual bytes to be transported with a bare - minimum of framing information added: - - An ASCII Escape ( == 0x1B) character marks the start of a - 4-ASCII-character control word. These are defined: - - PKT : marks the beginning of a packet. - END : marks the end of a packet. - ESC : represents an character in the packet - NOP : no meaning - - Any other bytes after is a protocol error. - - A stream is all the data transmitted during a single socket - connection. - - End of stream in the middle of a packet is a protocol error. - - All bytes not part of a control word are literal bytes of a packet. - - You can create a packet socket from a POSIX stream socket or a - Windows emulation of one. - - One use of the NOP control word is to validate that the connection - is still working. You might send one periodically to detect, for - example, an unplugged TCP/IP network cable. It's probably better - to use the TCP keepalive facility for that. -============================================================================*/ -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include // mingw32 doesn't have in 12.06. -#include - -#include -#include -#if MSVCRT -# include -# include -#else -# include -# include -# include -#endif - -#include - -#include "c_util.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/girerr.hpp" -using girerr::throwf; - -#include "xmlrpc-c/packetsocket.hpp" - -using namespace std; - -#define ESC 0x1B // ASCII Escape character -#define ESC_STR "\x1B" - -class BrokenConnectionEx { -}; - -class XMLRPC_DLLEXPORT socketx { - -public: - socketx(int const sockFd); - - ~socketx(); - - void - waitForReadable() const; - - void - waitForWritable() const; - - void - read(unsigned char * const buffer, - size_t const bufferSize, - bool * const wouldblockP, - size_t * const bytesReadP) const; - - void - writeWait(const unsigned char * const data, - size_t const size) const; -private: - int fd; - bool fdIsBorrowed; -}; - - - -/* Sockets are similar, but not identical between Unix and Windows. - Some Unix socket functions appear to be available on Windows (a - Unix compatibility feature), but work only for file descriptor - numbers < 32, so we don't use those. -*/ - -socketx::socketx(int const sockFd) { -#if MSVCRT - // We don't have any way to duplicate; we'll just have to borrow. - this->fdIsBorrowed = true; - this->fd = sockFd; - u_long iMode(1); // Nonblocking mode yes - ioctlsocket(this->fd, FIONBIO, &iMode); // Make socket nonblocking -#else - this->fdIsBorrowed = false; - - int dupRc; - - dupRc = dup(sockFd); - - if (dupRc < 0) - throwf("dup() failed. errno=%d (%s)", errno, strerror(errno)); - else { - this->fd = dupRc; - fcntl(this->fd, F_SETFL, O_NONBLOCK); // Make socket nonblocking - } -#endif -} - - - -socketx::~socketx() { - - if (!this->fdIsBorrowed) { -#if MSVCRT - ::closesocket(SOCKET(this->fd)); -#else - close(this->fd); -#endif - } -} - - - -void -socketx::waitForReadable() const { - /* Return when there is something to read from the socket - (an EOF indication counts as something to read). Also - return if there is a signal (handled, of course). Rarely, - it is OK to return when there isn't anything to read. - */ -#if MSVCRT - // poll() is not available; settle for select(). - // Starting in Windows Vista, there is WSApoll() - fd_set rd_set; - FD_ZERO(&rd_set); - FD_SET(this->fd, &rd_set); - - select(this->fd + 1, &rd_set, 0, 0, 0); -#else - // poll() beats select() because higher file descriptor numbers - // work. - struct pollfd pollfds[1]; - - pollfds[0].fd = this->fd; - pollfds[0].events = POLLIN; - - poll(pollfds, ARRAY_SIZE(pollfds), -1); -#endif -} - - - -void -socketx::waitForWritable() const { - /* Return when socket is able to be written to. */ -#if MSVCRT - fd_set wr_set; - FD_ZERO(&wr_set); - FD_SET(this->fd, &wr_set); - - select(this->fd + 1, 0, &wr_set, 0, 0); -#else - struct pollfd pollfds[1]; - - pollfds[0].fd = this->fd; - pollfds[0].events = POLLOUT; - - poll(pollfds, ARRAY_SIZE(pollfds), -1); -#endif -} - - - -static bool -wouldBlock() { -/*---------------------------------------------------------------------------- - The most recently executed system socket function, which we assume failed, - failed because the situation was such that it wanted to block, but the - socket had the nonblocking option. ------------------------------------------------------------------------------*/ -#if MSVCRT - return (WSAGetLastError() == WSAEWOULDBLOCK || - WSAGetLastError() == WSAEINPROGRESS); -#else - /* EWOULDBLOCK and EAGAIN are normally synonyms, but POSIX allows them - to be separate and allows the OS to return whichever one it wants - for the "would block" condition. - */ - return (errno == EWOULDBLOCK || errno == EAGAIN); -#endif -} - - - -static bool -lastErrorIsBrokenConn() { -/*---------------------------------------------------------------------------- - The last system call failure in this process, assuming the system call was - to read or write a steram socket, indicates the problem was that the - connection broke, e.g. because a network cable was cut, the peer powered - off, or the peer just got tired of talking to us and closed down the - connection. - - The underlying signficance of this distinction is that when a connection - has broken, the caller might reasonably respond by trying to establish a - new connection, and possibly doing so with a different network path or a - different peer. ------------------------------------------------------------------------------*/ - bool retval; - -#if MSVCRT - // We don't know how to determine this on Windows, so we just punt - retval = false; -#else - switch (errno) { - // Some of these are probably not defined on some systems; we will - // need some build system magic to deal with that as error reports - // come in. - case EPIPE: - case ETIMEDOUT: - case ECONNRESET: - case ENOTCONN: - case ESHUTDOWN: - retval = true; - break; - default: - retval = false; - } - -#endif - - return retval; -} - - - -static string const -lastErrorDesc() { -/*---------------------------------------------------------------------------- - A description suitable for an error message of why the most recent - failed system socket function failed. ------------------------------------------------------------------------------*/ - ostringstream msg; -#if MSVCRT - int const lastError = WSAGetLastError(); - msg << "winsock error code " << lastError << " " - << "(" << strerror(lastError) << ")"; -#else - msg << "errno = " << errno << ", (" << strerror(errno) << ")"; -#endif - return msg.str(); -} - - - - -void -socketx::read(unsigned char * const buffer, - size_t const bufferSize, - bool * const wouldblockP, - size_t * const bytesReadP) const { -/*---------------------------------------------------------------------------- - Put any bytes that are in the OS buffer waiting to be read in 'buffer', - up to 'bufferSize'. - - Return *wouldblockP == true iff the buffer is empty now, but more could - arrive later. - - Return as *bytesReadP the number of bytes put into 'buffer'. - - Throw a BrokenConnectionEx exception if the connection has been broken. ------------------------------------------------------------------------------*/ - int rc; - - // We've seen a Windows library whose recv() expects a char * buffer - // (cf POSIX void *), so we cast. - - rc = recv(this->fd, (char *)buffer, bufferSize, 0); - - if (rc < 0) { - if (wouldBlock()) { - *wouldblockP = true; - *bytesReadP = 0; - } else if (lastErrorIsBrokenConn()) - throw BrokenConnectionEx(); - else - throwf("read() of socket failed with %s", lastErrorDesc().c_str()); - } else { - *wouldblockP = false; - *bytesReadP = rc; - } -} - - - -static void -writeFd(int const fd, - const unsigned char * const data, - size_t const size, - size_t * const bytesWrittenP) { -/*---------------------------------------------------------------------------- - Write as much of the 'size' bytes at 'data' to socket 'fd' as can be - written immediately (i.e. into the OS buffer). - - Return as *bytesWrittenP the number of bytes written. - - Throw a BrokenConnectionEx exception if the connection has been broken. ------------------------------------------------------------------------------*/ - size_t totalBytesWritten; - bool full; // File image is "full" for now - won't take any more data - - full = false; - totalBytesWritten = 0; - - while (totalBytesWritten < size && !full) { - int rc; - - rc = send(fd, (char*)&data[totalBytesWritten], - size - totalBytesWritten, 0); - - if (rc < 0) { - if (wouldBlock()) - full = true; - else { - if (lastErrorIsBrokenConn()) - throw BrokenConnectionEx(); - else - throwf("write() of socket failed with %s", - lastErrorDesc().c_str()); - } - } else if (rc == 0) - throwf("Zero byte short write."); - else { - size_t const bytesWritten(rc); - totalBytesWritten += bytesWritten; - } - } - *bytesWrittenP = totalBytesWritten; -} - - - -void -socketx::writeWait(const unsigned char * const data, - size_t const size) const { -/*---------------------------------------------------------------------------- - Write the 'size' bytes at 'data' to the socket. Wait as long - as it takes for the file image to be able to take all the data. - - Throw a BrokenConnectionEx exception if the connection has been broken. ------------------------------------------------------------------------------*/ - size_t totalBytesWritten; - - // We do the first one blind because it will probably just work - // and we don't want to waste the poll() call and buffer arithmetic. - - writeFd(this->fd, data, size, &totalBytesWritten); - - while (totalBytesWritten < size) { - this->waitForWritable(); - - size_t bytesWritten; - - writeFd(this->fd, &data[totalBytesWritten], size - totalBytesWritten, - &bytesWritten); - - totalBytesWritten += bytesWritten; - } -} - - - -namespace xmlrpc_c { - - -packet::packet() : - bytes(NULL), length(0), allocSize(0) {} - - - -void -packet::initialize(const unsigned char * const data, - size_t const dataLength) { - - this->bytes = reinterpret_cast(malloc(dataLength)); - - if (this->bytes == NULL) - throwf("Can't get storage for a %u-byte packet", (unsigned)dataLength); - - this->allocSize = dataLength; - - memcpy(this->bytes, data, dataLength); - - this->length = dataLength; -} - - - -packet::packet(const unsigned char * const data, - size_t const dataLength) { - - this->initialize(data, dataLength); -} - - - -packet::packet(const char * const data, - size_t const dataLength) { - - this->initialize(reinterpret_cast(data), - dataLength); -} - - - -packet::~packet() { - - if (this->bytes) - free(bytes); -} - - - -void -packet::addData(const unsigned char * const data, - size_t const dataLength) { -/*---------------------------------------------------------------------------- - Add the 'length' bytes at 'data' to the packet. - - We allocate whatever additional memory is needed to fit the new - data in. ------------------------------------------------------------------------------*/ - size_t const neededSize(this->length + dataLength); - - if (this->allocSize < neededSize) - this->bytes = reinterpret_cast( - realloc(this->bytes, neededSize)); - - if (this->bytes == NULL) - throwf("Can't get storage for a %u-byte packet", (unsigned)neededSize); - - memcpy(this->bytes + this->length, data, dataLength); - - this->length += dataLength; -} - - - -packetPtr::packetPtr() { - // Base class constructor will construct pointer that points to nothing -} - - - -packetPtr::packetPtr(packet * const packetP) : autoObjectPtr(packetP) {} - - - -packet * -packetPtr::operator->() const { - - girmem::autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -class packetSocket_impl { - -public: - packetSocket_impl(int const sockFd); - - void - writeWait(packetPtr const& packetP) const; - - void - read(bool * const eofP, - bool * const gotPacketP, - packetPtr * const packetPP); - - void - readWait(volatile const int * const interruptP, - bool * const eofP, - bool * const gotPacketP, - packetPtr * const packetPP); - -private: - socketx sock; - // The kernel stream socket we use. - bool const mustTrace; - // We must trace our execution to Standard Error - bool eof; - // The packet socket is at end-of-file for reads. - // 'readBuffer' is empty and there won't be any more data to fill - // it because the underlying stream socket is closed. - std::queue readBuffer; - packetPtr packetAccumP; - // The receive packet we're currently accumulating; it will join - // 'readBuffer' when we've received the whole packet (and we've - // seen the END control word so we know we've received it all). - // If we're not currently accumulating a packet (haven't seen a - // PKT control word), this points to nothing. - bool inEscapeSeq; - // In our trek through the data read from the underlying stream - // socket, we are after an ESC character and before the end of the - // escape sequence. 'escAccum' shows what of the escape sequence - // we've seen so far. - bool inPacket; - // We're now receiving packet data from the underlying stream - // socket. We've seen a complete PKT control word, but have not - // seen a complete END control word since. - struct { - unsigned char bytes[3]; - size_t len; - } escAccum; - - void - takeSomeEscapeSeq(const unsigned char * const buffer, - size_t const length, - size_t * const bytesTakenP); - - void - takeSomePacket(const unsigned char * const buffer, - size_t const length, - size_t * const bytesTakenP); - - void - verifyNothingAccumulated(); - - void - processBytesRead(const unsigned char * const buffer, - size_t const bytesRead); - - void - readFromFile(); -}; - - - -packetSocket_impl::packetSocket_impl(int const sockFd) : - sock(sockFd), - mustTrace(getenv("XMLRPC_TRACE_PACKETSOCKET") != NULL) { - - this->inEscapeSeq = false; - this->inPacket = false; - this->escAccum.len = 0; - this->eof = false; - - if (this->mustTrace) - fprintf(stderr, "Tracing Xmlrpc-c packet socket\n"); -} - - - -/*---------------------------------------------------------------------------- - To complete the job, we should provide writing services analogous - to the reading services. That means a no-wait write method and - the ability to interrupt with a signal without corrupting the write - stream. - - We're a little to lazy to do that now, since we don't need it yet, - but here's a design for that: - - The packetSocket has a send queue of packets called the write - buffer. It stores packetPtr pointers to packets created by the - user. - - packetSocket::write() adds a packet to the write buffer, then calls - packetSocket::writeToFile(). If you give it a null packetPtr, - it just calls writeToFile(). - - packetSocket::writeToFile() writes from the write buffer to the - socket whatever the socket will take immediately. It writes the - start sequence, writes the packet data, then writes the end - sequence. The packetSocket keeps track of where it is in the - process of writing the current send packet (including start end - end sequences) it is. - - packetSocket::write() returns a "flushed" flag indicating that there - is nothing left in the write buffer. - - packetSocket::writeWait() just calls packetSocket::write(), then - packetSocket::flush() in a poll() loop. ------------------------------------------------------------------------------*/ - - -static void -traceWrite(const unsigned char * const data, - size_t const size) { - - fprintf(stderr, "Sending %u-byte packet\n", (unsigned) size); - - if (size > 0) { - fprintf(stderr, "Data: "); - for (unsigned int i = 0; i < size; ++i) - fprintf(stderr, "%02x", data[i]); - - fprintf(stderr, "\n"); - } -} - - - -static const unsigned char * -escapePos(const unsigned char * const start, - const unsigned char * const end) { -/*---------------------------------------------------------------------------- - Return a pointer to the next escape character at or after 'start', but - before 'end'. If there is none, return 'end'. ------------------------------------------------------------------------------*/ - const unsigned char * cursor; - - for (cursor = start; cursor < end; ++cursor) { - if (*cursor == ESC) - break; - } - return cursor; -} - - - -void -packetSocket_impl::writeWait(packetPtr const& packetP) const { -/*---------------------------------------------------------------------------- - Write the packet to the socket, waiting for the recipient to take it as - necessary. - - Throw a BrokenConnectionEx exception if we can't send because of a broken - connection. ------------------------------------------------------------------------------*/ - const unsigned char * const packetStart( - reinterpret_cast(ESC_STR "PKT")); - const unsigned char * const packetEnd( - reinterpret_cast(ESC_STR "END")); - const unsigned char * const escapeChar( - reinterpret_cast(ESC_STR "ESC")); - - if (this->mustTrace) - traceWrite(packetP->getBytes(), packetP->getLength()); - - - this->sock.writeWait(packetStart, 4); - - const unsigned char * const end( - packetP->getBytes() + packetP->getLength()); - - const unsigned char * cursor; - - for (cursor = packetP->getBytes(); cursor < end; ) { - // Send up to the next escape character in the packet (or end of - // packet). - - const unsigned char * const nextEscapePos(escapePos(cursor, end)); - - this->sock.writeWait(cursor, nextEscapePos - cursor); - - cursor = nextEscapePos; - - if (cursor == end) { - // We didn't find an escape character; we sent everything - } else { - // We stopped at an escape character. Send an ESC control word. - // for that. - this->sock.writeWait(escapeChar, 4); - - cursor += 1; - } - } - this->sock.writeWait(packetEnd, 4); -} - - - -static void -traceReceivedPacket(const unsigned char * const data, - size_t const size) { - - fprintf(stderr, "%u-byte packet received\n", (unsigned) size); - - if (size > 0) { - fprintf(stderr, "Data: "); - for (unsigned int i = 0; i < size; ++i) - fprintf(stderr, "%02x", data[i]); - - fprintf(stderr, "\n"); - } -} - - - -void // private -packetSocket_impl::takeSomeEscapeSeq(const unsigned char * const buffer, - size_t const length, - size_t * const bytesTakenP) { -/*---------------------------------------------------------------------------- - Take and process some bytes from the incoming stream 'buffer', - which contains 'length' bytes, assuming they are within an escape - sequence. ------------------------------------------------------------------------------*/ - size_t bytesTaken; - - bytesTaken = 0; - - while (this->escAccum.len < 3 && bytesTaken < length) - this->escAccum.bytes[this->escAccum.len++] = buffer[bytesTaken++]; - - assert(this->escAccum.len <= 3); - - if (this->escAccum.len == 3) { - if (0) { - } else if (xmlrpc_memeq(this->escAccum.bytes, "NOP", 3)) { - // Nothing to do - } else if (xmlrpc_memeq(this->escAccum.bytes, "PKT", 3)) { - this->packetAccumP = packetPtr(new packet); - this->inPacket = true; - } else if (xmlrpc_memeq(this->escAccum.bytes, "END", 3)) { - if (this->inPacket) { - if (this->mustTrace) - traceReceivedPacket(this->packetAccumP->getBytes(), - this->packetAccumP->getLength()); - this->readBuffer.push(this->packetAccumP); - this->inPacket = false; - this->packetAccumP = packetPtr(); - } else - throwf("END control word received without preceding PKT"); - } else if (xmlrpc_memeq(this->escAccum.bytes, "ESC", 3)) { - if (this->inPacket) - this->packetAccumP->addData((const unsigned char *)ESC_STR, 1); - else - throwf("ESC control word received outside of a packet"); - } else - throwf("Invalid escape sequence 0x%02x%02x%02x read from " - "stream socket under packet socket", - this->escAccum.bytes[0], - this->escAccum.bytes[1], - this->escAccum.bytes[2]); - - this->inEscapeSeq = false; - this->escAccum.len = 0; - } - *bytesTakenP = bytesTaken; -} - - - -void // private -packetSocket_impl::takeSomePacket(const unsigned char * const buffer, - size_t const length, - size_t * const bytesTakenP) { -/*---------------------------------------------------------------------------- - Add to the object's packet accumulator the data in 'buffer' (of which there - is 'length' bytes) up to the next escape sequence, or the whole buffer if - there isn't an escape sequence. - - Return as *bytesTakenP the number of bytes we added to the accumulator. ------------------------------------------------------------------------------*/ - assert(!this->inEscapeSeq); - - const unsigned char * const escPos( - (const unsigned char *)memchr(buffer, ESC, length)); - - if (escPos) { - size_t const escOffset(escPos - &buffer[0]); - // move everything before the escape sequence into the - // packet accumulator. - this->packetAccumP->addData(buffer, escOffset); - - // Caller can pick up from here; we don't know nothin' 'bout - // no escape sequences. - - *bytesTakenP = escOffset; - } else { - // No complete packet yet and no substitution to do; - // just throw the whole thing into the accumulator. - this->packetAccumP->addData(buffer, length); - *bytesTakenP = length; - } -} - - - -void // private -packetSocket_impl::verifyNothingAccumulated() { -/*---------------------------------------------------------------------------- - Throw an error if there is a partial packet accumulated. ------------------------------------------------------------------------------*/ - if (this->inEscapeSeq) - throwf("Streams socket closed in the middle of an " - "escape sequence"); - - if (this->inPacket) - throwf("Stream socket closed in the middle of a packet " - "(%u bytes of packet received; no END marker to mark " - "end of packet)", (unsigned)this->packetAccumP->getLength()); -} - - - -void // private -packetSocket_impl::processBytesRead(const unsigned char * const buffer, - size_t const bytesRead) { - - unsigned int cursor; // Cursor into buffer[] - cursor = 0; - while (cursor < bytesRead) { - size_t bytesTaken; - - if (this->inEscapeSeq) - this->takeSomeEscapeSeq(&buffer[cursor], - bytesRead - cursor, - &bytesTaken); - else if (buffer[cursor] == ESC) { - this->inEscapeSeq = true; - bytesTaken = 1; - } else if (this->inPacket) - this->takeSomePacket(&buffer[cursor], - bytesRead - cursor, - &bytesTaken); - else - throwf("Byte 0x%02x is not in a packet or escape sequence. " - "Sender is probably not using packet socket protocol", - buffer[cursor]); - - cursor += bytesTaken; - } -} - - - -static void -traceBytesRead(const unsigned char * const buffer, - size_t const bytesReadCt) { - - fprintf(stderr, "%u bytes read\n", (unsigned) bytesReadCt); - - fprintf(stderr, "Data: "); - - for (unsigned int i = 0; i < bytesReadCt; ++i) - fprintf(stderr, "%02x", buffer[i]); - - fprintf(stderr, "\n"); -} - - - -void //private -packetSocket_impl::readFromFile() { -/*---------------------------------------------------------------------------- - Read some data from the underlying stream socket. Read as much as is - available right now, up to 4K. Update *this to reflect the data read. - - E.g. if we read an entire packet, we add it to the packet buffer - (this->readBuffer). If we read the first part of a packet, we add - it to the packet accumulator (*this->packetAccumP). If we read the end - of a packet, we add the full packet to the packet buffer and empty - the packet accumulator. Etc. - - Throw a BrokenConnectionEx exception if we can't read because of a broken - connection. ------------------------------------------------------------------------------*/ - bool wouldblock; - - wouldblock = false; - - while (this->readBuffer.empty() && !this->eof && !wouldblock) { - unsigned char buffer[4096]; - size_t bytesRead; - - this->sock.read(buffer, sizeof(buffer), &wouldblock, &bytesRead); - - if (!wouldblock) { - if (bytesRead == 0) { - if (this->mustTrace) - fprintf(stderr, "EOF on read\n"); - this->eof = true; - this->verifyNothingAccumulated(); - } else { - if (this->mustTrace) - traceBytesRead(buffer, bytesRead); - this->processBytesRead(buffer, bytesRead); - } - } - } -} - - - -void -packetSocket_impl::read(bool * const eofP, - bool * const gotPacketP, - packetPtr * const packetPP) { -/*---------------------------------------------------------------------------- - Read one packet from the socket, through the internal packet buffer. - - If there is a packet immediately available, return it as *packetPP and - return *gotPacketP true. Otherwise, return *gotPacketP false. - - Iff the socket has no more data coming (it is shut down) and there - is no complete packet in the packet buffer, return *eofP true. - - This leaves one other possibility: there is no full packet immediately - available, but there may be in the future because the socket is still - alive. In that case, we return *eofP == false and *gotPacketP == false. - - Any packet we return belongs to caller; Caller must delete it. - - Throw a BrokenConnectionEx exception if we can't read because of a broken - connection. ------------------------------------------------------------------------------*/ - // Move any packets now waiting to be read in the underlying stream - // socket into our packet buffer (this->readBuffer). - - this->readFromFile(); - - if (this->readBuffer.empty()) { - *gotPacketP = false; - *eofP = this->eof; - } else { - *gotPacketP = true; - *eofP = false; - *packetPP = this->readBuffer.front(); - readBuffer.pop(); - } -} - - - -void -packetSocket_impl::readWait(volatile const int * const interruptP, - bool * const eofP, - bool * const gotPacketP, - packetPtr * const packetPP) { -/*---------------------------------------------------------------------------- - Read a packet from the packet socket. It may be already in the buffer. - If not, wait as long as it takes for one to arrive. - - But stop waiting and return without a packet when *interruptP is true (but - if we're in a system call, which we usually are, Caller will have to ensure - that call gets interrupted, e.g. by receiving a signal, so that we notice - *interruptP has changed). - - Also return without a packet if we reach EOF on the packet socket - (i.e. the other side disconnected). - - Return *gotPacketP true iff we return a packet. - - Return *eofP true iff we hit EOF. - - Throw a BrokenConnectionEx exception if we can't read because of a broken - connection. ------------------------------------------------------------------------------*/ - bool gotPacket; - bool eof; - - gotPacket = false; - eof = false; - - while (!gotPacket && !eof && !*interruptP) { - - this->sock.waitForReadable(); - this->read(&eof, &gotPacket, packetPP); - } - - *gotPacketP = gotPacket; - *eofP = eof; -} - - - -packetSocket::packetSocket(int const sockFd) { - - this->implP = new packetSocket_impl(sockFd); -} - - - -packetSocket::~packetSocket() { - - delete(this->implP); -} - - - -void -packetSocket::writeWait(packetPtr const& packetP) const { - - try { - implP->writeWait(packetP); - } catch (BrokenConnectionEx) { - throwf("Recipient hung up or connection broke"); - } -} - - - -void -packetSocket::writeWait(packetPtr const& packetP, - bool * const brokenConnP) const { - - try { - implP->writeWait(packetP); - *brokenConnP = false; - } catch (BrokenConnectionEx) { - *brokenConnP = true; - } -} - - - -void -packetSocket::read(bool * const eofP, - bool * const gotPacketP, - packetPtr * const packetPP) { - - try { - this->implP->read(eofP, gotPacketP, packetPP); - } catch (BrokenConnectionEx) { - *gotPacketP = false; - *eofP = true; - } -} - - - -void -packetSocket::readWait(volatile const int * const interruptP, - bool * const eofP, - bool * const gotPacketP, - packetPtr * const packetPP) { - - try { - this->implP->readWait(interruptP, eofP, gotPacketP, packetPP); - } catch (BrokenConnectionEx) { - *gotPacketP = false; - *eofP = true; - } -} - - - -void -packetSocket::readWait(volatile const int * const interruptP, - bool * const eofP, - packetPtr * const packetPP) { - - try { - bool gotPacket; - - this->implP->readWait(interruptP, eofP, &gotPacket, packetPP); - - if (!gotPacket && !*eofP) - throwf("Packet read was interrupted"); - } catch (BrokenConnectionEx) { - *eofP = true; - } -} - - - -void -packetSocket::readWait(bool * const eofP, - packetPtr * const packetPP) { - - int const interrupt(0); // Never interrupt - - this->readWait(&interrupt, eofP, packetPP); -} - - - -} // namespace diff --git a/trunk/src/cpp/param_list.cpp b/trunk/src/cpp/param_list.cpp deleted file mode 100644 index 1f7ae41f0..000000000 --- a/trunk/src/cpp/param_list.cpp +++ /dev/null @@ -1,303 +0,0 @@ -#include -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base.hpp" - -using namespace std; -using namespace xmlrpc_c; - -namespace xmlrpc_c { - - -paramList::paramList(unsigned int const paramCount) { - - this->paramVector.reserve(paramCount); -} - - - -paramList& -paramList::add(xmlrpc_c::value const param) { - - // Note: Before Xmlrpc-c 1.10, the return value was void. Old programs - // using this new add() won't notice the difference. New programs - // using this new add() against an old library will, since the old - // add() will not return anything. A new program that wants to get - // a link error instead of a crash in this case can use addx() instead. - - this->paramVector.push_back(param); - - return *this; -} - - - -paramList& -paramList::addx(xmlrpc_c::value const param) { - - // See add() for an explanation of why this exists. - - return this->add(param); -} - - - -unsigned int -paramList::size() const { - return this->paramVector.size(); -} - - - -xmlrpc_c::value -paramList::operator[](unsigned int const subscript) const { - - if (subscript >= this->paramVector.size()) - throw(girerr::error( - "Subscript of xmlrpc_c::paramList out of bounds")); - - return this->paramVector[subscript]; -} - - - -int -paramList::getInt(unsigned int const paramNumber, - int const minimum, - int const maximum) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - if (this->paramVector[paramNumber].type() != value::TYPE_INT) - throw(fault("Parameter that is supposed to be integer is not", - fault::CODE_TYPE)); - - int const intvalue(static_cast( - value_int(this->paramVector[paramNumber]))); - - if (intvalue < minimum) - throw(fault("Integer parameter too low", fault::CODE_TYPE)); - - if (intvalue > maximum) - throw(fault("Integer parameter too high", fault::CODE_TYPE)); - - return intvalue; -} - - - -bool -paramList::getBoolean(unsigned int const paramNumber) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - if (this->paramVector[paramNumber].type() != value::TYPE_BOOLEAN) - throw(fault("Parameter that is supposed to be boolean is not", - fault::CODE_TYPE)); - - return static_cast(value_boolean(this->paramVector[paramNumber])); -} - - - -double -paramList::getDouble(unsigned int const paramNumber, - double const minimum, - double const maximum) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - if (this->paramVector[paramNumber].type() != value::TYPE_DOUBLE) - throw(fault("Parameter that is supposed to be floating point number " - "is not", - fault::CODE_TYPE)); - - double const doublevalue(static_cast( - value_double(this->paramVector[paramNumber]))); - - if (doublevalue < minimum) - throw(fault("Floating point number parameter too low", - fault::CODE_TYPE)); - - if (doublevalue > maximum) - throw(fault("Floating point number parameter too high", - fault::CODE_TYPE)); - - return doublevalue; -} - - - -time_t -paramList::getDatetime_sec( - unsigned int const paramNumber, - paramList::timeConstraint const constraint) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - const xmlrpc_c::value * const paramP(&this->paramVector[paramNumber]); - - if (paramP->type() != value::TYPE_DATETIME) - throw(fault("Parameter that is supposed to be a datetime is not", - fault::CODE_TYPE)); - - time_t const timeValue(static_cast(value_datetime(*paramP))); - time_t const now(time(NULL)); - - switch (constraint) { - case TC_ANY: - /* He'll take anything; no problem */ - break; - case TC_NO_FUTURE: - if (timeValue > now) - throw(fault("Datetime parameter that is not supposed to be in " - "the future is.", fault::CODE_TYPE)); - break; - case TC_NO_PAST: - if (timeValue < now) - throw(fault("Datetime parameter that is not supposed to be in " - "the past is.", fault::CODE_TYPE)); - break; - } - - return timeValue; -} - - - -string -paramList::getString(unsigned int const paramNumber) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - if (this->paramVector[paramNumber].type() != value::TYPE_STRING) - throw(fault("Parameter that is supposed to be a string is not", - fault::CODE_TYPE)); - - return static_cast(value_string(this->paramVector[paramNumber])); -} - - - -std::vector -paramList::getBytestring(unsigned int const paramNumber) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - const xmlrpc_c::value * const paramP(&this->paramVector[paramNumber]); - - if (paramP->type() != value::TYPE_BYTESTRING) - throw(fault("Parameter that is supposed to be a byte string is not", - fault::CODE_TYPE)); - - return value_bytestring(*paramP).vectorUcharValue(); -} - - -std::vector -paramList::getArray(unsigned int const paramNumber, - unsigned int const minSize, - unsigned int const maxSize) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - const xmlrpc_c::value * const paramP(&this->paramVector[paramNumber]); - - if (paramP->type() != value::TYPE_ARRAY) - throw(fault("Parameter that is supposed to be an array is not", - fault::CODE_TYPE)); - - xmlrpc_c::value_array const arrayValue(*paramP); - - if (arrayValue.size() < minSize) - throw(fault("Array parameter has too few elements", - fault::CODE_TYPE)); - - if (arrayValue.size() > maxSize) - throw(fault("Array parameter has too many elements", - fault::CODE_TYPE)); - - return value_array(*paramP).vectorValueValue(); -} - - - -std::map -paramList::getStruct(unsigned int const paramNumber) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - const xmlrpc_c::value * const paramP(&this->paramVector[paramNumber]); - - if (paramP->type() != value::TYPE_STRUCT) - throw(fault("Parameter that is supposed to be a structure is not", - fault::CODE_TYPE)); - - return static_cast >( - value_struct(*paramP)); -} - - - -void -paramList::getNil(unsigned int const paramNumber) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - if (this->paramVector[paramNumber].type() != value::TYPE_NIL) - throw(fault("Parameter that is supposed to be nil is not", - fault::CODE_TYPE)); -} - - - -xmlrpc_int64 -paramList::getI8(unsigned int const paramNumber, - xmlrpc_int64 const minimum, - xmlrpc_int64 const maximum) const { - - if (paramNumber >= this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); - - if (this->paramVector[paramNumber].type() != value::TYPE_I8) - throw(fault("Parameter that is supposed to be 64-bit integer is not", - fault::CODE_TYPE)); - - long long const longlongvalue(static_cast( - value_i8(this->paramVector[paramNumber]))); - - if (longlongvalue < minimum) - throw(fault("64-bit integer parameter too low", fault::CODE_TYPE)); - - if (longlongvalue > maximum) - throw(fault("64-bit integer parameter too high", fault::CODE_TYPE)); - - return longlongvalue; -} - - - -void -paramList::verifyEnd(unsigned int const paramNumber) const { - - if (paramNumber < this->paramVector.size()) - throw(fault("Too many parameters", fault::CODE_TYPE)); - if (paramNumber > this->paramVector.size()) - throw(fault("Not enough parameters", fault::CODE_TYPE)); -} - -} // namespace diff --git a/trunk/src/cpp/pstream.cpp b/trunk/src/cpp/pstream.cpp deleted file mode 100644 index e15ac4c44..000000000 --- a/trunk/src/cpp/pstream.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/*============================================================================= - pstream -=============================================================================== - - Client XML transport for Xmlrpc-c based on a very simple byte - stream. - - The protocol we use is the "packet socket" protocol, which - is an Xmlrpc-c invention. It is an almost trivial representation of - a sequence of packets on a byte stream. - - A transport object talks to exactly one server over its lifetime. - - You can create a pstream transport from any file descriptor from which - you can read and write a bidirectional character stream. Typically, - it's a TCP socket. - - This transport is synchronous only. It does not provide a working - 'start' method. You have at most one outstanding RPC and wait for - it to complete. - - By Bryan Henderson 07.05.12. - - Contributed to the public domain by its author. -=============================================================================*/ - -#include - -using namespace std; - -#include "xmlrpc-c/girerr.hpp" -using girerr::throwf; -#include "xmlrpc-c/packetsocket.hpp" - -#include "xmlrpc-c/client_transport.hpp" - -typedef xmlrpc_c::clientXmlTransport_pstream::BrokenConnectionEx - BrokenConnectionEx; - -namespace xmlrpc_c { - -struct clientXmlTransport_pstream::constrOpt_impl { - - constrOpt_impl(); - - struct { - int fd; - bool useBrokenConnEx; - } value; - struct { - bool fd; - bool useBrokenConnEx; - } present; -}; - - - -clientXmlTransport_pstream::constrOpt_impl::constrOpt_impl() { - - this->present.fd = false; - this->present.useBrokenConnEx = false; -} - - - -#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ -clientXmlTransport_pstream::constrOpt & \ -clientXmlTransport_pstream::constrOpt::OPTION_NAME(TYPE const& arg) { \ - this->implP->value.OPTION_NAME = arg; \ - this->implP->present.OPTION_NAME = true; \ - return *this; \ -} - -DEFINE_OPTION_SETTER(fd, xmlrpc_socket); -DEFINE_OPTION_SETTER(useBrokenConnEx, bool); - -#undef DEFINE_OPTION_SETTER - - - -clientXmlTransport_pstream::constrOpt::constrOpt() { - - this->implP = new clientXmlTransport_pstream::constrOpt_impl(); -} - - - -clientXmlTransport_pstream::constrOpt::~constrOpt() { - - delete(this->implP); -} - - - -clientXmlTransport_pstream::constrOpt::constrOpt(constrOpt& arg) { - - this->implP = new clientXmlTransport_pstream::constrOpt_impl(*arg.implP); -} - - - -class clientXmlTransport_pstream_impl { - -public: - clientXmlTransport_pstream_impl( - clientXmlTransport_pstream::constrOpt_impl const& opt); - - ~clientXmlTransport_pstream_impl(); - - void - call(xmlrpc_c::carriageParm * const carriageParmP, - std::string const& callXml, - std::string * const responseXmlP); - -private: - packetSocket * packetSocketP; - - bool usingBrokenConnEx; - // We're throwing a Broken Connection object when something fails - // because the connection to the server is broken. When this is false, - // we throw an ordinary error when that happens. - - void - sendCall(std::string const& callXml); - - void - recvResp(std::string * const responseXmlP); -}; - - - -clientXmlTransport_pstream_impl::clientXmlTransport_pstream_impl( - clientXmlTransport_pstream::constrOpt_impl const& opt) { - - if (!opt.present.fd) - throwf("You must provide a 'fd' constructor option."); - - auto_ptr packetSocketAP; - - try { - auto_ptr p(new packetSocket(opt.value.fd)); - packetSocketAP = p; - } catch (exception const& e) { - throwf("Unable to create packet socket out of file descriptor %d. %s", - opt.value.fd, e.what()); - } - - if (opt.present.useBrokenConnEx) - this->usingBrokenConnEx = opt.value.useBrokenConnEx; - else - this->usingBrokenConnEx = false; - - this->packetSocketP = packetSocketAP.release(); -} - - - -clientXmlTransport_pstream::clientXmlTransport_pstream( - constrOpt const& optExt) : - - implP(new clientXmlTransport_pstream_impl(*optExt.implP)) -{} - - - -clientXmlTransport_pstream_impl::~clientXmlTransport_pstream_impl() { - - delete(this->packetSocketP); -} - - - -clientXmlTransport_pstream::~clientXmlTransport_pstream() { - - delete(this->implP); -} - - - -void // private -clientXmlTransport_pstream_impl::sendCall(string const& callXml) { -/*---------------------------------------------------------------------------- - Send the text 'callXml' down the pipe as a packet which is the RPC call. ------------------------------------------------------------------------------*/ - packetPtr const callPacketP(new packet(callXml.c_str(), callXml.length())); - - try { - bool brokenConn; - - this->packetSocketP->writeWait(callPacketP, &brokenConn); - - if (brokenConn) { - if (this->usingBrokenConnEx) - throw BrokenConnectionEx(); - else - throwf("Server hung up or connection broke"); - } - } catch (exception const& e) { - throwf("Failed to write the call to the packet socket. %s", e.what()); - } -} - - - -void -clientXmlTransport_pstream_impl::recvResp(string * const responseXmlP) { -/*---------------------------------------------------------------------------- - Receive a packet which is the RPC response and return its contents - as the text *responseXmlP. ------------------------------------------------------------------------------*/ - packetPtr responsePacketP; - - try { - bool eof; - this->packetSocketP->readWait(&eof, &responsePacketP); - - if (eof) { - if (this->usingBrokenConnEx) - throw BrokenConnectionEx(); - else - throwf("The other end closed the socket before sending " - "the response."); - } - } catch (exception const& e) { - throwf("We sent the call, but couldn't get the response. %s", - e.what()); - } - *responseXmlP = - string(reinterpret_cast(responsePacketP->getBytes()), - responsePacketP->getLength()); -} - - - -void -clientXmlTransport_pstream_impl::call( - carriageParm * const carriageParmP, - string const& callXml, - string * const responseXmlP) { - - carriageParm_pstream * const carriageParmPstreamP( - dynamic_cast(carriageParmP)); - - if (carriageParmPstreamP == NULL) - throwf("Pstream client XML transport called with carriage " - "parameter object not of class carriageParm_pstream"); - - this->sendCall(callXml); - - this->recvResp(responseXmlP); -} - - - -void -clientXmlTransport_pstream::call( - carriageParm * const carriageParmP, - string const& callXml, - string * const responseXmlP) { - - this->implP->call(carriageParmP, callXml, responseXmlP); -} - -} // namespace diff --git a/trunk/src/cpp/registry.cpp b/trunk/src/cpp/registry.cpp deleted file mode 100644 index 07f795a02..000000000 --- a/trunk/src/cpp/registry.cpp +++ /dev/null @@ -1,593 +0,0 @@ -#include -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::throwf; -#include "xmlrpc-c/girmem.hpp" -using girmem::autoObject; -using girmem::autoObjectPtr; -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/env_wrap.hpp" - -#include "xmlrpc-c/registry.hpp" - -using namespace std; -using namespace xmlrpc_c; - - -callInfo::callInfo() { - - // Even though this is the builtin default default constructor, we need - // this because some compilers won't use the builtin default to construct - // a constant (e.g. "callInfo const junk;"); I don't know why. -} - - -callInfo::~callInfo() {} - - -namespace { - -void -throwIfError(env_wrap const& env) { - - if (env.env_c.fault_occurred) - throw(girerr::error(env.env_c.fault_string)); -} - - -} // namespace - -namespace xmlrpc_c { - - -method::method() : - _signature("?"), - _help("No help is available for this method") - {}; - - - -method::~method() {} - - - -methodPtr::methodPtr(method * const methodP) { - this->point(methodP); -} - - - -method * -methodPtr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -method2::method2() {} - - - -method2::~method2() {} - - -void -method2::execute(xmlrpc_c::paramList const& paramList, - xmlrpc_c::value * const resultP) { - - callInfo const nullCallInfo; - - execute(paramList, &nullCallInfo, resultP); -} - - - -defaultMethod::~defaultMethod() {} - - - -defaultMethodPtr::defaultMethodPtr() {} - - -defaultMethodPtr::defaultMethodPtr(defaultMethod * const methodP) { - this->point(methodP); -} - - - -defaultMethod * -defaultMethodPtr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -defaultMethod * -defaultMethodPtr::get() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -struct registry_impl { - - xmlrpc_registry * c_registryP; - // Pointer to the C registry object we use to implement this - // object. - - std::list managedMethodList; - // This is a list of pointers to method objects whose existence is - // managed by methodPtr shared pointers (so that the reference to - // the object by the registry keeps it in existence and if the - // registry's reference is the last reference to a method object, - // the method object disappears when the registry does). - // - // The real registry is the C registry object, so the list of methods - // in that object, not this member, is the operative list of - // registered methods. - // - // The registry may refer to method objects that are not managed by - // methodPtrs (it's the user's choice), so this member is not - // necessarily a complete list. - - xmlrpc_c::defaultMethodPtr defaultMethodP; - // Analogous to 'managedMethodList', but for the default method object. - - registry_impl(); - - ~registry_impl(); -}; - - - -registry_impl::registry_impl() { - - env_wrap env; - - this->c_registryP = xmlrpc_registry_new(&env.env_c); - - throwIfError(env); -} - - - -registry_impl::~registry_impl() { - - xmlrpc_registry_free(this->c_registryP); -} - - -registry::registry() { - - this->implP = new registry_impl(); -} - - - -registry::~registry(void) { - - delete(this->implP); -} - - - -registryPtr::registryPtr() {} - - - -registryPtr::registryPtr(registry * const registryP) { - this->point(registryP); -} - - - -registry * -registryPtr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -registry * -registryPtr::get() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -static xmlrpc_c::paramList -pListFromXmlrpcArray(xmlrpc_value * const arrayP) { -/*---------------------------------------------------------------------------- - Convert an XML-RPC array in C (not C++) form to a parameter list object - that can be passed to a method execute method. - - This is glue code to allow us to hook up C++ Xmlrpc-c code to - C Xmlrpc-c code. ------------------------------------------------------------------------------*/ - env_wrap env; - - XMLRPC_ASSERT_ARRAY_OK(arrayP); - - unsigned int const arraySize = xmlrpc_array_size(&env.env_c, arrayP); - - assert(!env.env_c.fault_occurred); - - xmlrpc_c::paramList paramList(arraySize); - - for (unsigned int i = 0; i < arraySize; ++i) { - xmlrpc_value * arrayItemP; - - xmlrpc_array_read_item(&env.env_c, arrayP, i, &arrayItemP); - assert(!env.env_c.fault_occurred); - - paramList.add(xmlrpc_c::value(arrayItemP)); - - xmlrpc_DECREF(arrayItemP); - } - return paramList; -} - - - -static xmlrpc_value * -c_executeMethod(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const methodPtr, - void * const callInfoPtr) { -/*---------------------------------------------------------------------------- - This is a function designed to be called via a C registry to - execute an XML-RPC method, but use a C++ method object to do the - work. You register this function as the method function and a - pointer to the C++ method object as the method data in the C - registry. - - If we had a pure C++ registry, this would be unnecessary. - - Since we can't throw an error back to the C code, we catch anything - the XML-RPC method's execute() method throws, and any error we - encounter in processing the result it returns, and turn it into an - XML-RPC method failure. This will cause a leak if the execute() - method actually created a result, since it will not get destroyed. - - This function is of type 'xmlrpc_method2'. ------------------------------------------------------------------------------*/ - method * const methodP(static_cast(methodPtr)); - paramList const paramList(pListFromXmlrpcArray(paramArrayP)); - callInfo * const callInfoP(static_cast(callInfoPtr)); - - xmlrpc_value * retval; - retval = NULL; // silence used-before-set warning - - try { - value result; - - try { - method2 * const method2P(dynamic_cast(methodP)); - if (method2P) - method2P->execute(paramList, callInfoP, &result); - else - methodP->execute(paramList, &result); - } catch (xmlrpc_c::fault const& fault) { - xmlrpc_env_set_fault(envP, fault.getCode(), - fault.getDescription().c_str()); - } - if (!envP->fault_occurred) { - if (result.isInstantiated()) - retval = result.cValue(); - else - throwf("Xmlrpc-c user's xmlrpc_c::method object's " - "'execute method' failed to set the RPC result " - "value."); - } - } catch (exception const& e) { - xmlrpc_faultf(envP, "Unexpected error executing code for " - "particular method, detected by Xmlrpc-c " - "method registry code. Method did not " - "fail; rather, it did not complete at all. %s", - e.what()); - } catch (...) { - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, - "Unexpected error executing code for " - "particular method, detected by Xmlrpc-c " - "method registry code. Method did not " - "fail; rather, it did not complete at all."); - } - return retval; -} - - - -static xmlrpc_value * -c_executeDefaultMethod(xmlrpc_env * const envP, - const char * const , // host - const char * const methodName, - xmlrpc_value * const paramArrayP, - void * const methodPtr) { -/*---------------------------------------------------------------------------- - This is a function designed to be called via a C registry to - execute an XML-RPC method, but use a C++ method object to do the - work. You register this function as the default method function and a - pointer to the C++ default method object as the method data in the C - registry. - - If we had a pure C++ registry, this would be unnecessary. - - Since we can't throw an error back to the C code, we catch anything - the XML-RPC method's execute() method throws, and any error we - encounter in processing the result it returns, and turn it into an - XML-RPC method failure. This will cause a leak if the execute() - method actually created a result, since it will not get destroyed. ------------------------------------------------------------------------------*/ - defaultMethod * const methodP = - static_cast(methodPtr); - paramList const paramList(pListFromXmlrpcArray(paramArrayP)); - - xmlrpc_value * retval; - retval = NULL; // silence used-before-set warning - - try { - xmlrpc_c::value result; - - try { - methodP->execute(methodName, paramList, &result); - } catch (xmlrpc_c::fault const& fault) { - xmlrpc_env_set_fault(envP, fault.getCode(), - fault.getDescription().c_str()); - } - if (!envP->fault_occurred) { - if (result.isInstantiated()) - retval = result.cValue(); - else - throwf("Xmlrpc-c user's xmlrpc_c::defaultMethod object's " - "'execute method' failed to set the RPC result " - "value."); - } - } catch (exception const& e) { - xmlrpc_faultf(envP, "Unexpected error executing default " - "method code, detected by Xmlrpc-c " - "method registry code. Method did not " - "fail; rather, it did not complete at all. %s", - e.what()); - } catch (...) { - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, - "Unexpected error executing default " - "method code, detected by Xmlrpc-c " - "method registry code. Method did not " - "fail; rather, it did not complete at all."); - } - return retval; -} - - - -void -registry::addMethod(string const name, - method * const methodP) { -/*---------------------------------------------------------------------------- - Caller is responsible for ensuring *methodP exists as long as this - registry does. ------------------------------------------------------------------------------*/ - struct xmlrpc_method_info3 methodInfo; - env_wrap env; - - methodInfo.methodName = name.c_str(); - methodInfo.methodFunction = &c_executeMethod; - methodInfo.serverInfo = methodP; - methodInfo.stackSize = 0; - string const signatureString(methodP->signature()); - methodInfo.signatureString = signatureString.c_str(); - string const help(methodP->help()); - methodInfo.help = help.c_str(); - - xmlrpc_registry_add_method3(&env.env_c, this->implP->c_registryP, - &methodInfo); - - throwIfError(env); -} - - - -void -registry::addMethod(string const name, - methodPtr const methodP) { - - this->addMethod(name, dynamic_cast(methodP.get())); - - this->implP->managedMethodList.push_back(methodP); -} - - - -void -registry::setDefaultMethod(defaultMethod * const methodP) { -/*---------------------------------------------------------------------------- - Caller is responsible for ensuring *methodP exists as long as this - registry does. ------------------------------------------------------------------------------*/ - env_wrap env; - - xmlrpc_registry_set_default_method( - &env.env_c, this->implP->c_registryP, - &c_executeDefaultMethod, (void*) methodP); - - throwIfError(env); -} - - - -void -registry::setDefaultMethod(defaultMethodPtr const methodP) { - - this->setDefaultMethod(dynamic_cast(methodP.get())); - - this->implP->defaultMethodP = methodP; -} - - - -void -registry::disableIntrospection() { - - xmlrpc_registry_disable_introspection(this->implP->c_registryP); -} - - - -static xmlrpc_server_shutdown_fn shutdownServer; - -static void -shutdownServer(xmlrpc_env * const envP, - void * const context, - const char * const comment, - void * const callInfo) { - - registry::shutdown * const shutdownP( - static_cast(context)); - - assert(shutdownP != NULL); - - try { - shutdownP->doit(string(comment), callInfo); - } catch (exception const& e) { - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, e.what()); - } -} - - - -void -registry::setShutdown(const registry::shutdown * const shutdownP) { - - void * const context(const_cast(shutdownP)); - - xmlrpc_registry_set_shutdown(this->implP->c_registryP, - &shutdownServer, - context); -} - - - -void -registry::setDialect(xmlrpc_dialect const dialect) { - - env_wrap env; - - xmlrpc_registry_set_dialect(&env.env_c, this->implP->c_registryP, dialect); - - throwIfError(env); -} - - - -void -registry::processCall(string const& callXml, - const callInfo * const callInfoP, - string * const responseXmlP) const { -/*---------------------------------------------------------------------------- - Process an XML-RPC call whose XML is 'callXml'. - - Return the response XML as *responseXmlP. - - If we are unable to execute the call, we throw an error. But if - the call executes and the method merely fails in an XML-RPC sense, we - don't. In that case, *responseXmlP indicates the failure. ------------------------------------------------------------------------------*/ - env_wrap env; - xmlrpc_mem_block * response; - - // For the pure C++ version, this will have to parse 'callXml' - // into a method name and parameters, look up the method name in - // the registry, call the method's execute() method, then marshall - // the result into XML and return it as *responseXmlP. It will - // also have to execute system methods (e.g. introspection) - // itself. This will be more or less like what - // xmlrpc_registry_process_call() does. - - xmlrpc_registry_process_call2( - &env.env_c, this->implP->c_registryP, - callXml.c_str(), callXml.length(), - const_cast(callInfoP), - &response); - - throwIfError(env); - - *responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, response), - XMLRPC_MEMBLOCK_SIZE(char, response)); - - xmlrpc_mem_block_free(response); -} - - - -void -registry::processCall(string const& callXml, - string * const responseXmlP) const { -/*---------------------------------------------------------------------------- - Process an XML-RPC call whose XML is 'callXml'. - - Return the response XML as *responseXmlP. - - If we are unable to execute the call, we throw an error. But if - the call executes and the method merely fails in an XML-RPC sense, we - don't. In that case, *responseXmlP indicates the failure. ------------------------------------------------------------------------------*/ - env_wrap env; - xmlrpc_mem_block * output; - - // For the pure C++ version, this will have to parse 'callXml' - // into a method name and parameters, look up the method name in - // the registry, call the method's execute() method, then marshall - // the result into XML and return it as *responseXmlP. It will - // also have to execute system methods (e.g. introspection) - // itself. This will be more or less like what - // xmlrpc_registry_process_call() does. - - output = xmlrpc_registry_process_call( - &env.env_c, this->implP->c_registryP, NULL, - callXml.c_str(), callXml.length()); - - throwIfError(env); - - *responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, output), - XMLRPC_MEMBLOCK_SIZE(char, output)); - - xmlrpc_mem_block_free(output); -} - - - -#define PROCESS_CALL_STACK_SIZE 256 - // This is our liberal estimate of how much stack space - // registry::processCall() needs, not counting what - // the call the to C registry uses. - - - -size_t -registry::maxStackSize() const { - - return xmlrpc_registry_max_stackSize(this->implP->c_registryP) + - PROCESS_CALL_STACK_SIZE; -} - - - -} // namespace - - -registry::shutdown::~shutdown() {} diff --git a/trunk/src/cpp/server_abyss.cpp b/trunk/src/cpp/server_abyss.cpp deleted file mode 100644 index 2f70516de..000000000 --- a/trunk/src/cpp/server_abyss.cpp +++ /dev/null @@ -1,1064 +0,0 @@ -#include "xmlrpc_config.h" -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ -#include -#include -#include -#include -#include -#include -#if !MSVCRT -# include -#endif - -#include "assertx.hpp" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/abyss.h" -#include "xmlrpc-c/server_abyss.h" -#include "xmlrpc-c/registry.hpp" -#include "xmlrpc-c/env_wrap.hpp" - -#include "xmlrpc-c/server_abyss.hpp" - -using namespace std; -using namespace xmlrpc_c; - -namespace xmlrpc_c { - -namespace { - - -static void -sigterm(int const signalClass) { - - cerr << "Signal of Class " << signalClass << " received. Exiting" << endl; - - exit(1); -} - - - -static void -sigchld(int const ASSERT_ONLY_ARG(signalClass)) { -/*---------------------------------------------------------------------------- - This is a signal handler for a SIGCHLD signal (which informs us that - one of our child processes has terminated). - - The only child processes we have are those that belong to the Abyss - server (and then only if the Abyss server was configured to use - forking as a threading mechanism), so we respond by passing the - signal on to the Abyss server. And reaping the dead child. ------------------------------------------------------------------------------*/ -#ifndef _WIN32 - // Reap zombie children / report to Abyss until there aren't any more. - - bool zombiesExist; - bool error; - - assert(signalClass == SIGCHLD); - - zombiesExist = true; // initial assumption - error = false; // no error yet - while (zombiesExist && !error) { - int status; - pid_t const pid = waitpid((pid_t) -1, &status, WNOHANG); - - if (pid == 0) - zombiesExist = false; - else if (pid < 0) { - /* because of ptrace */ - if (errno == EINTR) { - // This is OK - it's a ptrace notification - } else - error = true; - } else - ServerHandleSigchld(pid); - } -#endif /* _WIN32 */ -} - - - -struct signalHandlers { -#ifndef WIN32 - struct sigaction term; - struct sigaction int_; - struct sigaction hup; - struct sigaction usr1; - struct sigaction pipe; - struct sigaction chld; -#else - int dummy; -#endif -}; - - - -void -setupSignalHandlers(struct signalHandlers * const oldHandlersP) { -#ifndef _WIN32 - struct sigaction mysigaction; - - sigemptyset(&mysigaction.sa_mask); - mysigaction.sa_flags = 0; - - /* These signals abort the program, with tracing */ - mysigaction.sa_handler = sigterm; - sigaction(SIGTERM, &mysigaction, &oldHandlersP->term); - sigaction(SIGINT, &mysigaction, &oldHandlersP->int_); - sigaction(SIGHUP, &mysigaction, &oldHandlersP->hup); - sigaction(SIGUSR1, &mysigaction, &oldHandlersP->usr1); - - /* This signal indicates connection closed in the middle */ - mysigaction.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &mysigaction, &oldHandlersP->pipe); - - /* This signal indicates a child process (request handler) has died */ - mysigaction.sa_handler = sigchld; - sigaction(SIGCHLD, &mysigaction, &oldHandlersP->chld); -#endif -} - - - -void -restoreSignalHandlers(struct signalHandlers const& oldHandlers) { - -#ifndef _WIN32 - sigaction(SIGCHLD, &oldHandlers.chld, NULL); - sigaction(SIGPIPE, &oldHandlers.pipe, NULL); - sigaction(SIGUSR1, &oldHandlers.usr1, NULL); - sigaction(SIGHUP, &oldHandlers.hup, NULL); - sigaction(SIGINT, &oldHandlers.int_, NULL); - sigaction(SIGTERM, &oldHandlers.term, NULL); -#endif -} - - - -// We need 'global' because methods of class serverAbyss call -// functions in the Abyss C library. By virtue of global's static -// storage class, the program loader will call its constructor and -// destructor and thus initialize and terminate the Abyss C library. - -class abyssGlobalState { -public: - abyssGlobalState() { - const char * error; - AbyssInit(&error); - if (error) { - string const e(error); - xmlrpc_strfree(error); - throwf("AbyssInit() failed. %s", e.c_str()); - } - } - ~abyssGlobalState() { - AbyssTerm(); - } -} const global; - -} // namespace - - - -callInfo_serverAbyss::callInfo_serverAbyss( - serverAbyss * const serverAbyssP, - TSession * const abyssSessionP) : - serverAbyssP(serverAbyssP), abyssSessionP(abyssSessionP) {} - - - -struct serverAbyss::constrOpt_impl { - - constrOpt_impl(); - - struct value { - xmlrpc_c::registryPtr registryPtr; - const xmlrpc_c::registry * registryP; - XMLRPC_SOCKET socketFd; - unsigned int portNumber; - unsigned int maxConn; - unsigned int maxConnBacklog; - size_t maxRpcMem; - unsigned int keepaliveTimeout; - unsigned int keepaliveMaxConn; - unsigned int timeout; - bool dontAdvertise; - std::string uriPath; - bool chunkResponse; - std::string allowOrigin; - unsigned int accessCtlMaxAge; - const struct sockaddr * sockAddrP; - socklen_t sockAddrLen; - std::string logFileName; - bool serverOwnsSignals; - bool expectSigchld; - } value; - struct { - bool registryPtr; - bool registryP; - bool socketFd; - bool portNumber; - bool maxConn; - bool maxConnBacklog; - bool maxRpcMem; - bool keepaliveTimeout; - bool keepaliveMaxConn; - bool timeout; - bool dontAdvertise; - bool uriPath; - bool chunkResponse; - bool allowOrigin; - bool accessCtlMaxAge; - bool sockAddrP; - bool sockAddrLen; - bool logFileName; - bool serverOwnsSignals; - bool expectSigchld; - } present; -}; - - - -serverAbyss::constrOpt_impl::constrOpt_impl() { - present.registryPtr = false; - present.registryP = false; - present.socketFd = false; - present.portNumber = false; - present.logFileName = false; - present.maxConn = false; - present.maxConnBacklog = false; - present.maxRpcMem = false; - present.keepaliveTimeout = false; - present.keepaliveMaxConn = false; - present.timeout = false; - present.dontAdvertise = false; - present.uriPath = false; - present.chunkResponse = false; - present.allowOrigin = false; - present.accessCtlMaxAge = false; - present.sockAddrP = false; - present.sockAddrLen = false; - present.serverOwnsSignals = false; - present.expectSigchld = false; - - // Set default values - value.dontAdvertise = false; - value.uriPath = string("/RPC2"); - value.chunkResponse = false; - value.serverOwnsSignals = true; - value.expectSigchld = false; -} - - - -#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ -serverAbyss::constrOpt & \ -serverAbyss::constrOpt::OPTION_NAME(TYPE const& arg) { \ - this->implP->value.OPTION_NAME = arg; \ - this->implP->present.OPTION_NAME = true; \ - return *this; \ -} - -DEFINE_OPTION_SETTER(registryPtr, xmlrpc_c::registryPtr); -DEFINE_OPTION_SETTER(registryP, const registry *); -DEFINE_OPTION_SETTER(socketFd, XMLRPC_SOCKET); -DEFINE_OPTION_SETTER(portNumber, unsigned int); -DEFINE_OPTION_SETTER(maxConn, unsigned int); -DEFINE_OPTION_SETTER(maxConnBacklog, unsigned int); -DEFINE_OPTION_SETTER(maxRpcMem, size_t); -DEFINE_OPTION_SETTER(keepaliveTimeout, unsigned int); -DEFINE_OPTION_SETTER(keepaliveMaxConn, unsigned int); -DEFINE_OPTION_SETTER(timeout, unsigned int); -DEFINE_OPTION_SETTER(dontAdvertise, bool); -DEFINE_OPTION_SETTER(uriPath, string); -DEFINE_OPTION_SETTER(chunkResponse, bool); -DEFINE_OPTION_SETTER(allowOrigin, string); -DEFINE_OPTION_SETTER(accessCtlMaxAge, unsigned int); -DEFINE_OPTION_SETTER(sockAddrP, const struct sockaddr *); -DEFINE_OPTION_SETTER(sockAddrLen, socklen_t); -DEFINE_OPTION_SETTER(logFileName, string); -DEFINE_OPTION_SETTER(serverOwnsSignals, bool); -DEFINE_OPTION_SETTER(expectSigchld, bool); - -#undef DEFINE_OPTION_SETTER - - -serverAbyss::constrOpt::constrOpt() { - - this->implP = new serverAbyss::constrOpt_impl(); -} - - - -serverAbyss::constrOpt::~constrOpt() { - - delete(this->implP); -} - - - -struct SockAddr { - - const struct sockaddr * const sockAddrP; - socklen_t const sockAddrLen; - - SockAddr(const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen) : - sockAddrP (sockAddrP), - sockAddrLen (sockAddrLen) - {} -}; - - - -struct serverAbyss_impl { - registryPtr regPtr; - // This just holds a reference to the registry so that it may - // get destroyed when the serverAbyss gets destroyed. If the - // creator of the serverAbyss is managing lifetime himself, - // this is a null pointer. 'registryP' is what you really use - // to access the registry. - - const registry * registryP; - - TServer cServer; - - TChanSwitch * chanSwitchP; - // Handle of the channel switch we created. Null if we didn't. - // When user wants us to accept connections, we create a channel - // switch and create a server based on it; otherwise, we don't. - - serverAbyss_impl(serverAbyss::constrOpt_impl const& opt, - serverAbyss * const serverAbyssP); - - ~serverAbyss_impl(); - - void - getListenName(struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP); - - void - run(); - - void - processCall(std::string const& call, - TSession * const abyssSessionP, - std::string * const responseP); - - serverAbyss * const serverAbyssP; - // The server for which we are the implementation. - - bool expectSigchld; - bool serverOwnsSignals; -}; - - - -static void -processXmlrpcCall(xmlrpc_env * const envP, - void * const arg, - const char * const callXml, - size_t const callXmlLen, - TSession * const abyssSessionP, - xmlrpc_mem_block ** const responseXmlPP) { -/*---------------------------------------------------------------------------- - This is an XML-RPC XML call processor, as called by the HTTP request - handler of the libxmlrpc_server_abyss C library. - - 'callXml'/'callXmlLen' is the XML text of a supposed XML-RPC call. - We execute the RPC and return the XML text of the XML-RPC response - as *responseXmlPP. - - 'arg' carries the information that tells us how to do that; e.g. - what XML-RPC methods are defined. ------------------------------------------------------------------------------*/ - serverAbyss_impl * const implP( - static_cast(arg)); - - try { - string const call(callXml, callXmlLen); - - string response; - - implP->processCall(call, abyssSessionP, &response); - - xmlrpc_mem_block * responseMbP; - - responseMbP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - - if (!envP->fault_occurred) { - XMLRPC_MEMBLOCK_APPEND(char, envP, responseMbP, - response.c_str(), response.length()); - - *responseXmlPP = responseMbP; - } - } catch (exception const& e) { - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, e.what()); - } -} - - - -static void -validateListenOptions(serverAbyss::constrOpt_impl const& opt) { - - if ((opt.present.portNumber ? 1 : 0) + - (opt.present.socketFd ? 1 : 0) + - (opt.present.sockAddrP ? 1 : 0) > 1) - throwf("You can specify at most one of portNumber, socketFd, " - "and sockAddrP options"); - - if (opt.present.sockAddrP && !opt.present.sockAddrLen) - throwf("You must specify the sockAddrLen option when you " - "specify sockAddrP"); - - if (!opt.present.sockAddrP && opt.present.sockAddrLen) - throwf("The sockAddrLen option does not make sense without " - "sockAddrP"); - - if (opt.present.portNumber) { - if (opt.value.portNumber > 0xffff) - throwf("Port number %u exceeds the maximum possible port number " - "(65535)", opt.value.portNumber); - } -} - - - -static void -createServerFromSwitch(TServer * const serverP, - TChanSwitch * const chanSwitchP) { - - const char * error; - - ServerCreateSwitch(serverP, chanSwitchP, &error); - - if (error) { - throwf("Abyss failed to create server. %s", error); - xmlrpc_strfree(error); - } -} - - - -static TChanSwitch * -newChanSwitchOsSocket(int const socketFd) { - - TChanSwitch * chanSwitchP; - const char * error; - -#ifdef WIN32 - ChanSwitchWinCreateWinsock(socketFd, &chanSwitchP, &error); -#else - ChanSwitchUnixCreateFd(socketFd, &chanSwitchP, &error); -#endif - - if (error) { - string const errorS(error); - xmlrpc_strfree(error); - - throwf("Abyss failed to create a channel switch from the " - "supplied listen socket. %s", errorS.c_str()); - } - return chanSwitchP; -} - - - -static void -chanSwitchCreateSockAddr(int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - TChanSwitch ** const chanSwitchPP) { - - const char * error; - -#ifdef WIN32 - ChanSwitchWinCreate2(protocolFamily, sockAddrP, sockAddrLen, - chanSwitchPP, &error); -#else - ChanSwitchUnixCreate2(protocolFamily, sockAddrP, sockAddrLen, - chanSwitchPP, &error); -#endif - if (error) { - string const errorS(error); - xmlrpc_strfree(error); - throwf("Unable to create Abyss channel switch from socket address. " - "%s", errorS.c_str()); - } -} - - - -static TChanSwitch * -newChanSwitchSockAddr(SockAddr const& sockAddr) { - - int protocolFamily; - - switch (sockAddr.sockAddrP->sa_family) { - case AF_INET: - protocolFamily = PF_INET; - break; - case AF_INET6: - protocolFamily = PF_INET6; - break; - default: - throwf("Unknown socket address family %d. " - "We know only AF_INET and AF_INET6.", - sockAddr.sockAddrP->sa_family); - } - - TChanSwitch * chanSwitchP; - - chanSwitchCreateSockAddr(protocolFamily, - sockAddr.sockAddrP, sockAddr.sockAddrLen, - &chanSwitchP); - - return chanSwitchP; -} - - - -static TChanSwitch * -newChanSwitchIpV4Port(unsigned int const portNumber) { - - struct sockaddr_in sockAddr; - - sockAddr.sin_family = AF_INET; - sockAddr.sin_port = htons(portNumber); - sockAddr.sin_addr.s_addr = INADDR_ANY; - - TChanSwitch * chanSwitchP; - - chanSwitchCreateSockAddr(PF_INET, (const struct sockaddr *)&sockAddr, - sizeof(sockAddr), - &chanSwitchP); - - return chanSwitchP; -} - - - -static void -createServerBare(bool const logFileNameGiven, - string const& logFileName, - bool const socketFdGiven, - int const socketFd, - bool const portNumberGiven, - unsigned int const portNumber, - bool const sockAddrPGiven, - SockAddr const& sockAddr, - TServer * const serverP, - TChanSwitch ** const chanSwitchPP) { - - const char * const serverName("XmlRpcServer"); - - if (socketFdGiven || sockAddrPGiven || portNumberGiven) { - - TChanSwitch * const chanSwitchP( - socketFdGiven ? - newChanSwitchOsSocket(socketFd) : - sockAddrPGiven ? - newChanSwitchSockAddr(sockAddr) : - portNumberGiven ? - newChanSwitchIpV4Port(portNumber) : - NULL); - - assert(chanSwitchP); - - try { - createServerFromSwitch(serverP, chanSwitchP); - - try { - ServerSetName(serverP, serverName); - - if (logFileNameGiven) - ServerSetLogFileName(serverP, logFileName.c_str()); - } catch (...) { - ServerFree(serverP); - throw; - } - } catch (...) { - ChanSwitchDestroy(chanSwitchP); - throw; - } - *chanSwitchPP = chanSwitchP; - } else { - const char * const logfileArg(logFileNameGiven ? - logFileName.c_str() : NULL); - - ServerCreateNoAccept(serverP, serverName, - DEFAULT_DOCS, logfileArg); - - *chanSwitchPP = NULL; - } -} - - - -static void -setAdditionalServerParms(TServer * const serverP, - serverAbyss::constrOpt_impl const& opt) { - - if (opt.present.maxConn) - ServerSetMaxConn(serverP, opt.value.maxConn); - if (opt.present.maxConnBacklog) - ServerSetMaxConnBacklog(serverP, opt.value.maxConnBacklog); - if (opt.present.maxRpcMem) - ServerSetMaxSessionMem(serverP, opt.value.maxRpcMem); - if (opt.present.keepaliveTimeout) - ServerSetKeepaliveTimeout(serverP, opt.value.keepaliveTimeout); - if (opt.present.keepaliveMaxConn) - ServerSetKeepaliveMaxConn(serverP, opt.value.keepaliveMaxConn); - if (opt.present.timeout) - ServerSetTimeout(serverP, opt.value.timeout); - ServerSetAdvertise(serverP, !opt.value.dontAdvertise); - if (opt.value.expectSigchld) - ServerUseSigchld(serverP); -} - - - -static void -setHttpReqHandlers(TServer * const serverP, - void * const serverHandle, - size_t const maxStackSize, - string const& uriPath, - bool const chunkResponse, - bool const doHttpAccessControl, - string const& allowOrigin, - bool const accessCtlExpires, - unsigned int const accessCtlMaxAge) { - - env_wrap env; - xmlrpc_server_abyss_handler_parms parms; - - parms.xml_processor = &processXmlrpcCall; - parms.xml_processor_arg = serverHandle; - parms.xml_processor_max_stack = maxStackSize; - parms.uri_path = uriPath.c_str(); - parms.chunk_response = chunkResponse; - parms.allow_origin = doHttpAccessControl ? allowOrigin.c_str() : NULL; - parms.access_ctl_expires = accessCtlExpires; - parms.access_ctl_max_age = accessCtlMaxAge; - - xmlrpc_server_abyss_set_handler3( - &env.env_c, serverP, - &parms, XMLRPC_AHPSIZE(access_ctl_max_age)); - - if (env.env_c.fault_occurred) - throwf("Failed to register the HTTP handler for XML-RPC " - "with the underlying Abyss HTTP server. " - "xmlrpc_server_abyss_set_handler3() failed with: %s", - env.env_c.fault_string); - - xmlrpc_server_abyss_set_default_handler(serverP); -} - - - -static void -createServer(serverAbyss::constrOpt_impl const& opt, - void * const serverHandle, - size_t const maxStackSize, - TServer * const serverP, - TChanSwitch ** const chanSwitchPP) { - - validateListenOptions(opt); - - createServerBare(opt.present.logFileName, opt.value.logFileName, - opt.present.socketFd, opt.value.socketFd, - opt.present.portNumber, opt.value.portNumber, - opt.present.sockAddrP, - SockAddr(opt.value.sockAddrP, opt.value.sockAddrLen), - serverP, chanSwitchPP); - - try { - setAdditionalServerParms(serverP, opt); - - setHttpReqHandlers(serverP, - serverHandle, - maxStackSize, - opt.value.uriPath, - opt.value.chunkResponse, - opt.present.allowOrigin, - opt.value.allowOrigin, - opt.present.accessCtlMaxAge, - opt.value.accessCtlMaxAge); - - if (opt.present.portNumber || opt.present.socketFd || - opt.present.sockAddrP) - ServerInit(serverP); - } catch (...) { - ServerFree(serverP); - throw; - } -} - - - -serverAbyss_impl::serverAbyss_impl( - serverAbyss::constrOpt_impl const& opt, - serverAbyss * const serverAbyssP) : - serverAbyssP(serverAbyssP) { - - if (!opt.present.registryP && !opt.present.registryPtr) - throwf("You must specify the 'registryP' or 'registryPtr' option"); - else if (opt.present.registryP && opt.present.registryPtr) - throwf("You may not specify both the 'registryP' and " - "the 'registryPtr' options"); - else { - if (opt.present.registryP) - this->registryP = opt.value.registryP; - else { - this->regPtr = opt.value.registryPtr; - this->registryP = this->regPtr.get(); - } - } - - this->serverOwnsSignals = opt.value.serverOwnsSignals; - - if (opt.value.serverOwnsSignals && opt.value.expectSigchld) - throwf("You can't specify both expectSigchld " - "and serverOwnsSignals options"); - - DateInit(); - - createServer(opt, this, this->registryP->maxStackSize(), - &this->cServer, &this->chanSwitchP); -} - - - -serverAbyss_impl::~serverAbyss_impl() { - - ServerFree(&this->cServer); - - if (this->chanSwitchP) - ChanSwitchDestroy(this->chanSwitchP); -} - - - -void -serverAbyss_impl::getListenName(struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP) { - - if (!this->chanSwitchP) - throwf("%s", - "Server is not configured to listen for client connections"); - - const char * error; - -#ifdef WIN32 - ChanSwitchWinGetListenName(this->chanSwitchP, - sockaddrPP, sockaddrLenP, &error); -#else - ChanSwitchUnixGetListenName(this->chanSwitchP, - sockaddrPP, sockaddrLenP, &error); -#endif - - if (error) { - string const e(error); - xmlrpc_strfree(error); - throwf("%s", e.c_str()); - } -} - - - -static void -setupSignalsAndRunAbyss(TServer * const abyssServerP) { - - /* We do some pretty ugly stuff for an object method: we set signal - handlers, which are process-global. - - One example of where this can be hairy is: Caller has a child - process unrelated to the Abyss server. That child dies. We - get his death of a child signal and Caller never knows. - - We really expect to be the only thing in the process, at least - for the time we're running. If you want the Abyss Server - to behave more like an object and own the signals yourself, - use runOnce() in a loop instead of run(). - */ - signalHandlers oldHandlers; - - setupSignalHandlers(&oldHandlers); - - ServerUseSigchld(abyssServerP); - - ServerRun(abyssServerP); - - restoreSignalHandlers(oldHandlers); -} - - - -void -serverAbyss_impl::run() { - - if (this->serverOwnsSignals) - setupSignalsAndRunAbyss(&this->cServer); - else { - if (this->expectSigchld) - ServerUseSigchld(&this->cServer); - - ServerRun(&this->cServer); - } -} - - - -void -serverAbyss_impl::processCall(string const& call, - TSession * const abyssSessionP, - string * const responseP) { - - callInfo_serverAbyss const callInfo(this->serverAbyssP, abyssSessionP); - - this->registryP->processCall(call, &callInfo, responseP); -} - - - -serverAbyss::shutdown::shutdown(serverAbyss * const serverAbyssP) : - serverAbyssP(serverAbyssP) {} - - - -serverAbyss::shutdown::~shutdown() {} - - - -void -serverAbyss::shutdown::doit(string const&, - void * const) const { - - this->serverAbyssP->terminate(); -} - - - -void -serverAbyss::initialize(constrOpt const& opt) { - - this->implP = new serverAbyss_impl(*opt.implP, this); -} - - - -serverAbyss::serverAbyss(constrOpt const& opt) { - - initialize(opt); -} - - - -serverAbyss::serverAbyss( - xmlrpc_c::registry const& registry, - unsigned int const portNumber, - string const& logFileName, - unsigned int const keepaliveTimeout, - unsigned int const keepaliveMaxConn, - unsigned int const timeout, - bool const dontAdvertise, - bool const socketBound, - XMLRPC_SOCKET const socketFd) { -/*---------------------------------------------------------------------------- - This is a backward compatibility interface. This used to be the only - constructor. ------------------------------------------------------------------------------*/ - serverAbyss::constrOpt opt; - - opt.registryP(®istry); - if (logFileName.length() > 0) - opt.logFileName(logFileName); - if (keepaliveTimeout > 0) - opt.keepaliveTimeout(keepaliveTimeout); - if (keepaliveMaxConn > 0) - opt.keepaliveMaxConn(keepaliveMaxConn); - if (timeout > 0) - opt.timeout(timeout); - opt.dontAdvertise(dontAdvertise); - if (socketBound) - opt.socketFd(socketFd); - else - opt.portNumber(portNumber); - - initialize(opt); -} - - - -serverAbyss::~serverAbyss() { - - delete(this->implP); -} - - - -void -serverAbyss::getListenName(struct sockaddr ** const sockaddrPP, - size_t * const sockaddrLenP) { - - this->implP->getListenName(sockaddrPP, sockaddrLenP); -} - - - -void -serverAbyss::run() { - - this->implP->run(); -} - - - -void -serverAbyss::runOnce() { - - ServerRunOnce(&this->implP->cServer); -} - - - -void -serverAbyss::runConn(int const socketFd) { - - ServerRunConn(&this->implP->cServer, socketFd); -} - - - -#ifndef WIN32 -void -serverAbyss::sigchld(pid_t const pid) { - - // There's a hole in the design here, because the Abyss server uses - // a process-global list of children (so there can't be more than one - // Abyss object in the process), so while this is an object method, - // it doesn't really refer to the object at all. - - // We might conceivably fix Abyss some day, then this method would do - // what you expect -- affect only its own object. But forking Abyss is - // obsolete anyway, so we just don't worry about it. - - ServerHandleSigchld(pid); -} -#endif - - - -void -serverAbyss::terminate() { - - ServerTerminate(&this->implP->cServer); -} - - - -callInfo_abyss::callInfo_abyss(TSession * const abyssSessionP) : - abyssSessionP(abyssSessionP) {} - - - -void -processXmlrpcCall2(xmlrpc_env * const envP, - void * const arg, - const char * const callXml, - size_t const callXmlLen, - TSession * const abyssSessionP, - xmlrpc_mem_block ** const responseXmlPP) { -/*---------------------------------------------------------------------------- - This is an XML-RPC XML call processor, as called by the HTTP request - handler of the libxmlrpc_server_abyss C library. - - 'callXml'/'callXmlLen' is the XML text of a supposed XML-RPC call. - We execute the RPC and return the XML text of the XML-RPC response - as *responseXmlPP. - - 'arg' carries the information that tells us how to do that; e.g. - what XML-RPC methods are defined. ------------------------------------------------------------------------------*/ - const registry * const registryP(static_cast(arg)); - - try { - string const call(callXml, callXmlLen); - callInfo_abyss const callInfo(abyssSessionP); - - string response; - - registryP->processCall(call, &callInfo, &response); - - xmlrpc_mem_block * responseMbP; - - responseMbP = XMLRPC_MEMBLOCK_NEW(char, envP, response.length()); - - if (!envP->fault_occurred) { - XMLRPC_MEMBLOCK_APPEND(char, envP, responseMbP, - response.c_str(), response.length()); - - *responseXmlPP = responseMbP; - } - } catch (exception const& e) { - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, e.what()); - } -} - - - -static void -setHandlers(TServer * const serverP, - string const& uriPath, - registry const& registry) { - - xmlrpc_server_abyss_set_handler2( - serverP, uriPath.c_str(), - processXmlrpcCall2, - const_cast(®istry), - registry.maxStackSize(), - false); - - xmlrpc_server_abyss_set_default_handler(serverP); -} - - - -void -server_abyss_set_handlers(TServer * const serverP, - registry const& registry, - string const& uriPath) { - - setHandlers(serverP, uriPath, registry); -} - - - -void -server_abyss_set_handlers(TServer * const serverP, - const registry * const registryP, - string const& uriPath) { - - setHandlers(serverP, uriPath, *registryP); -} - - - -void -server_abyss_set_handlers(TServer * const serverP, - registryPtr const registryPtr, - string const& uriPath) { - - setHandlers(serverP, uriPath, *registryPtr.get()); -} - - - -} // namespace diff --git a/trunk/src/cpp/server_cgi.cpp b/trunk/src/cpp/server_cgi.cpp deleted file mode 100644 index 7408cbaf4..000000000 --- a/trunk/src/cpp/server_cgi.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/*============================================================================= - server_cgi -=============================================================================== - - This is the definition of the xmlrpc_c::server_cgi class. An object of - this class is the guts of a CGI-based XML-RPC server. It runs inside - a CGI script and gets the XML-RPC call from and delivers the XML-RPC - response to the CGI environment. - - By Bryan Henderson 08.09.17. - - Contributed to the public domain by its author. -=============================================================================*/ - -#include "xmlrpc_config.h" -#if MSVCRT -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS -#endif -#include -#include -#endif -#include // for getenv -#include -#include - -using namespace std; - -#include "xmlrpc-c/girerr.hpp" -using girerr::throwf; -#include "xmlrpc-c/server_cgi.hpp" - - - -namespace { - -class httpInfo { - -public: - string requestMethod; - bool contentTypePresent; - string contentType; - unsigned int contentLength; - bool contentLengthPresent; - bool authCookiePresent; - string authCookie; - - httpInfo() { - - const char * const requestMethodC = getenv("REQUEST_METHOD"); - const char * const contentTypeC = getenv("CONTENT_TYPE"); - const char * const contentLengthC = getenv("CONTENT_LENGTH"); - const char * const authCookieC = getenv("HTTP_COOKIE_AUTH"); - - if (requestMethodC) - this->requestMethod = string(requestMethodC); - else - throwf("Invalid CGI environment; environment variable " - "REQUEST_METHOD is not set"); - - if (contentTypeC) { - this->contentTypePresent = true; - this->contentType = string(contentTypeC); - } else - this->contentTypePresent = false; - - if (contentLengthC) { - this->contentLengthPresent = true; - - int const lengthAtoi(atoi(string(contentLengthC).c_str())); - - if (lengthAtoi < 0) - throwf("Content-length HTTP header value is negative"); - else if (lengthAtoi == 0) - throwf("Content-length HTTP header value is zero"); - else - this->contentLength = lengthAtoi; - } else - this->contentLengthPresent = false; - - if (authCookieC) { - this->authCookie = string(authCookieC); - this->authCookiePresent = true; - } else - this->authCookiePresent = false; - } -}; - -} // unnamed namespace - - - -namespace { - -class HttpError { - -public: - - int const code; - string const msg; - - HttpError(int const code, - string const& msg) : - code(code), - msg(msg) - {} -}; - - -} // unnamed namespace - - - -namespace xmlrpc_c { - -struct serverCgi_impl { - // 'registryP' is what we actually use; 'registryHolder' just holds a - // reference to 'registryP' so the registry doesn't disappear while - // this server exists. But note that if the creator doesn't supply - // a registryPtr, 'registryHolder' is just a placeholder variable and - // the creator is responsible for making sure the registry doesn't - // go anywhere while the server exists. - - registryPtr registryHolder; - const registry * registryP; - - serverCgi_impl(serverCgi::constrOpt const& opt); - - void - establishRegistry(serverCgi::constrOpt const& opt); - - void - tryToProcessCall(); -}; - - - -void -serverCgi_impl::establishRegistry(serverCgi::constrOpt const& opt) { - - if (!opt.present.registryP && !opt.present.registryPtr) - throwf("You must specify the 'registryP' or 'registryPtr' option"); - else if (opt.present.registryP && opt.present.registryPtr) - throwf("You may not specify both the 'registryP' and " - "the 'registryPtr' options"); - else { - if (opt.present.registryP) - this->registryP = opt.value.registryP; - else { - this->registryHolder = opt.value.registryPtr; - this->registryP = opt.value.registryPtr.get(); - } - } -} - - - -serverCgi_impl::serverCgi_impl(serverCgi::constrOpt const& opt) { - this->establishRegistry(opt); -} - - - -serverCgi::constrOpt::constrOpt() { - - present.registryP = false; - present.registryPtr = false; -} - - - -#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ -serverCgi::constrOpt & \ -serverCgi::constrOpt::OPTION_NAME(TYPE const& arg) { \ - this->value.OPTION_NAME = arg; \ - this->present.OPTION_NAME = true; \ - return *this; \ -} - -DEFINE_OPTION_SETTER(registryP, const registry *); -DEFINE_OPTION_SETTER(registryPtr, xmlrpc_c::registryPtr); - -#undef DEFINE_OPTION_SETTER - - - -serverCgi::serverCgi(constrOpt const& opt) { - - this->implP = new serverCgi_impl(opt); -} - - - -serverCgi::~serverCgi() { - - delete(this->implP); -} - - - -#if MSVCRT -#define FILEVAR fileP -#else -#define FILEVAR -#endif - -static void -setModeBinary(FILE * const FILEVAR) { - -#if MSVCRT - /* Fix from Jeff Stewart: NT opens stdin and stdout in text mode - by default, badly confusing our length calculations. So we need - to set the file handle to binary. - */ - _setmode(_fileno(FILEVAR), _O_BINARY); -#endif -} - - - -static string -getHttpBody(FILE * const fileP, - size_t const length) { - - setModeBinary(fileP); - char * const buffer(new char[length]); - auto_ptr p(buffer); // To make it go away when we leave - - size_t count; - - count = fread(buffer, sizeof(buffer[0]), length, fileP); - if (count < length) - throwf("Expected %lu bytes, received %lu", - (unsigned long) length, (unsigned long) count); - - return string(buffer, length); -} - - - -static void -writeNormalHttpResp(FILE * const fileP, - bool const sendCookie, - string const& authCookie, - string const& httpBody) { - - setModeBinary(fileP); - - // HTTP headers - - fprintf(fileP, "Status: 200 OK\n"); - - if (sendCookie) - fprintf(fileP, "Set-Cookie: auth=%s\n", authCookie.c_str()); - - fprintf(fileP, "Content-type: text/xml; charset=\"utf-8\"\n"); - fprintf(fileP, "Content-length: %u\n", (unsigned)httpBody.size()); - fprintf(fileP, "\n"); - - // HTTP body - - fwrite(httpBody.c_str(), sizeof(char), httpBody.size(), fileP); -} - - - -void -processCall2(const registry * const registryP, - FILE * const callFileP, - unsigned int const callSize, - bool const sendCookie, - string const& authCookie, - FILE * const respFileP) { - - if (callSize > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) - throw(xmlrpc_c::fault(string("XML-RPC call is too large"), - fault::CODE_LIMIT_EXCEEDED)); - else { - string const callXml(getHttpBody(callFileP, callSize)); - - string responseXml; - - try { - registryP->processCall(callXml, &responseXml); - } catch (exception const& e) { - throw(HttpError(500, e.what())); - } - - writeNormalHttpResp(respFileP, sendCookie, authCookie, responseXml); - } -} - - - - -static void -sendHttpErrorResp(FILE * const fileP, - HttpError const& e) { - - setModeBinary(fileP); - - // HTTP headers - - fprintf(fileP, "Status: %d %s\n", e.code, e.msg.c_str()); - fprintf(fileP, "Content-type: text/html\n"); - fprintf(fileP, "\n"); - - // HTTP body: HTML error message - - fprintf(fileP, "%d %s\n", e.code, e.msg.c_str()); - fprintf(fileP, "

%d %s

\n", e.code, e.msg.c_str()); - fprintf(fileP, "

The Xmlrpc-c CGI server was unable to process " - "your request. It could not process it even enough to generate " - "an XML-RPC fault response.

\n"); -} - - - -void -serverCgi_impl::tryToProcessCall() { - - httpInfo httpInfo; - - if (httpInfo.requestMethod != string("POST")) - throw(HttpError(405, "Method must be POST")); - - if (!httpInfo.contentTypePresent) - throw(HttpError(400, "Must have content-type header")); - - if (httpInfo.contentType != string("text/xml")) - throw(HttpError(400, string("ContentType must be 'text/xml', not '") + - httpInfo.contentType + string("'"))); - - if (!httpInfo.contentLengthPresent) - throw(HttpError(411, "Content-length required")); - - processCall2(this->registryP, stdin, httpInfo.contentLength, - httpInfo.authCookiePresent, httpInfo.authCookie, stdout); -} - - - -void -serverCgi::processCall() { -/*---------------------------------------------------------------------------- - Get the XML-RPC call from Standard Input and environment variables, - parse it, find the right method, call it, prepare an XML-RPC - response with the result, and write it to Standard Output. ------------------------------------------------------------------------------*/ - try { - this->implP->tryToProcessCall(); - } catch (HttpError const& e) { - sendHttpErrorResp(stdout, e); - } -} - - - -} // namespace diff --git a/trunk/src/cpp/server_pstream.cpp b/trunk/src/cpp/server_pstream.cpp deleted file mode 100644 index d66cb6209..000000000 --- a/trunk/src/cpp/server_pstream.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/*============================================================================= - server_pstream -=============================================================================== - - RPC server based on a very simple byte stream and XML-RPC XML - (But this is not an XML-RPC server because it doesn't use HTTP). - - The protocol we use is the "packet socket" protocol, which - is an Xmlrpc-c invention. It is an almost trivial representation of - a sequence of packets on a byte stream. - - By Bryan Henderson 09.03.22 - - Contributed to the public domain by its author. -=============================================================================*/ - -#include "xmlrpc_config.h" -#if MSVCRT -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS -#endif -#include -typedef int socklen_t; -#else -#include -#endif -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::throwf; - -#include "xmlrpc-c/server_pstream.hpp" - -using namespace std; - -namespace xmlrpc_c { - - -struct serverPstream::constrOpt_impl { - - constrOpt_impl(); - - struct value { - xmlrpc_c::registryPtr registryPtr; - const xmlrpc_c::registry * registryP; - XMLRPC_SOCKET socketFd; - } value; - struct { - bool registryPtr; - bool registryP; - bool socketFd; - } present; -}; - - - -serverPstream::constrOpt_impl::constrOpt_impl() { - - this->present.socketFd = false; - this->present.registryP = false; - this->present.registryPtr = false; -} - - - -serverPstream::constrOpt::constrOpt() { - - this->implP = new serverPstream::constrOpt_impl(); -} - - - -serverPstream::constrOpt::~constrOpt() { - - delete(this->implP); -} - - - -#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ -serverPstream::constrOpt & \ -serverPstream::constrOpt::OPTION_NAME(TYPE const& arg) { \ - this->implP->value.OPTION_NAME = arg; \ - this->implP->present.OPTION_NAME = true; \ - return *this; \ -} - -DEFINE_OPTION_SETTER(socketFd, XMLRPC_SOCKET); -DEFINE_OPTION_SETTER(registryP, const registry *); -DEFINE_OPTION_SETTER(registryPtr, xmlrpc_c::registryPtr); - -#undef DEFINE_OPTION_SETTER - - - -struct serverPstream_impl { - - serverPstream_impl(serverPstream::constrOpt_impl const& opt); - - ~serverPstream_impl(); - - void - establishRegistry(serverPstream::constrOpt_impl const& opt); - - // 'registryP' is what we actually use; 'registryHolder' just holds a - // reference to 'registryP' so the registry doesn't disappear while - // this server exists. But note that if the creator doesn't supply - // a registryPtr, 'registryHolder' is just a placeholder variable and - // the creator is responsible for making sure the registry doesn't - // go anywhere while the server exists. - - registryPtr registryHolder; - const registry * registryP; - - XMLRPC_SOCKET listenSocketFd; - // The socket on which we accept connections from clients. This comes - // to us from the creator, already bound and in listen mode. That - // way, this object doesn't have to know anything about socket - // addresses or listen parameters such as the maximum connection - // backlog size. - - bool termRequested; - // User has requested that the run method return ASAP; i.e. that - // the server cease servicing RPCs. -}; - - - -serverPstream_impl::serverPstream_impl( - serverPstream::constrOpt_impl const& opt) { - - this->establishRegistry(opt); - - if (!opt.present.socketFd) - throwf("You must provide a 'socketFd' constructor option."); - - this->listenSocketFd = opt.value.socketFd; - - this->termRequested = false; -} - - - -serverPstream_impl::~serverPstream_impl() { - -} - - - -void -serverPstream_impl::establishRegistry( - serverPstream::constrOpt_impl const& opt) { - - if (!opt.present.registryP && !opt.present.registryPtr) - throwf("You must specify the 'registryP' or 'registryPtr' option"); - else if (opt.present.registryP && opt.present.registryPtr) - throwf("You may not specify both the 'registryP' and " - "the 'registryPtr' options"); - else { - if (opt.present.registryP) - this->registryP = opt.value.registryP; - else { - this->registryHolder = opt.value.registryPtr; - this->registryP = opt.value.registryPtr.get(); - } - } -} - - -/*----------------------------------------------------------------------------- - serverPstream::shutdown is a derived class of registry::shutdown. You give - it to the registry object to allow XML-RPC method 'system.shutdown' to ------------------------------------------------------------------------------*/ - -serverPstream::shutdown::shutdown(serverPstream * const serverPstreamP) : - serverPstreamP(serverPstreamP) {} - - - -serverPstream::shutdown::~shutdown() {} - - - -void -serverPstream::shutdown::doit(string const&, - void * const) const { - - this->serverPstreamP->terminate(); -} -/*---------------------------------------------------------------------------*/ - - - -serverPstream::serverPstream(constrOpt const& opt) { - - this->implP = new serverPstream_impl(*opt.implP); -} - - - -serverPstream::~serverPstream() { - - delete(this->implP); -} - - - -void -serverPstream::runSerial(volatile const int * const interruptP) { - - while (!this->implP->termRequested && !*interruptP) { - struct sockaddr peerAddr; - socklen_t size = sizeof(peerAddr); - int rc; - - rc = accept(this->implP->listenSocketFd, &peerAddr, &size); - - if (!*interruptP) { - if (rc < 0) - if (errno == EINTR) { - // system call was interrupted, but user doesn't want - // to interrupt the server, so just keep trying - } else - throwf("Failed to accept a connection " - "on the listening socket. accept() failed " - "with errno %d (%s)", errno, strerror(errno)); - else { - int const acceptedFd = rc; - - serverPstreamConn connectionServer( - xmlrpc_c::serverPstreamConn::constrOpt() - .socketFd(acceptedFd) - .registryP(this->implP->registryP)); - - callInfo_serverPstream callInfo(this, peerAddr, size); - - connectionServer.run(&callInfo, interruptP); - } - } - } -} - - - -void -serverPstream::runSerial() { - - int const interrupt(0); // Never interrupt - - this->runSerial(&interrupt); -} - - - -void -serverPstream::terminate() { - - this->implP->termRequested = true; -} - - - -callInfo_serverPstream::callInfo_serverPstream( - serverPstream * const serverP, - struct sockaddr const clientAddr, - socklen_t const clientAddrSize) : - - serverP (serverP), - clientAddr (clientAddr), - clientAddrSize (clientAddrSize) - -{} - - - -} // namespace diff --git a/trunk/src/cpp/server_pstream_conn.cpp b/trunk/src/cpp/server_pstream_conn.cpp deleted file mode 100644 index 3598164b9..000000000 --- a/trunk/src/cpp/server_pstream_conn.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/*============================================================================= - server_pstream -=============================================================================== - - RPC server based on a very simple byte stream and XML-RPC XML - (But this is not an XML-RPC server because it doesn't use HTTP). - - The protocol we use is the "packet socket" protocol, which - is an Xmlrpc-c invention. It is an almost trivial representation of - a sequence of packets on a byte stream. - - You can create a pstream server from any file descriptor from which - you can read and write a bidirectional character stream. Typically, - it's a TCP socket. Such a server talks to one client its entire life. - - Some day, we'll also have a version that you create from a "listening" - socket, which can talk to multiple clients serially (a client connects, - does some RPCs, and disconnects). - - By Bryan Henderson 07.05.12. - - Contributed to the public domain by its author. -=============================================================================*/ - -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::throwf; -#include "xmlrpc-c/packetsocket.hpp" - -#include "xmlrpc-c/server_pstream.hpp" - -using namespace std; - -namespace xmlrpc_c { - - -struct serverPstreamConn::constrOpt_impl { - - constrOpt_impl(); - - struct value { - xmlrpc_c::registryPtr registryPtr; - const xmlrpc_c::registry * registryP; - XMLRPC_SOCKET socketFd; - } value; - struct { - bool registryPtr; - bool registryP; - bool socketFd; - } present; -}; - - - -serverPstreamConn::constrOpt_impl::constrOpt_impl() { - - this->present.socketFd = false; - this->present.registryP = false; - this->present.registryPtr = false; -} - - - -serverPstreamConn::constrOpt::constrOpt() { - - this->implP = new constrOpt_impl(); -} - - - -serverPstreamConn::constrOpt::~constrOpt() { - - delete(this->implP); -} - - - -#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ -serverPstreamConn::constrOpt & \ -serverPstreamConn::constrOpt::OPTION_NAME(TYPE const& arg) { \ - this->implP->value.OPTION_NAME = arg; \ - this->implP->present.OPTION_NAME = true; \ - return *this; \ -} - -DEFINE_OPTION_SETTER(socketFd, XMLRPC_SOCKET); -DEFINE_OPTION_SETTER(registryP, const registry *); -DEFINE_OPTION_SETTER(registryPtr, xmlrpc_c::registryPtr); - -#undef DEFINE_OPTION_SETTER - - - -struct serverPstreamConn_impl { - - serverPstreamConn_impl(serverPstreamConn::constrOpt_impl const& opt); - - ~serverPstreamConn_impl(); - - void - establishRegistry(serverPstreamConn::constrOpt_impl const& opt); - - void - establishPacketSocket(serverPstreamConn::constrOpt_impl const& opt); - - void - processRecdPacket(packetPtr const callPacketP, - callInfo * const callInfoP); - - // 'registryP' is what we actually use; 'registryHolder' just holds a - // reference to 'registryP' so the registry doesn't disappear while - // this server exists. But note that if the creator doesn't supply - // a registryPtr, 'registryHolder' is just a placeholder variable and - // the creator is responsible for making sure the registry doesn't - // go anywhere while the server exists. - - registryPtr registryHolder; - const registry * registryP; - - packetSocket * packetSocketP; - // The packet socket over which we received RPCs. - // This is permanently connected to our fixed client. -}; - - - -serverPstreamConn_impl::serverPstreamConn_impl( - serverPstreamConn::constrOpt_impl const& opt) { - - this->establishRegistry(opt); - - this->establishPacketSocket(opt); -} - - - -serverPstreamConn_impl::~serverPstreamConn_impl() { - - delete(this->packetSocketP); -} - - - -void -serverPstreamConn_impl::establishRegistry( - serverPstreamConn::constrOpt_impl const& opt) { - - if (!opt.present.registryP && !opt.present.registryPtr) - throwf("You must specify the 'registryP' or 'registryPtr' option"); - else if (opt.present.registryP && opt.present.registryPtr) - throwf("You may not specify both the 'registryP' and " - "the 'registryPtr' options"); - else { - if (opt.present.registryP) - this->registryP = opt.value.registryP; - else { - this->registryHolder = opt.value.registryPtr; - this->registryP = opt.value.registryPtr.get(); - } - } -} - - - -void -serverPstreamConn_impl::establishPacketSocket( - serverPstreamConn::constrOpt_impl const& opt) { - - if (!opt.present.socketFd) - throwf("You must provide a 'socketFd' constructor option."); - - auto_ptr packetSocketAP; - - try { - auto_ptr p(new packetSocket(opt.value.socketFd)); - packetSocketAP = p; - } catch (exception const& e) { - throwf("Unable to create packet socket out of file descriptor %d. %s", - opt.value.socketFd, e.what()); - } - this->packetSocketP = packetSocketAP.get(); - packetSocketAP.release(); -} - - - -serverPstreamConn::serverPstreamConn(constrOpt const& opt) { - - this->implP = new serverPstreamConn_impl(*opt.implP); -} - - - -serverPstreamConn::~serverPstreamConn() { - - delete(this->implP); -} - - - -static void -processCall(const registry * const registryP, - packetPtr const& callPacketP, - callInfo * const callInfoP, - packetPtr * const responsePacketPP) { - - string const callXml(reinterpret_cast(callPacketP->getBytes()), - callPacketP->getLength()); - - string responseXml; - - registryP->processCall(callXml, callInfoP, &responseXml); - - *responsePacketPP = packetPtr(new packet(responseXml.c_str(), - responseXml.length())); -} - - - -void -serverPstreamConn_impl::processRecdPacket(packetPtr const callPacketP, - callInfo * const callInfoP) { - - packetPtr responsePacketP; - try { - processCall(this->registryP, callPacketP, callInfoP, &responsePacketP); - } catch (exception const& e) { - throwf("Error executing received packet as an XML-RPC RPC. %s", - e.what()); - } - try { - this->packetSocketP->writeWait(responsePacketP); - } catch (exception const& e) { - throwf("Failed to write the response to the packet socket. %s", - e.what()); - } -} - - - -void -serverPstreamConn::runOnce(callInfo * const callInfoP, - volatile const int * const interruptP, - bool * const eofP) { -/*---------------------------------------------------------------------------- - Get and execute one RPC from the client. - - Unless *interruptP gets set nonzero first. ------------------------------------------------------------------------------*/ - bool gotPacket; - packetPtr callPacketP; - - try { - this->implP->packetSocketP->readWait(interruptP, eofP, &gotPacket, - &callPacketP); - } catch (exception const& e) { - throwf("Error reading a packet from the packet socket. %s", - e.what()); - } - if (gotPacket) - this->implP->processRecdPacket(callPacketP, callInfoP); -} - - - -void -serverPstreamConn::runOnce(volatile const int * const interruptP, - bool * const eofP) { - - this->runOnce(NULL, interruptP, eofP); -} - - - -void -serverPstreamConn::runOnce(bool * const eofP) { -/*---------------------------------------------------------------------------- - Get and execute one RPC from the client. ------------------------------------------------------------------------------*/ - int const interrupt(0); // Never interrupt - - this->runOnce(&interrupt, eofP); -} - - - -void -serverPstreamConn::runOnceNoWait(callInfo * const callInfoP, - bool * const eofP, - bool * const didOneP) { -/*---------------------------------------------------------------------------- - Get and execute one RPC from the client, unless none has been - received yet. Return as *didOneP whether or not one has been - received. Unless didOneP is NULL. ------------------------------------------------------------------------------*/ - bool gotPacket; - packetPtr callPacketP; - - try { - this->implP->packetSocketP->read(eofP, &gotPacket, &callPacketP); - } catch (exception const& e) { - throwf("Error reading a packet from the packet socket. %s", - e.what()); - } - if (gotPacket) - this->implP->processRecdPacket(callPacketP, callInfoP); - - if (didOneP) - *didOneP = gotPacket; -} - - - -void -serverPstreamConn::runOnceNoWait(bool * const eofP, - bool * const didOneP) { - - this->runOnceNoWait(NULL, eofP, didOneP); -} - - - -void -serverPstreamConn::runOnceNoWait(bool * const eofP) { -/*---------------------------------------------------------------------------- - Get and execute one RPC from the client, unless none has been - received yet. ------------------------------------------------------------------------------*/ - this->runOnceNoWait(eofP, NULL); -} - - - -void -serverPstreamConn::run(callInfo * const callInfoP, - volatile const int * const interruptP) { - - for (bool clientHasDisconnected = false; - !clientHasDisconnected && !*interruptP;) - this->runOnce(callInfoP, interruptP, &clientHasDisconnected); -} - - - -void -serverPstreamConn::run(volatile const int * const interruptP) { - - this->run(NULL, interruptP); -} - - - -void -serverPstreamConn::run() { - - int const interrupt(0); // Never interrupt - - this->run(&interrupt); -} - - - -} // namespace diff --git a/trunk/src/cpp/value.cpp b/trunk/src/cpp/value.cpp deleted file mode 100644 index b319430ea..000000000 --- a/trunk/src/cpp/value.cpp +++ /dev/null @@ -1,1140 +0,0 @@ -/***************************************************************************** - value.cpp -****************************************************************************** - This module provides services for dealing with XML-RPC values. Each - type of XML-RPC value is a C++ class. An object represents a - particular XML-RPC value. - - Everything is based on the C services in libxmlrpc. - - We could make things more efficient by using the internal interfaces - via xmlrpc_int.h. We could make them even more efficient by dumping - libxmlrpc altogether for some or all of these services. - - An xmlrpc_c::value object is really just a handle for a C xmlrpc_value - object. You're not supposed to make a pointer to an xmlrpc_c::value - object, but rather copy the object around. - - Because the C xmlrpc_value object does reference counting, it - disappears automatically when the last handle does. To go pure C++, - we'd have to have a C++ object for the value itself and a separate - handle object, like Boost's shared_ptr<>. - - The C++ is designed so that the user never sees the C interface at - all. Unfortunately, the user can see it if he wants because some - class members had to be declared public so that other components of - the library could see them, but the user is not supposed to access - those members. -*****************************************************************************/ - -#include -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/env_wrap.hpp" - -#include "xmlrpc-c/base.hpp" - -using namespace std; -using namespace xmlrpc_c; - -namespace { - -void -throwIfError(env_wrap const& env) { - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -class cDatetimeValueWrapper { -public: - xmlrpc_value * valueP; - - cDatetimeValueWrapper(xmlrpc_datetime const cppvalue) { - env_wrap env; - - this->valueP = xmlrpc_datetime_new(&env.env_c, cppvalue); - throwIfError(env); - } - cDatetimeValueWrapper(time_t const cppvalue) { - env_wrap env; - - this->valueP = xmlrpc_datetime_new_sec(&env.env_c, cppvalue); - throwIfError(env); - } -#if XMLRPC_HAVE_TIMEVAL - cDatetimeValueWrapper(struct timeval const cppvalue) { - env_wrap env; - - this->valueP = xmlrpc_datetime_new_timeval(&env.env_c, cppvalue); - throwIfError(env); - } -#endif -#if XMLRPC_HAVE_TIMESPEC - cDatetimeValueWrapper(struct timespec const cppvalue) { - env_wrap env; - - this->valueP = xmlrpc_datetime_new_timespec(&env.env_c, cppvalue); - throwIfError(env); - } -#endif - ~cDatetimeValueWrapper() { - xmlrpc_DECREF(this->valueP); - } -}; - - -class cStringWrapper { -public: - const char * str; - size_t length; - cStringWrapper(xmlrpc_value * valueP) { - env_wrap env; - - xmlrpc_read_string_lp(&env.env_c, valueP, &length, &str); - throwIfError(env); - } - ~cStringWrapper() { - free((char*)str); - } -}; - - - -} // namespace - - - -namespace xmlrpc_c { - -value::value() { // default constructor - this->cValueP = NULL; -} - - - -value::value(xmlrpc_value * const valueP) { - - this->instantiate(valueP); -} - - - -value::value(xmlrpc_c::value const& value) { // copy constructor - this->cValueP = value.cValue(); -} - - - -xmlrpc_c::value& -value::operator=(xmlrpc_c::value const& value) { - - if (this->cValueP != NULL) - throw(error("Assigning to already instantiated xmlrpc_c::value")); - - this->cValueP = value.cValue(); - return *this; // The result of the (a = b) expression -} - - - -value::~value() { - if (this->cValueP) { - xmlrpc_DECREF(this->cValueP); - } -} - - - -bool -value::isInstantiated() const { -/*---------------------------------------------------------------------------- - Return whether the object is actually a value, as opposed to a placeholder - variable waiting to be assigned a value. ------------------------------------------------------------------------------*/ - return (this->cValueP != NULL); -} - - - -void -value::validateInstantiated() const { // private -/*---------------------------------------------------------------------------- - Throw an exception if the object is just a placeholder, rather than an - actual XML-RPC value. ------------------------------------------------------------------------------*/ - if (!this->cValueP) - throw(error("Reference to xmlrpc_c::value that has not been " - "instantiated. (xmlrpc_c::value::isInstantiated may be " - "useful in diagnosing)")); -} - - - -void -value::instantiate(xmlrpc_value * const valueP) { - - xmlrpc_INCREF(valueP); - this->cValueP = valueP; -} - - - -xmlrpc_value * -value::cValue() const { - - if (this->cValueP) { - xmlrpc_INCREF(this->cValueP); // For Caller - } - return this->cValueP; -} - - - -void -value::appendToCArray(xmlrpc_value * const arrayP) const { -/*---------------------------------------------------------------------------- - Append this value to the C array 'arrayP'. -----------------------------------------------------------------------------*/ - this->validateInstantiated(); - - env_wrap env; - - xmlrpc_array_append_item(&env.env_c, arrayP, this->cValueP); - - throwIfError(env); -} - - - -void -value::addToCStruct(xmlrpc_value * const structP, - string const key) const { -/*---------------------------------------------------------------------------- - Add this value to the C array 'arrayP' with key 'key'. -----------------------------------------------------------------------------*/ - this->validateInstantiated(); - - env_wrap env; - - xmlrpc_struct_set_value_n(&env.env_c, structP, - key.c_str(), key.length(), - this->cValueP); - - throwIfError(env); -} - - - -value::type_t -value::type() const { - - this->validateInstantiated(); - - /* You'd think we could just cast from xmlrpc_type to - value::type_t, but Gcc warns if we do that. So we have to do this - even messier union nonsense. - */ - union { - xmlrpc_type x; - value::type_t y; - } u; - - u.x = xmlrpc_value_type(this->cValueP); - - return u.y; -} - - - -ostream& operator<<(ostream& out, value::type_t const& type) { - - string typeName; - - return out << string(xmlrpc_type_name((xmlrpc_type)type)); -} - - - -value_int::value_int(int const cppvalue) { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper(int const cppvalue) { - env_wrap env; - - this->valueP = xmlrpc_int_new(&env.env_c, cppvalue); - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(this->valueP); - } - }; - - cWrapper wrapper(cppvalue); - - this->instantiate(wrapper.valueP); -} - - - -value_int::value_int(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_INT) - throw(error("Not integer type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -value_int::operator int() const { - - this->validateInstantiated(); - - int retval; - env_wrap env; - - xmlrpc_read_int(&env.env_c, this->cValueP, &retval); - throwIfError(env); - - return retval; -} - - - -int -value_int::cvalue() const { - - return static_cast(*this); -} - - - -value_double::value_double(double const cppvalue) { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper(double const cppvalue) { - env_wrap env; - - this->valueP = xmlrpc_double_new(&env.env_c, cppvalue); - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(this->valueP); - } - }; - - this->instantiate(cWrapper(cppvalue).valueP); -} - - - -value_double::value_double(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_DOUBLE) - throw(error("Not double type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -value_double::operator double() const { - - this->validateInstantiated(); - - double retval; - - env_wrap env; - - xmlrpc_read_double(&env.env_c, this->cValueP, &retval); - throwIfError(env); - - return retval; -} - - - -double -value_double::cvalue() const { - - return static_cast(*this); -} - - - -value_boolean::value_boolean(bool const cppvalue) { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper(xmlrpc_bool const cppvalue) { - env_wrap env; - - this->valueP = xmlrpc_bool_new(&env.env_c, cppvalue); - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(this->valueP); - } - }; - - cWrapper wrapper(cppvalue); - - this->instantiate(wrapper.valueP); -} - - - -value_boolean::value_boolean(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_BOOLEAN) - throw(error("Not boolean type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -value_boolean::operator bool() const { - - this->validateInstantiated(); - - xmlrpc_bool retval; - - env_wrap env; - - xmlrpc_read_bool(&env.env_c, this->cValueP, &retval); - throwIfError(env); - - return (retval != false); -} - - - -bool -value_boolean::cvalue() const { - - return static_cast(*this); -} - - - -value_datetime::value_datetime(string const cppvalue) { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper(string const cppvalue) { - env_wrap env; - - this->valueP = xmlrpc_datetime_new_str(&env.env_c, - cppvalue.c_str()); - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(this->valueP); - } - }; - - cWrapper wrapper(cppvalue); - - this->instantiate(wrapper.valueP); -} - - - -value_datetime::value_datetime(xmlrpc_datetime const cppvalue) { - - cDatetimeValueWrapper wrapper(cppvalue); - - this->instantiate(wrapper.valueP); -} - - - -value_datetime::value_datetime(time_t const cppvalue) { - - cDatetimeValueWrapper wrapper(cppvalue); - - this->instantiate(wrapper.valueP); -} - - - -#if XMLRPC_HAVE_TIMEVAL -value_datetime::value_datetime(struct timeval const& cppvalue) { - - cDatetimeValueWrapper wrapper(cppvalue); - - this->instantiate(wrapper.valueP); -} -#endif - - - -#if XMLRPC_HAVE_TIMESPEC -value_datetime::value_datetime(struct timespec const& cppvalue) { - - cDatetimeValueWrapper wrapper(cppvalue); - - this->instantiate(wrapper.valueP); -} -#endif - - - -value_datetime::value_datetime(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_DATETIME) - throw(error("Not datetime type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -value_datetime::operator xmlrpc_datetime() const { - - this->validateInstantiated(); - - xmlrpc_datetime retval; - env_wrap env; - - xmlrpc_read_datetime(&env.env_c, this->cValueP, &retval); - throwIfError(env); - - return retval; -} - - - -value_datetime::operator time_t() const { - - this->validateInstantiated(); - - time_t retval; - env_wrap env; - - xmlrpc_read_datetime_sec(&env.env_c, this->cValueP, &retval); - throwIfError(env); - - return retval; -} - - - -#if XMLRPC_HAVE_TIMEVAL - -value_datetime::operator timeval() const { - - this->validateInstantiated(); - - struct timeval retval; - env_wrap env; - - xmlrpc_read_datetime_timeval(&env.env_c, this->cValueP, &retval); - throwIfError(env); - - return retval; -} -#endif - - - -#if XMLRPC_HAVE_TIMESPEC - -value_datetime::operator timespec() const { - - this->validateInstantiated(); - - struct timespec retval; - env_wrap env; - - xmlrpc_read_datetime_timespec(&env.env_c, this->cValueP, &retval); - throwIfError(env); - - return retval; -} -#endif - - - -time_t -value_datetime::cvalue() const { - - return static_cast(*this); -} - - - -string -value_datetime::iso8601Value() const { - - string retval; - - this->validateInstantiated(); - - const char * iso8601; - env_wrap env; - - xmlrpc_read_datetime_8601(&env.env_c, this->cValueP, &iso8601); - throwIfError(env); - - retval = iso8601; - - xmlrpc_strfree(iso8601); - - return retval; -} - - - -class cNewStringWrapper { -public: - xmlrpc_value * valueP; - - cNewStringWrapper(string const cppvalue, - value_string::nlCode const nlCode) { - env_wrap env; - - switch (nlCode) { - case value_string::nlCode_all: - this->valueP = xmlrpc_string_new_lp(&env.env_c, - cppvalue.length(), - cppvalue.c_str()); - break; - case value_string::nlCode_lf: - this->valueP = xmlrpc_string_new_lp_cr(&env.env_c, - cppvalue.length(), - cppvalue.c_str()); - break; - default: - throw(error("Newline encoding argument to value_string " - "constructor is not one of the defined " - "enumerations of value_string::nlCode")); - } - throwIfError(env); - } - ~cNewStringWrapper() { - xmlrpc_DECREF(this->valueP); - } -}; - - - -value_string::value_string(std::string const& cppvalue, - value_string::nlCode const nlCode) { - - cNewStringWrapper wrapper(cppvalue, nlCode); - - this->instantiate(wrapper.valueP); -} - - - -value_string::value_string(std::string const& cppvalue) { - - cNewStringWrapper wrapper(cppvalue, nlCode_all); - - this->instantiate(wrapper.valueP); -} - - - -value_string::value_string(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_STRING) - throw(error("Not string type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -std::string -value_string::crlfValue() const { - - class cWrapper { - public: - const char * str; - size_t length; - cWrapper(xmlrpc_value * valueP) { - env_wrap env; - - xmlrpc_read_string_lp_crlf(&env.env_c, valueP, &length, &str); - throwIfError(env); - } - ~cWrapper() { - free((char*)str); - } - }; - - this->validateInstantiated(); - - cWrapper wrapper(this->cValueP); - - return string(wrapper.str, wrapper.length); -} - - - -void -value_string::validate() const { -/*---------------------------------------------------------------------------- - Throw an error if the value contains non-XML characters, so that if it - were serialized into a call or response, it would not be valid XML, and - therefore not proper XML-RPC. - - Note that the object must have the ability to have this property (i.e. it - is possible to construct an object that fails this validation) because of - the poor original specification of XML-RPC. Some recipients of XML-RPC - don't mind it being invalid XML. ------------------------------------------------------------------------------*/ - env_wrap env; - - xmlrpc_string_validate(&env.env_c, this->cValueP); - - throwIfError(env); -} - - - -value_string::operator string() const { - - this->validateInstantiated(); - - cStringWrapper adapter(this->cValueP); - - return string(adapter.str, adapter.length); -} - - - -std::string -value_string::cvalue() const { - - return static_cast(*this); -} - - - -value_bytestring::value_bytestring( - vector const& cppvalue) { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper(vector const& cppvalue) { - env_wrap env; - - this->valueP = - xmlrpc_base64_new(&env.env_c, cppvalue.size(), &cppvalue[0]); - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(this->valueP); - } - }; - - cWrapper wrapper(cppvalue); - - this->instantiate(wrapper.valueP); -} - - - -value_bytestring::value_bytestring(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_BYTESTRING) - throw(error("Not byte string type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -vector -value_bytestring::vectorUcharValue() const { - - class cWrapper { - public: - const unsigned char * contents; - size_t length; - - cWrapper(xmlrpc_value * const valueP) { - env_wrap env; - - xmlrpc_read_base64(&env.env_c, valueP, &length, &contents); - throwIfError(env); - } - ~cWrapper() { - free((void*)contents); - } - }; - - this->validateInstantiated(); - - cWrapper wrapper(this->cValueP); - - return vector(&wrapper.contents[0], - &wrapper.contents[wrapper.length]); -} - - - -vector -value_bytestring::cvalue() const { - - return this->vectorUcharValue(); -} - - - -size_t -value_bytestring::length() const { - - this->validateInstantiated(); - - env_wrap env; - size_t length; - - xmlrpc_read_base64_size(&env.env_c, this->cValueP, &length); - throwIfError(env); - - return length; -} - - - -value_array::value_array(vector const& cppvalue) { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper() { - env_wrap env; - - this->valueP = xmlrpc_array_new(&env.env_c); - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(this->valueP); - } - }; - - cWrapper wrapper; - - vector::const_iterator i; - for (i = cppvalue.begin(); i != cppvalue.end(); ++i) - i->appendToCArray(wrapper.valueP); - - this->instantiate(wrapper.valueP); -} - - - -value_array::value_array(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_ARRAY) - throw(error("Not array type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -vector -value_array::vectorValueValue() const { - - this->validateInstantiated(); - - env_wrap env; - - unsigned int arraySize; - - arraySize = xmlrpc_array_size(&env.env_c, this->cValueP); - throwIfError(env); - - vector retval(arraySize); - - for (unsigned int i = 0; i < arraySize; ++i) { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper(xmlrpc_value * const arrayP, - unsigned int const index) { - env_wrap env; - - xmlrpc_array_read_item(&env.env_c, arrayP, index, &valueP); - - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(valueP); - } - }; - - cWrapper wrapper(this->cValueP, i); - - retval[i].instantiate(wrapper.valueP); - } - - return retval; -} - - - -vector -value_array::cvalue() const { - - return this->vectorValueValue(); -} - - - -size_t -value_array::size() const { - - this->validateInstantiated(); - - env_wrap env; - unsigned int arraySize; - - arraySize = xmlrpc_array_size(&env.env_c, this->cValueP); - throwIfError(env); - - return arraySize; -} - - - -value_struct::value_struct( - map const &cppvalue) { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper() { - env_wrap env; - - this->valueP = xmlrpc_struct_new(&env.env_c); - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(this->valueP); - } - }; - - cWrapper wrapper; - - map::const_iterator i; - for (i = cppvalue.begin(); i != cppvalue.end(); ++i) { - xmlrpc_c::value mapvalue(i->second); - string mapkey(i->first); - mapvalue.addToCStruct(wrapper.valueP, mapkey); - } - - this->instantiate(wrapper.valueP); -} - - - -value_struct::value_struct(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_STRUCT) - throw(error("Not struct type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -value_struct::operator map() const { - - this->validateInstantiated(); - - env_wrap env; - unsigned int structSize; - - structSize = xmlrpc_struct_size(&env.env_c, this->cValueP); - throwIfError(env); - - map retval; - - for (unsigned int i = 0; i < structSize; ++i) { - class cMemberWrapper { - public: - xmlrpc_value * keyP; - xmlrpc_value * valueP; - - cMemberWrapper(xmlrpc_value * const structP, - unsigned int const index) { - - env_wrap env; - - xmlrpc_struct_read_member(&env.env_c, structP, index, - &keyP, &valueP); - - throwIfError(env); - } - ~cMemberWrapper() { - xmlrpc_DECREF(keyP); - xmlrpc_DECREF(valueP); - } - }; - - cMemberWrapper memberWrapper(this->cValueP, i); - - cStringWrapper keyWrapper(memberWrapper.keyP); - - string const key(keyWrapper.str, keyWrapper.length); - - retval[key] = xmlrpc_c::value(memberWrapper.valueP); - } - - return retval; -} - - - -map -value_struct::cvalue() const { - - return static_cast >(*this); -} - - - -value_nil::value_nil() { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper() { - env_wrap env; - - this->valueP = xmlrpc_nil_new(&env.env_c); - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(this->valueP); - } - }; - - cWrapper wrapper; - - this->instantiate(wrapper.valueP); -} - - - -value_nil::value_nil(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_NIL) - throw(error("Not nil type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -void * -value_nil::cvalue() const { - - return NULL; -} - - - -value_i8::value_i8(xmlrpc_int64 const cppvalue) { - - class cWrapper { - public: - xmlrpc_value * valueP; - - cWrapper(xmlrpc_int64 const cppvalue) { - env_wrap env; - - this->valueP = xmlrpc_i8_new(&env.env_c, cppvalue); - throwIfError(env); - } - ~cWrapper() { - xmlrpc_DECREF(this->valueP); - } - }; - - cWrapper wrapper(cppvalue); - - this->instantiate(wrapper.valueP); -} - - - -value_i8::value_i8(xmlrpc_c::value const baseValue) { - - if (baseValue.type() != xmlrpc_c::value::TYPE_I8) - throw(error("Not 64 bit integer type. See type() method")); - else { - this->instantiate(baseValue.cValueP); - } -} - - - -value_i8::operator xmlrpc_int64() const { - - this->validateInstantiated(); - - xmlrpc_int64 retval; - env_wrap env; - - xmlrpc_read_i8(&env.env_c, this->cValueP, &retval); - throwIfError(env); - - return retval; -} - - - -xmlrpc_int64 -value_i8::cvalue() const { - - return static_cast(*this); -} - - - -} // namespace diff --git a/trunk/src/cpp/wininet.cpp b/trunk/src/cpp/wininet.cpp deleted file mode 100644 index 1762968f8..000000000 --- a/trunk/src/cpp/wininet.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/*============================================================================= - wininet.cpp -=============================================================================== - This is the Wininet XML transport of the C++ XML-RPC client library for - Xmlrpc-c. -=============================================================================*/ - -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/girmem.hpp" -using girmem::autoObjectPtr; -using girmem::autoObject; -#include "xmlrpc-c/env_wrap.hpp" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/transport.h" -#include "xmlrpc-c/base_int.h" - -/* transport_config.h defines MUST_BUILD_WININET_CLIENT */ -#include "transport_config.h" - -#include "xmlrpc-c/client_transport.hpp" - - -using namespace std; -using namespace xmlrpc_c; - - -namespace { - -class globalConstant { -public: - globalConstant(); - ~globalConstant(); -}; - - - -globalConstant::globalConstant() { - - // Not thread safe - - xmlrpc_transport_setup setupFn; - -#if MUST_BUILD_WININET_CLIENT - setupFn = xmlrpc_wininet_transport_ops.setup_global_const; -#else - setupFn = NULL; -#endif - if (setupFn) { - env_wrap env; - - setupFn(&env.env_c); // Not thread safe - - if (env.env_c.fault_occurred) - throwf("Failed to do global initialization " - "of Wininet transport code. %s", env.env_c.fault_string); - } -} - - - -globalConstant::~globalConstant() { - - // Not thread safe - - xmlrpc_transport_teardown teardownFn; - -#if MUST_BUILD_WININET_CLIENT - teardownFn = xmlrpc_wininet_transport_ops.teardown_global_const; -#else - teardownFn = NULL; -#endif - if (teardownFn) - teardownFn(); // not thread safe -} - - - -globalConstant globalConst; - // This object is never accessed. Its whole purpose to to be born and - // to die, which it does automatically as part of C++ program - // program initialization and termination. - -} // namespace - - -namespace xmlrpc_c { - -carriageParm_wininet0::carriageParm_wininet0( - string const serverUrl - ) { - - this->instantiate(serverUrl); -} - - - -carriageParm_wininet0Ptr::carriageParm_wininet0Ptr() { - // Base class constructor will construct pointer that points to nothing -} - - - -carriageParm_wininet0Ptr::carriageParm_wininet0Ptr( - carriageParm_wininet0 * const carriageParmP) { - this->point(carriageParmP); -} - - - -carriageParm_wininet0 * -carriageParm_wininet0Ptr::operator->() const { - - autoObject * const p(this->objectP); - return dynamic_cast(p); -} - - - -#if MUST_BUILD_WININET_CLIENT - -clientXmlTransport_wininet::clientXmlTransport_wininet( - bool const allowInvalidSslCerts - ) { - - struct xmlrpc_wininet_xportparms transportParms; - - transportParms.allowInvalidSSLCerts = allowInvalidSslCerts; - - this->c_transportOpsP = &xmlrpc_wininet_transport_ops; - - env_wrap env; - - xmlrpc_wininet_transport_ops.create( - &env.env_c, 0, "", "", - &transportParms, XMLRPC_WXPSIZE(allowInvalidSSLCerts), - &this->c_transportP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - -#else // MUST_BUILD_WININET_CLIENT - -clientXmlTransport_wininet::clientXmlTransport_wininet(bool const) { - - throw(error("There is no Wininet client XML transport " - "in this XML-RPC client library")); -} - -#endif - - - -clientXmlTransport_wininet::~clientXmlTransport_wininet() { - - this->c_transportOpsP->destroy(this->c_transportP); -} - -} // namespace diff --git a/trunk/src/cpp/xml.cpp b/trunk/src/cpp/xml.cpp deleted file mode 100644 index 90ab2a4e9..000000000 --- a/trunk/src/cpp/xml.cpp +++ /dev/null @@ -1,312 +0,0 @@ -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/env_wrap.hpp" - -#include "xmlrpc-c/xml.hpp" - -using namespace std; -using namespace xmlrpc_c; - - -namespace { - -class cValueWrapper { -/*---------------------------------------------------------------------------- - Use an object of this class to set up to remove a reference to an - xmlrpc_value object (a C object with manual reference management) - at the end of a scope -- even if the scope ends with a throw. ------------------------------------------------------------------------------*/ -public: - xmlrpc_value * const valueP; - cValueWrapper(xmlrpc_value * valueP) : valueP(valueP) {} - ~cValueWrapper() { xmlrpc_DECREF(valueP); } -}; - - - -class cStringWrapper { -public: - const char * const cString; - cStringWrapper(const char * const cString) : cString(cString) {} - ~cStringWrapper() { xmlrpc_strfree(cString); } -}; - - - -class memblockWrapper { - xmlrpc_mem_block * const memblockP; -public: - memblockWrapper(xmlrpc_mem_block * const memblockP) : - memblockP(memblockP) {} - - ~memblockWrapper() { - XMLRPC_MEMBLOCK_FREE(char, memblockP); - } -}; - - - -xmlrpc_value * -cArrayFromParamList(paramList const& paramList) { - - env_wrap env; - - xmlrpc_value * paramArrayP; - - paramArrayP = xmlrpc_array_new(&env.env_c); - if (!env.env_c.fault_occurred) { - for (unsigned int i = 0; - i < paramList.size() && !env.env_c.fault_occurred; - ++i) { - cValueWrapper const param(paramList[i].cValue()); - - xmlrpc_array_append_item(&env.env_c, paramArrayP, param.valueP); - } - } - if (env.env_c.fault_occurred) { - xmlrpc_DECREF(paramArrayP); - throw(error(env.env_c.fault_string)); - } - return paramArrayP; -} - - - -paramList const -paramListFromCArray(xmlrpc_value * const cArrayP) { - - paramList retval; - env_wrap env; - - unsigned int const nParam(xmlrpc_array_size(&env.env_c, cArrayP)); - - if (!env.env_c.fault_occurred) { - for (unsigned int i = 0; - i < nParam && !env.env_c.fault_occurred; - ++i) { - - xmlrpc_value * cParamP; - - xmlrpc_array_read_item(&env.env_c, cArrayP, i, &cParamP); - - if (!env.env_c.fault_occurred) { - - cValueWrapper const paramAuto(cParamP); - // Causes xmlrpc_DECREF(cParamP) at end of scope - - retval.add(cParamP); - } - } - } - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); - - return retval; -} - - - -} // namespace - - -namespace xmlrpc_c { -namespace xml { - - -void -generateCall(string const& methodName, - paramList const& paramList, - xmlrpc_dialect const dialect, - string * const callXmlP) { -/*---------------------------------------------------------------------------- - Generate the XML for an XML-RPC call, given a method name and parameter - list. - - Use dialect 'dialect' of XML-RPC. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * callXmlMP; - env_wrap env; - - callXmlMP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); - if (!env.env_c.fault_occurred) { - memblockWrapper callXmlHolder(callXmlMP); - // Makes callXmlMP get freed at end of scope - - xmlrpc_value * const paramArrayP(cArrayFromParamList(paramList)); - - xmlrpc_serialize_call2(&env.env_c, callXmlMP, methodName.c_str(), - paramArrayP, dialect); - - *callXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, callXmlMP), - XMLRPC_MEMBLOCK_SIZE(char, callXmlMP)); - - xmlrpc_DECREF(paramArrayP); - } - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -generateCall(string const& methodName, - paramList const& paramList, - string * const callXmlP) { - - generateCall(methodName, paramList, xmlrpc_dialect_i8, callXmlP); - -} - - - -void -parseCall(string const& callXml, - string * const methodNameP, - paramList * const paramListP) { - - env_wrap env; - const char * c_methodName; - xmlrpc_value * c_paramArrayP; - - xmlrpc_parse_call(&env.env_c, callXml.c_str(), callXml.size(), - &c_methodName, &c_paramArrayP); - - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); - else { - cValueWrapper const paramListAuto(c_paramArrayP); - // Causes XMLRPC_decref(c_paramArrayP) at end of scope - cStringWrapper const methodNameAuto(c_methodName); - // Causes xmlrpc_strfree(c_methodName) at end of scope - - *paramListP = paramListFromCArray(c_paramArrayP); - *methodNameP = string(c_methodName); - } -} - - - -void -generateResponse(rpcOutcome const& outcome, - xmlrpc_dialect const dialect, - string * const respXmlP) { -/*---------------------------------------------------------------------------- - Generate the XML for an XML-RPC resp, given the RPC outcome. - - Use dialect 'dialect' of XML-RPC. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * respXmlMP; - env_wrap env; - - respXmlMP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); - if (!env.env_c.fault_occurred) { - memblockWrapper respXmlAuto(respXmlMP); - // Makes respXmlMP get freed at end of scope - - if (outcome.succeeded()) { - cValueWrapper cResult(outcome.getResult().cValue()); - - xmlrpc_serialize_response2(&env.env_c, respXmlMP, - cResult.valueP, dialect); - - *respXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, respXmlMP), - XMLRPC_MEMBLOCK_SIZE(char, respXmlMP)); - } else { - env_wrap cFault; - - xmlrpc_env_set_fault(&cFault.env_c, outcome.getFault().getCode(), - outcome.getFault().getDescription().c_str()); - - xmlrpc_serialize_fault(&env.env_c, respXmlMP, &cFault.env_c); - - *respXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, respXmlMP), - XMLRPC_MEMBLOCK_SIZE(char, respXmlMP)); - } - } - if (env.env_c.fault_occurred) - throw(error(env.env_c.fault_string)); -} - - - -void -generateResponse(rpcOutcome const& outcome, - string * const respXmlP) { - - generateResponse(outcome, xmlrpc_dialect_i8, respXmlP); - -} - - - -void -parseResponse(string const& responseXml, - rpcOutcome * const outcomeP) { -/*---------------------------------------------------------------------------- - Parse the XML for an XML-RPC response into an XML-RPC result value. ------------------------------------------------------------------------------*/ - env_wrap env; - - xmlrpc_value * c_resultP; - int faultCode; - const char * faultString; - - xmlrpc_parse_response2(&env.env_c, responseXml.c_str(), responseXml.size(), - &c_resultP, &faultCode, &faultString); - - if (env.env_c.fault_occurred) - throwf("Unable to find XML-RPC response in what server sent back. %s", - env.env_c.fault_string); - else { - if (faultString) { - *outcomeP = - rpcOutcome(fault(faultString, - static_cast(faultCode))); - xmlrpc_strfree(faultString); - } else { - XMLRPC_ASSERT_VALUE_OK(c_resultP); - *outcomeP = rpcOutcome(value(c_resultP)); - xmlrpc_DECREF(c_resultP); - } - } -} - - - -void -parseSuccessfulResponse(string const& responseXml, - value * const resultP) { -/*---------------------------------------------------------------------------- - Same as parseResponse(), but expects the response to indicate success; - throws an error if it doesn't. ------------------------------------------------------------------------------*/ - rpcOutcome outcome; - - parseResponse(responseXml, &outcome); - - if (!outcome.succeeded()) - throwf("RPC response indicates it failed. %s", - outcome.getFault().getDescription().c_str()); - - *resultP = outcome.getResult(); -} - - - -void -trace(string const& label, - string const& xml) { - - xmlrpc_traceXml(label.c_str(), xml.c_str(), xml.size()); - -} - - -}} // namespace diff --git a/trunk/src/double.c b/trunk/src/double.c deleted file mode 100644 index 58f8f0056..000000000 --- a/trunk/src/double.c +++ /dev/null @@ -1,285 +0,0 @@ -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/util_int.h" - -#include "double.h" - -typedef struct { - char * bytes; - /* NULL means there has been a memory allocation failure. - bufferConcat() still works in this case, because we dont' want - callers to have to deal with the out-of-memory possibility; - it's just a no-op. - */ - char * next; - char * end; -} buffer; - - -static void -bufferInit(buffer * const bufferP) { - - unsigned int const initialSize = 64; - - bufferP->bytes = malloc(initialSize); - - if (bufferP->bytes) { - bufferP->next = bufferP->bytes; - bufferP->end = bufferP->bytes + initialSize; - } -} - - - -static void -bufferConcat(buffer * const bufferP, - char const newChar) { - - if (bufferP->bytes) { - if (bufferP->next >= bufferP->end) { - size_t const oldSize = bufferP->end - bufferP->bytes; - size_t const newSize = oldSize + 64; - bufferP->bytes = realloc(bufferP->bytes, newSize); - bufferP->next = bufferP->bytes + oldSize; - bufferP->end = bufferP->bytes + newSize; - } - - if (bufferP->bytes) - *(bufferP->next++) = newChar; - } -} - - - -static char -digitChar(unsigned int const digitValue) { - - assert(digitValue < 10); - - return '0' + digitValue; -} - - - -static unsigned int -leadDigit(double const arg, - double const precision) { -/*---------------------------------------------------------------------------- - Assuming 'arg' has one digit before the decimal point (which may be zero), - return that digit. - - We assume the precision of 'arg' is plus or minus 'precision', and bias our - estimation of the first digit up. We do that bias in order to bias toward - shorter decimal ciphers: It's cleaner to consider 2.9999999 to be 3 than to - consider 3 to be 2.999999. ------------------------------------------------------------------------------*/ - return MIN(9, (unsigned int)(arg + precision)); -} - - - -static void -floatWhole(double const value, - buffer * const formattedP, - double * const formattedAmountP, - double * const precisionP) { -/*---------------------------------------------------------------------------- - Format into *formattedP the whole part of 'value', i.e. the part before the - decimal point. - - 'value' is a finite number. - - Return as *formattedAmountP the whole amount; e.g. if 'value' is 35.2, - we return *formattedAmountP = 35. - - As there is imprecision involved in our calculations, return as *precisionP - the maximum difference there may be be between 'double' and what we - formatted. ------------------------------------------------------------------------------*/ - if (value < 1.0) { - /* No digits to add to the whole part */ - *formattedAmountP = 0; - *precisionP = DBL_EPSILON; - } else { - double nonLeastAmount; - double nonLeastPrecision; - unsigned int leastValue; - - /* Add all digits but the least significant to *formattedP */ - - floatWhole(value/10.0, formattedP, &nonLeastAmount, - &nonLeastPrecision); - - /* Add the least significant digit to *formattedP */ - - if (nonLeastPrecision > 0.1) { - /* We're down in the noise now; no point in showing any more - significant digits (and we couldn't if we wanted to, because - nonLeastPrecision * 10 might be more than 10 less than - 'value'). - */ - leastValue = 0; - } else - leastValue = leadDigit(value - nonLeastAmount * 10, - nonLeastPrecision * 10); - - bufferConcat(formattedP, digitChar(leastValue)); - - *formattedAmountP = nonLeastAmount * 10 + leastValue; - *precisionP = nonLeastPrecision * 10; - } -} - - - -static void -floatFractionPart(double const value, - double const wholePrecision, - buffer * const formattedP) { -/*---------------------------------------------------------------------------- - Serialize the part that comes after the decimal point, assuming there - is something (nonzero) before the decimal point that uses up all but - 'wholePrecision' of the available precision. ------------------------------------------------------------------------------*/ - double precision; - double d; - - assert(value < 1.0); - - for (d = value, precision = wholePrecision; - d > precision; - precision *= 10) { - - unsigned int digitValue; - - d *= 10; - digitValue = leadDigit(d, precision); - - d -= digitValue; - - assert(d < 1.0); - - bufferConcat(formattedP, digitChar(digitValue)); - } -} - - - -static void -floatFraction(double const value, - buffer * const formattedP) { -/*---------------------------------------------------------------------------- - Serialize the part that comes after the decimal point, assuming there - is nothing before the decimal point. ------------------------------------------------------------------------------*/ - double precision; - double d; - - assert(0.0 < value && value < 1.0); - - /* Do the leading zeroes, which eat no precision */ - - for (d = value * 10; d < 1.0; d *= 10) - bufferConcat(formattedP, '0'); - - /* Now the significant digits */ - - precision = DBL_EPSILON; - - while (d > precision) { - unsigned int const digitValue = leadDigit(d, precision); - - bufferConcat(formattedP, digitChar(digitValue)); - - d -= digitValue; - - assert(d < 1.0); - - d *= 10; - precision *= 10; - } -} - - - -static void -floatUnsigned(double const value, - buffer * const formattedP) { -/*---------------------------------------------------------------------------- - Serialize 'value', assuming it is positive, and append it to *formattedP, - without a sign. ------------------------------------------------------------------------------*/ - assert(value >= 0.0); - - if (value >= 1.0) { - double wholePart; - double wholePrecision; - - floatWhole(value, formattedP, &wholePart, &wholePrecision); - - if (wholePrecision >= 1.0) { - /* We ran out of precision before we got to the decimal - point - */ - } else { - double const fractionPart = value - wholePart; - - if (fractionPart > wholePrecision) { - bufferConcat(formattedP, '.'); - - floatFractionPart(fractionPart, wholePrecision, - formattedP); - } - } - } else { - bufferConcat(formattedP, '0'); - - if (value > 0.0) { - bufferConcat(formattedP, '.'); - floatFraction(value, formattedP); - } - } -} - - - -void -xmlrpc_formatFloat(xmlrpc_env * const envP, - double const value, - const char ** const formattedP) { -/*---------------------------------------------------------------------------- - Format the value 'value' in XML-RPC - just the characters that represent - the numbers - none of the XML markup. E.g. "1.234". - - Assume 'value' is finite, as there is no such thing as an infinite or - NaN value in XML-RPC. ------------------------------------------------------------------------------*/ - double absvalue; - buffer formatted; - - assert(XMLRPC_FINITE(value)); - - bufferInit(&formatted); - - if (value < 0.0) { - bufferConcat(&formatted, '-'); - absvalue = - value; - } else - absvalue = value; - - floatUnsigned(absvalue, &formatted); - - bufferConcat(&formatted, '\0'); - - if (formatted.bytes == NULL) - xmlrpc_faultf(envP, "Couldn't allocate memory to format %g", - value); - else - *formattedP = formatted.bytes; -} diff --git a/trunk/src/double.h b/trunk/src/double.h deleted file mode 100644 index dc563c2cd..000000000 --- a/trunk/src/double.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef DOUBLE_H_INCLUDED -#define DOUBLE_H_INCLUDED - -#include "xmlrpc-c/util.h" - -void -xmlrpc_formatFloat(xmlrpc_env * const envP, - double const value, - const char ** const formattedP); - -#endif diff --git a/trunk/src/json.c b/trunk/src/json.c deleted file mode 100644 index be0257722..000000000 --- a/trunk/src/json.c +++ /dev/null @@ -1,1485 +0,0 @@ -/*============================================================================= - json.c -=============================================================================== - - Bo Lorentsen (bl@lue.dk) had the idea to do XML-RPC values in JSON - and wrote the original version of this code in February and March - 2010. - - Bryan Henderson restructured the code and improved diagnostic information - (made it tell you where the JSON is screwed up) before its first release - in XML-RPC for C and C++ in Release 1.22. - - JSON: RFC-4627 -=============================================================================*/ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "xmlrpc-c/json.h" -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/string_number.h" - - - -/*============================================================================= - Tokenizer for the json parser -=============================================================================*/ -enum ttype { - typeNone, - typeOpenBrace, - typeCloseBrace, - typeOpenBracket, - typeCloseBracket, - typeColon, - typeComma, - typeString, - typeInteger, - typeFloat, - typeNull, - typeUndefined, - typeTrue, - typeFalse, - typeEof, -} ; - -static const char * -tokTypeName(enum ttype const type) { - - switch (type) { - case typeNone: return "None"; - case typeOpenBrace: return "Open brace"; - case typeCloseBrace: return "Close brace"; - case typeOpenBracket: return "Open bracket"; - case typeCloseBracket: return "Close bracket"; - case typeColon: return "Colon"; - case typeComma: return "Comma"; - case typeString: return "String"; - case typeInteger: return "Integer"; - case typeFloat: return "Float"; - case typeNull: return "Null"; - case typeUndefined: return "Undefined"; - case typeTrue: return "True"; - case typeFalse: return "False"; - case typeEof: return "Eof"; - default: return "???"; - } -} - - - -typedef struct { - const char * original; - size_t size; - const char * begin; - const char * end; - enum ttype type; -} Tokenizer; - - - -static void -initializeTokenizer(Tokenizer * const tokP, - const char * const str) { - - tokP->original = str; - tokP->end = str; /* end of the "previous" token */ - tokP->type = typeNone; -} - - - -static void -terminateTokenizer(Tokenizer * const tokP ATTR_UNUSED ) { - -} - - - -struct docPosition { - /* A position in the document, as meaningful to the user */ - unsigned int lineNum; /* First line is 1 */ - unsigned int colNum; /* First column is 1 */ -}; - - - -static struct docPosition -currentDocumentPosition(Tokenizer * const tokP) { -/*---------------------------------------------------------------------------- - Return the document position (line & column) of the start of the current - token ------------------------------------------------------------------------------*/ - struct docPosition retval; - - unsigned int curLine; - unsigned int curCol; - const char * cursor; - - curLine = 0; - curCol = 0; - - for (cursor = tokP->original; cursor < tokP->begin; ++cursor) { - ++curCol; - - if (*cursor == '\n') { - ++curLine; - curCol = 0; - } - } - retval.lineNum = curLine + 1; - retval.colNum = curCol + 1; - - return retval; -} - - - -static void -setParseErr(xmlrpc_env * const envP, - Tokenizer * const tokP, - const char * const format, - ...) { - - struct docPosition const pos = currentDocumentPosition(tokP); - - va_list args; - const char * msg; - - XMLRPC_ASSERT(envP != NULL); - XMLRPC_ASSERT(format != NULL); - - va_start(args, format); - - xmlrpc_vasprintf(&msg, format, args); - - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "JSON parse error at Line %u, Column %u: %s", - pos.lineNum, pos.colNum, msg); - - xmlrpc_strfree(msg); - - va_end(args); -} - - - -static void -finishStringToken(xmlrpc_env * const envP, - Tokenizer * const tokP) { - - ++tokP->end; - - while (*tokP->end != '"' && *tokP->end != '\0' && !envP->fault_occurred) { - if (*tokP->end == '\\') { - ++tokP->end; - switch (*tokP->end) { - case '"': - case '\\': - case '/': - case 'b': - case 'f': - case 'n': - case 'r': - case 't': - ++tokP->end; - break; - case 'u': { - const char * cur; - - ++tokP->end; - - cur = tokP->end; - - while (isxdigit(*cur) && cur - tokP->end < 4) - ++cur; - - if (cur - tokP->end < 4) - setParseErr(envP, tokP, - "hex unicode must contain 4 digits. " - "There are only %u here", cur - tokP->end); - else - tokP->end = cur; - } break; - case '\0': - setParseErr(envP, tokP, "JSON document ends in the middle " - "of a backslash escape sequence"); - break; - default: - setParseErr(envP, tokP, "unknown escape character " - "after backslash: '%c'", *tokP->end); - } - } else - ++tokP->end; - } - if (!envP->fault_occurred) { - if (*tokP->end == '\0') - setParseErr(envP, tokP, "JSON document ends in the middle " - "of a string literal"); - else { - ++tokP->end; - tokP->size = (tokP->end - tokP->begin) - 1; - } - } -} - - - -static bool -isInteger(const char * const token, - unsigned int const tokSize) { - - if (tokSize < 1) - return false; - else { - unsigned int i; - - i = 0; - - if (token[0] == '-') - ++i; - - while (i < tokSize) { - if (!isdigit(token[i])) - return false; - ++i; - } - return true; - } -} - - - -static bool -isFloat(const char * const token, - unsigned int const tokSize) { -/*---------------------------------------------------------------------------- - The token 'token', of size 'tokSize' is a syntactically valid floating - point number. - - N.B. This is true of any integer. - - We don't accept plus signs. - - Examples of valid floating point: 0, 32, 32.5, , 32.500, - 32.5E4 -5, 32.5E-4, 005. ------------------------------------------------------------------------------*/ - unsigned int i; - bool seenPeriod; - bool seenDigit; - - seenPeriod = false; - seenDigit = false; - i = 0; - - if (tokSize >= 1 && token[0] == '-') - ++i; - - while (i < tokSize) { - char const c = token[i]; - - if (c == 'e') - return isInteger(&token[i], tokSize - i); - else if (c == '.') { - if (seenPeriod) { - /* It's a second period */ - return false; - } else { - seenPeriod = true; - } - } else if (isdigit(c)) - seenDigit = true; - else - return false; - ++i; - } - if (seenDigit) - return true; - else - return false; -} - - - -static bool -isWordChar(char const candidate) { -/*---------------------------------------------------------------------------- - Return true iff 'candidate' is a character that can be in a "word" token. - A word token is a multi-character token that is either a JSON keyword or a - number. ------------------------------------------------------------------------------*/ - return (isalnum(candidate) || candidate == '.' || candidate == '-'); -} - - - -static void -finishAlphanumericWordToken(Tokenizer * const tokP) { - - ++tokP->end; - - while (isWordChar(*tokP->end)) - ++tokP->end; - - tokP->size = tokP->end - tokP->begin; -} - - - -static void -finishDelimiterToken(Tokenizer * const tokP) { - - ++tokP->end; - tokP->size = tokP->end - tokP->begin; -} - - - -static bool -atComment(Tokenizer * const tokP) { - - return (*tokP->begin == '/' && *(tokP->begin + 1) == '/'); -} - - - -static void -advancePastWhiteSpace(Tokenizer * const tokP) { - - while (isspace(*tokP->begin)) - ++tokP->begin; -} - - - -static void -advancePastComments(Tokenizer * const tokP) { -/*---------------------------------------------------------------------------- - Advance the pointer over any comments. ------------------------------------------------------------------------------*/ - while (atComment(tokP)) { - /* A comment ends at a newline or end of document */ - while (*tokP->begin != '\n' && *tokP->begin != '\0') - ++tokP->begin; - } -} - - - -static void -advanceToNextToken(Tokenizer * const tokP) { -/*---------------------------------------------------------------------------- - Advance the pointer over any white space and comments to the next - token, or end of document, whichever comes first. ------------------------------------------------------------------------------*/ - - while (*tokP->begin != '\0' && - (isspace(*tokP->begin) || atComment(tokP))) { - - advancePastWhiteSpace(tokP); - - advancePastComments(tokP); - } -} - - - -static void -getToken(xmlrpc_env * const envP, - Tokenizer * const tokP) { - - /* The token starts where the last one left off */ - tokP->begin = tokP->end; - - advanceToNextToken(tokP); - - if (*tokP->begin == '\0') { - /* End of document */ - tokP->end = tokP->begin; - tokP->type = typeEof; - tokP->size = tokP->end - tokP->begin; - } else { - tokP->end = tokP->begin; /* initial value */ - - if (*tokP->begin == '{') { - finishDelimiterToken(tokP); - tokP->type = typeOpenBrace; - } else if (*tokP->begin == '}') { - finishDelimiterToken(tokP); - tokP->type = typeCloseBrace; - } else if (*tokP->begin == '[') { - finishDelimiterToken(tokP); - tokP->type = typeOpenBracket; - } else if (*tokP->begin == ']') { - finishDelimiterToken(tokP); - tokP->type = typeCloseBracket; - } else if (*tokP->begin == ':') { - finishDelimiterToken(tokP); - tokP->type = typeColon; - } else if (*tokP->begin == ',') { - finishDelimiterToken(tokP); - tokP->type = typeComma; - } else if (*tokP->begin == '"') { - finishStringToken(envP, tokP); - - if (!envP->fault_occurred) - tokP->type = typeString; - } else { - if (isWordChar(*tokP->begin)) { - finishAlphanumericWordToken(tokP); - - if (isInteger(tokP->begin, tokP->size)) - tokP->type = typeInteger; - else if (isFloat(tokP->begin, tokP->size)) - tokP->type = typeFloat; - else if (xmlrpc_strneq(tokP->begin, "null", tokP->size)) - tokP->type = typeNull; - else if (xmlrpc_strneq(tokP->begin, "undefined", tokP->size)) - tokP->type = typeUndefined; - else if(xmlrpc_strneq(tokP->begin, "false", tokP->size)) - tokP->type = typeFalse; - else if(xmlrpc_strneq(tokP->begin, "true", tokP->size)) - tokP->type = typeTrue; - else - setParseErr(envP, tokP, "Invalid word token -- " - "Not a valid integer, floating point " - "number, 'null', 'true', or 'false'"); - } else { - setParseErr(envP, tokP, - "Not a valid token -- starts with '%c'; " - "a valid token starts with " - "one of []{}:,\"-. or digit or letter", - *tokP->begin); - } - } - } -} - - - -/*===========================================================================*/ - - - -static int -utf8Decode(uint32_t const c, - char * const out) { -/*--------------------------------------------------------------------------- - convert a unicode char to a utf8 char ----------------------------------------------------------------------------*/ - if (c <= 0x7F) { /* 0XXX XXXX one byte */ - out[0] = (char) c; - return 1; - } else if (c <= 0x7FF) { /* 110X XXXX two bytes */ - out[0] = (char)( 0xC0 | (c >> 6) ); - out[1] = (char)( 0x80 | (c & 0x3F) ); - return 2; - } else if (c <= 0xFFFF) { /* 1110 XXXX three bytes */ - out[0] = (char) (0xE0 | (c >> 12)); - out[1] = (char) (0x80 | ((c >> 6) & 0x3F)); - out[2] = (char) (0x80 | (c & 0x3F)); - return 3; - } else if (c <= 0x1FFFFF) { /* 1111 0XXX four bytes */ - out[0] = (char) (0xF0 | (c >> 18)); - out[1] = (char) (0x80 | ((c >> 12) & 0x3F)); - out[2] = (char) (0x80 | ((c >> 6) & 0x3F)); - out[3] = (char) (0x80 | (c & 0x3F)); - return 4; - } else - return 0; -} - - - -static void -getBackslashSequence(xmlrpc_env * const envP, - const char * const cur, - xmlrpc_mem_block * const memBlockP, - unsigned int * const nBytesConsumedP) { - - char buffer[5]; - unsigned int tsize; - - switch (*cur) { - case '"': - buffer[0] = '"'; - tsize = 1; - *nBytesConsumedP = 1; - break; - case '/': - buffer[0] = '/'; - tsize = 1; - *nBytesConsumedP = 1; - break; - case '\\': - buffer[0] = '\\'; - tsize = 1; - *nBytesConsumedP = 1; - break; - case 'b': - buffer[0] = '\b'; - tsize = 1; - *nBytesConsumedP = 1; - break; - case 'f': - buffer[0] = '\f'; - tsize = 1; - *nBytesConsumedP = 1; - break; - case 'n': - buffer[0] = '\n'; - tsize = 1; - *nBytesConsumedP = 1; - break; - case 'r': - buffer[0] = '\r'; - tsize = 1; - *nBytesConsumedP = 1; - break; - case 't': - buffer[0] = '\t'; - tsize = 1; - *nBytesConsumedP = 1; - break; - case 'u': { - long digit; - strncpy(buffer, cur + 1, 4); - digit = strtol(buffer, NULL, 16); - tsize = utf8Decode(digit, buffer); - *nBytesConsumedP = 5; /* uXXXX */ - break; - } - default: - xmlrpc_faultf(envP, "Invalid character after backslash " - "escape: '%c'", *cur); - *nBytesConsumedP = 0; /* quiet compiler warning */ - tsize = 0; /* quiet compiler warning */ - } - if (!envP->fault_occurred) - XMLRPC_MEMBLOCK_APPEND(char, envP, memBlockP, buffer, tsize ); -} - - - -static void -unescapeString(xmlrpc_env * const envP, - const char * const begin, - const char * const end, - xmlrpc_mem_block ** const memBlockPP) { - - xmlrpc_mem_block * memBlockP; - - memBlockP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - - if (!envP->fault_occurred) { - const char * cur; - const char * last; - - cur = begin; - last = cur; - - while (cur != end && !envP->fault_occurred) { - if (*cur == '\\') { - if (cur != last) { - XMLRPC_MEMBLOCK_APPEND( - char, envP, memBlockP, last, cur - last ); - if (!envP->fault_occurred) - last = cur; - } - if (!envP->fault_occurred) { - unsigned int nBytesConsumed; - - cur += 1; /* consume slash */ - - getBackslashSequence(envP, cur, memBlockP, - &nBytesConsumed); - - if (!envP->fault_occurred) { - cur += nBytesConsumed; - last = cur; - } - } - } else - ++cur; - } - if (!envP->fault_occurred) { - if (cur != last) { - XMLRPC_MEMBLOCK_APPEND(char, envP, - memBlockP, last, cur - last ); - } - } - if (!envP->fault_occurred) { - /* Append terminating NUL */ - XMLRPC_MEMBLOCK_APPEND(char, envP, memBlockP, "", 1); - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, memBlockP); - } - *memBlockPP = memBlockP; -} - - - -static xmlrpc_value * -makeUtf8String(xmlrpc_env * const envP, - const char * const begin, - const char * const end) { -/*---------------------------------------------------------------------------- - Copy a json string directly into a string value, and convert any json - escaping (\uXXXX) to something acceptable to the internal string handling. - - Try to do this in as few chunks as possible ! ------------------------------------------------------------------------------*/ - xmlrpc_value * valP; - - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_STRING; - valP->_wcs_block = NULL; - - if (!envP->fault_occurred) - unescapeString(envP, begin, end, &valP->blockP); - - if (envP->fault_occurred) - xmlrpc_DECREF(valP); - } - return valP; -} - - - -static xmlrpc_value * -stringTokenValue(xmlrpc_env * const envP, - Tokenizer * const tokP) { - - xmlrpc_env env; - xmlrpc_value * valP; - - xmlrpc_env_init(&env); - - assert(tokP->end >= tokP->begin + 2); - assert(*tokP->begin == '"'); - assert(*(tokP->end-1) == '"'); - - valP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); - - if (env.fault_occurred) { - setParseErr(envP, tokP, "Error in string token: %s", - env.fault_string); - } - xmlrpc_env_clean(&env); - - return valP; -} - - - -static xmlrpc_value * -integerTokenValue(xmlrpc_env * const envP, - Tokenizer * const tokP) { - - xmlrpc_env env; - char valueString[tokP->size + 1]; - xmlrpc_int64 value; - xmlrpc_value * valP; - - xmlrpc_env_init(&env); - - memcpy(valueString, tokP->begin, tokP->size); - valueString[tokP->size] = '\0'; - - xmlrpc_parse_int64(&env, valueString, &value); - - if (env.fault_occurred) - setParseErr(envP, tokP, "Error in integer token value '%s': %s", - tokP->begin, env.fault_string); - else - valP = xmlrpc_i8_new(envP, value); - - xmlrpc_env_clean(&env); - - return valP; -} - - - -/* Forward declarations for recursion: */ - -static xmlrpc_value * -parseValue(xmlrpc_env * const envP, - Tokenizer * const tokP); - -static xmlrpc_value * -parseList(xmlrpc_env * const envP, - Tokenizer * const tokP); - -static xmlrpc_value * -parseObject(xmlrpc_env * const envP, - Tokenizer * const tokP); - - - -static void -parseListElement(xmlrpc_env * const envP, - Tokenizer * const tokP, - xmlrpc_value * const listArrayP, - bool * const endOfListP) { - - xmlrpc_value * itemP; - - itemP = parseValue(envP, tokP); - - if (!envP->fault_occurred) { - xmlrpc_array_append_item(envP, listArrayP, itemP); - - if (!envP->fault_occurred) { - getToken(envP, tokP); - if (!envP->fault_occurred) { - if (tokP->type == typeComma) { - *endOfListP = false; - } else if (tokP->type == typeCloseBracket) - *endOfListP = true; - else - setParseErr(envP, tokP, - "Need comma or close bracket " - "after array item. Instead we have %s", - tokTypeName(tokP->type)); - } - } - xmlrpc_DECREF(itemP); - } -} - - - -static xmlrpc_value * -parseList(xmlrpc_env * const envP, - Tokenizer * const tokP) { - - xmlrpc_value * retval; - - XMLRPC_ASSERT_ENV_OK(envP); - - retval = xmlrpc_array_new(envP); - - if (!envP->fault_occurred) { - bool endOfList; - for (endOfList = false; !endOfList && !envP->fault_occurred; ) { - getToken(envP,tokP); - - if (!envP->fault_occurred) { - if (tokP->type == typeEof) - endOfList = true; - else if (tokP->type == typeCloseBracket) - endOfList = true; - else - parseListElement(envP, tokP, retval, &endOfList); - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(retval); - } - return retval; -} - - - -static void -parseObjectMemberValue(xmlrpc_env * const envP, - Tokenizer * const tokP, - xmlrpc_value * const keyP, - xmlrpc_value * const objectP) { - - xmlrpc_value * valP; - - getToken(envP,tokP); - - if (!envP->fault_occurred) { - valP = parseValue(envP, tokP); - - if (!envP->fault_occurred) { - xmlrpc_struct_set_value_v(envP, objectP, keyP, valP); - - xmlrpc_DECREF(valP); - } - } -} - - - -static void -parseObjectMember(xmlrpc_env * const envP, - Tokenizer * const tokP, - xmlrpc_value * const objectP) { - - xmlrpc_env env; - xmlrpc_value * keyP; - - xmlrpc_env_init(&env); - - /* The current token is the string which is the member name: */ - assert(tokP->type = typeString); - assert(tokP->end >= tokP->begin + 2); - assert(*tokP->begin == '"'); - assert(*(tokP->end-1) == '"'); - - keyP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); - - if (env.fault_occurred) - setParseErr(envP, tokP, "Error in what is supposed to be " - "the key of a member of an object: %s", - env.fault_string); - else { - getToken(envP, tokP); - - if (!envP->fault_occurred) { - if (tokP->type == typeColon) - parseObjectMemberValue(envP, tokP, keyP, objectP); - else - setParseErr(envP, tokP, - "Need a colon after member key " - "in object. Instead we have %s", - tokTypeName(tokP->type)); - } - xmlrpc_DECREF(keyP); - } - xmlrpc_env_clean(&env); -} - - - -static xmlrpc_value * -parseObject(xmlrpc_env * const envP, - Tokenizer * const tokP) { - - xmlrpc_value * retval; - - XMLRPC_ASSERT_ENV_OK(envP); - - retval = xmlrpc_struct_new(envP); - - if (!envP->fault_occurred) { - bool objectDone; - - objectDone = false; - while (!objectDone && !envP->fault_occurred) { - getToken(envP, tokP); - - if (!envP->fault_occurred) { - if (tokP->type == typeCloseBrace) { - objectDone = true; - } else if (tokP->type == typeString) { - parseObjectMember(envP, tokP, retval); - - if (!envP->fault_occurred) { - getToken(envP, tokP); - - if (!envP->fault_occurred) { - if (tokP->type == typeComma) { - /* member separator; keep going */ - } else if (tokP->type == typeCloseBrace) { - /* No more members in this object */ - objectDone = true; - } else - setParseErr( - envP, tokP, - "Need a comma or close brace after object " - "member. Instead we have %s", - tokTypeName(tokP->type)); - } - } - } else { - setParseErr(envP, tokP, - "Need a string (i.e. starting with " - "a quotation mark) as member key " - "in object, or closing brace to end the " - "object. Instead we have %s", - tokTypeName(tokP->type)); - } - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(retval); - } - return retval; -} - - - - - -static xmlrpc_value * -parseValue(xmlrpc_env * const envP, - Tokenizer * const tokP) { - - xmlrpc_value * retval; - - XMLRPC_ASSERT_ENV_OK(envP); - - switch (tokP->type) { - - case typeOpenBracket: - retval = parseList(envP, tokP); - break; - - case typeOpenBrace: - retval = parseObject(envP, tokP); - break; - - case typeNull: - retval = xmlrpc_nil_new(envP); - break; - - case typeUndefined: - retval = xmlrpc_nil_new(envP); - break; - - case typeFalse: - retval = xmlrpc_bool_new(envP, (xmlrpc_bool)false); - break; - - case typeTrue: - retval = xmlrpc_bool_new(envP, (xmlrpc_bool)true); - break; - - case typeInteger: - retval = integerTokenValue(envP, tokP); - break; - - case typeFloat: - retval = xmlrpc_double_new(envP, strtod(tokP->begin, NULL)); - break; - - case typeString: - retval = stringTokenValue(envP, tokP); - break; - - default: - retval = NULL; - setParseErr(envP, tokP, "Invalid token " - "where a value is supposed to begin: %s. " - "Should be an open bracket, open brace, " - "'null', 'false', 'true', a number, or a string", - tokTypeName(tokP->type)); - } - return retval; -} - - - -xmlrpc_value * -xmlrpc_parse_json(xmlrpc_env * const envP, - const char * const str) { - - xmlrpc_value * retval = retval; - Tokenizer tok; - - XMLRPC_ASSERT_ENV_OK(envP); - - initializeTokenizer(&tok, str); - - getToken(envP, &tok); - - if (!envP->fault_occurred) { - retval = parseValue(envP, &tok); - - if (!envP->fault_occurred) { - getToken(envP, &tok); - - if (!envP->fault_occurred) { - if (tok.type != typeEof) - setParseErr(envP, &tok, "There is junk after the end of " - "the JSON value, to wit a %s token", - tokTypeName(tok.type)); - } - if (envP->fault_occurred) - xmlrpc_DECREF(retval); - } - } - - terminateTokenizer(&tok); - - return retval; -} - - - -/*============================================================================ - Serialize value to JSON -============================================================================*/ - -/* Borrowed from xmlrpc_serialize */ - -static void -formatOut(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - const char * const formatString, ... ) { - - va_list args; - char buffer[1024]; - int rc; - - XMLRPC_ASSERT_ENV_OK(envP); - - va_start(args, formatString); - - rc = XMLRPC_VSNPRINTF(buffer, sizeof(buffer), formatString, args); - - /* Old vsnprintf() (and Windows) fails with return value -1 if the full - string doesn't fit in the buffer. New vsnprintf() puts whatever will - fit in the buffer, and returns the length of the full string - regardless. For us, this truncation is a failure. - */ - - if (rc < 0) - xmlrpc_faultf(envP, "formatOut() overflowed internal buffer"); - else { - unsigned int const formattedLen = rc; - - if (formattedLen + 1 >= (sizeof(buffer))) - xmlrpc_faultf(envP, "formatOut() overflowed internal buffer"); - else - XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, buffer, formattedLen); - } - va_end(args); -} - - - -static void -indent(xmlrpc_env * const envP, - unsigned int const level, - xmlrpc_mem_block * const outP) { - - unsigned int i; - - for (i = 0; i < level * 2 && !envP->fault_occurred; ++i) - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, " ", 1); -} - - - -/* Forward declaration for recursion */ - -static void -serializeValue(xmlrpc_env * const envP, - xmlrpc_value * const valP, - unsigned int const level, - xmlrpc_mem_block * const outP); - - - -static void -appendEscapeSeq(xmlrpc_env * const envP, - xmlrpc_mem_block * const outP, - unsigned char const c) { -/*---------------------------------------------------------------------------- - Append to *outP the escaped representation of 'c'. - - This is e.g. "\t" for tab, or "\u001C" for something exotic. ------------------------------------------------------------------------------*/ - unsigned int size; - char buffer[6+1]; - char slashChar; - /* Character that goes after the backslash, including 'u' for \uHHHH */ - - switch (c) { - case '"' : slashChar = '"'; break; /* U+0022 */ - case '\\': slashChar = '\\'; break; /* U+005C */ - case '\b': slashChar = 'b'; break; /* U+0008 */ - case '\f': slashChar = 'f'; break; /* U+000C */ - case '\n': slashChar = 'n'; break; /* U+000A */ - case '\r': slashChar = 'r'; break; /* U+000D */ - case '\t': slashChar = 't'; break; /* U+0009 */ - default: - slashChar = 'u'; - }; - - buffer[0] = '\\'; - buffer[1] = slashChar; - - if (slashChar == 'u') { - sprintf(&buffer[2], "%04x", c); - size = 6; /* \u1234 */ - } else - size = 2; - - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, buffer, size); -} - - - -static void -makeJsonString(xmlrpc_env * const envP, - const char * const value, - size_t const length, - xmlrpc_mem_block * const outP) { -/*---------------------------------------------------------------------------- - Create a JSON representation of a string, appended to *outP. ------------------------------------------------------------------------------*/ - const char * const begin = &value[0]; - const char * const end = begin + length; - - const char * cur; - const char * last; - - last = cur = begin; - - while (cur != end && !envP->fault_occurred) { - unsigned char const c = *cur; - - if (c < 0x1F || c == '"' || c == '\\') { - /* This characters needs to be escaped. Put a backslash escape - sequence in the output for this character, after copying all - the characters before it to the output. - */ - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, last, cur - last); - - if (!envP->fault_occurred) { - appendEscapeSeq(envP, outP, c); - - ++cur; - last = cur; - } - } else - ++cur; - } - - /* Copy all characters since the last escaped character to the output */ - if (cur != last) - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, last, cur - last); -} - - - -static void -makeJsonStringFromXmlRpc(xmlrpc_env * const envP, - const xmlrpc_value * const valP, - xmlrpc_mem_block * const outP) { -/*---------------------------------------------------------------------------- - Convert a string XML-RPC value to JSON, appended to *outP. ------------------------------------------------------------------------------*/ - const char * value; - size_t length; - - xmlrpc_read_string_lp(envP, valP, &length, &value); - if (!envP->fault_occurred) { - makeJsonString(envP, value, length, outP); - - xmlrpc_strfree(value); - } -} - - - -static void -serializeInt(xmlrpc_env * const envP, - xmlrpc_value * const valP, - xmlrpc_mem_block * const outP) { - - xmlrpc_int value; - - xmlrpc_read_int(envP, valP, &value); - - formatOut(envP, outP, "%d", value); -} - - - -static void -serializeI8(xmlrpc_env * const envP, - xmlrpc_value * const valP, - xmlrpc_mem_block * const outP) { - - xmlrpc_int64 value; - - xmlrpc_read_i8(envP, valP, &value); - - formatOut(envP, outP, "%" XMLRPC_PRId64, value); -} - - - -static void -serializeBool(xmlrpc_env * const envP, - xmlrpc_value * const valP, - xmlrpc_mem_block * const outP) { - - xmlrpc_bool value; - xmlrpc_read_bool(envP, valP, &value); - - formatOut(envP, outP, "%s", value ? "true" : "false"); -} - - - -static void -serializeDouble(xmlrpc_env * const envP, - xmlrpc_value * const valP, - xmlrpc_mem_block * const outP) { - - xmlrpc_double value; - xmlrpc_read_double(envP, valP, &value); - - formatOut(envP, outP, "%e", value); -} - - - -static void -serializeDatetime(xmlrpc_env * const envP, - xmlrpc_value * const valP, - xmlrpc_mem_block * const outP) { - - /* ISO 8601 time string as JSON does not have a datetime type */ - - formatOut(envP, outP, "\"%u%02u%02uT%02u:%02u:%02u\"", - valP->_value.dt.Y, - valP->_value.dt.M, - valP->_value.dt.D, - valP->_value.dt.h, - valP->_value.dt.m, - valP->_value.dt.s); -} - - - -static void -serializeString(xmlrpc_env * const envP, - xmlrpc_value * const valP, - xmlrpc_mem_block * const outP) { - - formatOut(envP, outP, "\""); - - makeJsonStringFromXmlRpc(envP, valP, outP); - - formatOut(envP, outP, "\""); -} - - - -static void -serializeBitstring(xmlrpc_env * const envP, - xmlrpc_value * const valP, - xmlrpc_mem_block * const outP) { -/*---------------------------------------------------------------------------- - Append to *outP a JSON string whose value is the bit string *valP in - base64 ASCII. ------------------------------------------------------------------------------*/ - const unsigned char * bytes; - size_t size; - - xmlrpc_read_base64(envP, valP, &size, &bytes); - - if (!envP->fault_occurred) { - xmlrpc_mem_block * const base64P = - xmlrpc_base64_encode(envP, bytes, size); - - if (!envP->fault_occurred) { - - formatOut(envP, outP, "\""); - - XMLRPC_MEMBLOCK_APPEND( - char, envP, outP, - XMLRPC_MEMBLOCK_CONTENTS(char, base64P), - XMLRPC_MEMBLOCK_SIZE(char, base64P)); - - if (!envP->fault_occurred) - formatOut(envP, outP, "\""); - - XMLRPC_MEMBLOCK_FREE(char, base64P); - } - free((unsigned char*)bytes); - } -} - - - -static void -serializeArray(xmlrpc_env * const envP, - xmlrpc_value * const valP, - unsigned int const level, - xmlrpc_mem_block * const outP) { - - unsigned int const size = xmlrpc_array_size(envP, valP); - - if (!envP->fault_occurred) { - unsigned int i; - - formatOut(envP, outP, "[\n"); - - for (i = 0; i < size && !envP->fault_occurred; ++i) { - xmlrpc_value * const itemP = - xmlrpc_array_get_item(envP, valP, i); - - if (!envP->fault_occurred) { - if (!envP->fault_occurred) { - serializeValue(envP, itemP, level + 1, outP); - - if (i < size - 1) - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, ",\n", 2); - } - } - } - if (!envP->fault_occurred) { - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, "\n", 1); - indent(envP, level, outP); - if (!envP->fault_occurred) { - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, "]", 1); - } - } - } -} - - - -static void -serializeStructMember(xmlrpc_env * const envP, - xmlrpc_value * const memberKeyP, - xmlrpc_value * const memberValueP, - unsigned int const level, - xmlrpc_mem_block * const outP) { - - serializeValue(envP, memberKeyP, level, outP); - - if (!envP->fault_occurred) { - formatOut(envP, outP, ":"); - - if (!envP->fault_occurred) - serializeValue(envP, memberValueP, level, outP); - } -} - - - -static void -serializeStruct(xmlrpc_env * const envP, - xmlrpc_value * const valP, - unsigned int const level, - xmlrpc_mem_block * const outP) { - - if (!envP->fault_occurred) { - formatOut(envP, outP, "{\n"); - if (!envP->fault_occurred) { - unsigned int const size = xmlrpc_struct_size(envP, valP); - - if (!envP->fault_occurred) { - unsigned int i; - for (i = 0; i < size && !envP->fault_occurred; ++i) { - xmlrpc_value * memberKeyP; - xmlrpc_value * memberValueP; - - xmlrpc_struct_get_key_and_value(envP, valP, i, - &memberKeyP, - &memberValueP); - if (!envP->fault_occurred) { - serializeStructMember(envP, memberKeyP, memberValueP, - level + 1, outP); - - if (!envP->fault_occurred && i < size - 1) - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, ",\n", 2); - } - } - if (!envP->fault_occurred) { - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, "\n", 1); - indent(envP, level, outP); - XMLRPC_MEMBLOCK_APPEND(char, envP, outP, "}", 1); - } - } - } - } -} - - - -static void -serializeValue(xmlrpc_env * const envP, - xmlrpc_value * const valP, - unsigned int const level, - xmlrpc_mem_block * const outP) { -/*---------------------------------------------------------------------------- - Generate JSON to represent the value *valP. Append it to *outP. - - The JSON consists of lines of text. Indent them 'level' levels. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - - indent(envP, level, outP); - - switch (xmlrpc_value_type(valP)) { - case XMLRPC_TYPE_INT: - serializeInt(envP, valP, outP); - break; - - case XMLRPC_TYPE_I8: - serializeI8(envP, valP, outP); - break; - - case XMLRPC_TYPE_BOOL: - serializeBool(envP, valP, outP); - break; - - case XMLRPC_TYPE_DOUBLE: - serializeDouble(envP, valP, outP); - break; - - case XMLRPC_TYPE_DATETIME: - serializeDatetime(envP, valP, outP); - break; - - case XMLRPC_TYPE_STRING: - serializeString(envP, valP, outP); - break; - - case XMLRPC_TYPE_BASE64: - serializeBitstring(envP, valP, outP); - break; - - case XMLRPC_TYPE_ARRAY: - serializeArray(envP, valP, level, outP); - break; - - case XMLRPC_TYPE_STRUCT: - serializeStruct(envP, valP, level, outP); - break; - - case XMLRPC_TYPE_C_PTR: - xmlrpc_faultf(envP, "Tried to serialize a C pointer value."); - break; - - case XMLRPC_TYPE_NIL: - formatOut(envP, outP, "null"); - break; - - case XMLRPC_TYPE_DEAD: - xmlrpc_faultf(envP, "Tried to serialize a dead value."); - break; - - default: - xmlrpc_faultf(envP, "Invalid xmlrpc_value type: 0x%x", - xmlrpc_value_type(valP)); - } -} - - - -void -xmlrpc_serialize_json(xmlrpc_env * const envP, - xmlrpc_value * const valP, - xmlrpc_mem_block * const outP) { -/*---------------------------------------------------------------------------- - Generate JSON to represent the value *valP. Append it to *outP. ------------------------------------------------------------------------------*/ - serializeValue(envP, valP, 0, outP); -} diff --git a/trunk/src/method.c b/trunk/src/method.c deleted file mode 100644 index cd7961e2d..000000000 --- a/trunk/src/method.c +++ /dev/null @@ -1,455 +0,0 @@ -/*========================================================================= - XML-RPC server method registry - Method services -=========================================================================== - These are the functions that implement the method objects that - the XML-RPC method registry uses. - - By Bryan Henderson, December 2006. - - Contributed to the public domain by its author. -=========================================================================*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include "xmlrpc_config.h" - -#include -#include -#include - -#include "bool.h" -#include "mallocvar.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/base.h" -#include "registry.h" - -#include "method.h" - - -static void -signatureDestroy(struct xmlrpc_signature * const signatureP) { - - if (signatureP->argList) - free((void*)signatureP->argList); - - free(signatureP); -} - - - -static void -translateTypeSpecifierToName(xmlrpc_env * const envP, - char const typeSpecifier, - const char ** const typeNameP) { - - switch (typeSpecifier) { - case 'i': *typeNameP = "int"; break; - case 'b': *typeNameP = "boolean"; break; - case 'd': *typeNameP = "double"; break; - case 's': *typeNameP = "string"; break; - case '8': *typeNameP = "dateTime.iso8601"; break; - case '6': *typeNameP = "base64"; break; - case 'S': *typeNameP = "struct"; break; - case 'A': *typeNameP = "array"; break; - case 'n': *typeNameP = "nil"; break; - case 'I': *typeNameP = "i8"; break; - default: - xmlrpc_faultf(envP, - "Method registry contains invalid signature " - "data. It contains the type specifier '%c'", - typeSpecifier); - *typeNameP = NULL; /* quiet compiler warning */ - } -} - - - -/* MSVC 8 complains that const char ** is incompatible with void * in the - REALLOCARRAY. It's not. -*/ -#pragma warning(push) -#pragma warning(disable:4090) - -static void -makeRoomInArgList(xmlrpc_env * const envP, - struct xmlrpc_signature * const signatureP, - unsigned int const minArgCount) { - - if (signatureP->argListSpace < minArgCount) { - REALLOCARRAY(signatureP->argList, minArgCount); - if (signatureP->argList == NULL) { - xmlrpc_faultf(envP, "Couldn't get memory for a argument list for " - "a method signature with %u arguments", minArgCount); - signatureP->argListSpace = 0; - } - } -} - -#pragma warning(pop) - - - -static void -parseArgumentTypeSpecifiers(xmlrpc_env * const envP, - const char * const startP, - struct xmlrpc_signature * const signatureP, - const char ** const nextPP) { - const char * cursorP; - - cursorP = startP; /* start at the beginning */ - - while (!envP->fault_occurred && *cursorP != ',' && *cursorP != '\0') { - const char * typeName; - - translateTypeSpecifierToName(envP, *cursorP, &typeName); - - if (!envP->fault_occurred) { - ++cursorP; - - makeRoomInArgList(envP, signatureP, signatureP->argCount + 1); - - signatureP->argList[signatureP->argCount++] = typeName; - } - } - if (!envP->fault_occurred) { - if (*cursorP) { - XMLRPC_ASSERT(*cursorP == ','); - ++cursorP; /* Move past the signature and comma */ - } - } - if (envP->fault_occurred) - free((void*)signatureP->argList); - - *nextPP = cursorP; -} - - - -static void -parseOneSignature(xmlrpc_env * const envP, - const char * const startP, - struct xmlrpc_signature ** const signaturePP, - const char ** const nextPP) { -/*---------------------------------------------------------------------------- - Parse one signature from the signature string that starts at 'startP'. - - Return that signature as a signature object *signaturePP. - - Return as *nextP the location in the signature string of the next - signature (i.e. right after the next comma). If there is no next - signature (the string ends before any comma), make it point to the - terminating NUL. ------------------------------------------------------------------------------*/ - struct xmlrpc_signature * signatureP; - - MALLOCVAR(signatureP); - if (signatureP == NULL) - xmlrpc_faultf(envP, "Couldn't get memory for signature"); - else { - const char * cursorP; - - signatureP->argListSpace = 0; /* Start with no argument space */ - signatureP->argList = NULL; /* Nothing allocated yet */ - signatureP->argCount = 0; /* Start with no arguments */ - - cursorP = startP; /* start at the beginning */ - - if (*cursorP == ',' || *cursorP == '\0') - xmlrpc_faultf(envP, "empty signature (a signature " - "must have at least return value type)"); - else { - translateTypeSpecifierToName(envP, *cursorP, &signatureP->retType); - - ++cursorP; - - if (*cursorP != ':') - xmlrpc_faultf(envP, "No colon (':') after " - "the result type specifier"); - else { - ++cursorP; - - parseArgumentTypeSpecifiers(envP, cursorP, signatureP, nextPP); - } - } - if (envP->fault_occurred) - free(signatureP); - } - *signaturePP = signatureP; -} - - - -static void -destroySignatures(struct xmlrpc_signature * const firstSignatureP) { - - struct xmlrpc_signature * p; - struct xmlrpc_signature * nextP; - - for (p = firstSignatureP; p; p = nextP) { - nextP = p->nextP; - signatureDestroy(p); - } -} - - - -static void -listSignatures(xmlrpc_env * const envP, - const char * const sigListString, - struct xmlrpc_signature ** const firstSignaturePP) { - - struct xmlrpc_signature ** p; - const char * cursorP; - - *firstSignaturePP = NULL; /* Start with empty list */ - - p = firstSignaturePP; - cursorP = &sigListString[0]; - - while (!envP->fault_occurred && *cursorP != '\0') { - struct xmlrpc_signature * signatureP; - - parseOneSignature(envP, cursorP, &signatureP, &cursorP); - - /* cursorP now points at next signature in the list or the - terminating NUL. - */ - - if (!envP->fault_occurred) { - signatureP->nextP = NULL; - *p = signatureP; - p = &signatureP->nextP; - } - } - if (envP->fault_occurred) - destroySignatures(*firstSignaturePP); -} - - - -static void -signatureListCreate(xmlrpc_env * const envP, - const char * const sigListString, - xmlrpc_signatureList ** const signatureListPP) { - - xmlrpc_signatureList * signatureListP; - - XMLRPC_ASSERT_ENV_OK(envP); - - MALLOCVAR(signatureListP); - - if (signatureListP == NULL) - xmlrpc_faultf(envP, "Could not allocate memory for signature list"); - else { - signatureListP->firstSignatureP = NULL; - - if (sigListString == NULL || xmlrpc_streq(sigListString, "?")) { - /* No signatures -- leave the list empty */ - } else { - listSignatures(envP, sigListString, - &signatureListP->firstSignatureP); - - if (!envP->fault_occurred) { - if (!signatureListP->firstSignatureP) - xmlrpc_faultf(envP, "Signature string is empty."); - - if (envP->fault_occurred) - destroySignatures(signatureListP->firstSignatureP); - } - } - if (envP->fault_occurred) - free(signatureListP); - - *signatureListPP = signatureListP; - } -} - - - -static void -signatureListDestroy(xmlrpc_signatureList * const signatureListP) { - - destroySignatures(signatureListP->firstSignatureP); - - free(signatureListP); -} - - - -static void -makeSignatureList(xmlrpc_env * const envP, - const char * const signatureString, - xmlrpc_signatureList ** const signatureListPP) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - signatureListCreate(&env, signatureString, signatureListPP); - - if (env.fault_occurred) - xmlrpc_faultf(envP, "Can't interpret signature string '%s'. %s", - signatureString, env.fault_string); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_methodCreate(xmlrpc_env * const envP, - xmlrpc_method1 methodFnType1, - xmlrpc_method2 methodFnType2, - void * const userData, - const char * const signatureString, - const char * const helpText, - size_t const stackSize, - xmlrpc_methodInfo ** const methodPP) { - - xmlrpc_methodInfo * methodP; - - XMLRPC_ASSERT_ENV_OK(envP); - - MALLOCVAR(methodP); - - if (methodP == NULL) - xmlrpc_faultf(envP, "Unable to allocate storage for a method " - "descriptor"); - else { - methodP->methodFnType1 = methodFnType1; - methodP->methodFnType2 = methodFnType2; - methodP->userData = userData; - methodP->helpText = xmlrpc_strdupsol(helpText); - methodP->stackSize = stackSize; - - makeSignatureList(envP, signatureString, &methodP->signatureListP); - - if (envP->fault_occurred) { - xmlrpc_strfree(methodP->helpText); - free(methodP); - } - - *methodPP = methodP; - } -} - - - -void -xmlrpc_methodDestroy(xmlrpc_methodInfo * const methodP) { - - signatureListDestroy(methodP->signatureListP); - - xmlrpc_strfree(methodP->helpText); - - free(methodP); -} - - - -void -xmlrpc_methodListCreate(xmlrpc_env * const envP, - xmlrpc_methodList ** const methodListPP) { - - xmlrpc_methodList * methodListP; - - XMLRPC_ASSERT_ENV_OK(envP); - - MALLOCVAR(methodListP); - - if (methodListP == NULL) - xmlrpc_faultf(envP, "Couldn't allocate method list descriptor"); - else { - methodListP->firstMethodP = NULL; - methodListP->lastMethodP = NULL; - - *methodListPP = methodListP; - } -} - - - -void -xmlrpc_methodListDestroy(xmlrpc_methodList * methodListP) { - - xmlrpc_methodNode * p; - xmlrpc_methodNode * nextP; - - for (p = methodListP->firstMethodP; p; p = nextP) { - nextP = p->nextP; - - xmlrpc_methodDestroy(p->methodP); - xmlrpc_strfree(p->methodName); - free(p); - } - - free(methodListP); -} - - - -void -xmlrpc_methodListLookupByName(xmlrpc_methodList * const methodListP, - const char * const methodName, - xmlrpc_methodInfo ** const methodPP) { - - - /* We do a simple linear lookup along a linked list. - If speed is important, we can make this a binary tree instead. - */ - - xmlrpc_methodNode * p; - xmlrpc_methodInfo * methodP; - - for (p = methodListP->firstMethodP, methodP = NULL; - p && !methodP; - p = p->nextP) { - - if (xmlrpc_streq(p->methodName, methodName)) - methodP = p->methodP; - } - *methodPP = methodP; -} - - - -void -xmlrpc_methodListAdd(xmlrpc_env * const envP, - xmlrpc_methodList * const methodListP, - const char * const methodName, - xmlrpc_methodInfo * const methodP) { - - xmlrpc_methodInfo * existingMethodP; - - XMLRPC_ASSERT_ENV_OK(envP); - - xmlrpc_methodListLookupByName(methodListP, methodName, &existingMethodP); - - if (existingMethodP) - xmlrpc_faultf(envP, "Method named '%s' already registered", - methodName); - else { - xmlrpc_methodNode * methodNodeP; - - MALLOCVAR(methodNodeP); - - if (methodNodeP == NULL) - xmlrpc_faultf(envP, "Couldn't allocate method node"); - else { - methodNodeP->methodName = strdup(methodName); - methodNodeP->methodP = methodP; - methodNodeP->nextP = NULL; - - if (!methodListP->firstMethodP) - methodListP->firstMethodP = methodNodeP; - - if (methodListP->lastMethodP) - methodListP->lastMethodP->nextP = methodNodeP; - - methodListP->lastMethodP = methodNodeP; - } - } -} - diff --git a/trunk/src/method.h b/trunk/src/method.h deleted file mode 100644 index f1d56cb12..000000000 --- a/trunk/src/method.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef METHOD_H_INCLUDED -#define METHOD_H_INCLUDED - -#include "xmlrpc-c/base.h" - -struct xmlrpc_signature { - struct xmlrpc_signature * nextP; - const char * retType; - /* Name of the XML-RPC element that represents the return value - type, e.g. "int" or "dateTime.iso8601" - */ - unsigned int argCount; - /* Number of arguments method takes */ - unsigned int argListSpace; - /* Number of slots that exist in the argList[] (i.e. memory is - allocated) - */ - const char ** argList; - /* Array of size 'argCount'. argList[i] is the name of the type - of argument i. Like 'retType', e.g. "string". - - The strings are constants, not malloc'ed. - */ -}; - -typedef struct xmlrpc_signatureList { - /* A list of signatures for a method. Each signature describes one - alternative form of invoking the method (a - single method might have multiple forms, e.g. one takes two integer - arguments; another takes a single string). - */ - struct xmlrpc_signature * firstSignatureP; -} xmlrpc_signatureList; - -struct xmlrpc_registry { - bool introspectionEnabled; - struct xmlrpc_methodList * methodListP; - xmlrpc_default_method defaultMethodFunction; - void * defaultMethodUserData; - xmlrpc_preinvoke_method preinvokeFunction; - void * preinvokeUserData; - xmlrpc_server_shutdown_fn * shutdownServerFn; - /* Function that can be called to shut down the server that is - using this registry. NULL if none. - */ - void * shutdownContext; - /* Context for _shutdown_server_fn -- understood only by - that function, passed to it as argument. - */ - xmlrpc_dialect dialect; -}; - -typedef struct { -/*---------------------------------------------------------------------------- - Everything a registry knows about one XML-RPC method ------------------------------------------------------------------------------*/ - /* One of the methodTypeX fields is NULL and the other isn't. - (The reason there are two is backward compatibility. Old - programs set up the registry with Type 1; modern ones set it up - with Type 2. - */ - xmlrpc_method1 methodFnType1; - /* The method function, if it's type 1. Null if it's not */ - xmlrpc_method2 methodFnType2; - /* The method function, if it's type 2. Null if it's not */ - void * userData; - /* Passed to method function */ - size_t stackSize; - /* Amount of stack space 'methodFnType1' or 'methodFnType2' uses. - Zero means unspecified. - */ - struct xmlrpc_signatureList * signatureListP; - /* Stuff returned by system method system.methodSignature. - Empty list doesn't mean there are no valid forms of calling the - method -- just that the registry declines to state. - */ - const char * helpText; - /* Stuff returned by system method system.methodHelp */ -} xmlrpc_methodInfo; - -typedef struct xmlrpc_methodNode { - struct xmlrpc_methodNode * nextP; - const char * methodName; - xmlrpc_methodInfo * methodP; -} xmlrpc_methodNode; - -typedef struct xmlrpc_methodList { - xmlrpc_methodNode * firstMethodP; - xmlrpc_methodNode * lastMethodP; -} xmlrpc_methodList; - -void -xmlrpc_methodCreate(xmlrpc_env * const envP, - xmlrpc_method1 methodFnType1, - xmlrpc_method2 methodFnType2, - void * const userData, - const char * const signatureString, - const char * const helpText, - size_t const stackSize, - xmlrpc_methodInfo ** const methodPP); - -void -xmlrpc_methodDestroy(xmlrpc_methodInfo * const methodP); - -void -xmlrpc_methodListCreate(xmlrpc_env * const envP, - xmlrpc_methodList ** const methodListPP); - -void -xmlrpc_methodListDestroy(xmlrpc_methodList * methodListP); - -void -xmlrpc_methodListLookupByName(xmlrpc_methodList * const methodListP, - const char * const methodName, - xmlrpc_methodInfo ** const methodPP); - -void -xmlrpc_methodListAdd(xmlrpc_env * const envP, - xmlrpc_methodList * const methodListP, - const char * const methodName, - xmlrpc_methodInfo * const methodP); - - - -#endif diff --git a/trunk/src/parse_datetime.c b/trunk/src/parse_datetime.c deleted file mode 100644 index bedf67165..000000000 --- a/trunk/src/parse_datetime.c +++ /dev/null @@ -1,467 +0,0 @@ -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#if HAVE_REGEX -#include /* Missing from regex.h in GNU libc */ -#include -#endif - -#include "bool.h" -#include "c_util.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" - -#include "parse_datetime.h" - - - -#if HAVE_REGEX - -static unsigned int -digitStringValue(const char * const string, - regmatch_t const match) { -/*---------------------------------------------------------------------------- - Return the numerical value of the decimal whole number substring of - 'string' identified by 'match'. E.g. if 'string' is 'abc34d' and - 'match' says start at 3 and end at 5, we return 34. ------------------------------------------------------------------------------*/ - unsigned int i; - unsigned int accum; - - assert(match.rm_so >= 0); - assert(match.rm_eo >= 0); - - for (i = match.rm_so, accum = 0; i < (unsigned)match.rm_eo; ++i) { - accum *= 10; - assert(isdigit(string[i])); - accum += string[i] - '0'; - } - return accum; -} -#endif /* HAVE_REGEX */ - - - -#if HAVE_REGEX - -static unsigned int -digitStringMillionths(const char * const string, - regmatch_t const match) { -/*---------------------------------------------------------------------------- - Return the number of millionths represented by the digits after the - decimal point in a decimal string, where thse digits are the substring - of 'string' identified by 'match'. E.g. if the substring is - 34, we return 340,000. ------------------------------------------------------------------------------*/ - unsigned int i; - unsigned int accum; - - assert(match.rm_so >= 0); - assert(match.rm_eo >= 0); - - for (i = match.rm_so, accum = 0; i < (unsigned)match.rm_so+6; ++i) { - accum *= 10; - if (i < (unsigned)match.rm_eo) { - assert(isdigit(string[i])); - accum += string[i] - '0'; - } - } - return accum; -} -#endif /* HAVE_REGEX */ - - -#if HAVE_REGEX - -static void -subParseDtRegex_standard(regmatch_t * const matches, - const char * const datetimeString, - xmlrpc_datetime * const dtP) { - - dtP->Y = digitStringValue(datetimeString, matches[1]); - dtP->M = digitStringValue(datetimeString, matches[2]); - dtP->D = digitStringValue(datetimeString, matches[3]); - dtP->h = digitStringValue(datetimeString, matches[4]); - dtP->m = digitStringValue(datetimeString, matches[5]); - dtP->s = digitStringValue(datetimeString, matches[6]); - - if (matches[7].rm_so == -1) - dtP->u = 0; - else - dtP->u = digitStringMillionths(datetimeString, matches[7]); -} - - - -static void -subParseDtRegex_standardtzd(regmatch_t * const matches, - const char * const datetimeString, - xmlrpc_datetime * const dtP) { - - dtP->Y = digitStringValue(datetimeString, matches[1]); - dtP->M = digitStringValue(datetimeString, matches[2]); - dtP->D = digitStringValue(datetimeString, matches[3]); - dtP->h = digitStringValue(datetimeString, matches[4]); - dtP->m = digitStringValue(datetimeString, matches[5]); - dtP->s = digitStringValue(datetimeString, matches[6]); - dtP->u = 0; -} - -#endif /* HAVE_REGEX */ - - -#if HAVE_REGEX - -typedef void (*regparsefunc_t)(regmatch_t * const matches, - const char * const datetimeString, - xmlrpc_datetime * const dtP); - - -struct regexParser { - const char * const regex; - regparsefunc_t func; -}; - -static const struct regexParser iso8601Regex[] - - /* Each entry of this table is instructions for recognizing and parsing - some form of a "dateTime.iso8601" XML element. - - (Note that we recognize far more than just the XML-RPC standard - dateTime.iso8601). - */ - - = { - { - /* Examples: - YYYYMMDD[T]HHMMSS - YYYY-MM-DD[T]HH:MM:SS - YYYY-MM-DD[T]HH:MM:SS.ssss - */ - - "^([0-9]{4})\\-?([0-9]{2})\\-?([0-9]{2})T" - "([0-9]{2}):?([0-9]{2}):?([0-9]{2})\\.?([0-9]+)?$", - subParseDtRegex_standard - }, - - { - /* Examples: - YYYYMMDD[T]HHMMSS[Z] - YYYYMMDD[T]HHMMSS[+-]hh - YYYYMMDD[T]HHMMSS[+-]hhmm - */ - - "^([0-9]{4})\\-?([0-9]{2})\\-?([0-9]{2})T" - "([0-9]{2}):?([0-9]{2}):?([0-9]{2})[Z\\+\\-]([0-9]{2,4})?$", - subParseDtRegex_standardtzd - }, - { NULL, NULL } - }; -#endif /* HAVE_REGEX */ - - - -#if HAVE_REGEX -static void -parseDtRegex(xmlrpc_env * const envP, - const char * const datetimeString, - xmlrpc_datetime * const dtP) { - - unsigned int i; - const struct regexParser * parserP; - /* The parser that matches 'datetimeString'. Null if no match yet - found. - */ - regmatch_t matches[1024]; - - for (i = 0, parserP = NULL; iso8601Regex[i].regex && !parserP; ++i) { - const struct regexParser * const thisParserP = &iso8601Regex[i]; - - regex_t re; - int status; - - status = regcomp(&re, thisParserP->regex, REG_ICASE | REG_EXTENDED); - - /* Our regex is valid, so it must have compiled: */ - assert(status == 0); if (status){}; /* quiet compiler warning */ - { - int status; - - status = regexec(&re, datetimeString, ARRAY_SIZE(matches), - matches, 0); - - if (status == 0) { - assert(matches[0].rm_so != -1); /* Match of whole regex */ - - parserP = thisParserP; - } - } - regfree(&re); - } - - if (parserP) { - parserP->func(matches, datetimeString, dtP); - } else { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "value '%s' is not of any form we recognize " - "for a element", - datetimeString); - } - -} -#endif /* HAVE_REGEX */ - - - -static __inline__ void -parseDtNoRegex(xmlrpc_env * const envP, - const char * const datetimeString, - xmlrpc_datetime * const dtP) { - - unsigned int const dtStrlen = strlen(datetimeString); - - char year[4+1]; - char month[2+1]; - char day[2+1]; - char hour[2+1]; - char minute[2+1]; - char second[2+1]; - - if (dtStrlen < 17 || dtStrlen == 18 || dtStrlen > 24) - xmlrpc_faultf(envP, "could not parse date, size incompatible: '%d'", - dtStrlen); - else { - year[0] = datetimeString[ 0]; - year[1] = datetimeString[ 1]; - year[2] = datetimeString[ 2]; - year[3] = datetimeString[ 3]; - year[4] = '\0'; - - month[0] = datetimeString[ 4]; - month[1] = datetimeString[ 5]; - month[2] = '\0'; - - day[0] = datetimeString[ 6]; - day[1] = datetimeString[ 7]; - day[2] = '\0'; - - assert(datetimeString[ 8] == 'T'); - - hour[0] = datetimeString[ 9]; - hour[1] = datetimeString[10]; - hour[2] = '\0'; - - assert(datetimeString[11] == ':'); - - minute[0] = datetimeString[12]; - minute[1] = datetimeString[13]; - minute[2] = '\0'; - - assert(datetimeString[14] == ':'); - - second[0] = datetimeString[15]; - second[1] = datetimeString[16]; - second[2] = '\0'; - - if (dtStrlen > 17) { - unsigned int const pad = 24 - dtStrlen; - unsigned int i; - - dtP->u = atoi(&datetimeString[18]); - for (i = 0; i < pad; ++i) - dtP->u *= 10; - } else - dtP->u = 0; - - dtP->Y = atoi(year); - dtP->M = atoi(month); - dtP->D = atoi(day); - dtP->h = atoi(hour); - dtP->m = atoi(minute); - dtP->s = atoi(second); - } -} - - - -static void -validateFirst17(xmlrpc_env * const envP, - const char * const dt) { -/*---------------------------------------------------------------------------- - Assuming 'dt' is at least 17 characters long, validate that the first - 17 characters are a valid XML-RPC datetime, e.g. - "20080628T16:35:02" ------------------------------------------------------------------------------*/ - unsigned int i; - - for (i = 0; i < 8 && !envP->fault_occurred; ++i) - if (!isdigit(dt[i])) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[i]); - - if (dt[8] != 'T') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "9th character is '%c', not 'T'", - dt[8]); - if (!isdigit(dt[9])) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[9]); - if (!isdigit(dt[10])) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[10]); - if (dt[11] != ':') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Not a colon: '%c'", dt[11]); - if (!isdigit(dt[12])) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[12]); - if (!isdigit(dt[13])) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[13]); - if (dt[14] != ':') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Not a colon: '%c'", dt[14]); - if (!isdigit(dt[15])) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[15]); - if (!isdigit(dt[16])) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[16]); -} - - - -static void -validateFractionalSeconds(xmlrpc_env * const envP, - const char * const dt) { -/*---------------------------------------------------------------------------- - Validate the fractional seconds part of the XML-RPC datetime string - 'dt', if any. That's the decimal point and everything following - it. ------------------------------------------------------------------------------*/ - if (strlen(dt) > 17) { - if (dt[17] != '.') { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "'%c' where only a period is valid", dt[17]); - } else { - if (dt[18] == '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, "Nothing after decimal point"); - else { - unsigned int i; - for (i = 18; dt[i] != '\0' && !envP->fault_occurred; ++i) { - if (!isdigit(dt[i])) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Non-digit in fractional seconds: '%c'", dt[i]); - } - } - } - } -} - - - -static __inline__ void -validateFormatNoRegex(xmlrpc_env * const envP, - const char * const dt) { - - if (strlen(dt) < 17) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Invalid length of %u of datetime. " - "Must be at least 17 characters", - (unsigned)strlen(dt)); - else { - validateFirst17(envP, dt); - - validateFractionalSeconds(envP, dt); - } -} - - - -static void -validateXmlrpcDatetimeSome(xmlrpc_env * const envP, - xmlrpc_datetime const dt) { -/*---------------------------------------------------------------------------- - Type xmlrpc_datetime is defined such that it can represent a nonexistent - datetime such as February 30. - - Validate that 'dt' doesn't have glaring invalidities such as Hour 25. - We leave the possibility of more subtle invalidity such as February 30. ------------------------------------------------------------------------------*/ - - if (dt.M < 1 || dt.M > 12) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Month of year value %u is not in the range 1-12", dt.M); - else if (dt.D < 1 || dt.D > 31) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Day of month value %u is not in the range 1-31", dt.D); - else if (dt.h > 23) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Hour of day value %u is not in the range 0-23", dt.h); - else if (dt.m > 59) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Minute of hour value %u is not in the range 0-59", dt.m); - else if (dt.s > 59) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Second of minute value %u is not in the range 0-59", dt.s); - else if (dt.u > 999999) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Microsecond of second value %u is not in the range 0-1M", dt.u); -} - - - -void -xmlrpc_parseDatetime(xmlrpc_env * const envP, - const char * const datetimeString, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Parse the content of a XML-RPC XML element, e.g. - "20000301T00:00:00". - - 'str' is that content. - - Example of the format we parse: "19980717T14:08:55" - Note that this is not quite ISO 8601. It's a bizarre combination of - two ISO 8601 formats. - - Note that Xmlrpc-c recognizes various extensions of the XML-RPC - element type. - - 'str' may not be valid XML-RPC (with extensions). In that case we fail - with fault code XMLRPC_PARSE_ERROR. ------------------------------------------------------------------------------*/ - xmlrpc_datetime dt; - -#if HAVE_REGEX - parseDtRegex(envP, datetimeString, &dt); -#else - /* Note: validation is not as strong without regex */ - validateFormatNoRegex(envP, datetimeString); - if (!envP->fault_occurred) - parseDtNoRegex(envP, datetimeString, &dt); -#endif - - if (!envP->fault_occurred) { - validateXmlrpcDatetimeSome(envP, dt); - - if (!envP->fault_occurred) - *valuePP = xmlrpc_datetime_new(envP, dt); - } -} diff --git a/trunk/src/parse_datetime.h b/trunk/src/parse_datetime.h deleted file mode 100644 index 85207b7e5..000000000 --- a/trunk/src/parse_datetime.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef PARSE_DATETIME_H_INCLUDED -#define PARSE_DATETIME_H_INCLUDED - -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/base.h" - -void -xmlrpc_parseDatetime(xmlrpc_env * const envP, - const char * const str, - xmlrpc_value ** const valuePP); - -#endif diff --git a/trunk/src/parse_value.c b/trunk/src/parse_value.c deleted file mode 100644 index 7886c7d9d..000000000 --- a/trunk/src/parse_value.c +++ /dev/null @@ -1,744 +0,0 @@ -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "bool.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/string_number.h" -#include "xmlrpc-c/util.h" -#include "xmlparser.h" -#include "parse_datetime.h" - -#include "parse_value.h" - - - -static void -setParseFault(xmlrpc_env * const envP, - const char * const format, - ...) { - - va_list args; - va_start(args, format); - xmlrpc_set_fault_formatted_v(envP, XMLRPC_PARSE_ERROR, format, args); - va_end(args); -} - - - -static void -parseArrayDataChild(xmlrpc_env * const envP, - xml_element * const childP, - unsigned int const maxRecursion, - xmlrpc_value * const arrayP) { - - const char * const elemName = xml_element_name(childP); - - if (!xmlrpc_streq(elemName, "value")) - setParseFault(envP, " element has <%s> child. " - "Only makes sense.", elemName); - else { - xmlrpc_value * itemP; - - xmlrpc_parseValue(envP, maxRecursion-1, childP, &itemP); - - if (!envP->fault_occurred) { - xmlrpc_array_append_item(envP, arrayP, itemP); - - xmlrpc_DECREF(itemP); - } - } -} - - - -static void -parseArray(xmlrpc_env * const envP, - unsigned int const maxRecursion, - xml_element * const arrayElemP, - xmlrpc_value ** const arrayPP) { - - xmlrpc_value * arrayP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(arrayElemP != NULL); - - arrayP = xmlrpc_array_new(envP); - if (!envP->fault_occurred) { - size_t const childCount = xml_element_children_size(arrayElemP); - - if (childCount != 1) - setParseFault(envP, - " element has %u children. Only one " - "makes sense.", (unsigned int)childCount); - else { - xml_element * const dataElemP = - xml_element_children(arrayElemP)[0]; - const char * const elemName = xml_element_name(dataElemP); - - if (!xmlrpc_streq(elemName, "data")) - setParseFault(envP, - " element has <%s> child. Only " - "makes sense.", elemName); - else { - xml_element ** const values = xml_element_children(dataElemP); - unsigned int const size = xml_element_children_size(dataElemP); - - unsigned int i; - - for (i = 0; i < size && !envP->fault_occurred; ++i) - parseArrayDataChild(envP, values[i], maxRecursion, arrayP); - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(arrayP); - else - *arrayPP = arrayP; - } -} - - - -static void -parseName(xmlrpc_env * const envP, - xml_element * const nameElemP, - xmlrpc_value ** const valuePP) { - - size_t const childCount = xml_element_children_size(nameElemP); - - if (childCount > 0) - setParseFault(envP, " element has %u children. " - "Should have none.", (unsigned int)childCount); - else { - const char * const cdata = xml_element_cdata(nameElemP); - size_t const cdataSize = xml_element_cdata_size(nameElemP); - - *valuePP = xmlrpc_string_new_lp(envP, cdataSize, cdata); - } -} - - - -static void -getNameChild(xmlrpc_env * const envP, - xml_element * const parentP, - xml_element * * const childPP) { - - xml_element ** const children = xml_element_children(parentP); - size_t const childCount = xml_element_children_size(parentP); - - xml_element * childP; - unsigned int i; - - for (i = 0, childP = NULL; i < childCount && !childP; ++i) { - if (xmlrpc_streq(xml_element_name(children[i]), "name")) - childP = children[i]; - } - if (!childP) - xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, - " has no child"); - else - *childPP = childP; -} - - - -static void -getValueChild(xmlrpc_env * const envP, - xml_element * const parentP, - xml_element * * const childPP) { - - xml_element ** const children = xml_element_children(parentP); - size_t const childCount = xml_element_children_size(parentP); - - xml_element * childP; - unsigned int i; - - for (i = 0, childP = NULL; i < childCount && !childP; ++i) { - if (xmlrpc_streq(xml_element_name(children[i]), "value")) - childP = children[i]; - } - if (!childP) - xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, - " has no child"); - else - *childPP = childP; -} - - - -static void -parseMember(xmlrpc_env * const envP, - xml_element * const memberP, - unsigned int const maxRecursion, - xmlrpc_value ** const keyPP, - xmlrpc_value ** const valuePP) { - - size_t const childCount = xml_element_children_size(memberP); - - if (childCount != 2) - setParseFault(envP, - " element has %u children. Only one and " - "one make sense.", (unsigned int)childCount); - else { - xml_element * nameElemP; - - getNameChild(envP, memberP, &nameElemP); - - if (!envP->fault_occurred) { - parseName(envP, nameElemP, keyPP); - - if (!envP->fault_occurred) { - xml_element * valueElemP; - - getValueChild(envP, memberP, &valueElemP); - - if (!envP->fault_occurred) - xmlrpc_parseValue(envP, maxRecursion-1, valueElemP, - valuePP); - - if (envP->fault_occurred) - xmlrpc_DECREF(*keyPP); - } - } - } -} - - - -static void -parseStruct(xmlrpc_env * const envP, - unsigned int const maxRecursion, - xml_element * const elemP, - xmlrpc_value ** const structPP) { -/*---------------------------------------------------------------------------- - Parse the element 'elemP'. ------------------------------------------------------------------------------*/ - xmlrpc_value * structP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(elemP != NULL); - - structP = xmlrpc_struct_new(envP); - if (!envP->fault_occurred) { - /* Iterate over our children, extracting key/value pairs. */ - - xml_element ** const members = xml_element_children(elemP); - unsigned int const size = xml_element_children_size(elemP); - - unsigned int i; - - for (i = 0; i < size && !envP->fault_occurred; ++i) { - const char * const elemName = xml_element_name(members[i]); - - if (!xmlrpc_streq(elemName, "member")) - setParseFault(envP, "<%s> element found where only " - "makes sense", elemName); - else { - xmlrpc_value * keyP; - xmlrpc_value * valueP; - - parseMember(envP, members[i], maxRecursion, &keyP, &valueP); - - if (!envP->fault_occurred) { - xmlrpc_struct_set_value_v(envP, structP, keyP, valueP); - - xmlrpc_DECREF(keyP); - xmlrpc_DECREF(valueP); - } - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(structP); - else - *structPP = structP; - } -} - - - -static void -parseInt(xmlrpc_env * const envP, - const char * const str, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Parse the content of a XML-RPC XML element, e.g. "34". - - 'str' is that content. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(str); - - if (str[0] == '\0') - setParseFault(envP, " XML element content is empty"); - else if (isspace(str[0])) - setParseFault(envP, " content '%s' starts with white space", - str); - else { - long i; - char * tail; - - errno = 0; - i = strtol(str, &tail, 10); - - /* Look for ERANGE. */ - if (errno == ERANGE) - setParseFault(envP, " XML element value '%s' represents a " - "number beyond the range that " - "XML-RPC allows (%d - %d)", str, - XMLRPC_INT32_MIN, XMLRPC_INT32_MAX); - else if (errno != 0) - setParseFault(envP, "unexpected error parsing XML element " - "value '%s'. strtol() failed with errno %d (%s)", - str, errno, strerror(errno)); - else { - /* Look for out-of-range errors which didn't produce ERANGE. */ - if (i < XMLRPC_INT32_MIN) - setParseFault(envP, - " value %ld is below the range allowed " - "by XML-RPC (minimum is %d)", - i, XMLRPC_INT32_MIN); - else if (i > XMLRPC_INT32_MAX) - setParseFault(envP, - " value %ld is above the range allowed " - "by XML-RPC (maximum is %d)", - i, XMLRPC_INT32_MAX); - else { - if (tail[0] != '\0') - setParseFault(envP, - " value '%s' contains non-numerical " - "junk: '%s'", str, tail); - else - *valuePP = xmlrpc_int_new(envP, i); - } - } - } -} - - - -static void -parseBoolean(xmlrpc_env * const envP, - const char * const str, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Parse the content of a XML-RPC XML element, e.g. "1". - - 'str' is that content. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(str); - - if (xmlrpc_streq(str, "0") || xmlrpc_streq(str, "1")) - *valuePP = xmlrpc_bool_new(envP, xmlrpc_streq(str, "1") ? 1 : 0); - else - setParseFault(envP, " XML element content must be either " - "'0' or '1' according to XML-RPC. This one has '%s'", - str); -} - - - -static void -scanAndValidateDoubleString(xmlrpc_env * const envP, - const char * const string, - const char ** const mantissaP, - const char ** const mantissaEndP, - const char ** const fractionP, - const char ** const fractionEndP) { - - const char * mantissa; - const char * dp; - const char * p; - - if (string[0] == '-' || string[0] == '+') - mantissa = &string[1]; - else - mantissa = &string[0]; - - for (p = mantissa, dp = NULL; *p; ++p) { - char const c = *p; - if (c == '.') { - if (dp) { - setParseFault(envP, "Two decimal points"); - return; - } else - dp = p; - } else if (c < '0' || c > '9') { - setParseFault(envP, "Garbage (not sign, digit, or period) " - "starting at '%s'", p); - return; - } - } - *mantissaP = mantissa; - if (dp) { - *mantissaEndP = dp; - *fractionP = dp+1; - *fractionEndP = p; - } else { - *mantissaEndP = p; - *fractionP = p; - *fractionEndP = p; - } -} - - - -static bool -isInfinite(double const value) { - - return value > DBL_MAX; -} - - - -static void -parseDoubleString(xmlrpc_env * const envP, - const char * const string, - double * const valueP) { -/*---------------------------------------------------------------------------- - Turn e.g. "4.3" into 4.3 . ------------------------------------------------------------------------------*/ - /* strtod() is no good for this because it is designed for human - interfaces; it parses according to locale. As a practical - matter that sometimes means that it does not recognize "." as a - decimal point. In XML-RPC, "." is a decimal point. - - Design note: in my experiments, using strtod() was 10 times - slower than using this function. - */ - const char * mantissa; - const char * mantissaEnd; - const char * fraction; - const char * fractionEnd; - - scanAndValidateDoubleString(envP, string, &mantissa, &mantissaEnd, - &fraction, &fractionEnd); - - if (!envP->fault_occurred) { - double accum; - - accum = 0.0; - - if (mantissa == mantissaEnd && fraction == fractionEnd) { - setParseFault(envP, "No digits"); - return; - } - { - /* Add in the whole part */ - const char * p; - - for (p = mantissa; p < mantissaEnd; ++p) { - accum *= 10; - accum += (*p - '0'); - } - } - { - /* Add in the fractional part */ - double significance; - const char * p; - for (significance = 0.1, p = fraction; - p < fractionEnd; - ++p, significance *= 0.1) { - - accum += (*p - '0') * significance; - } - } - if (isInfinite(accum)) - setParseFault(envP, "Value exceeds the size allowed by XML-RPC"); - else - *valueP = string[0] == '-' ? (- accum) : accum; - } -} - - - -static void -parseDoubleStringStrtod(const char * const str, - bool * const failedP, - double * const valueP) { - - if (strlen(str) == 0) { - /* strtod() happily interprets empty string as 0.0. We don't think - the user will appreciate that XML-RPC extension. - */ - *failedP = true; - } else { - char * tail; - - errno = 0; - - *valueP = strtod(str, &tail); - - if (errno != 0) - *failedP = true; - else { - if (tail[0] != '\0') - *failedP = true; - else - *failedP = false; - } - } -} - - - -static void -parseDouble(xmlrpc_env * const envP, - const char * const str, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Parse the content of a XML-RPC XML element, e.g. "34.5". - - 'str' is that content. ------------------------------------------------------------------------------*/ - xmlrpc_env parseEnv; - double valueDouble; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(str); - - xmlrpc_env_init(&parseEnv); - - parseDoubleString(&parseEnv, str, &valueDouble); - - if (parseEnv.fault_occurred) { - /* As an alternative, try a strtod() parsing. strtod() - accepts other forms, e.g. "3.4E6"; "3,4"; " 3.4". These - are not permitted by XML-RPC, but an almost-XML-RPC partner - might use one. In fact, for many years, Xmlrpc-c generated - such alternatives (by mistake). - */ - bool failed; - parseDoubleStringStrtod(str, &failed, &valueDouble); - if (failed) - setParseFault(envP, " element value '%s' is not a valid " - "floating point number. %s", - str, parseEnv.fault_string); - } - - if (!envP->fault_occurred) - *valuePP = xmlrpc_double_new(envP, valueDouble); - - xmlrpc_env_clean(&parseEnv); -} - - - -static void -parseBase64(xmlrpc_env * const envP, - const char * const str, - size_t const strLength, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Parse the content of a XML-RPC XML element, e.g. "FD32YY". - - 'str' is that content. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * decoded; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(str); - - decoded = xmlrpc_base64_decode(envP, str, strLength); - if (!envP->fault_occurred) { - unsigned char * const bytes = - XMLRPC_MEMBLOCK_CONTENTS(unsigned char, decoded); - size_t const byteCount = - XMLRPC_MEMBLOCK_SIZE(unsigned char, decoded); - - *valuePP = xmlrpc_base64_new(envP, byteCount, bytes); - - XMLRPC_MEMBLOCK_FREE(unsigned char, decoded); - } -} - - - -static void -parseI8(xmlrpc_env * const envP, - const char * const str, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Parse the content of a XML-RPC XML element, e.g. "34". - - 'str' is that content. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(str); - - if (str[0] == '\0') - setParseFault(envP, " XML element content is empty"); - else if (isspace(str[0])) - setParseFault(envP, - " content '%s' starts with white space", str); - else { - xmlrpc_int64 i; - xmlrpc_env env; - - xmlrpc_env_init(&env); - - xmlrpc_parse_int64(&env, str, &i); - - if (env.fault_occurred) - setParseFault(envP, " XML element value '%s' is invalid " - "because it does not represent " - "a 64 bit integer. %s", env.fault_string); - else - *valuePP = xmlrpc_i8_new(envP, i); - - xmlrpc_env_clean(&env); - } -} - - - -static void -parseSimpleValueCdata(xmlrpc_env * const envP, - const char * const elementName, - const char * const cdata, - size_t const cdataLength, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Parse an XML element that is supposedly a data type element such as - . Its name is 'elementName', and it has no children, but - contains cdata 'cdata', which is 'dataLength' characters long. ------------------------------------------------------------------------------*/ - /* We need to straighten out the whole character set / encoding thing - some day. What is 'cdata', and what should it be? Does it have - embedded NUL? Some of the code here assumes it doesn't. Is it - text? - - The parser assumes it's UTF 8 with embedded NULs. - But the parser will get terribly confused if there are any - UTF-8 multibyte sequences or NUL characters. So will most of the - others. - - The "ex:XXX" element names are what the Apache XML-RPC facility - uses: http://ws.apache.org/xmlrpc/types.html. (Technically, it - isn't "ex" but an arbitrary prefix that identifies a namespace - declared earlier in the XML document -- this is an XML thing. - But we aren't nearly sophisticated enough to use real XML - namespaces, so we exploit the fact that XML-RPC actually uses - "ex"). - - "i1" and "i2" are just from my imagination. - */ - - if (xmlrpc_streq(elementName, "int") || - xmlrpc_streq(elementName, "i4") || - xmlrpc_streq(elementName, "i1") || - xmlrpc_streq(elementName, "i2") || - xmlrpc_streq(elementName, "ex:i1") || - xmlrpc_streq(elementName, "ex:i2")) - parseInt(envP, cdata, valuePP); - else if (xmlrpc_streq(elementName, "boolean")) - parseBoolean(envP, cdata, valuePP); - else if (xmlrpc_streq(elementName, "double")) - parseDouble(envP, cdata, valuePP); - else if (xmlrpc_streq(elementName, "dateTime.iso8601")) - xmlrpc_parseDatetime(envP, cdata, valuePP); - else if (xmlrpc_streq(elementName, "string")) - *valuePP = xmlrpc_string_new_lp(envP, cdataLength, cdata); - else if (xmlrpc_streq(elementName, "base64")) - parseBase64(envP, cdata, cdataLength, valuePP); - else if (xmlrpc_streq(elementName, "nil") || - xmlrpc_streq(elementName, "ex:nil")) - *valuePP = xmlrpc_nil_new(envP); - else if (xmlrpc_streq(elementName, "i8") || - xmlrpc_streq(elementName, "ex:i8")) - parseI8(envP, cdata, valuePP); - else - setParseFault(envP, "Unknown value type -- XML element is named " - "<%s>", elementName); -} - - - -static void -parseSimpleValue(xmlrpc_env * const envP, - xml_element * const elemP, - xmlrpc_value ** const valuePP) { - - size_t const childCount = xml_element_children_size(elemP); - - if (childCount > 0) - setParseFault(envP, "The child of a element " - "is neither nor , " - "but has %u child elements of its own.", - (unsigned int)childCount); - else { - const char * const elemName = xml_element_name(elemP); - const char * const cdata = xml_element_cdata(elemP); - size_t const cdataSize = xml_element_cdata_size(elemP); - - parseSimpleValueCdata(envP, elemName, cdata, cdataSize, valuePP); - } -} - - - -void -xmlrpc_parseValue(xmlrpc_env * const envP, - unsigned int const maxRecursion, - xml_element * const elemP, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Compute the xmlrpc_value represented by the XML element 'elem'. - Return that xmlrpc_value. - - We call convert_array() and convert_struct(), which may ultimately - call us recursively. Don't recurse any more than 'maxRecursion' - times. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(elemP != NULL); - - /* Assume we'll need to recurse, make sure we're allowed */ - if (maxRecursion < 1) - xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, - "Nested data structure too deep."); - else { - if (!xmlrpc_streq(xml_element_name(elemP), "value")) - setParseFault(envP, - "<%s> element where expected", - xml_element_name(elemP)); - else { - size_t const childCount = xml_element_children_size(elemP); - - if (childCount == 0) { - /* We have no type element, so treat the value as a string. */ - const char * const cdata = xml_element_cdata(elemP); - size_t const cdata_size = xml_element_cdata_size(elemP); - *valuePP = xmlrpc_string_new_lp(envP, cdata_size, cdata); - } else if (childCount > 1) - setParseFault(envP, " has %u child elements. " - "Only zero or one make sense.", - (unsigned int)childCount); - else { - /* We should have a type tag inside our value tag. */ - xml_element * const childP = xml_element_children(elemP)[0]; - const char * const childName = xml_element_name(childP); - - if (xmlrpc_streq(childName, "struct")) - parseStruct(envP, maxRecursion, childP, valuePP); - else if (xmlrpc_streq(childName, "array")) - parseArray(envP, maxRecursion, childP, valuePP); - else - parseSimpleValue(envP, childP, valuePP); - } - } - } -} - - - diff --git a/trunk/src/parse_value.h b/trunk/src/parse_value.h deleted file mode 100644 index bca801113..000000000 --- a/trunk/src/parse_value.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PARSE_VALUE_H_INCLUDED -#define PARSE_VALUE_H_INCLUDED - -#include "xmlrpc-c/base.h" -#include "xmlparser.h" - -void -xmlrpc_parseValue(xmlrpc_env * const envP, - unsigned int const maxRecursion, - xml_element * const elemP, - xmlrpc_value ** const valuePP); - -#endif diff --git a/trunk/src/parse_xml.c b/trunk/src/parse_xml.c deleted file mode 100644 index 2618a72df..000000000 --- a/trunk/src/parse_xml.c +++ /dev/null @@ -1,103 +0,0 @@ -/*============================================================================= - parse_xml -=============================================================================== - This is an example of using the XML parsing facilities of - XML-RPC For C/C++, in particular its libxmlrpc_xmlparse library. - - Feed XML (any XML - doesn't have to be XML-RPC) to this program as - standard input. It parses it and tells you what it sees. - - Example: - - $ ./gen_sample_add_xml | ./parse_xml - -=============================================================================*/ -#include -#include -#include - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/xmlparser.h" - - - -static const char * -getStdin(void) { - - size_t const maxInputSize = 64 * 1024; - char * retval; - - retval = malloc(maxInputSize + 1); - - if (retval == NULL) { - fprintf(stderr, "malloc failed."); - exit(100); - } else { - size_t rc; - - rc = fread(retval, 1, maxInputSize, stdin); - - if (rc < 0) - fprintf(stderr, "Failed to read Standard Input"); - else { - size_t const bytesRead = rc; - retval[bytesRead] = '\0'; - } - } - return retval; -} - - - -static void -describeXmlElement(const xml_element * const elemP, - const char * const prefix) { - - unsigned int i; - - printf("%sXML element type: '%s'\n", - prefix, xml_element_name(elemP)); - - printf("%sCdata: '%s'\n", - prefix, xml_element_cdata(elemP)); - - printf("%sNumber of child elements: %u\n", - prefix, xml_element_children_size(elemP)); - - if (xml_element_children_size(elemP) == 0) - printf("\n"); - - for (i = 0; i < xml_element_children_size(elemP); ++i) { - char * const newPrefix = malloc(strlen(prefix) + 2); - sprintf(newPrefix, "%s ", prefix); - describeXmlElement(xml_element_children(elemP)[i], newPrefix); - free(newPrefix); - } -} - - - -int -main(int argc, const char ** argv) { - - const char * xml; - xmlrpc_env env; - xml_element * elemP; - - xmlrpc_env_init(&env); - - xml = getStdin(); - - xml_parse(&env, xml, strlen(xml), &elemP); - - if (env.fault_occurred) - printf("xml_parse failed. %s\n", env.fault_string); - else { - printf("Parsed successfully.\n"); - - describeXmlElement(elemP, ""); - } - xmlrpc_env_clean(&env); - - return 0; -} diff --git a/trunk/src/registry.c b/trunk/src/registry.c deleted file mode 100644 index 4dae56515..000000000 --- a/trunk/src/registry.c +++ /dev/null @@ -1,499 +0,0 @@ -/*========================================================================= - XML-RPC Server Method Registry -=========================================================================== - These are the functions that implement the XML-RPC method registry. - - A method registry is a list of XML-RPC methods for a server to - implement, along with the details of how to implement each -- most - notably a function pointer for a function that executes the method. - - To build an XML-RPC server, just add a communication facility. - - Copyright information is at end of file - -=========================================================================*/ - -#include -#include -#include - -#include "xmlrpc_config.h" -#include "bool.h" -#include "mallocvar.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "method.h" -#include "system_method.h" -#include "version.h" - -#include "registry.h" - - -unsigned int const xmlrpc_server_version_major = XMLRPC_VERSION_MAJOR; -unsigned int const xmlrpc_server_version_minor = XMLRPC_VERSION_MINOR; -unsigned int const xmlrpc_server_version_point = XMLRPC_VERSION_POINT; - - - -void -xmlrpc_server_version(unsigned int * const majorP, - unsigned int * const minorP, - unsigned int * const pointP) { - - *majorP = XMLRPC_VERSION_MAJOR; - *minorP = XMLRPC_VERSION_MINOR; - *pointP = XMLRPC_VERSION_POINT; -} - - - -xmlrpc_registry * -xmlrpc_registry_new(xmlrpc_env * const envP) { - - xmlrpc_registry * registryP; - - XMLRPC_ASSERT_ENV_OK(envP); - - MALLOCVAR(registryP); - - if (registryP == NULL) - xmlrpc_faultf(envP, "Could not allocate memory for registry"); - else { - registryP->introspectionEnabled = true; - registryP->defaultMethodFunction = NULL; - registryP->preinvokeFunction = NULL; - registryP->shutdownServerFn = NULL; - registryP->dialect = xmlrpc_dialect_i8; - - xmlrpc_methodListCreate(envP, ®istryP->methodListP); - if (!envP->fault_occurred) - xmlrpc_installSystemMethods(envP, registryP); - - if (envP->fault_occurred) - free(registryP); - } - return registryP; -} - - - -void -xmlrpc_registry_free(xmlrpc_registry * const registryP) { - - XMLRPC_ASSERT_PTR_OK(registryP); - - xmlrpc_methodListDestroy(registryP->methodListP); - - free(registryP); -} - - - -static void -registryAddMethod(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const methodName, - xmlrpc_method1 method1, - xmlrpc_method2 method2, - const char * const signatureString, - const char * const help, - void * const userData, - size_t const stackSize) { - - const char * const helpString = - help ? help : "No help is available for this method."; - - xmlrpc_methodInfo * methodP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(registryP); - XMLRPC_ASSERT_PTR_OK(methodName); - XMLRPC_ASSERT(method1 != NULL || method2 != NULL); - - xmlrpc_methodCreate(envP, method1, method2, userData, - signatureString, helpString, stackSize, &methodP); - - if (!envP->fault_occurred) { - xmlrpc_methodListAdd(envP, registryP->methodListP, methodName, - methodP); - - if (envP->fault_occurred) - xmlrpc_methodDestroy(methodP); - } -} - - - -void -xmlrpc_registry_add_method_w_doc( - xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const host ATTR_UNUSED, - const char * const methodName, - xmlrpc_method1 const method, - void * const serverInfo, - const char * const signatureString, - const char * const help) { - - XMLRPC_ASSERT(host == NULL); - - registryAddMethod(envP, registryP, methodName, method, NULL, - signatureString, help, serverInfo, 0); -} - - - -void -xmlrpc_registry_add_method(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const host, - const char * const methodName, - xmlrpc_method1 const method, - void * const serverInfoP) { - - xmlrpc_registry_add_method_w_doc( - envP, registryP, host, methodName, - method, serverInfoP, "?", "No help is available for this method."); -} - - - -void -xmlrpc_registry_add_method2(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const methodName, - xmlrpc_method2 method, - const char * const signatureString, - const char * const help, - void * const serverInfo) { - - registryAddMethod(envP, registryP, methodName, NULL, method, - signatureString, help, serverInfo, 0); -} - - - -void -xmlrpc_registry_add_method3( - xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const struct xmlrpc_method_info3 * const infoP) { - - registryAddMethod(envP, registryP, infoP->methodName, NULL, - infoP->methodFunction, - infoP->signatureString, infoP->help, infoP->serverInfo, - infoP->stackSize); -} - - - -void -xmlrpc_registry_set_default_method( - xmlrpc_env * const envP ATTR_UNUSED, - xmlrpc_registry * const registryP ATTR_UNUSED, - xmlrpc_default_method const function, - void * const userData) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(registryP); - XMLRPC_ASSERT_PTR_OK(function); - - /* Note: this may be the first default method, or it may be a replacement - of the current one. - */ - - registryP->defaultMethodFunction = function; - registryP->defaultMethodUserData = userData; -} - - - -/* This is our guess at what a method function requires when the user - doesn't say. -*/ -#define METHOD_FUNCTION_STACK 128*1024 - - - -static size_t -methodStackSize(const xmlrpc_methodInfo * const methodP) { - - return methodP->stackSize == - 0 ? METHOD_FUNCTION_STACK : methodP->stackSize; -} - - - -size_t -xmlrpc_registry_max_stackSize(xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Return the maximum amount of stack required by the methods in registry - *registryP. - - If there are no methods, return 0. ------------------------------------------------------------------------------*/ - xmlrpc_methodNode * p; - size_t stackSize; - - for (p = registryP->methodListP->firstMethodP, stackSize = 0; - p; - p = p->nextP) { - - stackSize = MAX(stackSize, methodStackSize(p->methodP)); - } - return stackSize; -} - - - -void -xmlrpc_registry_set_preinvoke_method( - xmlrpc_env * const envP ATTR_UNUSED, - xmlrpc_registry * const registryP ATTR_UNUSED, - xmlrpc_preinvoke_method const function, - void * const userData) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(registryP); - XMLRPC_ASSERT_PTR_OK(function); - - registryP->preinvokeFunction = function; - registryP->preinvokeUserData = userData; -} - - - -void -xmlrpc_registry_set_shutdown(xmlrpc_registry * const registryP, - xmlrpc_server_shutdown_fn * const shutdownFn, - void * const context) { - - XMLRPC_ASSERT_PTR_OK(registryP); - XMLRPC_ASSERT_PTR_OK(shutdownFn); - - registryP->shutdownServerFn = shutdownFn; - - registryP->shutdownContext = context; -} - - - -void -xmlrpc_registry_set_dialect(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - xmlrpc_dialect const dialect) { - - if (dialect != xmlrpc_dialect_i8 && - dialect != xmlrpc_dialect_apache) - xmlrpc_faultf(envP, "Invalid dialect argument -- not of type " - "xmlrpc_dialect. Numerical value is %u", dialect); - else - registryP->dialect = dialect; -} - - - -static void -callNamedMethod(xmlrpc_env * const envP, - xmlrpc_methodInfo * const methodP, - xmlrpc_value * const paramArrayP, - void * const callInfoP, - xmlrpc_value ** const resultPP) { - - if (methodP->methodFnType2) - *resultPP = - methodP->methodFnType2(envP, paramArrayP, - methodP->userData, callInfoP); - else { - assert(methodP->methodFnType1); - *resultPP = - methodP->methodFnType1(envP, paramArrayP, methodP->userData); - } -} - - - -void -xmlrpc_dispatchCall(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - void * const callInfoP, - xmlrpc_value ** const resultPP) { - - if (registryP->preinvokeFunction) - registryP->preinvokeFunction(envP, methodName, paramArrayP, - registryP->preinvokeUserData); - - if (!envP->fault_occurred) { - xmlrpc_methodInfo * methodP; - - xmlrpc_methodListLookupByName(registryP->methodListP, methodName, - &methodP); - - if (methodP) - callNamedMethod(envP, methodP, paramArrayP, callInfoP, resultPP); - else { - if (registryP->defaultMethodFunction) - *resultPP = registryP->defaultMethodFunction( - envP, callInfoP, methodName, paramArrayP, - registryP->defaultMethodUserData); - else { - /* No matching method, and no default. */ - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NO_SUCH_METHOD_ERROR, - "Method '%s' not defined", methodName); - } - } - } - /* For backward compatibility, for sloppy users: */ - if (envP->fault_occurred) - *resultPP = NULL; -} - - - -/*========================================================================= -** xmlrpc_registry_process_call -**========================================================================= -** -*/ - -static void -serializeFault(xmlrpc_env * const envP, - xmlrpc_env const fault, - xmlrpc_mem_block * const responseXmlP) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - xmlrpc_serialize_fault(&env, responseXmlP, &fault); - - if (env.fault_occurred) - xmlrpc_faultf(envP, - "Executed XML-RPC method completely and it " - "generated a fault response, but we failed " - "to encode that fault response as XML-RPC " - "so we could send it to the client. %s", - env.fault_string); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_registry_process_call2(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const callXml, - size_t const callXmlLen, - void * const callInfo, - xmlrpc_mem_block ** const responseXmlPP) { - - xmlrpc_mem_block * responseXmlP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(callXml); - - xmlrpc_traceXml("XML-RPC CALL", callXml, callXmlLen); - - /* Allocate our output buffer. - ** If this fails, we need to die in a special fashion. */ - responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - const char * methodName; - xmlrpc_value * paramArrayP; - xmlrpc_env fault; - xmlrpc_env parseEnv; - - xmlrpc_env_init(&fault); - xmlrpc_env_init(&parseEnv); - - xmlrpc_parse_call(&parseEnv, callXml, callXmlLen, - &methodName, ¶mArrayP); - - if (parseEnv.fault_occurred) - xmlrpc_env_set_fault_formatted( - &fault, XMLRPC_PARSE_ERROR, - "Call XML not a proper XML-RPC call. %s", - parseEnv.fault_string); - else { - xmlrpc_value * resultP; - - xmlrpc_dispatchCall(&fault, registryP, methodName, paramArrayP, - callInfo, &resultP); - - if (!fault.fault_occurred) { - xmlrpc_serialize_response2(envP, responseXmlP, - resultP, registryP->dialect); - - xmlrpc_DECREF(resultP); - } - xmlrpc_strfree(methodName); - xmlrpc_DECREF(paramArrayP); - } - if (!envP->fault_occurred && fault.fault_occurred) - serializeFault(envP, fault, responseXmlP); - - xmlrpc_env_clean(&parseEnv); - xmlrpc_env_clean(&fault); - - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, responseXmlP); - else { - *responseXmlPP = responseXmlP; - xmlrpc_traceXml("XML-RPC RESPONSE", - XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlP), - XMLRPC_MEMBLOCK_SIZE(char, responseXmlP)); - } - } -} - - - -xmlrpc_mem_block * -xmlrpc_registry_process_call(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const host ATTR_UNUSED, - const char * const callXml, - size_t const callXmlLen) { - - xmlrpc_mem_block * responseXmlP; - - xmlrpc_registry_process_call2(envP, registryP, callXml, callXmlLen, NULL, - &responseXmlP); - - return responseXmlP; -} - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2001 by Eric Kidd. All rights reserved. -** Copyright (C) 2001 by Luke Howard. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ diff --git a/trunk/src/registry.h b/trunk/src/registry.h deleted file mode 100644 index 509d57886..000000000 --- a/trunk/src/registry.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef REGISTRY_H_INCLUDED -#define REGISTRY_H_INCLUDED - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" - -void -xmlrpc_dispatchCall(struct _xmlrpc_env * const envP, - struct xmlrpc_registry * const registryP, - const char * const methodName, - struct _xmlrpc_value * const paramArrayP, - void * const callInfoP, - struct _xmlrpc_value ** const resultPP); - -#endif diff --git a/trunk/src/resource.c b/trunk/src/resource.c deleted file mode 100644 index bed48a060..000000000 --- a/trunk/src/resource.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "xmlrpc_config.h" - -#include "xmlrpc-c/base.h" - - -/*========================================================================= -** Resource Limits -**========================================================================= -*/ - -static size_t limits[XMLRPC_LAST_LIMIT_ID + 1] = { - XMLRPC_NESTING_LIMIT_DEFAULT, - XMLRPC_XML_SIZE_LIMIT_DEFAULT -}; - -void -xmlrpc_limit_set (int const limit_id, - size_t const value) { - - XMLRPC_ASSERT(0 <= limit_id && limit_id <= XMLRPC_LAST_LIMIT_ID); - limits[limit_id] = value; -} - - - -size_t -xmlrpc_limit_get(int const limit_id) { - - XMLRPC_ASSERT(0 <= limit_id && limit_id <= XMLRPC_LAST_LIMIT_ID); - return limits[limit_id]; -} diff --git a/trunk/src/system_method.c b/trunk/src/system_method.c deleted file mode 100644 index bc6cf4999..000000000 --- a/trunk/src/system_method.c +++ /dev/null @@ -1,886 +0,0 @@ -/* Copyright information is at end of file */ - -#include "xmlrpc_config.h" - -#include -#include -#include - -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "version.h" -#include "registry.h" -#include "method.h" - -#include "system_method.h" - - -struct systemMethodReg { -/*---------------------------------------------------------------------------- - Information needed to register a system method ------------------------------------------------------------------------------*/ - const char * const methodName; - xmlrpc_method2 const methodFunction; - const char * const signatureString; - const char * const helpText; -}; - - - -void -xmlrpc_registry_disable_introspection(xmlrpc_registry * const registryP) { - - XMLRPC_ASSERT_PTR_OK(registryP); - - registryP->introspectionEnabled = false; -} - - - -/*========================================================================= - system.multicall -=========================================================================*/ - -static void -callOneMethod(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - xmlrpc_value * const rpcDescP, - void * const callInfo, - xmlrpc_value ** const resultPP) { - - const char * methodName; - xmlrpc_value * paramArrayP; - - XMLRPC_ASSERT_ENV_OK(envP); - - if (xmlrpc_value_type(rpcDescP) != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, - "An element of the multicall array is type %u, but should " - "be a struct (with members 'methodName' and 'params')", - xmlrpc_value_type(rpcDescP)); - else { - xmlrpc_decompose_value(envP, rpcDescP, "{s:s,s:A,*}", - "methodName", &methodName, - "params", ¶mArrayP); - if (!envP->fault_occurred) { - /* Watch out for a deep recursion attack. */ - if (xmlrpc_streq(methodName, "system.multicall")) - xmlrpc_env_set_fault_formatted( - envP, - XMLRPC_REQUEST_REFUSED_ERROR, - "Recursive system.multicall forbidden"); - else { - xmlrpc_env env; - xmlrpc_value * resultValP; - - xmlrpc_env_init(&env); - xmlrpc_dispatchCall(&env, registryP, methodName, paramArrayP, - callInfo, - &resultValP); - if (env.fault_occurred) { - /* Method failed, so result is a fault structure */ - *resultPP = - xmlrpc_build_value( - envP, "{s:i,s:s}", - "faultCode", (xmlrpc_int32) env.fault_code, - "faultString", env.fault_string); - } else { - *resultPP = xmlrpc_build_value(envP, "(V)", resultValP); - - xmlrpc_DECREF(resultValP); - } - xmlrpc_env_clean(&env); - } - xmlrpc_DECREF(paramArrayP); - xmlrpc_strfree(methodName); - } - } -} - - - -static void -getMethListFromMulticallPlist(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const methlistPP) { - - if (xmlrpc_array_size(envP, paramArrayP) != 1) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "system.multicall takes one parameter, which is an " - "array, each element describing one RPC. You " - "supplied %u arguments", - xmlrpc_array_size(envP, paramArrayP)); - else { - xmlrpc_value * methlistP; - - xmlrpc_array_read_item(envP, paramArrayP, 0, &methlistP); - - XMLRPC_ASSERT_ENV_OK(envP); - - if (xmlrpc_value_type(methlistP) != XMLRPC_TYPE_ARRAY) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, - "system.multicall's parameter should be an array, " - "each element describing one RPC. But it is type " - "%u instead.", xmlrpc_value_type(methlistP)); - else - *methlistPP = methlistP; - - if (envP->fault_occurred) - xmlrpc_DECREF(methlistP); - } -} - - - -static xmlrpc_value * -system_multicall(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo) { - - xmlrpc_registry * registryP; - xmlrpc_value * resultsP; - xmlrpc_value * methlistP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_ARRAY_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(serverInfo); - - resultsP = NULL; /* defeat compiler warning */ - - /* Turn our arguments into something more useful. */ - registryP = (xmlrpc_registry*) serverInfo; - - getMethListFromMulticallPlist(envP, paramArrayP, &methlistP); - if (!envP->fault_occurred) { - /* Create an initially empty result list. */ - resultsP = xmlrpc_array_new(envP); - if (!envP->fault_occurred) { - /* Loop over our input list, calling each method in turn. */ - unsigned int const methodCount = - xmlrpc_array_size(envP, methlistP); - unsigned int i; - for (i = 0; i < methodCount && !envP->fault_occurred; ++i) { - xmlrpc_value * const methinfoP = - xmlrpc_array_get_item(envP, methlistP, i); - - xmlrpc_value * resultP; - - XMLRPC_ASSERT_ENV_OK(envP); - - callOneMethod(envP, registryP, methinfoP, callInfo, &resultP); - - if (!envP->fault_occurred) { - /* Append this method result to our master array. */ - xmlrpc_array_append_item(envP, resultsP, resultP); - xmlrpc_DECREF(resultP); - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(resultsP); - xmlrpc_DECREF(methlistP); - } - } - return resultsP; -} - - - -static struct systemMethodReg const methodMulticall = { - "system.multicall", - &system_multicall, - "A:A", - "Process an array of calls, and return an array of results. Calls should " - "be structs of the form {'methodName': string, 'params': array}. Each " - "result will either be a single-item array containg the result value, or " - "a struct of the form {'faultCode': int, 'faultString': string}. This " - "is useful when you need to make lots of small calls without lots of " - "round trips.", -}; - - -/*========================================================================= - system.listMethods -=========================================================================*/ - - -static void -createMethodListArray(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - xmlrpc_value ** const methodListPP) { -/*---------------------------------------------------------------------------- - Create as an XML-RPC array value a list of names of methods registered - in registry 'registryP'. - - This is the type of value that the system.listMethods method is supposed - to return. ------------------------------------------------------------------------------*/ - xmlrpc_value * methodListP; - - methodListP = xmlrpc_array_new(envP); - - if (!envP->fault_occurred) { - xmlrpc_methodNode * methodNodeP; - for (methodNodeP = registryP->methodListP->firstMethodP; - methodNodeP && !envP->fault_occurred; - methodNodeP = methodNodeP->nextP) { - - xmlrpc_value * methodNameVP; - - methodNameVP = xmlrpc_string_new(envP, methodNodeP->methodName); - - if (!envP->fault_occurred) { - xmlrpc_array_append_item(envP, methodListP, methodNameVP); - - xmlrpc_DECREF(methodNameVP); - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(methodListP); - } - *methodListPP = methodListP; -} - - - -static xmlrpc_value * -system_listMethods(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo ATTR_UNUSED) { - - xmlrpc_registry * const registryP = serverInfo; - - xmlrpc_value * retvalP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(serverInfo); - - xmlrpc_decompose_value(envP, paramArrayP, "()"); - if (!envP->fault_occurred) { - if (!registryP->introspectionEnabled) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTROSPECTION_DISABLED_ERROR, - "Introspection is disabled in this server " - "for security reasons"); - else - createMethodListArray(envP, registryP, &retvalP); - } - return retvalP; -} - - - -static struct systemMethodReg const methodListMethods = { - "system.listMethods", - &system_listMethods, - "A:", - "Return an array of all available XML-RPC methods on this server.", -}; - - - -/*========================================================================= - system.methodExist -==========================================================================*/ - -static void -determineMethodExistence(xmlrpc_env * const envP, - const char * const methodName, - xmlrpc_registry * const registryP, - xmlrpc_value ** const existsPP) { - - xmlrpc_methodInfo * methodP; - - xmlrpc_methodListLookupByName(registryP->methodListP, methodName, - &methodP); - - *existsPP = xmlrpc_bool_new(envP, !!methodP); -} - - - -static xmlrpc_value * -system_methodExist(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo ATTR_UNUSED) { - - xmlrpc_registry * const registryP = serverInfo; - - xmlrpc_value * retvalP; - - const char * methodName; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(serverInfo); - - xmlrpc_decompose_value(envP, paramArrayP, "(s)", &methodName); - - if (!envP->fault_occurred) { - determineMethodExistence(envP, methodName, registryP, &retvalP); - - xmlrpc_strfree(methodName); - } - - return retvalP; -} - - - -static struct systemMethodReg const methodMethodExist = { - "system.methodExist", - &system_methodExist, - "s:b", - "Tell whether a method by a specified name exists on this server", -}; - - - -/*========================================================================= - system.methodHelp -=========================================================================*/ - - -static void -getHelpString(xmlrpc_env * const envP, - const char * const methodName, - xmlrpc_registry * const registryP, - xmlrpc_value ** const helpStringPP) { - - xmlrpc_methodInfo * methodP; - - xmlrpc_methodListLookupByName(registryP->methodListP, methodName, - &methodP); - - if (!methodP) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NO_SUCH_METHOD_ERROR, - "Method '%s' does not exist", methodName); - else - *helpStringPP = xmlrpc_string_new(envP, methodP->helpText); -} - - - -static xmlrpc_value * -system_methodHelp(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo ATTR_UNUSED) { - - xmlrpc_registry * const registryP = serverInfo; - - xmlrpc_value * retvalP; - - const char * methodName; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(serverInfo); - - xmlrpc_decompose_value(envP, paramArrayP, "(s)", &methodName); - - if (!envP->fault_occurred) { - if (!registryP->introspectionEnabled) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTROSPECTION_DISABLED_ERROR, - "Introspection is disabled in this server " - "for security reasons"); - else - getHelpString(envP, methodName, registryP, &retvalP); - - xmlrpc_strfree(methodName); - } - - return retvalP; -} - - -static struct systemMethodReg const methodMethodHelp = { - "system.methodHelp", - &system_methodHelp, - "s:s", - "Given the name of a method, return a help string.", -}; - - - -/*========================================================================= - system.methodSignature -==========================================================================*/ - -static void -buildNoSigSuppliedResult(xmlrpc_env * const envP, - xmlrpc_value ** const resultPP) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - *resultPP = xmlrpc_string_new(&env, "undef"); - if (env.fault_occurred) - xmlrpc_faultf(envP, "Unable to construct 'undef'. %s", - env.fault_string); - - xmlrpc_env_clean(&env); -} - - - -static void -buildSignatureValue(xmlrpc_env * const envP, - struct xmlrpc_signature * const signatureP, - xmlrpc_value ** const sigValuePP) { - - xmlrpc_value * sigValueP; - unsigned int i; - - sigValueP = xmlrpc_array_new(envP); - - { - xmlrpc_value * retTypeVP; - - retTypeVP = xmlrpc_string_new(envP, signatureP->retType); - - xmlrpc_array_append_item(envP, sigValueP, retTypeVP); - - xmlrpc_DECREF(retTypeVP); - } - for (i = 0; i < signatureP->argCount && !envP->fault_occurred; ++i) { - xmlrpc_value * argTypeVP; - - argTypeVP = xmlrpc_string_new(envP, signatureP->argList[i]); - if (!envP->fault_occurred) { - xmlrpc_array_append_item(envP, sigValueP, argTypeVP); - - xmlrpc_DECREF(argTypeVP); - } - } - - if (envP->fault_occurred) - xmlrpc_DECREF(sigValueP); - - *sigValuePP = sigValueP; -} - - - -static void -getSignatureList(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const methodName, - xmlrpc_value ** const signatureListPP) { -/*---------------------------------------------------------------------------- - Get the signature list array for method named 'methodName' from registry - 'registryP'. - - If there is no signature information for the method in the registry, - return *signatureListPP == NULL. - - Nonexistent method is considered a failure. ------------------------------------------------------------------------------*/ - xmlrpc_methodInfo * methodP; - - xmlrpc_methodListLookupByName(registryP->methodListP, methodName, - &methodP); - - if (!methodP) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NO_SUCH_METHOD_ERROR, - "Method '%s' does not exist", methodName); - else { - if (!methodP->signatureListP->firstSignatureP) - *signatureListPP = NULL; - else { - xmlrpc_value * signatureListP; - - signatureListP = xmlrpc_array_new(envP); - - if (!envP->fault_occurred) { - struct xmlrpc_signature * signatureP; - for (signatureP = methodP->signatureListP->firstSignatureP; - signatureP && !envP->fault_occurred; - signatureP = signatureP->nextP) { - - xmlrpc_value * signatureVP; - - buildSignatureValue(envP, signatureP, &signatureVP); - - xmlrpc_array_append_item(envP, - signatureListP, signatureVP); - - xmlrpc_DECREF(signatureVP); - } - if (envP->fault_occurred) - xmlrpc_DECREF(signatureListP); - } - *signatureListPP = signatureListP; - } - } -} - - - -/* Microsoft Visual C in debug mode produces code that complains about - returning an undefined value from system_methodSignature(). It's a bogus - complaint, because this function is defined to return nothing meaningful - those cases. So we disable the check. -*/ -#pragma runtime_checks("u", off) - - - -static xmlrpc_value * -system_methodSignature(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo ATTR_UNUSED) { - - xmlrpc_registry * const registryP = (xmlrpc_registry *) serverInfo; - - xmlrpc_value * retvalP; - const char * methodName; - xmlrpc_env env; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(serverInfo); - - xmlrpc_env_init(&env); - - /* Turn our arguments into something more useful. */ - xmlrpc_decompose_value(&env, paramArrayP, "(s)", &methodName); - if (env.fault_occurred) - xmlrpc_env_set_fault_formatted( - envP, env.fault_code, - "Invalid parameter list. %s", env.fault_string); - else { - if (!registryP->introspectionEnabled) - xmlrpc_env_set_fault(envP, XMLRPC_INTROSPECTION_DISABLED_ERROR, - "Introspection disabled on this server"); - else { - xmlrpc_value * signatureListP; - - getSignatureList(envP, registryP, methodName, &signatureListP); - - if (!envP->fault_occurred) { - if (signatureListP) - retvalP = signatureListP; - else - buildNoSigSuppliedResult(envP, &retvalP); - } - } - xmlrpc_strfree(methodName); - } - xmlrpc_env_clean(&env); - - return retvalP; -} - - - -#pragma runtime_checks("u", restore) - - - -static struct systemMethodReg const methodMethodSignature = { - "system.methodSignature", - &system_methodSignature, - "A:s", - "Given the name of a method, return an array of legal signatures. " - "Each signature is an array of strings. The first item of each signature " - "is the return type, and any others items are parameter types.", -}; - - - - -/*========================================================================= - system.shutdown -==========================================================================*/ - -static xmlrpc_value * -system_shutdown(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo) { - - xmlrpc_registry * const registryP = (xmlrpc_registry *) serverInfo; - - xmlrpc_value * retvalP; - const char * comment; - xmlrpc_env env; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(serverInfo); - - xmlrpc_env_init(&env); - - /* Turn our arguments into something more useful. */ - xmlrpc_decompose_value(&env, paramArrayP, "(s)", &comment); - if (env.fault_occurred) - xmlrpc_env_set_fault_formatted( - envP, env.fault_code, - "Invalid parameter list. %s", env.fault_string); - else { - if (!registryP->shutdownServerFn) - xmlrpc_env_set_fault( - envP, 0, "This server program is not capable of " - "shutting down"); - else { - registryP->shutdownServerFn( - &env, registryP->shutdownContext, comment, callInfo); - - if (env.fault_occurred) - xmlrpc_env_set_fault(envP, env.fault_code, env.fault_string); - else { - retvalP = xmlrpc_int_new(&env, 0); - - if (env.fault_occurred) - xmlrpc_faultf(envP, - "Failed to construct return value. %s", - env.fault_string); - } - } - xmlrpc_strfree(comment); - } - xmlrpc_env_clean(&env); - - return retvalP; -} - - - -static struct systemMethodReg const methodShutdown = { - "system.shutdown", - &system_shutdown, - "i:s", - "Shut down the server. Return code is always zero.", -}; - - - -/*========================================================================= - system.capabilities -=========================================================================*/ - -static void -constructCapabilities(xmlrpc_env * const envP, - xmlrpc_registry * const registryP ATTR_UNUSED, - xmlrpc_value ** const capabilitiesPP) { - - *capabilitiesPP = - xmlrpc_build_value( - envP, "{s:s,s:i,s:i,s:i,s:i}", - "facility", "xmlrpc-c", - "version_major", XMLRPC_VERSION_MAJOR, - "version_minor", XMLRPC_VERSION_MINOR, - "version_point", XMLRPC_VERSION_POINT, - "protocol_version", 2 - ); - -} - - - -static xmlrpc_value * -system_capabilities(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo ATTR_UNUSED) { - - xmlrpc_registry * const registryP = serverInfo; - - xmlrpc_value * retvalP; - - unsigned int paramCount; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(serverInfo); - - paramCount = xmlrpc_array_size(envP, paramArrayP); - - if (paramCount > 0) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, - "There are no parameters. You supplied %u", paramCount); - else - constructCapabilities(envP, registryP, &retvalP); - - return retvalP; -} - - - -static struct systemMethodReg const methodCapabilities = { - "system.capabilities", - &system_capabilities, - "S:", - "Return the capabilities of XML-RPC server. This includes the " - "version number of the XML-RPC For C/C++ software" -}; - - - -/*========================================================================= - system.getCapabilities -=========================================================================*/ - -/* This implements a standard. - See http://tech.groups.yahoo.com/group/xml-rpc/message/2897 . -*/ - -static void -listCapabilities(xmlrpc_env * const envP, - xmlrpc_registry * const registryP ATTR_UNUSED, - xmlrpc_value ** const capabilitiesPP) { - - *capabilitiesPP = - xmlrpc_build_value( - envP, "{s:{s:s,s:i}}", - "introspect", - "specUrl", - "http://xmlrpc-c.sourceforge.net/xmlrpc-c/introspection.html", - "specVersion", - 1 - ); -} - - - -static xmlrpc_value * -system_getCapabilities(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo ATTR_UNUSED) { - - xmlrpc_registry * const registryP = serverInfo; - - xmlrpc_value * retvalP; - - unsigned int paramCount; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(serverInfo); - - paramCount = xmlrpc_array_size(envP, paramArrayP); - - if (paramCount > 0) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, - "There are no parameters. You supplied %u", paramCount); - else - listCapabilities(envP, registryP, &retvalP); - - return retvalP; -} - - - -static struct systemMethodReg const methodGetCapabilities = { - "system.getCapabilities", - &system_getCapabilities, - "S:", - "Return the list of standard capabilities of XML-RPC server. " - "See http://tech.groups.yahoo.com/group/xml-rpc/message/2897" -}; - - - -/*============================================================================ - Installer of system methods -============================================================================*/ - -static void -registerSystemMethod(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - struct systemMethodReg const methodReg) { - - xmlrpc_env env; - xmlrpc_env_init(&env); - - xmlrpc_registry_add_method2( - &env, registryP, methodReg.methodName, - methodReg.methodFunction, - methodReg.signatureString, methodReg.helpText, registryP); - - if (env.fault_occurred) - xmlrpc_faultf(envP, "Failed to register '%s' system method. %s", - methodReg.methodName, env.fault_string); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_installSystemMethods(xmlrpc_env * const envP, - xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Install the built-in methods (system.*) into registry 'registryP'. ------------------------------------------------------------------------------*/ - if (!envP->fault_occurred) - registerSystemMethod(envP, registryP, methodListMethods); - - if (!envP->fault_occurred) - registerSystemMethod(envP, registryP, methodMethodExist); - - if (!envP->fault_occurred) - registerSystemMethod(envP, registryP, methodMethodHelp); - - if (!envP->fault_occurred) - registerSystemMethod(envP, registryP, methodMethodSignature); - - if (!envP->fault_occurred) - registerSystemMethod(envP, registryP, methodMulticall); - - if (!envP->fault_occurred) - registerSystemMethod(envP, registryP, methodShutdown); - - if (!envP->fault_occurred) - registerSystemMethod(envP, registryP, methodCapabilities); - - if (!envP->fault_occurred) - registerSystemMethod(envP, registryP, methodGetCapabilities); -} - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2001 by Eric Kidd. All rights reserved. -** Copyright (C) 2001 by Luke Howard. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - diff --git a/trunk/src/system_method.h b/trunk/src/system_method.h deleted file mode 100644 index cf2df3858..000000000 --- a/trunk/src/system_method.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SYSTEM_METHOD_H_INCLUDED -#define SYSTEM_METHOD_H_INCLUDED - - -void -xmlrpc_installSystemMethods(struct _xmlrpc_env * const envP, - struct xmlrpc_registry * const registryP); - -void -xmlrpc_buildSignatureArray(xmlrpc_env * const envP, - const char * const sigListString, - xmlrpc_value ** const resultPP); - -#endif diff --git a/trunk/src/trace.c b/trunk/src/trace.c deleted file mode 100644 index bb6594539..000000000 --- a/trunk/src/trace.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include - -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" - - -static size_t -nextLineSize(const char * const string, - size_t const startPos, - size_t const stringSize) { -/*---------------------------------------------------------------------------- - Return the length of the line that starts at offset 'startPos' in the - string 'string', which is 'stringSize' characters long. - - 'string' in not NUL-terminated. - - A line begins at beginning of string or after a newline character and - runs through the next newline character or end of string. The line - includes the newline character at the end, if any. ------------------------------------------------------------------------------*/ - size_t i; - - for (i = startPos; i < stringSize && string[i] != '\n'; ++i); - - if (i < stringSize) - ++i; /* Include the newline */ - - return i - startPos; -} - - - -void -xmlrpc_traceXml(const char * const label, - const char * const xml, - size_t const xmlLength) { - - if (getenv("XMLRPC_TRACE_XML")) { - size_t cursor; /* Index into xml[] */ - - fprintf(stderr, "%s:\n\n", label); - - for (cursor = 0; cursor < xmlLength; ) { - /* Print one line of XML */ - - size_t const lineSize = nextLineSize(xml, cursor, xmlLength); - const char * const xmlPrintableLine = - xmlrpc_makePrintable_lp(&xml[cursor], lineSize); - - fprintf(stderr, "%s\n", xmlPrintableLine); - - cursor += lineSize; - - xmlrpc_strfree(xmlPrintableLine); - } - fprintf(stderr, "\n"); - } -} - - diff --git a/trunk/src/version.c b/trunk/src/version.c deleted file mode 100644 index 07a2d4334..000000000 --- a/trunk/src/version.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "version.h" - -#include "xmlrpc-c/base.h" - -unsigned int const xmlrpc_version_major = XMLRPC_VERSION_MAJOR; -unsigned int const xmlrpc_version_minor = XMLRPC_VERSION_MINOR; -unsigned int const xmlrpc_version_point = XMLRPC_VERSION_POINT; - -void -xmlrpc_version(unsigned int * const majorP, - unsigned int * const minorP, - unsigned int * const pointP) { - - *majorP = XMLRPC_VERSION_MAJOR; - *minorP = XMLRPC_VERSION_MINOR; - *pointP = XMLRPC_VERSION_POINT; -} - diff --git a/trunk/src/xmlparser.h b/trunk/src/xmlparser.h deleted file mode 100644 index 3dc17d69f..000000000 --- a/trunk/src/xmlparser.h +++ /dev/null @@ -1,131 +0,0 @@ -/* Copyright and license information is at the end of the file */ - -#ifndef XMLRPC_XMLPARSER_H_INCLUDED -#define XMLRPC_XMLPARSER_H_INCLUDED - -#include "xmlrpc-c/util_int.h" -/*============================================================================= - Abstract XML Parser Interface -=============================================================================== - This file provides an abstract interface to the XML parser, so we can - use multiple XML parsers with the main XML-RPC code not having to know - their specific interfaces. - - It works like this: When you need to parse some XML (we don't care what the - XML is as long as it is one valid XML element, but in practice it is going - to be an XML-RPC call or response), you call our 'xml_init' with the XML - text as argument. That generates an object of type 'xml_element' to - represent the XML element. - - You then call methods of that object to parse the XML element, e.g. to - find out its name or its children. -=============================================================================*/ - - -typedef struct _xml_element xml_element; - /* An object that represents an XML element */ - -void -xml_element_free(xml_element * const elemP); - /* Destroy the element */ - -const char * -xml_element_name(const xml_element * const elemP); - /* The XML element name. UTF-8. - - This points to memory owned by *elemP. - */ - -size_t -xml_element_cdata_size(const xml_element * const elemP); - /* The size of the element's cdata */ - -const char * -xml_element_cdata(const xml_element * const elemP); - /* The XML element's CDATA. UTF-8. - - This is a pointer to the cdata. - - There is a NUL character appended to the CDATA, but it is not part of - the CDATA, so is not included in the value returned by - xml_element_cdata_size(). - - This is memory owned by *elemP. - - 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. - */ - -unsigned int -xml_element_children_size(const xml_element * const elemP); - /* Number of children the XML element has */ - -xml_element ** -xml_element_children(const xml_element * const elemP); - /* All the child elements of the element. - - Each pointer points to an object owned by *elemP. - */ - -void -xml_parse(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - xml_element ** const resultPP); - /* - Create an xml_elemnt object to represent it. - - Caller must ultimately destroy this object. - - Parse the XML text 'xmlData', of length 'xmlDataLen'. Return the - description of the element that the XML text contains as *resultPP. - Normally, the element has children, so that *resultPP is just the - root of a tree of elements. - - Use *memPoolP for some memory allocations. It is primarily for memory - uses whose size we cannot bound right now, like because it depends on - what the XML looks like - *memPoolP has bounds, so this prevents us - from using more than our share of system memory. If 'memPoolP' is - null, just use the default system pool (which is unbounded). - */ - - -/* Initialize and terminate static global parser state. This should be done - once per run of a program, and while the program is just one thread. -*/ -void -xml_init(xmlrpc_env * const envP); - -void -xml_term(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. */ - -#endif diff --git a/trunk/src/xmlrpc_array.c b/trunk/src/xmlrpc_array.c deleted file mode 100644 index 45f15c3d7..000000000 --- a/trunk/src/xmlrpc_array.c +++ /dev/null @@ -1,278 +0,0 @@ -/* Copyright information is at the end of the file */ - -/*========================================================================= -** XML-RPC Array Functions -**========================================================================= -*/ - -#include "xmlrpc_config.h" - -#include -#include -#include - -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" - - - -void -xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP) { - - if (arrayP == NULL) - abort(); - else if (arrayP->_type != XMLRPC_TYPE_ARRAY) - abort(); - else { - size_t const arraySize = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); - xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); - - if (contents == NULL) - abort(); - else { - size_t index; - - for (index = 0; index < arraySize; ++index) { - xmlrpc_value * const itemP = contents[index]; - if (itemP == NULL) - abort(); - else if (itemP->refcount < 1) - abort(); - } - } - } -} - - - -void -xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP) { -/*---------------------------------------------------------------------------- - Dispose of the contents of an array (but not the array value itself). - The value is not valid after this. ------------------------------------------------------------------------------*/ - size_t const arraySize = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); - xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); - - size_t index; - - XMLRPC_ASSERT_ARRAY_OK(arrayP); - - /* Release our reference to each item in the array */ - for (index = 0; index < arraySize; ++index) { - xmlrpc_value * const itemP = contents[index]; - xmlrpc_DECREF(itemP); - } - XMLRPC_MEMBLOCK_FREE(xmlrpc_value *, arrayP->blockP); -} - - - -int -xmlrpc_array_size(xmlrpc_env * const envP, - const xmlrpc_value * const arrayP) { - - int retval; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(arrayP); - - if (arrayP->_type != XMLRPC_TYPE_ARRAY) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not an array"); - retval = -1; - } else { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); - - assert((size_t)(int)(size) == size); - - retval = (int)size; - } - return retval; -} - - - -void -xmlrpc_array_append_item(xmlrpc_env * const envP, - xmlrpc_value * const arrayP, - xmlrpc_value * const valueP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(arrayP); - - if (xmlrpc_value_type(arrayP) != XMLRPC_TYPE_ARRAY) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not an array"); - else { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); - - XMLRPC_MEMBLOCK_RESIZE(xmlrpc_value *, envP, arrayP->blockP, size+1); - - if (!envP->fault_occurred) { - xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); - xmlrpc_INCREF(valueP); - contents[size] = valueP; - } - } -} - - - -void -xmlrpc_array_read_item(xmlrpc_env * const envP, - const xmlrpc_value * const arrayP, - unsigned int const index, - xmlrpc_value ** const valuePP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(arrayP); - XMLRPC_ASSERT_PTR_OK(valuePP); - - if (arrayP->_type != XMLRPC_TYPE_ARRAY) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Attempt to read array item from " - "a value that is not an array"); - else { - xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); - - if (index >= size) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Array index %u is beyond end " - "of %u-item array", index, (unsigned int)size); - else { - *valuePP = contents[index]; - xmlrpc_INCREF(*valuePP); - } - } -} - - - -xmlrpc_value * -xmlrpc_array_get_item(xmlrpc_env * const envP, - const xmlrpc_value * const arrayP, - int const index) { - - xmlrpc_value * valueP; - - if (index < 0) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Index %d is negative.", index); - else { - xmlrpc_array_read_item(envP, arrayP, index, &valueP); - - if (!envP->fault_occurred) - xmlrpc_DECREF(valueP); - } - if (envP->fault_occurred) - valueP = NULL; - - return valueP; -} - - - -xmlrpc_value * -xmlrpc_array_new(xmlrpc_env * const envP) { -/*---------------------------------------------------------------------------- - Create an empty array xmlrpc_value. ------------------------------------------------------------------------------*/ - xmlrpc_value * arrayP; - - xmlrpc_createXmlrpcValue(envP, &arrayP); - if (!envP->fault_occurred) { - arrayP->_type = XMLRPC_TYPE_ARRAY; - arrayP->blockP = XMLRPC_MEMBLOCK_NEW(xmlrpc_value *, envP, 0); - if (envP->fault_occurred) - free(arrayP); - } - return arrayP; -} - - - -xmlrpc_value * -xmlrpc_array_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * arrayP; - - if (valueP->_type != XMLRPC_TYPE_ARRAY) { - xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, - "Value is not an array. " - "It is type #%d", valueP->_type); - arrayP = NULL; - } else { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, valueP->blockP); - - xmlrpc_createXmlrpcValue(envP, &arrayP); - if (!envP->fault_occurred) { - arrayP->_type = XMLRPC_TYPE_ARRAY; - - arrayP->blockP = XMLRPC_MEMBLOCK_NEW(xmlrpc_value *, envP, 0); - - if (envP->fault_occurred) - free(arrayP); - else { - xmlrpc_value ** const srcValuePList = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, valueP->blockP); - - unsigned int i; - - for (i = 0; i < size && !envP->fault_occurred; ++i) { - xmlrpc_value * const newEltP = - xmlrpc_value_new(envP, srcValuePList[i]); - if (!envP->fault_occurred) - xmlrpc_array_append_item(envP, arrayP, newEltP); - } - if (envP->fault_occurred) - xmlrpc_destroyArrayContents(arrayP); - } - - if (envP->fault_occurred) - free(arrayP); - } - } - return arrayP; -} - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ diff --git a/trunk/src/xmlrpc_authcookie.c b/trunk/src/xmlrpc_authcookie.c deleted file mode 100644 index c0f19eb8d..000000000 --- a/trunk/src/xmlrpc_authcookie.c +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright (C) 2002 by jeff@ourexchange.net. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include -#include - -#include "mallocvar.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/util_int.h" - -/***************************************************************************** - I don't see how these were expected to be used. And I probably - broke it somehow at some point by removing code from somewhere else. - But I doubt that, whatever it's supposed to do, environment - variables are the right tool. - - Note that on a platform that doesn't have SETENV, - xmlrpc_authcookie_set() is just a no-op. - - -Bryan 2005.06.10 -****************************************************************************/ - -void -xmlrpc_authcookie_set(xmlrpc_env * const envP, - const char * const username, - const char * const password) { - - char * unencoded; - xmlrpc_mem_block * token; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(username); - XMLRPC_ASSERT_PTR_OK(password); - - /* Create unencoded string/hash. */ - - MALLOCARRAY(unencoded,(strlen(username) + strlen(password) + 1 + 1)); - sprintf(unencoded, "%s:%s", username, password); - - /* Create encoded string. */ - token = xmlrpc_base64_encode_without_newlines( - envP, (unsigned char *)unencoded, strlen(unencoded)); - if (!envP->fault_occurred) { - /* Set HTTP_COOKIE_AUTH to the character representation of the - encoded string. - */ -#if HAVE_SETENV - setenv("HTTP_COOKIE_AUTH", - XMLRPC_MEMBLOCK_CONTENTS(char, token), - 1); -#endif - xmlrpc_mem_block_free(token); - } - free(unencoded); -} - - - -char *xmlrpc_authcookie ( void ) { - return getenv("HTTP_COOKIE_AUTH"); -} diff --git a/trunk/src/xmlrpc_build.c b/trunk/src/xmlrpc_build.c deleted file mode 100644 index b44f4716d..000000000 --- a/trunk/src/xmlrpc_build.c +++ /dev/null @@ -1,430 +0,0 @@ -/* Copyright information is at end of file */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#include "bool.h" -#include "c_util.h" -#include "mallocvar.h" -#include "stdargx.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" - - - -static void -getString(xmlrpc_env * const envP, - const char ** const formatP, - va_listx * const argsP, - xmlrpc_value ** const valPP) { - - const char * str; - size_t len; - - str = (const char*) va_arg(argsP->v, char*); - if (*(*formatP) == '#') { - ++(*formatP); - len = (size_t) va_arg(argsP->v, size_t); - } else - len = strlen(str); - - *valPP = xmlrpc_string_new_lp(envP, len, str); -} - - - -static void -getWideString(xmlrpc_env * const envP ATTR_UNUSED, - const char ** const formatP ATTR_UNUSED, - va_listx * const argsP ATTR_UNUSED, - xmlrpc_value ** const valPP ATTR_UNUSED) { - -#if HAVE_UNICODE_WCHAR - wchar_t *wcs; - size_t len; - - wcs = (wchar_t*) va_arg(argsP->v, wchar_t*); - if (**formatP == '#') { - (*formatP)++; - len = (size_t) va_arg(argsP->v, size_t); - } else - len = wcslen(wcs); - - *valPP = xmlrpc_string_w_new_lp(envP, len, wcs); - -#endif /* HAVE_UNICODE_WCHAR */ -} - - - -static void -getBase64(xmlrpc_env * const envP, - va_listx * const argsP, - xmlrpc_value ** const valPP) { - - unsigned char * value; - size_t length; - - value = (unsigned char*) va_arg(argsP->v, unsigned char*); - length = (size_t) va_arg(argsP->v, size_t); - - *valPP = xmlrpc_base64_new(envP, length, value); -} - - - -static void -getValue(xmlrpc_env * const envP, - const char** const format, - va_listx * const argsP, - xmlrpc_value ** const valPP); - - - -static void -getArray(xmlrpc_env * const envP, - const char ** const formatP, - char const delimiter, - va_listx * const argsP, - xmlrpc_value ** const arrayPP) { - - xmlrpc_value * arrayP; - - arrayP = xmlrpc_array_new(envP); - - /* Add items to the array until we hit our delimiter. */ - - while (**formatP != delimiter && !envP->fault_occurred) { - - xmlrpc_value * itemP; - - if (**formatP == '\0') - xmlrpc_env_set_fault( - envP, XMLRPC_INTERNAL_ERROR, - "format string ended before closing ')'."); - else { - getValue(envP, formatP, argsP, &itemP); - if (!envP->fault_occurred) { - xmlrpc_array_append_item(envP, arrayP, itemP); - xmlrpc_DECREF(itemP); - } - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(arrayP); - - *arrayPP = arrayP; -} - - - -static void -getStructMember(xmlrpc_env * const envP, - const char ** const formatP, - va_listx * const argsP, - xmlrpc_value ** const keyPP, - xmlrpc_value ** const valuePP) { - - - /* Get the key */ - getValue(envP, formatP, argsP, keyPP); - if (!envP->fault_occurred) { - if (**formatP != ':') - xmlrpc_env_set_fault( - envP, XMLRPC_INTERNAL_ERROR, - "format string does not have ':' after a " - "structure member key."); - else { - /* Skip over colon that separates key from value */ - (*formatP)++; - - /* Get the value */ - getValue(envP, formatP, argsP, valuePP); - } - if (envP->fault_occurred) - xmlrpc_DECREF(*keyPP); - } -} - - - -static void -getStruct(xmlrpc_env * const envP, - const char ** const formatP, - char const delimiter, - va_listx * const argsP, - xmlrpc_value ** const structPP) { - - xmlrpc_value * structP; - - structP = xmlrpc_struct_new(envP); - if (!envP->fault_occurred) { - while (**formatP != delimiter && !envP->fault_occurred) { - xmlrpc_value * keyP; - xmlrpc_value * valueP; - - getStructMember(envP, formatP, argsP, &keyP, &valueP); - - if (!envP->fault_occurred) { - if (**formatP == ',') - (*formatP)++; /* Skip over the comma */ - else if (**formatP == delimiter) { - /* End of the line */ - } else - xmlrpc_env_set_fault( - envP, XMLRPC_INTERNAL_ERROR, - "format string does not have ',' or ')' after " - "a structure member"); - - if (!envP->fault_occurred) - /* Add the new member to the struct. */ - xmlrpc_struct_set_value_v(envP, structP, keyP, valueP); - - xmlrpc_DECREF(valueP); - xmlrpc_DECREF(keyP); - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(structP); - } - *structPP = structP; -} - - - -static void -mkArrayFromVal(xmlrpc_env * const envP, - xmlrpc_value * const value, - xmlrpc_value ** const valPP) { - - if (xmlrpc_value_type(value) != XMLRPC_TYPE_ARRAY) - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, - "Array format ('A'), non-array xmlrpc_value"); - else - xmlrpc_INCREF(value); - - *valPP = value; -} - - - -static void -mkStructFromVal(xmlrpc_env * const envP, - xmlrpc_value * const value, - xmlrpc_value ** const valPP) { - - if (xmlrpc_value_type(value) != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, - "Struct format ('S'), non-struct xmlrpc_value"); - else - xmlrpc_INCREF(value); - - *valPP = value; -} - - - -static void -getValue(xmlrpc_env * const envP, - const char** const formatP, - va_listx * const argsP, - xmlrpc_value ** const valPP) { -/*---------------------------------------------------------------------------- - Get the next value from the list. *formatP points to the specifier - for the next value in the format string (i.e. to the type code - character) and we move *formatP past the whole specifier for the - next value. We read the required arguments from 'argsP'. We return - the value as *valPP with a reference to it. - - For example, if *formatP points to the "i" in the string "sis", - we read one argument from 'argsP' and return as *valP an integer whose - value is the argument we read. We advance *formatP to point to the - last 's' and advance 'argsP' to point to the argument that belongs to - that 's'. ------------------------------------------------------------------------------*/ - char const formatChar = *(*formatP)++; - - switch (formatChar) { - case 'i': - *valPP = - xmlrpc_int_new(envP, (xmlrpc_int32) va_arg(argsP->v, - xmlrpc_int32)); - break; - - case 'b': - *valPP = - xmlrpc_bool_new(envP, (xmlrpc_bool) va_arg(argsP->v, xmlrpc_bool)); - break; - - case 'd': - *valPP = - xmlrpc_double_new(envP, (double) va_arg(argsP->v, double)); - break; - - case 's': - getString(envP, formatP, argsP, valPP); - break; - - case 'w': - getWideString(envP, formatP, argsP, valPP); - break; - - case 't': - *valPP = xmlrpc_datetime_new_sec(envP, va_arg(argsP->v, time_t)); - break; - - case '8': - *valPP = xmlrpc_datetime_new_str(envP, va_arg(argsP->v, char*)); - break; - - case '6': - getBase64(envP, argsP, valPP); - break; - - case 'n': - *valPP = - xmlrpc_nil_new(envP); - break; - - case 'I': - *valPP = - xmlrpc_i8_new(envP, (xmlrpc_int64) va_arg(argsP->v, xmlrpc_int64)); - break; - - case 'p': - *valPP = - xmlrpc_cptr_new(envP, (void*) va_arg(argsP->v, void*)); - break; - - case 'A': - mkArrayFromVal(envP, (xmlrpc_value*) va_arg(argsP->v, xmlrpc_value*), - valPP); - break; - - case 'S': - mkStructFromVal(envP, (xmlrpc_value*) va_arg(argsP->v, xmlrpc_value*), - valPP); - break; - - case 'V': - *valPP = (xmlrpc_value*) va_arg(argsP->v, xmlrpc_value*); - xmlrpc_INCREF(*valPP); - break; - - case '(': - getArray(envP, formatP, ')', argsP, valPP); - if (!envP->fault_occurred) { - XMLRPC_ASSERT(**formatP == ')'); - (*formatP)++; /* Skip over closing parenthesis */ - } - break; - - case '{': - getStruct(envP, formatP, '}', argsP, valPP); - if (!envP->fault_occurred) { - XMLRPC_ASSERT(**formatP == '}'); - (*formatP)++; /* Skip over closing brace */ - } - break; - - default: { - const char * const badCharacter = xmlrpc_makePrintableChar(formatChar); - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Unexpected character '%s' in format string", badCharacter); - xmlrpc_strfree(badCharacter); - } - } -} - - - -void -xmlrpc_build_value_va(xmlrpc_env * const envP, - const char * const format, - va_list const args, - xmlrpc_value ** const valPP, - const char ** const tailP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(format != NULL); - - if (strlen(format) == 0) - xmlrpc_faultf(envP, "Format string is empty."); - else { - va_listx currentArgs; - const char * formatCursor; - - init_va_listx(¤tArgs, args); - formatCursor = &format[0]; - getValue(envP, &formatCursor, ¤tArgs, valPP); - - if (!envP->fault_occurred) - XMLRPC_ASSERT_VALUE_OK(*valPP); - - *tailP = formatCursor; - } -} - - - -xmlrpc_value * -xmlrpc_build_value(xmlrpc_env * const envP, - const char * const format, - ...) { - - va_list args; - xmlrpc_value * retval; - const char * suffix; - - va_start(args, format); - xmlrpc_build_value_va(envP, format, args, &retval, &suffix); - va_end(args); - - if (!envP->fault_occurred) { - if (*suffix != '\0') - xmlrpc_faultf(envP, "Junk after the format specifier: '%s'. " - "The format string must describe exactly " - "one XML-RPC value " - "(but it might be a compound value " - "such as an array)", - suffix); - - if (envP->fault_occurred) - xmlrpc_DECREF(retval); - } - return retval; -} - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ diff --git a/trunk/src/xmlrpc_client.c b/trunk/src/xmlrpc_client.c deleted file mode 100644 index 9466b5b5d..000000000 --- a/trunk/src/xmlrpc_client.c +++ /dev/null @@ -1,1201 +0,0 @@ -/* Copyright information is at end of file */ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include "xmlrpc_config.h" - -#undef PACKAGE -#undef VERSION - -#include -#include -#include -#include -#include -#include -#include - -#include "bool.h" -#include "mallocvar.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/client_int.h" -/* transport_config.h defines XMLRPC_DEFAULT_TRANSPORT, - MUST_BUILD_WININET_CLIENT, MUST_BUILD_CURL_CLIENT, - MUST_BUILD_LIBWWW_CLIENT -*/ -#include "transport_config.h" -#include "version.h" - -struct xmlrpc_client { -/*---------------------------------------------------------------------------- - This represents a client object. ------------------------------------------------------------------------------*/ - bool myTransport; - /* The transport described below was created by this object; - No one else knows it exists and this object is responsible - for destroying it. - */ - struct xmlrpc_client_transport * transportP; - struct xmlrpc_client_transport_ops transportOps; - xmlrpc_dialect dialect; - xmlrpc_progress_fn * progressFn; -}; - - - -struct xmlrpc_call_info { - /* This is all the information needed to finish executing a started - RPC. - - You don't need this for an RPC the user executes synchronously, - because then you can just use the storage in which the user passed - his arguments. But for asynchronous, the user will take back his - storage, and we need to keep this info in our own. - */ - - void * userHandle; - /* This is a handle for this call that is meaningful to our - user. - */ - xmlrpc_progress_fn * progressFn; - struct { - /* These are arguments to pass to the completion function. It - doesn't make sense to use them for anything else. In fact, it - really doesn't make sense for them to be arguments to the - completion function, but they are historically. */ - const char * serverUrl; - const char * methodName; - xmlrpc_value * paramArrayP; - } completionArgs; - xmlrpc_response_handler * completionFn; - - - /* The serialized XML data passed to this call. We keep this around - ** for use by our source_anchor field. */ - xmlrpc_mem_block *serialized_xml; -}; - - - -/*========================================================================= - Global Constant Setup/Teardown -=========================================================================*/ - -static void -callTransportSetup(xmlrpc_env * const envP, - xmlrpc_transport_setup setupFn) { - - if (setupFn) - setupFn(envP); -} - - - -int xmlrpc_trace_transport; - - - -static void -setupTransportGlobalConst(xmlrpc_env * const envP) { - - xmlrpc_trace_transport = getenv("XMLRPC_TRACE_TRANSPORT") ? 1 : 0; - -#if MUST_BUILD_WININET_CLIENT - if (!envP->fault_occurred) - callTransportSetup(envP, - xmlrpc_wininet_transport_ops.setup_global_const); -#endif -#if MUST_BUILD_CURL_CLIENT - if (!envP->fault_occurred) - callTransportSetup(envP, - xmlrpc_curl_transport_ops.setup_global_const); -#endif -#if MUST_BUILD_LIBWWW_CLIENT - if (!envP->fault_occurred) - callTransportSetup(envP, - xmlrpc_libwww_transport_ops.setup_global_const); -#endif -} - - - -static void -callTransportTeardown(xmlrpc_transport_teardown teardownFn) { - - if (teardownFn) - teardownFn(); -} - - - -static void -teardownTransportGlobalConst(void) { - -#if MUST_BUILD_WININET_CLIENT - callTransportTeardown( - xmlrpc_wininet_transport_ops.teardown_global_const); -#endif -#if MUST_BUILD_CURL_CLIENT - callTransportTeardown( - xmlrpc_curl_transport_ops.teardown_global_const); -#endif -#if MUST_BUILD_LIBWWW_CLIENT - callTransportTeardown( - xmlrpc_libwww_transport_ops.teardown_global_const); -#endif -} - - - -/*========================================================================= - Global stuff (except the global client) -=========================================================================*/ - -static unsigned int constSetupCount = 0; - - -void -xmlrpc_client_setup_global_const(xmlrpc_env * const envP) { -/*---------------------------------------------------------------------------- - Set up pseudo-constant global variables (they'd be constant, except that - the library loader doesn't set them. An explicit call from the loaded - program does). - - This function is not thread-safe. The user is supposed to call it - (perhaps cascaded down from a multitude of higher level libraries) - as part of early program setup, when the program is only one thread. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - - if (constSetupCount == 0) - setupTransportGlobalConst(envP); - - ++constSetupCount; -} - - - -void -xmlrpc_client_teardown_global_const(void) { -/*---------------------------------------------------------------------------- - Complement to xmlrpc_client_setup_global_const(). - - This function is not thread-safe. The user is supposed to call it - (perhaps cascaded down from a multitude of higher level libraries) - as part of final program cleanup, when the program is only one thread. ------------------------------------------------------------------------------*/ - assert(constSetupCount > 0); - - --constSetupCount; - - if (constSetupCount == 0) - teardownTransportGlobalConst(); -} - - - -unsigned int const xmlrpc_client_version_major = XMLRPC_VERSION_MAJOR; -unsigned int const xmlrpc_client_version_minor = XMLRPC_VERSION_MINOR; -unsigned int const xmlrpc_client_version_point = XMLRPC_VERSION_POINT; - -void -xmlrpc_client_version(unsigned int * const majorP, - unsigned int * const minorP, - unsigned int * const pointP) { - - *majorP = XMLRPC_VERSION_MAJOR; - *minorP = XMLRPC_VERSION_MINOR; - *pointP = XMLRPC_VERSION_POINT; -} - - - -/*========================================================================= - Client Create/Destroy -=========================================================================*/ - -static void -getTransportOps( - xmlrpc_env * const envP, - const char * const transportName, - const struct xmlrpc_client_transport_ops ** const opsPP) { - - if (false) { - } -#if MUST_BUILD_WININET_CLIENT - else if (xmlrpc_streq(transportName, "wininet")) - *opsPP = &xmlrpc_wininet_transport_ops; -#endif -#if MUST_BUILD_CURL_CLIENT - else if (xmlrpc_streq(transportName, "curl")) - *opsPP = &xmlrpc_curl_transport_ops; -#endif -#if MUST_BUILD_LIBWWW_CLIENT - else if (xmlrpc_streq(transportName, "libwww")) - *opsPP = &xmlrpc_libwww_transport_ops; -#endif - else - xmlrpc_faultf(envP, "Unrecognized XML transport name '%s'", - transportName); -} - - - -struct xportParms { - const void * parmsP; - size_t size; -}; - - - -static void -getTransportParmsFromClientParms( - xmlrpc_env * const envP, - const struct xmlrpc_clientparms * const clientparmsP, - unsigned int const parmSize, - struct xportParms * const xportParmsP) { - - if (parmSize < XMLRPC_CPSIZE(transportparmsP) || - clientparmsP->transportparmsP == NULL) { - - xportParmsP->parmsP = NULL; - xportParmsP->size = 0; - } else { - xportParmsP->parmsP = clientparmsP->transportparmsP; - if (parmSize < XMLRPC_CPSIZE(transportparm_size)) - xmlrpc_faultf(envP, "Your 'clientparms' argument contains the " - "transportparmsP member, " - "but no transportparms_size member"); - else - xportParmsP->size = clientparmsP->transportparm_size; - } -} - - - -static void -getTransportInfo( - xmlrpc_env * const envP, - const struct xmlrpc_clientparms * const clientparmsP, - unsigned int const parmSize, - const char ** const transportNameP, - struct xportParms * const transportParmsP, - const struct xmlrpc_client_transport_ops ** const transportOpsPP, - xmlrpc_client_transport ** const transportPP) { - - const char * transportNameParm; - xmlrpc_client_transport * transportP; - const struct xmlrpc_client_transport_ops * transportOpsP; - - if (parmSize < XMLRPC_CPSIZE(transport)) - transportNameParm = NULL; - else - transportNameParm = clientparmsP->transport; - - if (parmSize < XMLRPC_CPSIZE(transportP)) - transportP = NULL; - else - transportP = clientparmsP->transportP; - - if (parmSize < XMLRPC_CPSIZE(transportOpsP)) - transportOpsP = NULL; - else - transportOpsP = clientparmsP->transportOpsP; - - if ((transportOpsP && !transportP) || (transportP && ! transportOpsP)) - xmlrpc_faultf(envP, "'transportOpsP' and 'transportP' go together. " - "You must specify both or neither"); - else if (transportNameParm && transportP) - xmlrpc_faultf(envP, "You cannot specify both 'transport' and " - "'transportP' transport parameters."); - else if (transportP) - *transportNameP = NULL; - else if (transportNameParm) - *transportNameP = transportNameParm; - else - *transportNameP = xmlrpc_client_get_default_transport(envP); - - *transportOpsPP = transportOpsP; - *transportPP = transportP; - - if (!envP->fault_occurred) { - getTransportParmsFromClientParms( - envP, clientparmsP, parmSize, transportParmsP); - - if (!envP->fault_occurred) { - if (transportParmsP->parmsP && !transportNameParm) - xmlrpc_faultf( - envP, - "You specified transport parameters, but did not " - "specify a transport type. Parameters are specific " - "to a particular type."); - } - } -} - - - -static void -getDialectFromClientParms( - const struct xmlrpc_clientparms * const clientparmsP, - unsigned int const parmSize, - xmlrpc_dialect * const dialectP) { - - if (parmSize < XMLRPC_CPSIZE(dialect)) - *dialectP = xmlrpc_dialect_i8; - else - *dialectP = clientparmsP->dialect; -} - - - -static void -clientCreate( - xmlrpc_env * const envP, - bool const myTransport, - const struct xmlrpc_client_transport_ops * const transportOpsP, - struct xmlrpc_client_transport * const transportP, - xmlrpc_dialect const dialect, - xmlrpc_progress_fn * const progressFn, - xmlrpc_client ** const clientPP) { - - XMLRPC_ASSERT_PTR_OK(transportOpsP); - XMLRPC_ASSERT_PTR_OK(transportP); - XMLRPC_ASSERT_PTR_OK(clientPP); - - if (constSetupCount == 0) { - xmlrpc_faultf(envP, - "You have not called " - "xmlrpc_client_setup_global_const()."); - /* Impl note: We can't just call it now because it isn't - thread-safe. - */ - } else { - xmlrpc_client * clientP; - - MALLOCVAR(clientP); - - if (clientP == NULL) - xmlrpc_faultf(envP, "Unable to allocate memory for " - "client descriptor."); - else { - clientP->myTransport = myTransport; - clientP->transportOps = *transportOpsP; - clientP->transportP = transportP; - clientP->dialect = dialect; - clientP->progressFn = progressFn; - - *clientPP = clientP; - } - } -} - - - -static void -createTransportAndClient( - xmlrpc_env * const envP, - const char * const transportName, - const void * const transportparmsP, - size_t const transportparmSize, - int const flags, - const char * const appname, - const char * const appversion, - xmlrpc_dialect const dialect, - xmlrpc_progress_fn * const progressFn, - xmlrpc_client ** const clientPP) { - - const struct xmlrpc_client_transport_ops * transportOpsP; - - getTransportOps(envP, transportName, &transportOpsP); - if (!envP->fault_occurred) { - xmlrpc_client_transport * transportP; - - /* The following call is not thread-safe */ - transportOpsP->create( - envP, flags, appname, appversion, - transportparmsP, transportparmSize, - &transportP); - if (!envP->fault_occurred) { - bool const myTransportTrue = true; - - clientCreate(envP, myTransportTrue, transportOpsP, transportP, - dialect, progressFn, clientPP); - - if (envP->fault_occurred) - transportOpsP->destroy(transportP); - } - } -} - - - -void -xmlrpc_client_create(xmlrpc_env * const envP, - int const flags, - const char * const appname, - const char * const appversion, - const struct xmlrpc_clientparms * const clientparmsP, - unsigned int const parmSize, - xmlrpc_client ** const clientPP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(clientPP); - - if (constSetupCount == 0) { - xmlrpc_faultf(envP, - "You have not called " - "xmlrpc_client_setup_global_const()."); - /* Impl note: We can't just call it now because it isn't - thread-safe. - */ - } else { - const char * transportName; - struct xportParms transportparms; - const struct xmlrpc_client_transport_ops * transportOpsP; - xmlrpc_client_transport * transportP; - xmlrpc_dialect dialect; - xmlrpc_progress_fn * progressFn; - - getTransportInfo(envP, clientparmsP, parmSize, &transportName, - &transportparms, &transportOpsP, &transportP); - - getDialectFromClientParms(clientparmsP, parmSize, &dialect); - - progressFn = parmSize >= XMLRPC_CPSIZE(progressFn) ? - clientparmsP->progressFn : NULL; - - if (!envP->fault_occurred) { - if (transportName) - createTransportAndClient(envP, transportName, - transportparms.parmsP, - transportparms.size, - flags, appname, appversion, dialect, - progressFn, - clientPP); - else { - bool myTransportFalse = false; - clientCreate(envP, myTransportFalse, - transportOpsP, transportP, dialect, progressFn, - clientPP); - } - } - } -} - - - -void -xmlrpc_client_destroy(xmlrpc_client * const clientP) { - - XMLRPC_ASSERT_PTR_OK(clientP); - - if (clientP->myTransport) - clientP->transportOps.destroy(clientP->transportP); - - free(clientP); -} - - - -/*========================================================================= - Call/Response Utilities -=========================================================================*/ - -static void -makeCallXml(xmlrpc_env * const envP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_dialect const dialect, - xmlrpc_mem_block ** const callXmlPP) { -/*---------------------------------------------------------------------------- - Make the XML for an XML-RPC call of method named 'methodName', with - parameters *paramArrayP, in XML-RPC dialect 'dialect'. - - Return the XML in a newly created xmlrpc_memblock and return a pointer to - it as *callXmlPP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(callXmlPP); - - if (methodName == NULL) - xmlrpc_faultf(envP, "method name argument is NULL pointer"); - else { - xmlrpc_mem_block * callXmlP; - - callXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - xmlrpc_serialize_call2(envP, callXmlP, methodName, paramArrayP, - dialect); - - *callXmlPP = callXmlP; - - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, callXmlP); - } - } -} - - - -/*========================================================================= - Synchronous Call -=========================================================================*/ - -void -xmlrpc_client_transport_call2( - xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block ** const respXmlPP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(clientP); - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(callXmlP); - XMLRPC_ASSERT_PTR_OK(respXmlPP); - - clientP->transportOps.call( - envP, clientP->transportP, serverP, callXmlP, - respXmlPP); -} - - - -static void -parseResponse(xmlrpc_env * const envP, - xmlrpc_mem_block * const respXmlP, - xmlrpc_value ** const resultPP, - int * const faultCodeP, - const char ** const faultStringP) { - - xmlrpc_env respEnv; - - XMLRPC_ASSERT_ENV_OK(envP); - - xmlrpc_env_init(&respEnv); - - xmlrpc_parse_response2( - &respEnv, - XMLRPC_MEMBLOCK_CONTENTS(char, respXmlP), - XMLRPC_MEMBLOCK_SIZE(char, respXmlP), - resultPP, faultCodeP, faultStringP); - - if (respEnv.fault_occurred) - xmlrpc_env_set_fault_formatted( - envP, respEnv.fault_code, - "Unable to make sense of XML-RPC response from server. " - "%s. Use XMLRPC_TRACE_XML to see for yourself", - respEnv.fault_string); - - xmlrpc_env_clean(&respEnv); -} - - - -void -xmlrpc_client_call2(xmlrpc_env * const envP, - struct xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const resultPP) { - - xmlrpc_mem_block * callXmlP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(clientP); - XMLRPC_ASSERT_PTR_OK(serverInfoP); - XMLRPC_ASSERT_PTR_OK(paramArrayP); - - makeCallXml(envP, methodName, paramArrayP, clientP->dialect, &callXmlP); - - if (!envP->fault_occurred) { - xmlrpc_mem_block * respXmlP; - - xmlrpc_traceXml("XML-RPC CALL", - XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP), - XMLRPC_MEMBLOCK_SIZE(char, callXmlP)); - - clientP->transportOps.call( - envP, clientP->transportP, serverInfoP, callXmlP, &respXmlP); - if (!envP->fault_occurred) { - int faultCode; - const char * faultString; - - xmlrpc_traceXml("XML-RPC RESPONSE", - XMLRPC_MEMBLOCK_CONTENTS(char, respXmlP), - XMLRPC_MEMBLOCK_SIZE(char, respXmlP)); - - parseResponse(envP, respXmlP, resultPP, &faultCode, &faultString); - - if (!envP->fault_occurred) { - if (faultString) { - xmlrpc_env_set_fault_formatted( - envP, faultCode, - "RPC failed at server. %s", faultString); - xmlrpc_strfree(faultString); - } else - XMLRPC_ASSERT_VALUE_OK(*resultPP); - } - XMLRPC_MEMBLOCK_FREE(char, respXmlP); - } - XMLRPC_MEMBLOCK_FREE(char, callXmlP); - } -} - - - -static void -computeParamArray(xmlrpc_env * const envP, - const char * const format, - va_list args, - xmlrpc_value ** const paramArrayPP) { -/*---------------------------------------------------------------------------- - 'format' and 'args' specify the parameter list of an RPC, in the form - of an XML-RPC array value, with one element per RPC parameter. - - 'format' is an XML-RPC value format string, e.g. "(ii{s:i,s:i})". - 'args' is the list of substitution values for that string - (6 values in this example, 4 integers and 2 strings). - - We return the XML-RPC value 'format' and 'args' represent, but throw an - error if they don't validly specify a single array. - - Note that it is a common user error to specify the format string as a - single or string of argument types, instead of as an array of argument - types. E.g. "i" or "ii" instead of "(i)" and "(ii)". So we try - especially hard to give an informative message for that case. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * paramArrayP; - const char * suffix; - /* Stuff left over in format string after parameter array - specification. - */ - - xmlrpc_env_init(&env); - xmlrpc_build_value_va(&env, format, args, ¶mArrayP, &suffix); - if (env.fault_occurred) - xmlrpc_env_set_fault_formatted( - envP, env.fault_code, "Invalid RPC arguments. " - "The format argument must indicate a single array (each element " - "of which is one argument to the XML-RPC call), and the " - "following arguments must correspond to that format argument. " - "The failure is: %s", - env.fault_string); - else { - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - - if (*suffix != '\0') - xmlrpc_faultf(envP, - "Junk after the parameter array specifier: '%s'. " - "The format string must specify exactly one value: " - "an array of RPC parameters", - suffix); - else { - if (xmlrpc_value_type(paramArrayP) != XMLRPC_TYPE_ARRAY) - xmlrpc_faultf( - envP, - "You must specify the parameter list as an " - "XML-RPC array value, " - "each element of which is a parameter of the RPC. " - "But your format string specifies an XML-RPC %s, not " - "an array", - xmlrpc_type_name(xmlrpc_value_type(paramArrayP))); - } - if (env.fault_occurred) - xmlrpc_DECREF(paramArrayP); - else - *paramArrayPP = paramArrayP; - } - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_call_server2_va(xmlrpc_env * const envP, - struct xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - const char * const format, - va_list args, - xmlrpc_value ** const resultPP) { - - /* This function exists only for use by the global client function - xmlrpc_client_call_server(). - */ - - xmlrpc_value * paramArrayP; - /* The XML-RPC parameter list array */ - - XMLRPC_ASSERT_ENV_OK(envP); - - computeParamArray(envP, format, args, ¶mArrayP); - - if (!envP->fault_occurred) { - xmlrpc_client_call2(envP, clientP, - serverInfoP, methodName, paramArrayP, - resultPP); - - xmlrpc_DECREF(paramArrayP); - } -} - - - -void -xmlrpc_client_call2f_va(xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const char * const serverUrl, - const char * const methodName, - const char * const format, - xmlrpc_value ** const resultPP, - va_list args) { - - xmlrpc_value * paramArrayP; - /* The XML-RPC parameter list array */ - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(clientP); - XMLRPC_ASSERT_PTR_OK(serverUrl); - XMLRPC_ASSERT_PTR_OK(methodName); - XMLRPC_ASSERT_PTR_OK(format); - XMLRPC_ASSERT_PTR_OK(resultPP); - - computeParamArray(envP, format, args, ¶mArrayP); - - if (!envP->fault_occurred) { - xmlrpc_server_info * serverInfoP; - - serverInfoP = xmlrpc_server_info_new(envP, serverUrl); - - if (!envP->fault_occurred) { - /* Perform the actual XML-RPC call. */ - xmlrpc_client_call2(envP, clientP, - serverInfoP, methodName, paramArrayP, - resultPP); - if (!envP->fault_occurred) - XMLRPC_ASSERT_VALUE_OK(*resultPP); - xmlrpc_server_info_free(serverInfoP); - } - xmlrpc_DECREF(paramArrayP); - } -} - - - -void -xmlrpc_client_call2f(xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_value ** const resultPP, - const char * const format, - ...) { - - va_list args; - - XMLRPC_ASSERT_PTR_OK(format); - - va_start(args, format); - xmlrpc_client_call2f_va(envP, clientP, serverUrl, - methodName, format, resultPP, args); - va_end(args); -} - - - -/*========================================================================= - Asynchronous Call -=========================================================================*/ - -static void -callInfoSetCompletion(xmlrpc_env * const envP, - struct xmlrpc_call_info * const callInfoP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_response_handler completionFn, - xmlrpc_progress_fn progressFn, - void * const userHandle) { -/*---------------------------------------------------------------------------- - Set the members of callinfo structure *callInfoP that are used for - the completion and progress calls from the transport to us. ------------------------------------------------------------------------------*/ - callInfoP->completionFn = completionFn; - callInfoP->progressFn = progressFn; - callInfoP->userHandle = userHandle; - callInfoP->completionArgs.serverUrl = strdup(serverUrl); - if (callInfoP->completionArgs.serverUrl == NULL) - xmlrpc_faultf(envP, "Couldn't get memory to store server URL"); - else { - callInfoP->completionArgs.methodName = strdup(methodName); - if (callInfoP->completionArgs.methodName == NULL) - xmlrpc_faultf(envP, "Couldn't get memory to store method name"); - else { - callInfoP->completionArgs.paramArrayP = paramArrayP; - xmlrpc_INCREF(paramArrayP); - } - if (envP->fault_occurred) - xmlrpc_strfree(callInfoP->completionArgs.serverUrl); - } -} - - - -static void -callInfoCreate(xmlrpc_env * const envP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_dialect const dialect, - const char * const serverUrl, - xmlrpc_response_handler completionFn, - xmlrpc_progress_fn progressFn, - void * const userHandle, - struct xmlrpc_call_info ** const callInfoPP) { -/*---------------------------------------------------------------------------- - Create a call_info object. A call_info object represents an XML-RPC - call. ------------------------------------------------------------------------------*/ - struct xmlrpc_call_info * callInfoP; - - XMLRPC_ASSERT_PTR_OK(serverUrl); - XMLRPC_ASSERT_PTR_OK(methodName); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - XMLRPC_ASSERT_PTR_OK(callInfoPP); - - MALLOCVAR(callInfoP); - if (callInfoP == NULL) - xmlrpc_faultf(envP, "Couldn't allocate memory for xmlrpc_call_info"); - else { - xmlrpc_mem_block * callXmlP; - - makeCallXml(envP, methodName, paramArrayP, dialect, &callXmlP); - - if (!envP->fault_occurred) { - callInfoP->serialized_xml = callXmlP; - - callInfoSetCompletion(envP, callInfoP, serverUrl, methodName, - paramArrayP, - completionFn, progressFn, userHandle); - - if (envP->fault_occurred) - free(callInfoP); - } - } - *callInfoPP = callInfoP; -} - - - -static void -callInfoDestroy(struct xmlrpc_call_info * const callInfoP) { - - XMLRPC_ASSERT_PTR_OK(callInfoP); - - if (callInfoP->completionFn) { - xmlrpc_DECREF(callInfoP->completionArgs.paramArrayP); - xmlrpc_strfree(callInfoP->completionArgs.methodName); - xmlrpc_strfree(callInfoP->completionArgs.serverUrl); - } - if (callInfoP->serialized_xml) - xmlrpc_mem_block_free(callInfoP->serialized_xml); - - free(callInfoP); -} - - - -void -xmlrpc_client_event_loop_finish(xmlrpc_client * const clientP) { - - XMLRPC_ASSERT_PTR_OK(clientP); - - clientP->transportOps.finish_asynch( - clientP->transportP, timeout_no, 0); -} - - - -void -xmlrpc_client_event_loop_finish_timeout(xmlrpc_client * const clientP, - xmlrpc_timeout const timeout) { - - XMLRPC_ASSERT_PTR_OK(clientP); - - clientP->transportOps.finish_asynch( - clientP->transportP, timeout_yes, timeout); -} - - - -/* Microsoft Visual C in debug mode produces code that complains about - passing an undefined value of 'resultP' to xmlrpc_parse_response2(). - It's a bogus complaint, because this function knows in those cases - that the value of 'resultP' is meaningless. So we disable the check. -*/ -#pragma runtime_checks("u", off) - - - -static void -asynchComplete(struct xmlrpc_call_info * const callInfoP, - xmlrpc_mem_block * const responseXmlP, - xmlrpc_env const transportEnv) { -/*---------------------------------------------------------------------------- - Complete an asynchronous XML-RPC call request. - - This includes calling the user's RPC completion routine. - - 'transportEnv' describes an error that the transport - encountered in processing the call. If the transport successfully - sent the call to the server and processed the response but the - server failed the call, 'transportEnv' indicates no error, and the - response in *responseXmlP might very well indicate that the server - failed the request. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * resultP; - - xmlrpc_env_init(&env); - - if (transportEnv.fault_occurred) - xmlrpc_env_set_fault_formatted( - &env, transportEnv.fault_code, - "Client transport failed to execute the RPC. %s", - transportEnv.fault_string); - - if (!env.fault_occurred) { - int faultCode; - const char * faultString; - - xmlrpc_parse_response2(&env, - XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlP), - XMLRPC_MEMBLOCK_SIZE(char, responseXmlP), - &resultP, &faultCode, &faultString); - - if (!env.fault_occurred) { - if (faultString) { - xmlrpc_env_set_fault_formatted( - &env, faultCode, - "RPC failed at server. %s", faultString); - xmlrpc_strfree(faultString); - } - } - } - /* Call the user's completion function with the RPC result */ - (*callInfoP->completionFn)(callInfoP->completionArgs.serverUrl, - callInfoP->completionArgs.methodName, - callInfoP->completionArgs.paramArrayP, - callInfoP->userHandle, - &env, resultP); - - if (!env.fault_occurred) - xmlrpc_DECREF(resultP); - - callInfoDestroy(callInfoP); - - xmlrpc_env_clean(&env); -} - - - -#pragma runtime_checks("u", restore) - - - -static void -progress(struct xmlrpc_call_info * const callInfoP, - struct xmlrpc_progress_data const progressData) { - - /* We wouldn't have asked the transport to call our progress - function if we didn't have a user progress function to call: - */ - assert(callInfoP->progressFn); - - callInfoP->progressFn(callInfoP->userHandle, progressData); -} - - - -void -xmlrpc_client_start_rpc(xmlrpc_env * const envP, - struct xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_response_handler completionFn, - void * const userHandle) { - - struct xmlrpc_call_info * callInfoP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(clientP); - XMLRPC_ASSERT_PTR_OK(serverInfoP); - XMLRPC_ASSERT_PTR_OK(methodName); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - - callInfoCreate(envP, methodName, paramArrayP, clientP->dialect, - serverInfoP->serverUrl, - completionFn, clientP->progressFn, userHandle, - &callInfoP); - - if (!envP->fault_occurred) { - xmlrpc_traceXml( - "XML-RPC CALL", - XMLRPC_MEMBLOCK_CONTENTS(char, callInfoP->serialized_xml), - XMLRPC_MEMBLOCK_SIZE(char, callInfoP->serialized_xml)); - - clientP->transportOps.send_request( - envP, clientP->transportP, serverInfoP, - callInfoP->serialized_xml, - &asynchComplete, clientP->progressFn ? &progress : NULL, - callInfoP); - } - if (envP->fault_occurred) - callInfoDestroy(callInfoP); - else { - /* asynchComplete() will destroy *callInfoP */ - } -} - - - -void -xmlrpc_client_start_rpcf_server_va( - xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userHandle, - const char * const format, - va_list args) { - - xmlrpc_value * paramArrayP; - /* The XML-RPC parameter list array */ - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(clientP); - XMLRPC_ASSERT_PTR_OK(serverInfoP); - XMLRPC_ASSERT_PTR_OK(methodName); - XMLRPC_ASSERT_PTR_OK(format); - - computeParamArray(envP, format, args, ¶mArrayP); - - if (!envP->fault_occurred) { - xmlrpc_client_start_rpc(envP, clientP, - serverInfoP, methodName, paramArrayP, - responseHandler, userHandle); - - xmlrpc_DECREF(paramArrayP); - } -} - - - -void -xmlrpc_client_start_rpcf_va(xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userHandle, - const char * const format, - va_list args) { - - xmlrpc_server_info * serverInfoP; - - XMLRPC_ASSERT_ENV_OK(envP); - - serverInfoP = xmlrpc_server_info_new(envP, serverUrl); - if (!envP->fault_occurred) { - xmlrpc_client_start_rpcf_server_va( - envP, clientP, - serverInfoP, methodName, - responseHandler, userHandle, - format, args); - - xmlrpc_server_info_free(serverInfoP); - } -} - - - -void -xmlrpc_client_start_rpcf(xmlrpc_env * const envP, - xmlrpc_client * const clientP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userHandle, - const char * const format, - ...) { - - va_list args; - - XMLRPC_ASSERT_PTR_OK(format); - - va_start(args, format); - xmlrpc_client_start_rpcf_va(envP, clientP, serverUrl, methodName, - responseHandler, - userHandle, format, args); - va_end(args); -} - - - -/*========================================================================= - Miscellaneous -=========================================================================*/ - -const char * -xmlrpc_client_get_default_transport(xmlrpc_env * const envP ATTR_UNUSED) { - - return XMLRPC_DEFAULT_TRANSPORT; -} - - - -void -xmlrpc_client_set_interrupt(xmlrpc_client * const clientP, - int * const interruptP) { - - if (clientP->transportOps.set_interrupt) - clientP->transportOps.set_interrupt(clientP->transportP, interruptP); -} - - - -/* 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. -*/ diff --git a/trunk/src/xmlrpc_client_global.c b/trunk/src/xmlrpc_client_global.c deleted file mode 100644 index 362b99f5c..000000000 --- a/trunk/src/xmlrpc_client_global.c +++ /dev/null @@ -1,370 +0,0 @@ -#include - -#include "xmlrpc_config.h" - -#include "bool.h" - -#include -#include -#include -#include - -/*========================================================================= - Global Client -=========================================================================*/ - -static struct xmlrpc_client * globalClientP; -static bool globalClientExists = false; - - -void -xmlrpc_client_init2(xmlrpc_env * const envP, - int const flags, - const char * const appname, - const char * const appversion, - const struct xmlrpc_clientparms * const clientparmsP, - unsigned int const parmSize) { -/*---------------------------------------------------------------------------- - This function is not thread-safe. ------------------------------------------------------------------------------*/ - if (globalClientExists) - xmlrpc_faultf( - envP, - "Xmlrpc-c global client instance has already been created " - "(need to call xmlrpc_client_cleanup() before you can " - "reinitialize)."); - else { - /* The following call is not thread-safe */ - xmlrpc_client_setup_global_const(envP); - if (!envP->fault_occurred) { - xmlrpc_client_create(envP, flags, appname, appversion, - clientparmsP, parmSize, &globalClientP); - if (!envP->fault_occurred) - globalClientExists = true; - - if (envP->fault_occurred) - xmlrpc_client_teardown_global_const(); - } - } -} - - - -void -xmlrpc_client_init(int const flags, - const char * const appname, - const char * const appversion) { -/*---------------------------------------------------------------------------- - This function is not thread-safe. ------------------------------------------------------------------------------*/ - struct xmlrpc_clientparms clientparms; - - /* As our interface does not allow for failure, we just fail silently ! */ - - xmlrpc_env env; - xmlrpc_env_init(&env); - - clientparms.transport = NULL; - - /* The following call is not thread-safe */ - xmlrpc_client_init2(&env, flags, - appname, appversion, - &clientparms, XMLRPC_CPSIZE(transport)); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_cleanup() { -/*---------------------------------------------------------------------------- - This function is not thread-safe ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(globalClientExists); - - xmlrpc_client_destroy(globalClientP); - - globalClientExists = false; - - /* The following call is not thread-safe */ - xmlrpc_client_teardown_global_const(); -} - - - -static void -validateGlobalClientExists(xmlrpc_env * const envP) { - - if (!globalClientExists) - xmlrpc_faultf(envP, - "Xmlrpc-c global client instance " - "has not been created " - "(need to call xmlrpc_client_init2())."); -} - - - -void -xmlrpc_client_transport_call( - xmlrpc_env * const envP, - void * const reserved ATTR_UNUSED, - /* for client handle */ - const xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block ** const respXmlPP) { - - validateGlobalClientExists(envP); - if (!envP->fault_occurred) - xmlrpc_client_transport_call2(envP, globalClientP, serverP, - callXmlP, respXmlPP); -} - - - -xmlrpc_value * -xmlrpc_client_call(xmlrpc_env * const envP, - const char * const serverUrl, - const char * const methodName, - const char * const format, - ...) { - - xmlrpc_value * resultP; - - validateGlobalClientExists(envP); - - if (!envP->fault_occurred) { - va_list args; - - va_start(args, format); - - xmlrpc_client_call2f_va(envP, globalClientP, serverUrl, - methodName, format, &resultP, args); - - va_end(args); - } - return resultP; -} - - - -xmlrpc_value * -xmlrpc_client_call_server(xmlrpc_env * const envP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - const char * const format, - ...) { - - xmlrpc_value * resultP; - - validateGlobalClientExists(envP); - - if (!envP->fault_occurred) { - va_list args; - - va_start(args, format); - - xmlrpc_client_call_server2_va(envP, globalClientP, serverInfoP, - methodName, format, args, &resultP); - va_end(args); - } - return resultP; -} - - - -xmlrpc_value * -xmlrpc_client_call_server_params( - xmlrpc_env * const envP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_value * const paramArrayP) { - - xmlrpc_value * resultP; - - validateGlobalClientExists(envP); - - if (!envP->fault_occurred) - xmlrpc_client_call2(envP, globalClientP, - serverInfoP, methodName, paramArrayP, - &resultP); - - return resultP; -} - - - -xmlrpc_value * -xmlrpc_client_call_params(xmlrpc_env * const envP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_value * const paramArrayP) { - - xmlrpc_value * resultP; - - validateGlobalClientExists(envP); - - if (!envP->fault_occurred) { - xmlrpc_server_info * serverInfoP; - - serverInfoP = xmlrpc_server_info_new(envP, serverUrl); - - if (!envP->fault_occurred) { - xmlrpc_client_call2(envP, globalClientP, - serverInfoP, methodName, paramArrayP, - &resultP); - - xmlrpc_server_info_free(serverInfoP); - } - } - return resultP; -} - - - -void -xmlrpc_client_call_server_asynch_params( - xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - xmlrpc_value * const paramArrayP) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - validateGlobalClientExists(&env); - - if (!env.fault_occurred) - xmlrpc_client_start_rpc(&env, globalClientP, - serverInfoP, methodName, paramArrayP, - responseHandler, userData); - - if (env.fault_occurred) { - /* Unfortunately, we have no way to return an error and the - regular callback for a failed RPC is designed to have the - parameter array passed to it. This was probably an oversight - of the original asynch design, but now we have to be as - backward compatible as possible, so we do this: - */ - (*responseHandler)(serverInfoP->serverUrl, - methodName, paramArrayP, userData, - &env, NULL); - } - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_call_asynch(const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - const char * const format, - ...) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - validateGlobalClientExists(&env); - - if (!env.fault_occurred) { - va_list args; - - va_start(args, format); - - xmlrpc_client_start_rpcf_va(&env, globalClientP, - serverUrl, methodName, - responseHandler, userData, - format, args); - - va_end(args); - } - if (env.fault_occurred) - (*responseHandler)(serverUrl, methodName, NULL, userData, &env, NULL); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_call_asynch_params(const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - xmlrpc_value * const paramArrayP) { - xmlrpc_env env; - xmlrpc_server_info * serverInfoP; - - xmlrpc_env_init(&env); - - serverInfoP = xmlrpc_server_info_new(&env, serverUrl); - - if (!env.fault_occurred) { - xmlrpc_client_call_server_asynch_params( - serverInfoP, methodName, responseHandler, userData, paramArrayP); - - xmlrpc_server_info_free(serverInfoP); - } - if (env.fault_occurred) - (*responseHandler)(serverUrl, methodName, paramArrayP, userData, - &env, NULL); - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_call_server_asynch(xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - const char * const format, - ...) { - - xmlrpc_env env; - - validateGlobalClientExists(&env); - - if (!env.fault_occurred) { - va_list args; - - xmlrpc_env_init(&env); - - va_start(args, format); - - xmlrpc_client_start_rpcf_server_va( - &env, globalClientP, serverInfoP, methodName, - responseHandler, userData, format, args); - - va_end(args); - } - if (env.fault_occurred) - (*responseHandler)(serverInfoP->serverUrl, methodName, NULL, - userData, &env, NULL); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_event_loop_finish_asynch(void) { - - XMLRPC_ASSERT(globalClientExists); - xmlrpc_client_event_loop_finish(globalClientP); -} - - - -void -xmlrpc_client_event_loop_finish_asynch_timeout( - unsigned long const milliseconds) { - - XMLRPC_ASSERT(globalClientExists); - xmlrpc_client_event_loop_finish_timeout(globalClientP, milliseconds); -} diff --git a/trunk/src/xmlrpc_data.c b/trunk/src/xmlrpc_data.c deleted file mode 100644 index 605cac1eb..000000000 --- a/trunk/src/xmlrpc_data.c +++ /dev/null @@ -1,721 +0,0 @@ -/* Copyright information is at end of file */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include - -#include "bool.h" -#include "mallocvar.h" - -#include "xmlrpc-c/lock.h" -#include "xmlrpc-c/lock_platform.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" - - -/*============================================================================= - - xmlrpc_value is designed to enable cheap copies by sharing pointers and - maintaining reference counts. Multiple threads can use an xmlrpc_value - simultaneously because there is locking around the reference count - manipulation (but only since Xmlrpc-c 1.33). But there is no copy on - write, so the scheme depends upon the user not modifying an xmlrpc_value - after building it, and not copying it while building it. Another reason - to observe this sequence is that there is no locking around modifications, - so a reader could see a half-updated xmlrpc_value. - - We could enforce a prohibition against modifying an xmlrpc_value that has - references other than the one by the party doing the modifying, but we - don't because we allowed it for a long time before we noticed the problem - adn we're afraid of breaking an existing program that does these updates in - such a way that it actually works. - -=============================================================================*/ - - - -static void -destroyCptr(xmlrpc_value * const valueP) { - - if (valueP->_value.cptr.dtor) - valueP->_value.cptr.dtor(valueP->_value.cptr.dtorContext, - valueP->_value.cptr.objectP); -} - - - -static void -destroyValue(xmlrpc_value * const valueP) { - - /* First, we need to destroy this value's contents, if any. */ - switch (valueP->_type) { - case XMLRPC_TYPE_INT: - break; - - case XMLRPC_TYPE_BOOL: - break; - - case XMLRPC_TYPE_DOUBLE: - break; - - case XMLRPC_TYPE_DATETIME: - xmlrpc_destroyDatetime(valueP); - break; - - case XMLRPC_TYPE_STRING: - xmlrpc_destroyString(valueP); - break; - - case XMLRPC_TYPE_BASE64: - xmlrpc_mem_block_free(valueP->blockP); - break; - - case XMLRPC_TYPE_ARRAY: - xmlrpc_destroyArrayContents(valueP); - break; - - case XMLRPC_TYPE_STRUCT: - xmlrpc_destroyStruct(valueP); - break; - - case XMLRPC_TYPE_C_PTR: - destroyCptr(valueP); - break; - - case XMLRPC_TYPE_NIL: - break; - - case XMLRPC_TYPE_I8: - break; - - case XMLRPC_TYPE_DEAD: - XMLRPC_ASSERT(false); /* Can't happen, per entry conditions */ - - default: - XMLRPC_ASSERT(false); /* There are no other possible values */ - } - - valueP->lockP->destroy(valueP->lockP); - - /* Next, we mark this value as invalid, to help catch refcount errors. - */ - valueP->_type = XMLRPC_TYPE_DEAD; - - /* Finally, we destroy the value itself. */ - free(valueP); -} - - - -/*=========================================================================== - Reference Counting -============================================================================= - Some simple reference-counting code. The xmlrpc_DECREF routine is in - charge of destroying values when their reference count reaches zero. -============================================================================*/ - -void -xmlrpc_INCREF (xmlrpc_value * const valueP) { - - XMLRPC_ASSERT_VALUE_OK(valueP); - - valueP->lockP->acquire(valueP->lockP); - - XMLRPC_ASSERT(valueP->refcount > 0); - - ++valueP->refcount; - - valueP->lockP->release(valueP->lockP); -} - - - -void -xmlrpc_DECREF (xmlrpc_value * const valueP) { - - bool died; - - XMLRPC_ASSERT_VALUE_OK(valueP); - - valueP->lockP->acquire(valueP->lockP); - - XMLRPC_ASSERT(valueP->refcount > 0); - XMLRPC_ASSERT(valueP->_type != XMLRPC_TYPE_DEAD); - - --valueP->refcount; - - died = (valueP->refcount == 0); - - valueP->lockP->release(valueP->lockP); - - if (died) - destroyValue(valueP); -} - - - -/*========================================================================= - Utiltiies -=========================================================================*/ - -const char * -xmlrpc_type_name(xmlrpc_type const type) { - - switch (type) { - - case XMLRPC_TYPE_INT: return "INT"; - case XMLRPC_TYPE_BOOL: return "BOOL"; - case XMLRPC_TYPE_DOUBLE: return "DOUBLE"; - case XMLRPC_TYPE_DATETIME: return "DATETIME"; - case XMLRPC_TYPE_STRING: return "STRING"; - case XMLRPC_TYPE_BASE64: return "BASE64"; - case XMLRPC_TYPE_ARRAY: return "ARRAY"; - case XMLRPC_TYPE_STRUCT: return "STRUCT"; - case XMLRPC_TYPE_C_PTR: return "C_PTR"; - case XMLRPC_TYPE_NIL: return "NIL"; - case XMLRPC_TYPE_I8: return "I8"; - case XMLRPC_TYPE_DEAD: return "DEAD"; - default: return "???"; - - } -} - - - -static void -validateType(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_type const expectedType) { - - if (valueP->_type != expectedType) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " - "type %s was expected.", - xmlrpc_type_name(valueP->_type), xmlrpc_type_name(expectedType)); - } -} - - - -/*========================================================================= - Extracting XML-RPC value -=========================================================================== - These routines extract XML-RPC values into ordinary C data types. - - For array and struct values, see the separates files xmlrpc_array.c - and xmlrpc_struct.c. -=========================================================================*/ - -void -xmlrpc_read_int(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_int32 * const intValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_INT); - if (!envP->fault_occurred) - *intValueP = valueP->_value.i; -} - - - -void -xmlrpc_read_bool(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_bool * const boolValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_BOOL); - if (!envP->fault_occurred) - *boolValueP = valueP->_value.b; -} - - - -void -xmlrpc_read_double(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_double * const doubleValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_DOUBLE); - if (!envP->fault_occurred) - *doubleValueP = valueP->_value.d; - -} - - - -/* datetime stuff is in xmlrpc_datetime.c */ - -/* string stuff is in xmlrpc_string.c */ - - - -void -xmlrpc_read_base64(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const unsigned char ** const byteStringValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_BASE64); - if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); - - char * byteStringValue; - - byteStringValue = malloc(size); - if (byteStringValue == NULL) - xmlrpc_faultf(envP, - "Unable to allocate %u bytes for byte string.", - (unsigned)size); - else { - memcpy(byteStringValue, contents, size); - *byteStringValueP = (const unsigned char *)byteStringValue; - *lengthP = size; - } - } -} - - - -void -xmlrpc_read_base64_old(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const unsigned char ** const byteStringValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_BASE64); - if (!envP->fault_occurred) { - *lengthP = - XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); - *byteStringValueP = (const unsigned char *) - XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); - } -} - - - -void -xmlrpc_read_base64_size(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP) { - - validateType(envP, valueP, XMLRPC_TYPE_BASE64); - if (!envP->fault_occurred) - *lengthP = XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); -} - - - -void -xmlrpc_read_cptr(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - void ** const ptrValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_C_PTR); - if (!envP->fault_occurred) - *ptrValueP = valueP->_value.cptr.objectP; -} - - - -void -xmlrpc_read_nil(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { -/*---------------------------------------------------------------------------- - Read out the value of a nil value. It doesn't have one, of course, so - this is essentially a no-op. But it does validate the type and is - necessary to match all the other types. ------------------------------------------------------------------------------*/ - validateType(envP, valueP, XMLRPC_TYPE_NIL); -} - - - -void -xmlrpc_read_i8(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_int64 * const intValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_I8); - if (!envP->fault_occurred) - *intValueP = valueP->_value.i8; -} - - - -xmlrpc_type xmlrpc_value_type (xmlrpc_value* const value) -{ - XMLRPC_ASSERT_VALUE_OK(value); - return value->_type; -} - - - -void -xmlrpc_createXmlrpcValue(xmlrpc_env * const envP, - xmlrpc_value ** const valPP) { -/*---------------------------------------------------------------------------- - Create a blank xmlrpc_value to be filled in. - - Set the reference count to 1. ------------------------------------------------------------------------------*/ - xmlrpc_value * valP; - - MALLOCVAR(valP); - if (!valP) - xmlrpc_faultf(envP, "Could not allocate memory for xmlrpc_value"); - else { - valP->lockP = xmlrpc_lock_create(); - - if (!valP->lockP) - xmlrpc_faultf(envP, "Could not allocate memory for lock for " - "xmlrpc_value"); - else - valP->refcount = 1; - - if (envP->fault_occurred) { - free(valP); - valP = NULL; - } - } - *valPP = valP; -} - - - -xmlrpc_value * -xmlrpc_value_new(xmlrpc_env * const envP, - xmlrpc_value * const sourceValP) { - - switch (sourceValP->_type) { - case XMLRPC_TYPE_INT: - return xmlrpc_int_new_value(envP, sourceValP); - case XMLRPC_TYPE_I8: - return xmlrpc_i8_new_value(envP, sourceValP); - case XMLRPC_TYPE_BOOL: - return xmlrpc_bool_new_value(envP, sourceValP); - case XMLRPC_TYPE_DOUBLE: - return xmlrpc_double_new_value(envP, sourceValP); - case XMLRPC_TYPE_DATETIME: - return xmlrpc_datetime_new_value(envP, sourceValP); - case XMLRPC_TYPE_STRING: - return xmlrpc_string_new_value(envP, sourceValP); - case XMLRPC_TYPE_BASE64: - return xmlrpc_base64_new_value(envP, sourceValP); - case XMLRPC_TYPE_ARRAY: - return xmlrpc_array_new_value(envP, sourceValP); - case XMLRPC_TYPE_STRUCT: - return xmlrpc_struct_new_value(envP, sourceValP); - case XMLRPC_TYPE_C_PTR: - return xmlrpc_cptr_new_value(envP, sourceValP); - case XMLRPC_TYPE_NIL: - return xmlrpc_nil_new(envP); - case XMLRPC_TYPE_DEAD: - xmlrpc_faultf(envP, "Attempt to copy a dead xmlrpc_value"); - return NULL; - } - assert(false); /* All cases are handled above */ - - return NULL; /* Quiet compiler warning */ -} - - - -xmlrpc_value * -xmlrpc_int_new(xmlrpc_env * const envP, - xmlrpc_int32 const value) { - - xmlrpc_value * valP; - - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_INT; - valP->_value.i = value; - } - return valP; -} - - - -xmlrpc_value * -xmlrpc_int_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * retval; - - if (valueP->_type != XMLRPC_TYPE_INT) { - xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, - "Value is not an integer. " - "It is type #%d", valueP->_type); - retval = NULL; - } else - retval = xmlrpc_int_new(envP, valueP->_value.i); - - return retval; -} - - - -xmlrpc_value * -xmlrpc_i8_new(xmlrpc_env * const envP, - xmlrpc_int64 const value) { - - xmlrpc_value * valP; - - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_I8; - valP->_value.i8 = value; - } - return valP; -} - - - -xmlrpc_value * -xmlrpc_i8_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * retval; - - if (valueP->_type != XMLRPC_TYPE_I8) { - xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, - "Value is not a 64-bit integer. " - "It is type #%d", valueP->_type); - retval = NULL; - } else - retval = xmlrpc_i8_new(envP, valueP->_value.i8); - - return retval; -} - - - -xmlrpc_value * -xmlrpc_bool_new(xmlrpc_env * const envP, - xmlrpc_bool const value) { - - xmlrpc_value * valP; - - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_BOOL; - valP->_value.b = value; - } - return valP; -} - - - -xmlrpc_value * -xmlrpc_bool_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * retval; - - if (valueP->_type != XMLRPC_TYPE_BOOL) { - xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, - "Value is not a boolean. " - "It is type #%d", valueP->_type); - retval = NULL; - } else - retval = xmlrpc_bool_new(envP, valueP->_value.b); - - return retval; -} - - - -xmlrpc_value * -xmlrpc_double_new(xmlrpc_env * const envP, - double const value) { - - xmlrpc_value * valP; - - if (!XMLRPC_FINITE(value)) { - xmlrpc_faultf(envP, "Value is not a finite number, " - "so cannot be represented in XML-RPC"); - valP = NULL; - } else { - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_DOUBLE; - valP->_value.d = value; - } - } - return valP; -} - - - -xmlrpc_value * -xmlrpc_double_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * retval; - - if (valueP->_type != XMLRPC_TYPE_DOUBLE) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, - "Value is not a floating point number. " - "It is type #%d", valueP->_type); - retval = NULL; - } else - retval = xmlrpc_double_new(envP, valueP->_value.d); - - return retval; -} - - - -xmlrpc_value * -xmlrpc_base64_new(xmlrpc_env * const envP, - size_t const length, - const unsigned char * const value) { - - xmlrpc_value * valP; - - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_BASE64; - - valP->blockP = xmlrpc_mem_block_new(envP, length); - if (!envP->fault_occurred) { - char * const contents = - xmlrpc_mem_block_contents(valP->blockP); - memcpy(contents, value, length); - } - if (envP->fault_occurred) - free(valP); - } - return valP; -} - - - -xmlrpc_value * -xmlrpc_base64_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * retval; - - if (valueP->_type != XMLRPC_TYPE_BASE64) { - xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, - "Value is not a datetime. " - "It is type #%d", valueP->_type); - retval = NULL; - } else - retval = xmlrpc_base64_new(envP, - xmlrpc_mem_block_size(valueP->blockP), - xmlrpc_mem_block_contents(valueP->blockP)); - - return retval; -} - - - -/* array stuff is in xmlrpc_array.c */ - - - -xmlrpc_value * -xmlrpc_cptr_new(xmlrpc_env * const envP, - void * const value) { - - return xmlrpc_cptr_new_dtor(envP, value, NULL, NULL); -} - - - -xmlrpc_value * -xmlrpc_cptr_new_dtor(xmlrpc_env * const envP, - void * const value, - xmlrpc_cptr_dtor_fn const dtor, - void * const dtorContext) { - - xmlrpc_value * valP; - - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_C_PTR; - valP->_value.cptr.objectP = value; - valP->_value.cptr.dtor = dtor; - valP->_value.cptr.dtorContext = dtorContext; - } - return valP; -} - - - -xmlrpc_value * -xmlrpc_cptr_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * retval; - - if (valueP->_type != XMLRPC_TYPE_C_PTR) { - xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, - "Value is not a C poitner. " - "It is type #%d", valueP->_type); - retval = NULL; - } else - retval = xmlrpc_cptr_new_dtor(envP, - valueP->_value.cptr.objectP, - valueP->_value.cptr.dtor, - valueP->_value.cptr.dtorContext); - return retval; -} - - - -xmlrpc_value * -xmlrpc_nil_new(xmlrpc_env * const envP) { - xmlrpc_value * valP; - - xmlrpc_createXmlrpcValue(envP, &valP); - if (!envP->fault_occurred) - valP->_type = XMLRPC_TYPE_NIL; - - return valP; -} - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ diff --git a/trunk/src/xmlrpc_datetime.c b/trunk/src/xmlrpc_datetime.c deleted file mode 100644 index 117f5297c..000000000 --- a/trunk/src/xmlrpc_datetime.c +++ /dev/null @@ -1,672 +0,0 @@ -#include "xmlrpc_config.h" - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include -#include -#include -#include -#if MSVCRT -# define WIN32_LEAN_AND_MEAN -# include -#endif - -#include "bool.h" -#include "mallocvar.h" - -#include "xmlrpc-c/c_util.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/time_int.h" - - -#if HAVE_REGEX -#include -#endif - -#if MSVCRT - -static const __int64 SECS_BETWEEN_EPOCHS = 11644473600; -static const __int64 SECS_TO_100NS = 10000000; /* 10^7 */ - - -void -UnixTimeToFileTime(time_t const t, - LPFILETIME const pft) { - - int64_t const ll = - Int32x32To64(t, SECS_TO_100NS) + SECS_BETWEEN_EPOCHS * SECS_TO_100NS; - - pft->dwLowDateTime = (DWORD)ll; - pft->dwHighDateTime = (DWORD)(ll >> 32); -} - - - -void -UnixTimeToSystemTime(time_t const t, - LPSYSTEMTIME const pst) { - FILETIME ft; - - UnixTimeToFileTime(t, &ft); - FileTimeToSystemTime(&ft, pst); -} - - - -static void -UnixTimeFromFileTime(xmlrpc_env * const envP, - LPFILETIME const pft, - time_t * const timeValueP) { - - int64_t const WinEpoch100Ns = - ((int64_t)pft->dwHighDateTime << 32) + pft->dwLowDateTime; - int64_t const unixEpoch100Ns = - WinEpoch100Ns - (SECS_BETWEEN_EPOCHS * SECS_TO_100NS); - int64_t const unixEpochSeconds = - unixEpoch100Ns / SECS_TO_100NS; - - if ((time_t)unixEpochSeconds != unixEpochSeconds) { - /* Value is too big for a time_t; fail. */ - xmlrpc_faultf(envP, "Does not indicate a valid date"); - *timeValueP = (time_t)(-1); - } else - *timeValueP = (time_t)unixEpochSeconds; -} - - - -static void -UnixTimeFromSystemTime(xmlrpc_env * const envP, - LPSYSTEMTIME const pst, - time_t * const timeValueP) { - FILETIME filetime; - - SystemTimeToFileTime(pst, &filetime); - UnixTimeFromFileTime(envP, &filetime, timeValueP); -} - -#endif /* MSVCRT */ - - - -static void -validateDatetimeType(xmlrpc_env * const envP, - const xmlrpc_value * const valueP) { - - if (valueP->_type != XMLRPC_TYPE_DATETIME) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " - "type %s was expected.", - xmlrpc_type_name(valueP->_type), - xmlrpc_type_name(XMLRPC_TYPE_DATETIME)); - } -} - - - -void -xmlrpc_read_datetime(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_datetime * const dtP) { - - validateDatetimeType(envP, valueP); - if (!envP->fault_occurred) { - *dtP = valueP->_value.dt; - } -} - - - -void -xmlrpc_read_datetime_str(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP) { -/*---------------------------------------------------------------------------- - This exists for backward compatibility. No normal modern program would - want to see a datetime value in this format. Note that the format isn't - even ISO 8601 -- it's a bizarre hybrid of two ISO 8601 formats. - - Do not extend this. - - This exists because Xmlrpc-c was at one time lazy and this was the only way - to extract the value. An xmlrpc_value in those days represented a datetime - with the actual XML-RPC wire format of a datetime, and this function simply - returned a copy of it. ------------------------------------------------------------------------------*/ - validateDatetimeType(envP, valueP); - if (!envP->fault_occurred) { - time_t secs; - unsigned int usecs; - - xmlrpc_read_datetime_usec(envP, valueP, &secs, &usecs); - - if (!envP->fault_occurred) { - struct tm brokenTime; - char dtString[64]; - - xmlrpc_gmtime(secs, &brokenTime); - - /* Note that this format is NOT ISO 8601 -- it's a bizarre - hybrid of two ISO 8601 formats. - */ - strftime(dtString, sizeof(dtString), "%Y%m%dT%H:%M:%S", - &brokenTime); - - if (usecs != 0) { - char usecString[64]; - assert(usecs < 1000000); - XMLRPC_SNPRINTF(usecString, sizeof(usecString), - ".%06u", usecs); - STRSCAT(dtString, usecString); - } - - *stringValueP = strdup(dtString); - if (*stringValueP == NULL) - xmlrpc_faultf(envP, - "Unable to allocate memory for datetime string"); - } - } -} - - - -void -xmlrpc_read_datetime_str_old(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP) { - - assert(valueP->_cache); - - validateDatetimeType(envP, valueP); - if (!envP->fault_occurred) { - const char ** const readBufferP = valueP->_cache; - - if (!*readBufferP) - /* Nobody's asked for the internal buffer before. Set it up. */ - xmlrpc_read_datetime_str(envP, valueP, readBufferP); - - *stringValueP = *readBufferP; - } -} - - - -void -xmlrpc_read_datetime_usec(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - time_t * const secsP, - unsigned int * const usecsP) { - - validateDatetimeType(envP, valueP); - - if (!envP->fault_occurred) { - if (valueP->_value.dt.Y < 1970) - xmlrpc_faultf(envP, "Year (%u) is too early to represent as " - "a standard Unix time", - valueP->_value.dt.Y); - else { - struct tm brokenTime; - const char * error; - - brokenTime.tm_sec = valueP->_value.dt.s; - brokenTime.tm_min = valueP->_value.dt.m; - brokenTime.tm_hour = valueP->_value.dt.h; - brokenTime.tm_mday = valueP->_value.dt.D; - brokenTime.tm_mon = valueP->_value.dt.M - 1; - brokenTime.tm_year = valueP->_value.dt.Y - 1900; - - xmlrpc_timegm(&brokenTime, secsP, &error); - - if (error) { - /* Ideally, this wouldn't be possible - it wouldn't be - possible to create an xmlrpc_value that doesn't actually - represent a real datetime. But today, we're lazy and - don't fully validate incoming XML-RPC - elements, and we also have the legacy - xmlrpc_datetime_new_str() constructor to which the user - may feed garbage. - - We should tighten that up and then simply assert here that - xmlrpc_timegm() succeeded. - */ - xmlrpc_env_set_fault_formatted(envP, XMLRPC_PARSE_ERROR, - "A datetime received in an XML-RPC message " - "or generated with legacy Xmlrpc-c facilities " - "does not validly describe a datetime. %s", - error); - xmlrpc_strfree(error); - } else - *usecsP = valueP->_value.dt.u; - } - } -} - - - -void -xmlrpc_read_datetime_sec(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - time_t * const timeValueP) { - - unsigned int usecs; - - xmlrpc_read_datetime_usec(envP, valueP, timeValueP, &usecs); -} - - - -#if XMLRPC_HAVE_TIMEVAL - -void -xmlrpc_read_datetime_timeval(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - struct timeval * const timeValueP) { - - time_t secs; - unsigned int usecs; - - xmlrpc_read_datetime_usec(envP, valueP, &secs, &usecs); - - timeValueP->tv_sec = secs; - timeValueP->tv_usec = usecs; -} -#endif - - - -#if XMLRPC_HAVE_TIMESPEC - -void -xmlrpc_read_datetime_timespec(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - struct timespec * const timeValueP) { - - time_t secs; - unsigned int usecs; - - xmlrpc_read_datetime_usec(envP, valueP, &secs, &usecs); - - timeValueP->tv_sec = secs; - timeValueP->tv_nsec = usecs * 1000; -} -#endif - - - -void -xmlrpc_read_datetime_8601(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const iso8601ValueP) { -/*---------------------------------------------------------------------------- - Get the datetime in ISO 8601 format. - - ISO 8601 allows a variety of representations for each datetime. - The particular one we return is as in the following example. - - 19930214T131030,250000Z - - (13:10:30.25 on February 14, 1993) - - There are always 4 digits for the year. There are always 6 digits after the - comma (microseconds). Midnight is hour 0, not 24. ------------------------------------------------------------------------------*/ - validateDatetimeType(envP, valueP); - if (!envP->fault_occurred) { - xmlrpc_datetime dt; - - xmlrpc_read_datetime(envP, valueP, &dt); - - if (!envP->fault_occurred) { - if (dt.Y > 9999) - xmlrpc_faultf(envP, "Too far in future (year %u). " - "ISO 8601 cannot " - "represent years after AD 9999", dt.Y); - else { - xmlrpc_asprintf(iso8601ValueP, - "%04u%02u%02uT%02u%02u%02u,%06uZ", - dt.Y, dt.M, dt.D, dt.h, dt.m, dt.s, dt.u); - - if (xmlrpc_strnomem(*iso8601ValueP)) - xmlrpc_faultf(envP, - "Unable to allocate memory " - "for datetime string"); - - if (envP->fault_occurred) - xmlrpc_strfree(*iso8601ValueP); - } - } - } -} - - - -xmlrpc_value * -xmlrpc_datetime_new(xmlrpc_env * const envP, - xmlrpc_datetime const dt) { - - xmlrpc_value * valP; - - const char ** readBufferP; - - MALLOCVAR(readBufferP); - - if (!readBufferP) - xmlrpc_faultf(envP, "Couldn't get memory for the cache part of the " - "XML-RPC datetime value object"); - - else { - *readBufferP = NULL; - - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_DATETIME; - - valP->_value.dt = dt; - - valP->_cache = readBufferP; - } - if (envP->fault_occurred) - free(readBufferP); - } - return valP; -} - - - -static void -parseDatetimeString(const char * const datetimeString, - xmlrpc_datetime * const dtP) { - - size_t const dtStrlen = strlen(datetimeString); - - char year[4+1]; - char month[2+1]; - char day[2+1]; - char hour[2+1]; - char minute[2+1]; - char second[2+1]; - - /* Because we require input to be valid: */ - assert(dtStrlen >= 17 && dtStrlen != 18 && dtStrlen <= 24); - - year[0] = datetimeString[ 0]; - year[1] = datetimeString[ 1]; - year[2] = datetimeString[ 2]; - year[3] = datetimeString[ 3]; - year[4] = '\0'; - - month[0] = datetimeString[ 4]; - month[1] = datetimeString[ 5]; - month[2] = '\0'; - - day[0] = datetimeString[ 6]; - day[1] = datetimeString[ 7]; - day[2] = '\0'; - - assert(datetimeString[ 8] == 'T'); - - hour[0] = datetimeString[ 9]; - hour[1] = datetimeString[10]; - hour[2] = '\0'; - - assert(datetimeString[11] == ':'); - - minute[0] = datetimeString[12]; - minute[1] = datetimeString[13]; - minute[2] = '\0'; - - assert(datetimeString[14] == ':'); - - second[0] = datetimeString[15]; - second[1] = datetimeString[16]; - second[2] = '\0'; - - if (dtStrlen > 17) { - size_t const pad = 24 - dtStrlen; - size_t i; - - dtP->u = atoi(&datetimeString[18]); - for (i = 0; i < pad; ++i) - dtP->u *= 10; - } else - dtP->u = 0; - - dtP->Y = atoi(year); - dtP->M = atoi(month); - dtP->D = atoi(day); - dtP->h = atoi(hour); - dtP->m = atoi(minute); - dtP->s = atoi(second); -} - - - -static void -validateFirst17(xmlrpc_env * const envP, - const char * const dt) { -/*---------------------------------------------------------------------------- - Assuming 'dt' is at least 17 characters long, validate that the first - 17 characters are a valid XML-RPC datetime, e.g. - "20080628T16:35:02" ------------------------------------------------------------------------------*/ - unsigned int i; - - for (i = 0; i < 8 && !envP->fault_occurred; ++i) - if (!isdigit(dt[i])) - xmlrpc_faultf(envP, "Not a digit: '%c'", dt[i]); - - if (dt[8] != 'T') - xmlrpc_faultf(envP, "9th character is '%c', not 'T'", dt[8]); - if (!isdigit(dt[9])) - xmlrpc_faultf(envP, "Not a digit: '%c'", dt[9]); - if (!isdigit(dt[10])) - xmlrpc_faultf(envP, "Not a digit: '%c'", dt[10]); - if (dt[11] != ':') - xmlrpc_faultf(envP, "Not a colon: '%c'", dt[11]); - if (!isdigit(dt[12])) - xmlrpc_faultf(envP, "Not a digit: '%c'", dt[12]); - if (!isdigit(dt[13])) - xmlrpc_faultf(envP, "Not a digit: '%c'", dt[13]); - if (dt[14] != ':') - xmlrpc_faultf(envP, "Not a colon: '%c'", dt[14]); - if (!isdigit(dt[15])) - xmlrpc_faultf(envP, "Not a digit: '%c'", dt[15]); - if (!isdigit(dt[16])) - xmlrpc_faultf(envP, "Not a digit: '%c'", dt[16]); -} - - - -static void -validateFractionalSeconds(xmlrpc_env * const envP, - const char * const dt) { -/*---------------------------------------------------------------------------- - Validate the fractional seconds part of the XML-RPC datetime string - 'dt', if any. That's the decimal point and everything following - it. ------------------------------------------------------------------------------*/ - if (strlen(dt) > 17) { - if (dt[17] != '.') { - xmlrpc_faultf(envP, "'%c' where only a period is valid", dt[17]); - } else { - if (dt[18] == '\0') - xmlrpc_faultf(envP, "Nothing after decimal point"); - else { - unsigned int i; - for (i = 18; dt[i] != '\0' && !envP->fault_occurred; ++i) { - if (!isdigit(dt[i])) - xmlrpc_faultf(envP, - "Non-digit in fractional seconds: '%c'", - dt[i]); - } - } - } - } -} - - - -static void -validateFormat(xmlrpc_env * const envP, - const char * const dt) { - - if (strlen(dt) < 17) - xmlrpc_faultf(envP, - "Invalid length of %u of datetime string. " - "Must be at least 17 characters", - (unsigned)strlen(dt)); - else { - validateFirst17(envP, dt); - - if (!envP->fault_occurred) - validateFractionalSeconds(envP, dt); - } -} - - - -/* Microsoft Visual C in debug mode produces code that complains about - returning an undefined value from xmlrpc_datetime_new_str(). It's a bogus - complaint, because this function is defined to return nothing meaningful - those cases. So we disable the check. -*/ -#pragma runtime_checks("u", off) - - - -xmlrpc_value * -xmlrpc_datetime_new_str(xmlrpc_env * const envP, - const char * const datetimeString) { -/*---------------------------------------------------------------------------- - This exists only for backward compatibility. Originally, this was the - only way to create a datetime XML-RPC value, because we had a really - lazy implementation of XML-RPC serialization and parsing (basically, the - user did it!). - - Do not extend this. The user should use more normal C representations - of datetimes. ------------------------------------------------------------------------------*/ - xmlrpc_value * retval; - - validateFormat(envP, datetimeString); - if (!envP->fault_occurred) { - xmlrpc_datetime dt; - - parseDatetimeString(datetimeString, &dt); - - /* Note that parseDatetimeString() can generate an invalid datetime - value, e.g. Hour 25 or February 30. Ideally, we would catch that - here, but because of laziness, we simply accept the possibility of - invalid xmlrpc_datetime in xmlrpc_value and whoever uses the the - xmlrpc_value has to deal with it. - */ - retval = xmlrpc_datetime_new(envP, dt); - } - - return retval; -} - - - -#pragma runtime_checks("u", restore) - - - -xmlrpc_value * -xmlrpc_datetime_new_usec(xmlrpc_env * const envP, - time_t const secs, - unsigned int const usecs) { - - xmlrpc_value * valueP; - - if (usecs >= 1000000) - xmlrpc_faultf(envP, "Number of fractional microseconds must be less " - "than one million. You specified %u", usecs); - else { - struct tm brokenTime; - xmlrpc_datetime dt; - - xmlrpc_gmtime(secs, &brokenTime); - - dt.s = brokenTime.tm_sec; - dt.m = brokenTime.tm_min; - dt.h = brokenTime.tm_hour; - dt.D = brokenTime.tm_mday; - dt.M = brokenTime.tm_mon + 1; - dt.Y = 1900 + brokenTime.tm_year; - dt.u = usecs; - - valueP = xmlrpc_datetime_new(envP, dt); - } - return valueP; -} - - - -xmlrpc_value * -xmlrpc_datetime_new_sec(xmlrpc_env * const envP, - time_t const value) { - - return xmlrpc_datetime_new_usec(envP, value, 0); -} - - - -#if XMLRPC_HAVE_TIMEVAL - -xmlrpc_value * -xmlrpc_datetime_new_timeval(xmlrpc_env * const envP, - struct timeval const value) { - - return xmlrpc_datetime_new_usec(envP, value.tv_sec, value.tv_usec); -} -#endif - - - -#if XMLRPC_HAVE_TIMESPEC - -xmlrpc_value * -xmlrpc_datetime_new_timespec(xmlrpc_env * const envP, - struct timespec const value) { - - return xmlrpc_datetime_new_usec(envP, value.tv_sec, value.tv_nsec/1000); -} -#endif - - - -xmlrpc_value * -xmlrpc_datetime_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * retval; - - if (valueP->_type != XMLRPC_TYPE_DATETIME) { - xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, - "Value is not a datetime. " - "It is type #%d", valueP->_type); - retval = NULL; - } else - retval = xmlrpc_datetime_new(envP, valueP->_value.dt); - - return retval; -} - - - -void -xmlrpc_destroyDatetime(xmlrpc_value * const datetimeP) { - - const char ** const readBufferP = datetimeP->_cache; - - if (*readBufferP) - xmlrpc_strfree(*readBufferP); - - free(datetimeP->_cache); -} diff --git a/trunk/src/xmlrpc_decompose.c b/trunk/src/xmlrpc_decompose.c deleted file mode 100644 index 86727121a..000000000 --- a/trunk/src/xmlrpc_decompose.c +++ /dev/null @@ -1,1153 +0,0 @@ -/* By Bryan Henderson July 2006. - - Contributed to the public domain. -*/ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#include "bool.h" -#include "c_util.h" -#include "mallocvar.h" -#include "stdargx.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" - - -/* THE DECOMPOSITION TREE - - We execute xmlrpc_decompose_value() in two steps: - - 1) Create a "decomposition tree" that tells how Caller wants the XML-RPC - value decomposed. - - 2) Using that tree, decompose the value. I.e. store stuff in the variables - in which Caller wants it stored. - - The decomposition tree is composed of information from the format - string and the variable arguments that the format string describes. - Nothing in the tree is derived from the actual XML-RPC value being - decomposed, and the tree may in fact be invalid for the particular - XML-RPC value it's meant for. - - If the XML-RPC value is a simple value such as an integer, the - decomposition tree is trivial -- it's a single node that says - "store the value of an integer via pointer P". - - Where it gets interesting is where the XML-RPC value to be decomposed - is a complex value (array or struct). Then, the root node of the tree - says, e.g., "decompose a 5-item array according to the following - 5 decomposition trees" and it points to 5 additional nodes. Each of - those nodes is the root of another decomposition tree (which can also - be called a branch in this context). Each of those branches tells - how to decompose one of the items of the array. - - Roots, interior nodes, and leaves are all essentially the same data - type. -*/ - -struct integerDecomp { - xmlrpc_int32 * valueP; -}; - -struct boolDecomp { - xmlrpc_bool * valueP; -}; - -struct doubleDecomp { - double * valueP; -}; - -struct datetimeTDecomp { - time_t * valueP; -}; - -struct datetime8Decomp { - const char ** valueP; -}; - -struct stringDecomp { - const char ** valueP; - size_t * sizeP; - /* NULL means don't store a size */ -}; - -struct wideStringDecomp { -#if HAVE_UNICODE_WCHAR - const wchar_t ** valueP; -#endif - size_t * sizeP; - /* NULL means don't store a size */ -}; - -struct bitStringDecomp { - const unsigned char ** valueP; - size_t * sizeP; -}; - -struct cptrDecomp { - void ** valueP; -}; - -struct i8Decomp { - xmlrpc_int64 * valueP; -}; - -struct valueDecomp { - xmlrpc_value ** valueP; -}; - -struct arrayValDecomp { - xmlrpc_value ** valueP; -}; - -struct structValDecomp { - xmlrpc_value ** valueP; -}; - -struct arrayDecomp { - unsigned int itemCnt; - bool ignoreExcess; - /* If there are more than 'itemCnt' items in the array, just - extract the first 'itemCnt' and ignore the rest, rather than - fail the decomposition. - */ - struct decompTreeNode * itemArray[16]; - /* Only first 'itemCnt' elements of this array are defined */ -}; - -struct mbrDecomp { - const char * key; - /* The key for the member whose value client wants to extract */ - struct decompTreeNode * decompTreeP; - /* Instructions on how to decompose (extract) member's value */ -}; - -struct structDecomp { - unsigned int mbrCnt; - struct mbrDecomp mbrArray[16]; -}; - - -struct decompTreeNode { - char formatSpecChar; - /* e.g. 'i', 'b', '8', 'A'. '(' means array; '{' means struct */ - union { - /*------------------------------------------------------------------------ - 'formatSpecChar' selects among these members. - -------------------------------------------------------------------------*/ - struct integerDecomp Tinteger; - struct boolDecomp Tbool; - struct doubleDecomp Tdouble; - struct datetimeTDecomp TdatetimeT; - struct datetime8Decomp Tdatetime8; - struct stringDecomp Tstring; - struct wideStringDecomp TwideString; - struct bitStringDecomp TbitString; - struct cptrDecomp Tcptr; - struct i8Decomp Ti8; - struct valueDecomp Tvalue; - struct arrayValDecomp TarrayVal; - struct structValDecomp TstructVal; - struct arrayDecomp Tarray; - struct structDecomp Tstruct; - } store; - -}; - - - -/* prototype for recursive calls */ -static void -releaseDecomposition(const struct decompTreeNode * const decompRootP); - - -static void -releaseDecompArray(struct arrayDecomp const arrayDecomp) { - - unsigned int i; - for (i = 0; i < arrayDecomp.itemCnt; ++i) { - releaseDecomposition(arrayDecomp.itemArray[i]); - } -} - - - -static void -releaseDecompStruct(struct structDecomp const structDecomp) { - - unsigned int i; - for (i = 0; i < structDecomp.mbrCnt; ++i) { - releaseDecomposition(structDecomp.mbrArray[i].decompTreeP); - } -} - - - -static void -releaseDecomposition(const struct decompTreeNode * const decompRootP) { -/*---------------------------------------------------------------------------- - Assuming that Caller has decomposed something according to 'decompRootP', - release whatever resources the decomposed information occupies. - - E.g. if it's an XML-RPC string, Caller would have allocated memory - for the C string that represents the decomposed value of XML-RPC string, - and we release that memory. ------------------------------------------------------------------------------*/ - switch (decompRootP->formatSpecChar) { - case 'i': - case 'b': - case 'd': - case 'n': - case 'I': - case 't': - case 'p': - /* Nothing was allocated; nothing to release */ - break; - case '8': - xmlrpc_strfree(*decompRootP->store.Tdatetime8.valueP); - break; - case 's': - xmlrpc_strfree(*decompRootP->store.Tstring.valueP); - break; - case 'w': -#if HAVE_UNICODE_WCHAR - free((void*)*decompRootP->store.TwideString.valueP); -#else - XMLRPC_ASSERT(false); -#endif - break; - case '6': - free((void*)*decompRootP->store.TbitString.valueP); - break; - case 'V': - xmlrpc_DECREF(*decompRootP->store.Tvalue.valueP); - break; - case 'A': - xmlrpc_DECREF(*decompRootP->store.TarrayVal.valueP); - break; - case 'S': - xmlrpc_DECREF(*decompRootP->store.TstructVal.valueP); - break; - case '(': - releaseDecompArray(decompRootP->store.Tarray); - break; - case '{': - releaseDecompStruct(decompRootP->store.Tstruct); - break; - } -} - - - -/* Prototype for recursive invocation: */ - -static void -decomposeValueWithTree(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - bool const oldstyleMemMgmt, - const struct decompTreeNode * const decompRootP); - - - -static void -validateArraySize(xmlrpc_env * const envP, - const xmlrpc_value * const arrayP, - struct arrayDecomp const arrayDecomp) { - - unsigned int size; - - size = xmlrpc_array_size(envP, arrayP); - if (!envP->fault_occurred) { - if (arrayDecomp.itemCnt > size) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, - "Format string requests %u items from array, but array " - "has only %u items.", arrayDecomp.itemCnt, size); - else if (arrayDecomp.itemCnt < size && !arrayDecomp.ignoreExcess) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, - "Format string requests exactly %u items from array, " - "but array has %u items. (A '*' at the end would avoid " - "this failure)", arrayDecomp.itemCnt, size); - } -} - - - -static void -parsearray(xmlrpc_env * const envP, - const xmlrpc_value * const arrayP, - struct arrayDecomp const arrayDecomp, - bool const oldstyleMemMgmt) { - - validateArraySize(envP, arrayP, arrayDecomp); - - if (!envP->fault_occurred) { - unsigned int doneCnt; - - doneCnt = 0; - while(doneCnt < arrayDecomp.itemCnt && !envP->fault_occurred) { - xmlrpc_value * itemP; - - xmlrpc_array_read_item(envP, arrayP, doneCnt, &itemP); - - if (!envP->fault_occurred) { - XMLRPC_ASSERT(doneCnt < ARRAY_SIZE(arrayDecomp.itemArray)); - decomposeValueWithTree(envP, itemP, oldstyleMemMgmt, - arrayDecomp.itemArray[doneCnt]); - - if (!envP->fault_occurred) - ++doneCnt; - - xmlrpc_DECREF(itemP); - } - } - if (envP->fault_occurred) { - if (!oldstyleMemMgmt) { - /* Release the items we completed before we failed. */ - unsigned int i; - for (i = 0; i < doneCnt; ++i) - releaseDecomposition(arrayDecomp.itemArray[i]); - } - } - } -} - - - -static void -parsestruct(xmlrpc_env * const envP, - xmlrpc_value * const structP, - struct structDecomp const structDecomp, - bool const oldstyleMemMgmt) { - - unsigned int doneCount; - - doneCount = 0; /* No members done yet */ - - while (doneCount < structDecomp.mbrCnt && !envP->fault_occurred) { - const char * const key = structDecomp.mbrArray[doneCount].key; - - xmlrpc_value * valueP; - - xmlrpc_struct_read_value(envP, structP, key, &valueP); - - if (!envP->fault_occurred) { - decomposeValueWithTree( - envP, valueP, oldstyleMemMgmt, - structDecomp.mbrArray[doneCount].decompTreeP); - - if (!envP->fault_occurred) - ++doneCount; - - xmlrpc_DECREF(valueP); - } - } - - if (envP->fault_occurred) { - if (!oldstyleMemMgmt) { - /* Release the items we completed before we failed. */ - unsigned int i; - for (i = 0; i < doneCount; ++i) - releaseDecomposition(structDecomp.mbrArray[i].decompTreeP); - } - } -} - - - -static void -readString(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP, - bool const oldstyleMemMgmt) { - - if (oldstyleMemMgmt) { - xmlrpc_read_string_old(envP, valueP, stringValueP); - } else - xmlrpc_read_string(envP, valueP, stringValueP); -} - - - -static void -readStringLp(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const char ** const stringValueP, - bool const oldstyleMemMgmt) { - - if (oldstyleMemMgmt) { - xmlrpc_read_string_lp_old(envP, valueP, lengthP, stringValueP); - } else - xmlrpc_read_string_lp(envP, valueP, lengthP, stringValueP); -} - - - -#if HAVE_UNICODE_WCHAR -static void -readStringW(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const wchar_t ** const stringValueP, - bool const oldstyleMemMgmt) { - - if (oldstyleMemMgmt) { - xmlrpc_read_string_w_old(envP, valueP, stringValueP); - } else - xmlrpc_read_string_w(envP, valueP, stringValueP); -} - - - -static void -readStringWLp(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - size_t * const lengthP, - const wchar_t ** const stringValueP, - bool const oldstyleMemMgmt) { - - if (oldstyleMemMgmt) { - xmlrpc_read_string_w_lp_old(envP, valueP, lengthP, stringValueP); - } else - xmlrpc_read_string_w_lp(envP, valueP, lengthP, stringValueP); -} -#endif - - -static void -readDatetime8Str(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP, - bool const oldstyleMemMgmt) { - - if (oldstyleMemMgmt) - xmlrpc_read_datetime_str_old(envP, valueP, stringValueP); - else - xmlrpc_read_datetime_str(envP, valueP, stringValueP); -} - - - -static void -readBase64(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const unsigned char ** const byteStringValueP, - bool const oldstyleMemMgmt) { - - if (oldstyleMemMgmt) - xmlrpc_read_base64_old(envP, valueP, lengthP, byteStringValueP); - else - xmlrpc_read_base64(envP, valueP, lengthP, byteStringValueP); -} - - -static void -decomposeValueWithTree(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - bool const oldstyleMemMgmt, - const struct decompTreeNode * const decompRootP) { -/*---------------------------------------------------------------------------- - Decompose XML-RPC value *valueP, given the decomposition tree - *decompRootP. The decomposition tree tells what structure *valueP - is expected to have and where to put the various components of it - (e.g. it says "it's an array of 3 integers. Put their values at - locations x, y, and z") ------------------------------------------------------------------------------*/ - switch (decompRootP->formatSpecChar) { - case '-': - /* There's nothing to validate or return */ - break; - case 'i': - xmlrpc_read_int(envP, valueP, decompRootP->store.Tinteger.valueP); - break; - - case 'b': - xmlrpc_read_bool(envP, valueP, decompRootP->store.Tbool.valueP); - break; - - case 'd': - xmlrpc_read_double(envP, valueP, decompRootP->store.Tdouble.valueP); - break; - - case 't': - xmlrpc_read_datetime_sec(envP, valueP, - decompRootP->store.TdatetimeT.valueP); - break; - - case '8': - readDatetime8Str(envP, valueP, decompRootP->store.Tdatetime8.valueP, - oldstyleMemMgmt); - break; - - case 's': - if (decompRootP->store.Tstring.sizeP) - readStringLp(envP, valueP, - decompRootP->store.Tstring.sizeP, - decompRootP->store.Tstring.valueP, - oldstyleMemMgmt); - else - readString(envP, valueP, decompRootP->store.Tstring.valueP, - oldstyleMemMgmt); - break; - - case 'w': -#if HAVE_UNICODE_WCHAR - if (decompRootP->store.Tstring.sizeP) - readStringWLp(envP, valueP, - decompRootP->store.TwideString.sizeP, - decompRootP->store.TwideString.valueP, - oldstyleMemMgmt); - else - readStringW(envP, valueP, decompRootP->store.TwideString.valueP, - oldstyleMemMgmt); -#else - XMLRPC_ASSERT(false); -#endif /* HAVE_UNICODE_WCHAR */ - break; - - case '6': - readBase64(envP, valueP, - decompRootP->store.TbitString.sizeP, - decompRootP->store.TbitString.valueP, - oldstyleMemMgmt); - break; - - case 'n': - xmlrpc_read_nil(envP, valueP); - break; - - case 'I': - xmlrpc_read_i8(envP, valueP, decompRootP->store.Ti8.valueP); - break; - - case 'p': - xmlrpc_read_cptr(envP, valueP, decompRootP->store.Tcptr.valueP); - break; - - case 'V': - *decompRootP->store.Tvalue.valueP = valueP; - if (!oldstyleMemMgmt) - xmlrpc_INCREF(valueP); - break; - - case 'A': - if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type " - "%s, but the 'A' specifier requires type ARRAY", - xmlrpc_type_name(xmlrpc_value_type(valueP))); - else { - *decompRootP->store.TarrayVal.valueP = valueP; - if (!oldstyleMemMgmt) - xmlrpc_INCREF(valueP); - } - break; - - case 'S': - if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type " - "%s, but the 'S' specifier requires type STRUCT.", - xmlrpc_type_name(xmlrpc_value_type(valueP))); - else { - *decompRootP->store.TstructVal.valueP = valueP; - if (!oldstyleMemMgmt) - xmlrpc_INCREF(valueP); - } - break; - - case '(': - if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type " - "%s, but the '(...)' specifier requires type ARRAY", - xmlrpc_type_name(xmlrpc_value_type(valueP))); - else - parsearray(envP, valueP, decompRootP->store.Tarray, - oldstyleMemMgmt); - break; - - case '{': - if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type " - "%s, but the '{...}' specifier requires type STRUCT", - xmlrpc_type_name(xmlrpc_value_type(valueP))); - else - parsestruct(envP, valueP, decompRootP->store.Tstruct, - oldstyleMemMgmt); - break; - - default: - /* Every format character that is allowed in a decomposition tree - node is handled above. - */ - XMLRPC_ASSERT(false); - } -} - - -/* Forward declaration for recursive calls */ - -static void -createDecompTreeNext(xmlrpc_env * const envP, - const char ** const formatP, - va_listx * const argsP, - struct decompTreeNode ** const decompNodePP); - - - -static void -buildWideStringNode(xmlrpc_env * const envP ATTR_UNUSED, - const char ** const formatP, - va_listx * const argsP, - struct decompTreeNode * const decompNodeP) { - -#if HAVE_UNICODE_WCHAR - decompNodeP->store.TwideString.valueP = - (const wchar_t**) va_arg(argsP->v, wchar_t**); - if (**formatP == '#') { - decompNodeP->store.TwideString.sizeP = - (size_t*) va_arg(argsP->v, size_t**); - (*formatP)++; - } else - decompNodeP->store.TwideString.sizeP = NULL; -#else - xmlrpc_faultf(envP, - "This XML-RPC For C/C++ library was built without Unicode " - "wide character capability. 'w' isn't available."); -#endif /* HAVE_UNICODE_WCHAR */ -} - - - -static void -destroyDecompTree(struct decompTreeNode * const decompRootP) { - - switch (decompRootP->formatSpecChar) { - case '(': { - unsigned int i; - for (i = 0; i < decompRootP->store.Tarray.itemCnt; ++i) - destroyDecompTree(decompRootP->store.Tarray.itemArray[i]); - } break; - case '{': { - unsigned int i; - for (i = 0; i < decompRootP->store.Tstruct.mbrCnt; ++i) - destroyDecompTree( - decompRootP->store.Tstruct.mbrArray[i].decompTreeP); - } break; - } - - free(decompRootP); -} - - - -static void -processArraySpecTail(xmlrpc_env * const envP, - const char ** const formatP, - bool * const hasTrailingAsteriskP, - char const delim) { - - if (**formatP == '*') { - *hasTrailingAsteriskP = true; - - ++*formatP; - - if (!**formatP) - xmlrpc_faultf(envP, "missing closing delimiter ('%c')", delim); - else if (**formatP != delim) - xmlrpc_faultf(envP, "character following '*' in array " - "specification should be the closing delimiter " - "'%c', but is '%c'", delim, **formatP); - } else { - *hasTrailingAsteriskP = false; - - if (!**formatP) - xmlrpc_faultf(envP, "missing closing delimiter ('%c')", delim); - } - if (!envP->fault_occurred) - XMLRPC_ASSERT(**formatP == delim); -} - - - -static void -buildArrayDecompBranch(xmlrpc_env * const envP, - const char ** const formatP, - char const delim, - va_listx * const argsP, - struct decompTreeNode * const decompNodeP) { -/*---------------------------------------------------------------------------- - Fill in the decomposition tree node *decompNodeP to cover an array - whose items are described by *formatP. To wit, they are the values - described by successive format specifiers in *formatP up to but not - including the next 'delim' character. - - Plus, the last character before the delimiter might be a '*', which - means "ignore any additional items in the array." - - We create a node (and whole branch if required) to describe each array - item. - - The pointers to where those items are to be stored are given by - 'argsP'. - - We advance *formatP to the delimiter character, and advance 'argsP' - past whatever arguments we use. ------------------------------------------------------------------------------*/ - unsigned int itemCnt; - /* Number of array items in the branch so far */ - - itemCnt = 0; /* Branch is empty so far */ - - while (**formatP && **formatP != delim && **formatP != '*' && - !envP->fault_occurred) { - if (itemCnt >= ARRAY_SIZE(decompNodeP->store.Tarray.itemArray)) - xmlrpc_faultf(envP, "Too many array items in format string. " - "The most items you can have for an array in " - "a format string is %u.", (unsigned) - ARRAY_SIZE(decompNodeP->store.Tarray.itemArray)); - else { - struct decompTreeNode * itemNodeP; - - createDecompTreeNext(envP, formatP, argsP, &itemNodeP); - - if (!envP->fault_occurred) - decompNodeP->store.Tarray.itemArray[itemCnt++] = itemNodeP; - } - } - if (!envP->fault_occurred) { - decompNodeP->store.Tarray.itemCnt = itemCnt; - processArraySpecTail(envP, formatP, - &decompNodeP->store.Tarray.ignoreExcess, - delim); - } - if (envP->fault_occurred) { - unsigned int i; - for (i = 0; i < itemCnt; ++i) - destroyDecompTree(decompNodeP->store.Tarray.itemArray[i]); - } -} - - - -static void -doStructValue(xmlrpc_env * const envP, - const char ** const formatP, - va_listx * const argsP, - struct mbrDecomp * const mbrP) { - - struct decompTreeNode * valueNodeP; - - mbrP->key = (const char*) va_arg(argsP->v, char*); - - createDecompTreeNext(envP, formatP, argsP, &valueNodeP); - - if (!envP->fault_occurred) - mbrP->decompTreeP = valueNodeP; -} - - - -static void -skipAsterisk(xmlrpc_env * const envP, - const char ** const formatP, - char const delim) { - - if (**formatP == '*') { - ++*formatP; - - if (!**formatP) - xmlrpc_faultf(envP, "missing closing delimiter ('%c')", delim); - else if (**formatP != delim) - xmlrpc_faultf(envP, "junk after '*' in the specifier of an " - "array. First character='%c'", **formatP); - } else - /* Conceptually, one can make it an error to leave some struct - members behind, but we have never had code that knows how to - recognize that case. - */ - xmlrpc_faultf(envP, - "You must put a trailing '*' in the specifiers for " - "struct members to signify it's OK if there are " - "additional members you didn't get."); -} - - - -static void -skipColon(xmlrpc_env * const envP, - const char ** const formatP, - char const delim) { - - if (**formatP == '\0') - xmlrpc_faultf(envP, "format string ends in the middle of a struct " - "member specifier"); - else if (**formatP == delim) - xmlrpc_faultf(envP, "member list ends in the middle of a member"); - else if (**formatP != ':') - xmlrpc_faultf(envP, "In a struct specifier, '%c' found " - "where a colon (':') separating key and " - "value was expected.", **formatP); -} - - - -static void -skipComma(xmlrpc_env * const envP, - const char ** const formatP, - char const delim) { - - if (**formatP && **formatP != delim) { - if (**formatP == ',') - ++*formatP; /* skip over comma */ - else - xmlrpc_faultf(envP, "'%c' where we expected a ',' " - "to separate struct members", **formatP); - } -} - - - -static void -buildStructDecompBranch(xmlrpc_env * const envP, - const char ** const formatP, - char const delim, - va_listx * const argsP, - struct decompTreeNode * const decompNodeP) { -/*---------------------------------------------------------------------------- - Fill in the decomposition tree node *decompNodeP to cover a struct - whose members are described by *formatP. To wit, they are the values - described by successive format specifiers in *formatP up to but not - including the next 'delim' character. - - We create a node (and whole branch if required) to describe each - struct member value. - - The pointers to where those values are to be stored are given by - 'argsP'. - - The names of the members to be extracted are also given by 'argsP'. - - We advance *formatP to the delimiter character, and advance 'argsP' - past whatever arguments we use. ------------------------------------------------------------------------------*/ - unsigned int memberCnt; - /* Number of struct members in the branch so far */ - - memberCnt = 0; /* Branch is empty so far */ - - while (**formatP && **formatP != delim && **formatP != '*' && - !envP->fault_occurred) { - if (memberCnt >= ARRAY_SIZE(decompNodeP->store.Tstruct.mbrArray)) - xmlrpc_faultf(envP, - "Too many structure members in format string. " - "The most members you can specify in " - "a format string is %u.", (unsigned) - ARRAY_SIZE(decompNodeP->store.Tstruct.mbrArray)); - else { - struct mbrDecomp * const mbrP = - &decompNodeP->store.Tstruct.mbrArray[memberCnt]; - - if (**formatP != 's') - xmlrpc_faultf(envP, "In a struct specifier, the specifier " - "for the key is '%c', but it must be 's'.", - **formatP); - else { - ++*formatP; - - skipColon(envP, formatP, delim); - - if (!envP->fault_occurred) { - ++*formatP; - - doStructValue(envP, formatP, argsP, mbrP); - - if (!envP->fault_occurred) - ++memberCnt; - - skipComma(envP, formatP, delim); - } - } - } - } - decompNodeP->store.Tstruct.mbrCnt = memberCnt; - - if (!envP->fault_occurred) { - skipAsterisk(envP, formatP, delim); - if (!envP->fault_occurred) - XMLRPC_ASSERT(**formatP == delim); - } - - if (envP->fault_occurred) { - unsigned int i; - for (i = 0; i < memberCnt; ++i) - destroyDecompTree( - decompNodeP->store.Tstruct.mbrArray[i].decompTreeP); - } -} - - - -static void -createDecompTreeNext(xmlrpc_env * const envP, - const char ** const formatP, - va_listx * const argsP, - struct decompTreeNode ** const decompNodePP) { -/*---------------------------------------------------------------------------- - Create a branch of a decomposition tree that applies to the first - value described by '*formatP', and advance *formatP past the description - of that first value. E.g.: - - - If *formatP is "isb", we create a branch consisting of one - node -- for an integer. We advance *formatP by one character, so - it points to the "s". - - - If *formatP is "(isb)s", we create a branch that represents the - array (isb) and advance *formatP past the closing parenthesis to - point to the final "s". We return as *decompNodePP a pointer to - a node for the array, and that array in turn points to nodes for - each of the 3 array items: one for an integer, one for a string, - and one for a boolean. - - The locations at which the components of that value are to be - stored (which is the main contents of the branch we create) are - given by 'argsP'. - - Return as *decompNodeP a pointer to the root node of the branch we - generate. ------------------------------------------------------------------------------*/ - struct decompTreeNode * decompNodeP; - - MALLOCVAR(decompNodeP); - - if (decompNodeP == NULL) - xmlrpc_faultf(envP, "Could not allocate space for a decomposition " - "tree node"); - else { - decompNodeP->formatSpecChar = *(*formatP)++; - - switch (decompNodeP->formatSpecChar) { - case '-': - /* There's nothing to store */ - break; - case 'i': - decompNodeP->store.Tinteger.valueP = - (xmlrpc_int32*) va_arg(argsP->v, xmlrpc_int32*); - break; - - case 'b': - decompNodeP->store.Tbool.valueP = - (xmlrpc_bool*) va_arg(argsP->v, xmlrpc_bool*); - break; - - case 'd': - decompNodeP->store.Tdouble.valueP = - (double*) va_arg(argsP->v, double*); - break; - - case 't': - decompNodeP->store.TdatetimeT.valueP = - va_arg(argsP->v, time_t*); - break; - - case '8': - decompNodeP->store.Tdatetime8.valueP = - (const char**) va_arg(argsP->v, char**); - break; - - case 's': - decompNodeP->store.Tstring.valueP = - (const char**) va_arg(argsP->v, char**); - if (**formatP == '#') { - decompNodeP->store.Tstring.sizeP = - (size_t*) va_arg(argsP->v, size_t**); - ++*formatP; - } else - decompNodeP->store.Tstring.sizeP = NULL; - break; - - case 'w': - buildWideStringNode(envP, formatP, argsP, decompNodeP); - break; - - case '6': - decompNodeP->store.TbitString.valueP = - (const unsigned char**) va_arg(argsP->v, unsigned char**); - decompNodeP->store.TbitString.sizeP = - (size_t*) va_arg(argsP->v, size_t**); - break; - - case 'n': - /* There's no value to store */ - break; - - case 'I': - decompNodeP->store.Ti8.valueP = - (xmlrpc_int64 *) va_arg(argsP->v, xmlrpc_int64 *); - break; - - case 'p': - decompNodeP->store.Tcptr.valueP = - (void**) va_arg(argsP->v, void**); - break; - - case 'V': - decompNodeP->store.Tvalue.valueP = - (xmlrpc_value**) va_arg(argsP->v, xmlrpc_value**); - break; - - case 'A': - decompNodeP->store.TarrayVal.valueP = - (xmlrpc_value**) va_arg(argsP->v, xmlrpc_value**); - break; - - case 'S': - decompNodeP->store.TstructVal.valueP = - (xmlrpc_value**) va_arg(argsP->v, xmlrpc_value**); - break; - - case '(': - buildArrayDecompBranch(envP, formatP, ')', argsP, decompNodeP); - ++(*formatP); /* skip past closing ')' */ - break; - - case '{': - buildStructDecompBranch(envP, formatP, '}', argsP, decompNodeP); - ++(*formatP); /* skip past closing '}' */ - break; - - default: - xmlrpc_faultf(envP, "Invalid format character '%c'", - decompNodeP->formatSpecChar); - } - if (envP->fault_occurred) - free(decompNodeP); - else - *decompNodePP = decompNodeP; - } -} - - - -static void -createDecompTree(xmlrpc_env * const envP, - const char * const format, - va_listx const args, - struct decompTreeNode ** const decompRootPP) { - - const char * formatCursor; - struct decompTreeNode * decompRootP; - va_listx currentArgs; - - currentArgs = args; - formatCursor = &format[0]; - createDecompTreeNext(envP, &formatCursor, ¤tArgs, &decompRootP); - if (!envP->fault_occurred) { - if (*formatCursor != '\0') - xmlrpc_faultf(envP, "format string '%s' has garbage at the end: " - "'%s'. It should be a specifier of a single value " - "(but that might be a complex value, such as an " - "array)", format, formatCursor); - - if (envP->fault_occurred) - destroyDecompTree(decompRootP); - } - *decompRootPP = decompRootP; -} - - - -static void -decomposeValue(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - bool const oldstyleMemMgmt, - const char * const format, - va_listx const args) { - - struct decompTreeNode * decompRootP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(valueP); - XMLRPC_ASSERT(format != NULL); - - createDecompTree(envP, format, args, &decompRootP); - - if (!envP->fault_occurred) { - decomposeValueWithTree(envP, valueP, oldstyleMemMgmt, decompRootP); - - destroyDecompTree(decompRootP); - } -} - - - -void -xmlrpc_decompose_value_va(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const char * const format, - va_list const args) { - - bool const oldstyleMemMgtFalse = false; - va_listx argsx; - - init_va_listx(&argsx, args); - - decomposeValue(envP, valueP, oldstyleMemMgtFalse, format, argsx); -} - - - -void -xmlrpc_decompose_value(xmlrpc_env * const envP, - xmlrpc_value * const value, - const char * const format, - ...) { - - va_list args; - - va_start(args, format); - xmlrpc_decompose_value_va(envP, value, format, args); - va_end(args); -} - - - -void -xmlrpc_parse_value_va(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const char * const format, - va_list const args) { - - bool const oldstyleMemMgmtTrue = true; - va_listx argsx; - - init_va_listx(&argsx, args); - - decomposeValue(envP, valueP, oldstyleMemMgmtTrue, format, argsx); -} - - - -void -xmlrpc_parse_value(xmlrpc_env * const envP, - xmlrpc_value * const value, - const char * const format, - ...) { - - va_list args; - - va_start(args, format); - xmlrpc_parse_value_va(envP, value, format, args); - va_end(args); -} diff --git a/trunk/src/xmlrpc_expat.c b/trunk/src/xmlrpc_expat.c deleted file mode 100644 index 30fae15c7..000000000 --- a/trunk/src/xmlrpc_expat.c +++ /dev/null @@ -1,546 +0,0 @@ -/* Copyright information is at end of file */ - -#include "xmlrpc_config.h" - -#include -#include -#include - -#include /* Expat */ - -#include "bool.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" - -#include "xmlparser.h" - -struct _xml_element { -/*---------------------------------------------------------------------------- - Information about an XML element ------------------------------------------------------------------------------*/ - struct _xml_element * parentP; - const char * name; - xmlrpc_mem_block * cdataP; /* char */ - xmlrpc_mem_block * childrenP; /* xml_element* */ -}; - -/* Check that we're using expat in UTF-8 mode, not wchar_t mode. -** If you need to use expat in wchar_t mode, write a subroutine to -** copy a wchar_t string to a char string & return an error for -** any non-ASCII characters. Then call this subroutine on all -** XML_Char strings passed to our event handlers before using the -** data. */ -/* #if sizeof(char) != sizeof(XML_Char) -** #error expat must define XML_Char to be a regular char. -** #endif -*/ - -#define XMLRPC_ASSERT_ELEM_OK(elem) \ - XMLRPC_ASSERT((elem) != NULL && (elem)->name != XMLRPC_BAD_POINTER) - - -void -xml_init(xmlrpc_env * const envP) { - - XMLRPC_ASSERT_ENV_OK(envP); -} - - - -void -xml_term(void) { - -} - - - -static xml_element * -xmlElementNew(xmlrpc_env * const envP, - const char * const name) { -/*---------------------------------------------------------------------------- - A new skeleton element object - ready to be filled in to represent an - actual element. ------------------------------------------------------------------------------*/ - xml_element * retval; - int name_valid, cdata_valid, children_valid; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(name != NULL); - - /* Set up our error-handling preconditions. */ - retval = NULL; - name_valid = cdata_valid = children_valid = 0; - - /* Allocate our xml_element structure. */ - retval = (xml_element*) malloc(sizeof(xml_element)); - XMLRPC_FAIL_IF_NULL(retval, envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for XML element"); - - /* Set our parent field to NULL. */ - retval->parentP = NULL; - - /* Copy over the element name. */ - retval->name = xmlrpc_strdupnull(name); - XMLRPC_FAIL_IF_NULL(retval->name, envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for XML element"); - name_valid = 1; - - retval->cdataP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - XMLRPC_FAIL_IF_FAULT(envP); - cdata_valid = 1; - - retval->childrenP = XMLRPC_MEMBLOCK_NEW(xml_element *, envP, 0); - XMLRPC_FAIL_IF_FAULT(envP); - children_valid = 1; - - cleanup: - if (envP->fault_occurred) { - if (retval) { - if (name_valid) - xmlrpc_strfree(retval->name); - if (cdata_valid) - XMLRPC_MEMBLOCK_FREE(char, retval->cdataP); - if (children_valid) - XMLRPC_MEMBLOCK_FREE(xml_element *, retval->childrenP); - free(retval); - } - return NULL; - } else { - return retval; - } -} - - -/*========================================================================= -** xml_element_free -**========================================================================= -** Blow away an existing element & all of its child elements. -*/ -void -xml_element_free(xml_element * const elemP) { - - xmlrpc_mem_block * childrenP; - size_t size, i; - xml_element ** contents; - - XMLRPC_ASSERT_ELEM_OK(elemP); - - xmlrpc_strfree(elemP->name); - elemP->name = XMLRPC_BAD_POINTER; - - XMLRPC_MEMBLOCK_FREE(char, elemP->cdataP); - - /* Deallocate all of our children recursively. */ - childrenP = elemP->childrenP; - contents = XMLRPC_MEMBLOCK_CONTENTS(xml_element *, childrenP); - size = XMLRPC_MEMBLOCK_SIZE(xml_element *, childrenP); - for (i = 0; i < size; ++i) - xml_element_free(contents[i]); - - XMLRPC_MEMBLOCK_FREE(xml_element *, elemP->childrenP); - - free(elemP); -} - - -/*========================================================================= -** Miscellaneous Accessors -**========================================================================= -** Return the fields of the xml_element. See the header for more -** documentation on each function works. -*/ - - - -const char * -xml_element_name(const xml_element * const elemP) { - - XMLRPC_ASSERT_ELEM_OK(elemP); - - return elemP->name; -} - - - -size_t -xml_element_cdata_size (const xml_element * const elemP) { -/*---------------------------------------------------------------------------- - The result of this function is NOT VALID until the end_element handler - has been called! ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ELEM_OK(elemP); - - return XMLRPC_MEMBLOCK_SIZE(char, elemP->cdataP) - 1; -} - - - -const char * -xml_element_cdata(const xml_element * const elemP) { - - XMLRPC_ASSERT_ELEM_OK(elemP); - - return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(const char, elemP->cdataP); -} - - - -unsigned int -xml_element_children_size(const xml_element * const elemP) { - - XMLRPC_ASSERT_ELEM_OK(elemP); - - return XMLRPC_MEMBLOCK_SIZE(xml_element *, elemP->childrenP); -} - - - -xml_element ** -xml_element_children(const xml_element * const elemP) { - XMLRPC_ASSERT_ELEM_OK(elemP); - return XMLRPC_MEMBLOCK_CONTENTS(xml_element *, elemP->childrenP); -} - - - -/*============================================================================= - Internal xml_element Utility Functions -=============================================================================*/ - -static void -xml_element_append_cdata(xmlrpc_env * const envP, - xml_element * const elemP, - const char * const cdata, - size_t const size) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_ELEM_OK(elemP); - - XMLRPC_MEMBLOCK_APPEND(char, envP, elemP->cdataP, cdata, size); -} - - - -static void -xml_element_append_child(xmlrpc_env * const envP, - xml_element * const elemP, - xml_element * const childP) { -/*---------------------------------------------------------------------------- - Whether or not this function succeeds, it takes ownership of *childP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_ELEM_OK(elemP); - XMLRPC_ASSERT_ELEM_OK(childP); - XMLRPC_ASSERT(childP->parentP == NULL); - - XMLRPC_MEMBLOCK_APPEND(xml_element *, envP, elemP->childrenP, &childP, 1); - if (!envP->fault_occurred) - childP->parentP = elemP; - else - xml_element_free(childP); -} - - - -typedef struct { -/*---------------------------------------------------------------------------- - Our parse context. We pass this around as expat user data. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xml_element * rootP; - xml_element * currentP; - xmlrpc_mem_pool * memPoolP; - /* The memory pool we use for as much memory allocation as we can; - It's purpose is that it is of limited size, so especially use it - for things that need to be limited, like to prevent an XML-RPC - client from using up all the memory by sending a cleverly crafted - XML document. - */ -} ParseContext; - - - -static void -initParseContext(ParseContext * const contextP, - xmlrpc_mem_pool * const memPoolP) { - - xmlrpc_env_init(&contextP->env); - - contextP->rootP = NULL; - contextP->currentP = NULL; - contextP->memPoolP = memPoolP; -} - - - -static void -termParseContext(ParseContext * const contextP) { - - xmlrpc_env_clean(&contextP->env); -} - - -/*============================================================================= - Expat Event Handler Functions -=============================================================================*/ - -static void -startElement(void * const userData, - XML_Char * const name, - XML_Char ** const atts ATTR_UNUSED) { - - ParseContext * const contextP = userData; - - XMLRPC_ASSERT(contextP != NULL); - XMLRPC_ASSERT(name != NULL); - - if (!contextP->env.fault_occurred) { - xml_element * elemP; - - elemP = xmlElementNew(&contextP->env, name); - if (!contextP->env.fault_occurred) { - XMLRPC_ASSERT(elemP != NULL); - - /* Insert the new element in the appropriate place. */ - if (!contextP->rootP) { - /* No root yet, so this element must be the root. */ - contextP->rootP = elemP; - contextP->currentP = elemP; - } else { - XMLRPC_ASSERT(contextP->currentP != NULL); - - /* (We need to watch our error handling invariants - very carefully here. Read the docs for - xml_element_append_child. - */ - xml_element_append_child(&contextP->env, contextP->currentP, - elemP); - if (!contextP->env.fault_occurred) - contextP->currentP = elemP; - } - if (contextP->env.fault_occurred) - xml_element_free(elemP); - } - if (contextP->env.fault_occurred) { - /* Having changed *contextP to reflect failure, we are responsible - for undoing everything that has been done so far in this - context. - */ - if (contextP->rootP) - xml_element_free(contextP->rootP); - } - } -} - - - -static void -endElement(void * const userData, - XML_Char * const name ATTR_UNUSED) { - - ParseContext * const contextP = userData; - - XMLRPC_ASSERT(contextP != NULL); - XMLRPC_ASSERT(name != NULL); - - if (!contextP->env.fault_occurred) { - /* I think Expat enforces these facts: */ - XMLRPC_ASSERT(xmlrpc_streq(name, contextP->currentP->name)); - XMLRPC_ASSERT(contextP->currentP->parentP != NULL || - contextP->currentP == contextP->rootP); - - /* Add a trailing NUL to our cdata. */ - xml_element_append_cdata(&contextP->env, contextP->currentP, "\0", 1); - if (!contextP->env.fault_occurred) - /* Pop our "stack" of elements. */ - contextP->currentP = contextP->currentP->parentP; - - if (contextP->env.fault_occurred) { - /* Having changed *contextP to reflect failure, we are responsible - for undoing everything that has been done so far in this - context. - */ - if (contextP->rootP) - xml_element_free(contextP->rootP); - } - } -} - - - -static void -characterData(void * const userData, - XML_Char * const s, - int const len) { -/*---------------------------------------------------------------------------- - This is an Expat character data (cdata) handler. When an Expat - parser comes across cdata, he calls one of these with the cdata as - argument. He can call it multiple times for consecutive cdata. - - We simply append the cdata to the cdata buffer for whatever XML - element the parser is presently parsing. ------------------------------------------------------------------------------*/ - ParseContext * const contextP = userData; - - XMLRPC_ASSERT(contextP != NULL); - XMLRPC_ASSERT(s != NULL); - XMLRPC_ASSERT(len >= 0); - - if (!contextP->env.fault_occurred) { - XMLRPC_ASSERT(contextP->currentP != NULL); - - xml_element_append_cdata(&contextP->env, contextP->currentP, s, len); - } -} - - - -static void -createParser(xmlrpc_env * const envP, - xmlrpc_mem_pool * const memPoolP, - ParseContext * const contextP, - XML_Parser * const parserP) { -/*---------------------------------------------------------------------------- - Create an Expat parser to parse our XML. - - Return the parser handle as *parserP. - - Set up *contextP as a context specific to this module for Expat to - associate with the parser. The XML element handlers in this module get a - pointer to *contextP to use for context. - - Use memory pool *memPoolP for certain memory allocations needed to parse - the document. Especially allocations for which we cannot predict a bound - until we see the XML. ------------------------------------------------------------------------------*/ - XML_Parser parser; - - parser = xmlrpc_XML_ParserCreate(NULL); - if (parser == NULL) - xmlrpc_faultf(envP, "Could not create expat parser"); - else { - initParseContext(contextP, memPoolP); - - xmlrpc_XML_SetUserData(parser, contextP); - xmlrpc_XML_SetElementHandler( - parser, - (XML_StartElementHandler) startElement, - (XML_EndElementHandler) endElement); - xmlrpc_XML_SetCharacterDataHandler( - parser, - (XML_CharacterDataHandler) characterData); - } - *parserP = parser; -} - - - -static void -destroyParser(XML_Parser const parser, - ParseContext * const contextP) { - - termParseContext(contextP); - - xmlrpc_XML_ParserFree(parser); -} - - - -void -xml_parse(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - xml_element ** const resultPP) { -/*---------------------------------------------------------------------------- - This is an implementation of the interface declared in xmlparser.h. This - implementation uses Xmlrpc-c's private fork of Expat. ------------------------------------------------------------------------------*/ - /* - This is an Expat driver. - - We set up event-based parser handlers for Expat and set Expat loose - on the XML. Expat walks through the XML, calling our handlers along - the way. Our handlers build up the element description in our - 'context' variable, so that when Expat is finished, our results are - in 'context' and we just have to pluck them out. - - We should allow the user to specify the encoding in 'xmlData', but - we don't. - */ - XML_Parser parser; - ParseContext context; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(xmlData != NULL); - - createParser(envP, memPoolP, &context, &parser); - - if (!envP->fault_occurred) { - bool ok; - - ok = xmlrpc_XML_Parse(parser, xmlData, xmlDataLen, 1); - /* sets 'context', *envP */ - if (!ok) { - /* Expat failed on its own to parse it -- this is not an error - that our handlers detected. - */ - xmlrpc_env_set_fault( - envP, XMLRPC_PARSE_ERROR, - xmlrpc_XML_GetErrorString(parser)); - if (!context.env.fault_occurred) { - /* Have to clean up what our handlers built before Expat - barfed. - */ - if (context.rootP) - xml_element_free(context.rootP); - } - } else { - /* Expat got through the XML OK, but when it called our handlers, - they might have detected a problem. They would have noted - such a problem in *contextP. - */ - if (context.env.fault_occurred) - xmlrpc_env_set_fault_formatted( - envP, context.env.fault_code, - "XML doesn't parse. %s", context.env.fault_string); - else { - XMLRPC_ASSERT(context.rootP != NULL); - XMLRPC_ASSERT(context.currentP == NULL); - - *resultPP = context.rootP; - } - } - destroyParser(parser, &context); - } -} - - -/* 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. */ diff --git a/trunk/src/xmlrpc_libxml2.c b/trunk/src/xmlrpc_libxml2.c deleted file mode 100644 index 207036ffb..000000000 --- a/trunk/src/xmlrpc_libxml2.c +++ /dev/null @@ -1,533 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2002 Ximian, Inc. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -/* There was code here from 2006-2013 that included - instead of when compiling for Windows. It was probably - compiled rarely if ever (this file is an optional part of the build). - In Feburary 2013, a Mingw user found was necessary, - and that makes more sense, so we changed it. -*/ -#include - -#include "mallocvar.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" - -#include "xmlparser.h" - -struct _xml_element { - xml_element * parentP; - const char * name; - xmlrpc_mem_block cdata; /* char */ - xmlrpc_mem_block children; /* xml_element* */ -}; - -#define XMLRPC_ASSERT_ELEM_OK(elem) \ - XMLRPC_ASSERT((elem) != NULL && (elem)->name != XMLRPC_BAD_POINTER) - - - -void -xml_init(xmlrpc_env * const envP) { - - XMLRPC_ASSERT_ENV_OK(envP); - - /* N.B. xmlInitParser() does not stack. Calling it twice is the - same as calling it once. Consequently, the same is true - of xml_init(). - - N.B. xmlInitParser() is necessary for form only, because every - libxml2 subroutine that needs it to be called just calls it itself. - */ - xmlInitParser(); -} - - - -void -xml_term(void) { - - /* N.B xmlCleanupParser() doesn't know how many times you called - xmlInitParser(). Calling it twice is the same as calling it once. - This means you must not call xml_term() while anything else in - the process is still using libxml2. - */ - xmlCleanupParser(); -} - - - -static xml_element * -xmlElementNew(xmlrpc_env * const envP, - const char * const name) { -/*---------------------------------------------------------------------------- - Create a new xml_element. This routine isn't exported, because the - arguments are implementation-dependent. ------------------------------------------------------------------------------*/ - - xml_element * retval; - bool nameIsValid; - bool cdataIsValid; - bool childrenAreValid; - - XMLRPC_ASSERT_ENV_OK(envP); - assert(name != NULL); - - /* Set up our error-handling preconditions. */ - retval = NULL; - nameIsValid = cdataIsValid = childrenAreValid = false; - - MALLOCVAR(retval); - XMLRPC_FAIL_IF_NULL(retval, envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for XML element"); - - retval->parentP = NULL; - - /* Copy over the element name. */ - retval->name = strdup(name); - XMLRPC_FAIL_IF_NULL(retval->name, envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for XML element"); - nameIsValid = true; - - /* Initialize a block to hold our CDATA. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(char, envP, &retval->cdata, 0); - XMLRPC_FAIL_IF_FAULT(envP); - cdataIsValid = true; - - /* Initialize a block to hold our child elements. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(xml_element *, envP, &retval->children, 0); - XMLRPC_FAIL_IF_FAULT(envP); - childrenAreValid = true; - -cleanup: - if (envP->fault_occurred) { - if (retval) { - if (nameIsValid) - xmlrpc_strfree(retval->name); - if (cdataIsValid) - xmlrpc_mem_block_clean(&retval->cdata); - if (childrenAreValid) - xmlrpc_mem_block_clean(&retval->children); - free(retval); - } - retval = NULL; - } - return retval; -} - - - -void -xml_element_free(xml_element * const elemP) { -/*---------------------------------------------------------------------------- - Blow away an existing element & all of its child elements. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * children; - unsigned int size; - unsigned int i; - xml_element ** contents; - - XMLRPC_ASSERT_ELEM_OK(elemP); - - xmlrpc_strfree(elemP->name); - elemP->name = XMLRPC_BAD_POINTER; - xmlrpc_mem_block_clean(&elemP->cdata); - - /* Deallocate all of our children recursively. */ - children = &elemP->children; - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element *, children); - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, children); - for (i = 0; i < size; ++i) - xml_element_free(contents[i]); - - xmlrpc_mem_block_clean(&elemP->children); - - free(elemP); -} - - - -/*========================================================================= -** Miscellaneous Accessors -**========================================================================= -** Return the fields of the xml_element. See the header for more -** documentation on each function works. -*/ - -const char * -xml_element_name(const xml_element * const elemP) { - - XMLRPC_ASSERT_ELEM_OK(elemP); - return elemP->name; -} - -size_t -xml_element_cdata_size(const xml_element * const elemP) { - /* The result of this function is NOT VALID until the end_element handler - has been called! - */ - XMLRPC_ASSERT_ELEM_OK(elemP); - return XMLRPC_TYPED_MEM_BLOCK_SIZE(char, &elemP->cdata) - 1; -} - - - -const char * -xml_element_cdata(const xml_element * const elemP) { - XMLRPC_ASSERT_ELEM_OK(elemP); - return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &elemP->cdata); -} - - - -unsigned int -xml_element_children_size(const xml_element * const elemP) { - XMLRPC_ASSERT_ELEM_OK(elemP); - return XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, &elemP->children); -} - - - -xml_element ** -xml_element_children(const xml_element * const elemP) { - XMLRPC_ASSERT_ELEM_OK(elemP); - return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element *, &elemP->children); -} - - - -/*========================================================================= -** Internal xml_element Utility Functions -**========================================================================= -*/ - -static void -xmlElementAppendCdata(xmlrpc_env * const envP, - xml_element * const elemP, - const char * const cdata, - size_t const size) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_ELEM_OK(elemP); - - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, envP, &elemP->cdata, cdata, size); -} - - - -static void -xmlElementAppendChild(xmlrpc_env * const envP, - xml_element * const elemP, - xml_element * const childP) { - - /* Whether or not this function succeeds, it takes ownership of the 'child' - argument. - WARNING - This is the exact opposite of the usual memory ownership - rules for xmlrpc_value! So please pay attention. - */ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_ELEM_OK(elemP); - XMLRPC_ASSERT_ELEM_OK(childP); - assert(childP->parentP == NULL); - - XMLRPC_TYPED_MEM_BLOCK_APPEND(xml_element *, envP, &elemP->children, - &childP, 1); - if (!envP->fault_occurred) - childP->parentP = elemP; - else - xml_element_free(childP); -} - - - -typedef struct { -/*---------------------------------------------------------------------------- - Our parse context. We pass this around as libxml user data. ------------------------------------------------------------------------------*/ - - xmlrpc_env env; - xml_element * rootP; - xml_element * currentP; -} ParseContext; - - - -/*========================================================================= -** LibXML Event Handler Functions -**========================================================================= -*/ - -static void -startElement_(void * const userData, - const xmlChar * const name, - const xmlChar ** const attrs ATTR_UNUSED) { - - ParseContext * contextP; - xml_element * elemP; - xml_element * newCurrentP; - - assert(userData != NULL && name != NULL); - - /* Get our context and see if an error has already occured. */ - contextP = (ParseContext*) userData; - if (!contextP->env.fault_occurred) { - /* Build a new element. */ - elemP = xmlElementNew(&contextP->env, (char *) name); - XMLRPC_FAIL_IF_FAULT(&contextP->env); - - /* Insert it in the appropriate place. */ - if (!contextP->rootP) { - contextP->rootP = elemP; - contextP->currentP = elemP; - elemP = NULL; - } else { - assert(contextP->currentP != NULL); - - /* (We need to watch our error handling invariants very carefully - ** here. Read the docs for xml_elementAppendChild. */ - newCurrentP = elemP; - xmlElementAppendChild(&contextP->env, contextP->currentP, elemP); - elemP = NULL; - XMLRPC_FAIL_IF_FAULT(&contextP->env); - contextP->currentP = newCurrentP; - } - - cleanup: - if (elemP) - xml_element_free(elemP); - } -} - - - -static void -endElement_(void * const userData, - const xmlChar * const name ATTR_UNUSED) { - - ParseContext * contextP; - - assert(userData != NULL && name != NULL); - - /* Get our context and see if an error has already occured. */ - contextP = (ParseContext*) userData; - if (!contextP->env.fault_occurred) { - assert(xmlrpc_streq((const char *)name, - contextP->currentP->name)); - assert(contextP->currentP->parentP != NULL || - contextP->currentP == contextP->rootP); - - /* Add a trailing '\0' to our cdata. */ - xmlElementAppendCdata(&contextP->env, contextP->currentP, "\0", 1); - if (!contextP->env.fault_occurred) { - /* Pop our "stack" of elements. */ - contextP->currentP = contextP->currentP->parentP; - } - } -} - - - -static void -characterData(void * const userData, - const xmlChar * const s, - int const len) { - - ParseContext * contextP; - - assert(userData != NULL && s != NULL); - - /* Get our context and see if an error has already occured. */ - contextP = (ParseContext*)userData; - if (!contextP->env.fault_occurred) { - assert(contextP->currentP != NULL); - - xmlElementAppendCdata(&contextP->env, - contextP->currentP, - (char *)s, - len); - } -} - - - -/*========================================================================= -** LibXML Driver -**========================================================================= -** XXX - We should allow the user to specify the encoding of our xml_data. -*/ - -static xmlSAXHandler const saxHandler = { - NULL, /* internalSubset */ - NULL, /* isStandalone */ - NULL, /* hasInternalSubset */ - NULL, /* hasExternalSubset */ - NULL, /* resolveEntity */ - NULL, /* getEntity */ - NULL, /* entityDecl */ - NULL, /* notationDecl */ - NULL, /* attributeDecl */ - NULL, /* elementDecl */ - NULL, /* unparsedEntityDecl */ - NULL, /* setDocumentLocator */ - NULL, /* startDocument */ - NULL, /* endDocument */ - startElement_, /* startElement */ - endElement_, /* endElement */ - NULL, /* reference */ - characterData, /* characters */ - NULL, /* ignorableWhitespace */ - NULL, /* processingInstruction */ - NULL, /* comment */ - NULL, /* warning */ - NULL, /* error */ - NULL, /* fatalError */ - NULL, /* getParameterEntity */ - NULL, /* cdataBlock */ - NULL, /* externalSubset */ - 1 /* initialized */ - - /* Following are SAX2 fields. Any ifdef here? */ - - ,NULL, /* _private */ - NULL, /* startElementNs */ - NULL, /* endElementNs */ - NULL /* serror */ -}; - - - -static void -removeDocSizeLimit(xmlParserCtx * const parserP ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - Set up *parserP to accept a document of any size. - - Newer Libxml2 by default fails any attempt to parse a document larger than - 10 MiB, because it wants to avoid running the system out of resources. - This is not an appropriate role for the library, and 10 MiB is a completely - arbitrary number anyway, so we don't use this feature. ------------------------------------------------------------------------------*/ -#if LIBXML_VERSION > 20700 - - xmlCtxtUseOptions(parserP, XML_PARSE_HUGE); - -#else - - /* There's never a size limit */ - -#endif -} - - - -static void -createParser(xmlrpc_env * const envP, - ParseContext * const contextP, - xmlParserCtx ** const parserPP) { -/*---------------------------------------------------------------------------- - Create an appropriate Libxml2 parser for our purpose. ------------------------------------------------------------------------------*/ - xmlParserCtx * parserP; - - parserP = xmlCreatePushParserCtxt((xmlSAXHandler *)&saxHandler, contextP, - NULL, 0, NULL); - - if (!parserP) - xmlrpc_faultf(envP, "Failed to create libxml2 parser."); - else { - removeDocSizeLimit(parserP); - - *parserPP = parserP; - } -} - - - -void -xml_parse(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP ATTR_UNUSED, - xml_element ** const resultPP) { -/*---------------------------------------------------------------------------- - This is an implementation of the interface declared in xmlparser.h. This - implementation uses Libxml2. ------------------------------------------------------------------------------*/ - ParseContext context; - xmlParserCtxt * parserP; - - XMLRPC_ASSERT_ENV_OK(envP); - assert(xmlData != NULL); - - xmlrpc_env_init(&context.env); - context.rootP = NULL; - context.currentP = NULL; - - createParser(envP, &context, &parserP); - - if (!envP->fault_occurred) { - int rc; - - rc = xmlParseChunk(parserP, xmlData, xmlDataLen, 1); - - if (rc != 0) - xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, - "XML parsing failed"); - else { - if (context.env.fault_occurred) { - xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, - context.env.fault_string); - /* This should be done by the parser, but I'm not sure which - callbacks need to do it. - */ - if (context.rootP) - xml_element_free(context.rootP); - } else { - assert(context.rootP != NULL); - assert(context.currentP == NULL); - - *resultPP = context.rootP; - } - } - /* xmlParseChunk() creates a document. You find it with - parserP->myDoc. - */ - if (parserP->myDoc) - xmlFreeDoc(parserP->myDoc); - xmlFreeParserCtxt(parserP); - } - xmlrpc_env_clean(&context.env); -} - - - diff --git a/trunk/src/xmlrpc_parse.c b/trunk/src/xmlrpc_parse.c deleted file mode 100644 index 0d86d72a4..000000000 --- a/trunk/src/xmlrpc_parse.c +++ /dev/null @@ -1,754 +0,0 @@ -/* Copyright information is at end of file. */ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "bool.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/util.h" -#include "xmlparser.h" -#include "parse_value.h" - -#include "xmlrpc_parse.h" - -/* Notes about XML-RPC XML documents: - - Contain CDATA: methodName, i4, int, boolean, string, double, - dateTime.iso8601, base64, name - - We attempt to validate the structure of the XML document carefully. - We also try *very* hard to handle malicious data gracefully, and without - leaking memory. - - The CHECK_NAME and CHECK_CHILD_COUNT macros examine an XML element, and - invoke XMLRPC_FAIL if something looks wrong. -*/ - -static void -setParseFault(xmlrpc_env * const envP, - const char * const format, - ...) { - - va_list args; - va_start(args, format); - xmlrpc_set_fault_formatted_v(envP, XMLRPC_PARSE_ERROR, format, args); - va_end(args); -} - - - -static void -validateName(xmlrpc_env * const envP, - const xml_element * const elemP, - const char * const name) { - - if (!xmlrpc_streq(name, xml_element_name(elemP))) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Expected element of type <%s>, found <%s>", - name, xml_element_name(elemP)); -} - - - -static void -validateChildCount(xmlrpc_env * const envP, - const xml_element * const elemP, - unsigned int const requiredCount) { - - if (xml_element_children_size(elemP) != requiredCount) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Expected <%s> to have %u children, found %u", - xml_element_name(elemP), requiredCount, - (unsigned)xml_element_children_size(elemP)); -} - - - -static xml_element * -getChildByName (xmlrpc_env * const envP, - xml_element * const parentP, - const char * const name) { - - size_t const childCount = xml_element_children_size(parentP); - xml_element ** const childrenP = xml_element_children(parentP); - - unsigned int i; - - for (i = 0; i < childCount; ++i) { - if (xmlrpc_streq(xml_element_name(childrenP[i]), name)) - return childrenP[i]; - } - - setParseFault(envP, "Expected <%s> to have child <%s>", - xml_element_name(parentP), name); - return NULL; -} - - - -static xmlrpc_value * -convertParams(xmlrpc_env * const envP, - const xml_element * const elemP) { -/*---------------------------------------------------------------------------- - Convert an XML element representing a list of parameters (i.e. a - element) to an xmlrpc_value of type array. Note that an xmlrpc_value is - normally represented in XML by a element, not a element. - We use type xmlrpc_value to represent the parameter list just for - convenience. ------------------------------------------------------------------------------*/ - xmlrpc_value * arrayP; - xmlrpc_value * itemP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(elemP != NULL); - - /* Allocate an array to hold our parameters. */ - arrayP = xmlrpc_array_new(envP); - if (!envP->fault_occurred) { - /* We're responsible for checking our own element name. */ - validateName(envP, elemP, "params"); - - if (!envP->fault_occurred) { - /* Iterate over our children. */ - unsigned int const size = xml_element_children_size(elemP); - xml_element ** const paramPList = xml_element_children(elemP); - - unsigned int i; - - for (i = 0; i < size; ++i) { - xml_element * const paramP = paramPList[i]; - unsigned int const maxNest = (unsigned int) - xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); - - validateName(envP, paramP, "param"); - if (!envP->fault_occurred) { - validateChildCount(envP, paramP, 1); - if (!envP->fault_occurred) { - xml_element * const valueEltP = - xml_element_children(paramP)[0]; - - validateName(envP, valueEltP, "value"); - - if (!envP->fault_occurred) { - xmlrpc_parseValue(envP, maxNest, valueEltP, - &itemP); - if (!envP->fault_occurred) { - xmlrpc_array_append_item(envP, arrayP, itemP); - xmlrpc_DECREF(itemP); - } - } - } - } - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(arrayP); - } - return arrayP; -} - - - -static void -parseCallXml(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - xml_element ** const callElemPP) { -/*---------------------------------------------------------------------------- - Parse the XML of an XML-RPC call. ------------------------------------------------------------------------------*/ - xml_element * callElemP; - xmlrpc_env env; - - xmlrpc_env_init(&env); - xml_parse(&env, xmlData, xmlDataLen, memPoolP, &callElemP); - if (env.fault_occurred) - xmlrpc_env_set_fault_formatted( - envP, env.fault_code, "Call is not valid XML. %s", - env.fault_string); - else { - if (!xmlrpc_streq(xml_element_name(callElemP), "methodCall")) - setParseFault(envP, - "XML-RPC call should be a element. " - "Instead, we have a <%s> element.", - xml_element_name(callElemP)); - - if (envP->fault_occurred) - xml_element_free(callElemP); - } - *callElemPP = callElemP; - - xmlrpc_env_clean(&env); -} - - - -static void -parseMethodNameElement(xmlrpc_env * const envP, - xml_element * const nameElemP, - const char ** const methodNameP) { - - XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(nameElemP), "methodName")); - - if (xml_element_children_size(nameElemP) > 0) - setParseFault(envP, "A element should not have " - "children. This one has %u of them.", - xml_element_children_size(nameElemP)); - else { - const char * const cdata = xml_element_cdata(nameElemP); - - xmlrpc_validate_utf8(envP, cdata, strlen(cdata)); - - if (!envP->fault_occurred) { - *methodNameP = strdup(cdata); - if (*methodNameP == NULL) - xmlrpc_faultf(envP, - "Could not allocate memory for method name"); - } - } -} - - - -static void -parseCallChildren(xmlrpc_env * const envP, - xml_element * const callElemP, - const char ** const methodNameP, - xmlrpc_value ** const paramArrayPP ) { -/*---------------------------------------------------------------------------- - Parse the children of a XML element *callElemP. They should - be and . ------------------------------------------------------------------------------*/ - size_t const callChildCount = xml_element_children_size(callElemP); - - xml_element * nameElemP; - - XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(callElemP), "methodCall")); - - nameElemP = getChildByName(envP, callElemP, "methodName"); - - if (!envP->fault_occurred) { - parseMethodNameElement(envP, nameElemP, methodNameP); - - if (!envP->fault_occurred) { - /* Convert our parameters. */ - if (callChildCount > 1) { - xml_element * paramsElemP; - - paramsElemP = getChildByName(envP, callElemP, "params"); - - if (!envP->fault_occurred) - *paramArrayPP = convertParams(envP, paramsElemP); - } else { - /* Workaround for Ruby XML-RPC and old versions of - xmlrpc-epi. Future improvement: Instead of looking - at child count, we should just check for existence - of . - */ - *paramArrayPP = xmlrpc_array_new(envP); - } - if (!envP->fault_occurred) { - if (callChildCount > 2) - setParseFault(envP, " has extraneous " - "children, other than and " - ". Total child count = %u", - callChildCount); - - if (envP->fault_occurred) - xmlrpc_DECREF(*paramArrayPP); - } - if (envP->fault_occurred) - xmlrpc_strfree(*methodNameP); - } - } -} - - - -void -xmlrpc_parse_call2(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - const char ** const methodNameP, - xmlrpc_value ** const paramArrayPP) { -/*---------------------------------------------------------------------------- - Given some XML text, attempt to parse it as an XML-RPC call. - Return as *methodNameP the name of the method identified in the call - and as *paramArrayPP the parameter list as an XML-RPC array. - Caller must free() and xmlrpc_DECREF() these, respectively). ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(xmlData != NULL); - XMLRPC_ASSERT(methodNameP != NULL && paramArrayPP != NULL); - - /* SECURITY: Last-ditch attempt to make sure our content length is - legal. XXX - This check occurs too late to prevent an attacker - from creating an enormous memory block, so you should try to - enforce it *before* reading any data off the network. - */ - if (xmlDataLen > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_LIMIT_EXCEEDED_ERROR, - "XML-RPC request too large. Max allowed is %u bytes", - (unsigned)xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)); - else { - xml_element * callElemP; - parseCallXml(envP, xmlData, xmlDataLen, memPoolP, &callElemP); - if (!envP->fault_occurred) { - parseCallChildren(envP, callElemP, methodNameP, paramArrayPP); - - xml_element_free(callElemP); - } - } - if (envP->fault_occurred) { - /* Should not be necessary, but for backward compatibility: */ - *methodNameP = NULL; - *paramArrayPP = NULL; - } -} - - - -void -xmlrpc_parse_call(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - const char ** const methodNameP, - xmlrpc_value ** const paramArrayPP) { - - xmlrpc_parse_call2(envP, xmlData, xmlDataLen, NULL, - methodNameP, paramArrayPP); -} - - - -static void -interpretFaultCode(xmlrpc_env * const envP, - xmlrpc_value * const faultCodeVP, - int * const faultCodeP) { - - xmlrpc_env fcEnv; - xmlrpc_env_init(&fcEnv); - - xmlrpc_read_int(&fcEnv, faultCodeVP, faultCodeP); - if (fcEnv.fault_occurred) - xmlrpc_faultf(envP, "Invalid value for 'faultCode' member. %s", - fcEnv.fault_string); - - xmlrpc_env_clean(&fcEnv); -} - - - -static void -interpretFaultString(xmlrpc_env * const envP, - xmlrpc_value * const faultStringVP, - const char ** const faultStringP) { - - xmlrpc_env fsEnv; - xmlrpc_env_init(&fsEnv); - - xmlrpc_read_string(&fsEnv, faultStringVP, faultStringP); - - if (fsEnv.fault_occurred) - xmlrpc_faultf(envP, "Invalid value for 'faultString' member. %s", - fsEnv.fault_string); - - xmlrpc_env_clean(&fsEnv); -} - - - -static void -interpretFaultValue(xmlrpc_env * const envP, - xmlrpc_value * const faultVP, - int * const faultCodeP, - const char ** const faultStringP) { - - if (faultVP->_type != XMLRPC_TYPE_STRUCT) - setParseFault(envP, - " element of response is not " - "of structure type"); - else { - xmlrpc_value * faultCodeVP; - xmlrpc_env fvEnv; - - xmlrpc_env_init(&fvEnv); - - xmlrpc_struct_read_value(&fvEnv, faultVP, "faultCode", &faultCodeVP); - if (!fvEnv.fault_occurred) { - interpretFaultCode(&fvEnv, faultCodeVP, faultCodeP); - - if (!fvEnv.fault_occurred) { - xmlrpc_value * faultStringVP; - - xmlrpc_struct_read_value(&fvEnv, faultVP, "faultString", - &faultStringVP); - if (!fvEnv.fault_occurred) { - interpretFaultString(&fvEnv, faultStringVP, faultStringP); - - xmlrpc_DECREF(faultStringVP); - } - } - xmlrpc_DECREF(faultCodeVP); - } - if (fvEnv.fault_occurred) - setParseFault(envP, "Invalid struct for value. %s", - fvEnv.fault_string); - - xmlrpc_env_clean(&fvEnv); - } -} - - - -static void -parseFaultElement(xmlrpc_env * const envP, - const xml_element * const faultElement, - int * const faultCodeP, - const char ** const faultStringP) { - - unsigned int const maxRecursion = (unsigned int) - xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); - - XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(faultElement), "fault")); - - if (xml_element_children_size(faultElement) != 1) - setParseFault(envP, " element should have 1 child, " - "but it has %u.", - xml_element_children_size(faultElement)); - else { - xml_element * const faultValueP = - xml_element_children(faultElement)[0]; - const char * const elemName = xml_element_name(faultValueP); - - if (!xmlrpc_streq(elemName, "value")) - setParseFault(envP, - " contains a <%s> element. " - "Only makes sense.", - elemName); - else { - xmlrpc_value * faultVP; - - xmlrpc_parseValue(envP, maxRecursion, faultValueP, &faultVP); - - if (!envP->fault_occurred) { - interpretFaultValue(envP, faultVP, faultCodeP, faultStringP); - - xmlrpc_DECREF(faultVP); - } - } - } -} - - - -static void -parseParamsElement(xmlrpc_env * const envP, - const xml_element * const paramsElementP, - xmlrpc_value ** const resultPP) { - - xmlrpc_value * paramsVP; - xmlrpc_env env; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(paramsElementP), "params")); - - paramsVP = convertParams(envP, paramsElementP); - - if (!envP->fault_occurred) { - int arraySize; - xmlrpc_env sizeEnv; - - XMLRPC_ASSERT_ARRAY_OK(paramsVP); - - xmlrpc_env_init(&sizeEnv); - - arraySize = xmlrpc_array_size(&sizeEnv, paramsVP); - /* Since it's a valid array, as asserted above, can't fail */ - XMLRPC_ASSERT(!sizeEnv.fault_occurred); - - if (arraySize != 1) - setParseFault(envP, "Contains %d items. It should have 1.", - arraySize); - else { - xmlrpc_array_read_item(envP, paramsVP, 0, resultPP); - } - xmlrpc_DECREF(paramsVP); - xmlrpc_env_clean(&sizeEnv); - } - if (env.fault_occurred) - xmlrpc_env_set_fault_formatted( - envP, env.fault_code, - "Invalid element. %s", env.fault_string); - - xmlrpc_env_clean(&env); -} - - - -static void -parseMethodResponseElt(xmlrpc_env * const envP, - const xml_element * const methodResponseEltP, - xmlrpc_value ** const resultPP, - int * const faultCodeP, - const char ** const faultStringP) { - - XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(methodResponseEltP), - "methodResponse")); - - if (xml_element_children_size(methodResponseEltP) == 1) { - xml_element * const child = - xml_element_children(methodResponseEltP)[0]; - - if (xmlrpc_streq(xml_element_name(child), "params")) { - /* It's a successful response */ - parseParamsElement(envP, child, resultPP); - *faultStringP = NULL; - } else if (xmlrpc_streq(xml_element_name(child), "fault")) { - /* It's a failure response */ - parseFaultElement(envP, child, faultCodeP, faultStringP); - } else - setParseFault(envP, - " must contain or , " - "but contains <%s>.", xml_element_name(child)); - } else - setParseFault(envP, - " has %u children, should have 1.", - xml_element_children_size(methodResponseEltP)); -} - - - -static void -parseResponseXml(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - xml_element ** const responseEltPP) { - - xmlrpc_env env; - xmlrpc_env_init(&env); - - xml_parse(&env, xmlData, xmlDataLen, memPoolP, responseEltPP); - - if (env.fault_occurred) - setParseFault(envP, "Not valid XML. %s", env.fault_string); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_parse_response3(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - xmlrpc_value ** const resultPP, - int * const faultCodeP, - const char ** const faultStringP) { -/*---------------------------------------------------------------------------- - Given some XML text, attempt to parse it as an XML-RPC response. - - If the response is a regular, valid response, return a new reference - to the appropriate value as *resultP and return NULL as - *faultStringP and nothing as *faultCodeP. - - If the response is valid, but indicates a failure of the RPC, return the - fault string in newly malloc'ed space as *faultStringP and the fault - code as *faultCodeP and nothing as *resultP. - - If the XML text is not a valid response or something prevents us from - parsing it, return a description of the error as *envP and nothing else. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(xmlData != NULL); - - /* SECURITY: Last-ditch attempt to make sure our content length is legal. - ** XXX - This check occurs too late to prevent an attacker from creating - ** an enormous memory block, so you should try to enforce it - ** *before* reading any data off the network. */ - if (xmlDataLen > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_LIMIT_EXCEEDED_ERROR, - "XML-RPC response too large. Our limit is %u characters. " - "We got %u characters", - (unsigned)xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID), - (unsigned)xmlDataLen); - else { - xml_element * responseEltP; - parseResponseXml(envP, xmlData, xmlDataLen, memPoolP, &responseEltP); - - if (!envP->fault_occurred) { - if (xmlrpc_streq(xml_element_name(responseEltP), - "methodResponse")) { - parseMethodResponseElt(envP, responseEltP, - resultPP, faultCodeP, faultStringP); - } else - setParseFault(envP, "XML-RPC response must consist of a " - " element. " - "This has a <%s> instead.", - xml_element_name(responseEltP)); - - xml_element_free(responseEltP); - } - } -} - - - -void -xmlrpc_parse_response2(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_value ** const resultPP, - int * const faultCodeP, - const char ** const faultStringP) { -/*---------------------------------------------------------------------------- - This exists for backward compatibility. It is like - xmlrpc_parse_response3(), except that it uses the unlimited system memory - pool. ------------------------------------------------------------------------------*/ - xmlrpc_parse_response3(envP, xmlData, xmlDataLen, NULL, - resultPP, faultCodeP, faultStringP); -} - - - -xmlrpc_value * -xmlrpc_parse_response(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen) { -/*---------------------------------------------------------------------------- - This exists for backward compatibility. It is like - xmlrpc_parse_response2(), except that it merges the concepts of a - failed RPC and an error in executing the RPC. ------------------------------------------------------------------------------*/ - xmlrpc_value * retval; - xmlrpc_value * result; - const char * faultString; - int faultCode; - - xmlrpc_parse_response3(envP, xmlData, xmlDataLen, NULL, - &result, &faultCode, &faultString); - - if (envP->fault_occurred) - retval = NULL; - else { - if (faultString) { - xmlrpc_env_set_fault(envP, faultCode, faultString); - xmlrpc_strfree(faultString); - retval = NULL; - } else - retval = result; /* transfer reference */ - } - return retval; -} - - - -void -xmlrpc_parse_value_xml2(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Compute the xmlrpc_value represented by the XML document 'xmlData' (of - length 'xmlDataLen' characters), which must consist of a single - element. Return that xmlrpc_value. - - We call convert_array() and convert_struct(), which may ultimately - call us recursively. Don't recurse any more than 'maxRecursion' - times. - - This isn't generally useful in XML-RPC programs, because such programs - parse a whole XML-RPC call or response document, and never see the XML text - of just a element. But a program may do some weird form of XML-RPC - processing or just borrow Xmlrpc-c's value serialization facilities for - something unrelated to XML-RPC. In any case, it makes sense to have an - inverse of xmlrpc_serialize_value2(), which generates XML text from an - xmlrpc_value. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - - xml_element * valueEltP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(xmlData != NULL); - - xmlrpc_env_init(&env); - - xml_parse(&env, xmlData, xmlDataLen, memPoolP, &valueEltP); - - if (env.fault_occurred) { - setParseFault(envP, "Not valid XML. %s", env.fault_string); - } else { - if (xmlrpc_streq(xml_element_name(valueEltP), "value")) { - unsigned int const maxRecursion = (unsigned int) - xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); - xmlrpc_parseValue(envP, maxRecursion, valueEltP, valuePP); - } else - setParseFault(envP, "XML-RPC value XML document must consist of " - "a element. This has a <%s> instead.", - xml_element_name(valueEltP)); - xml_element_free(valueEltP); - } - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_parse_value_xml(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_value ** const valuePP) { - - xmlrpc_parse_value_xml2(envP, xmlData, xmlDataLen, NULL, valuePP); -} - - - -/* 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. */ diff --git a/trunk/src/xmlrpc_parse.h b/trunk/src/xmlrpc_parse.h deleted file mode 100644 index 79bf1afc0..000000000 --- a/trunk/src/xmlrpc_parse.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef XMLRPC_PARSE_H_INCLUDED -#define XMLRPC_PARSE_H_INCLUDED -/*============================================================================= - xmlrpc_parse.h -=============================================================================== - This declares the interface to the _internal_ XML-RPC XML parsing functions - in xmlrpc_parse.c. - - There are also _external_ functions in xmlrpc_parse.c, and those are - declared in an external interface header file. - - xmlrpc_parse.c is split that way because some functions use memory pools, - which is an internal concept we don't feel like making external right now. -=============================================================================*/ - -#include "xmlrpc-c/util_int.h" - -void -xmlrpc_parse_call2(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - const char ** const methodNameP, - xmlrpc_value ** const paramArrayPP); - -void -xmlrpc_parse_response3(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - xmlrpc_value ** const resultPP, - int * const faultCodeP, - const char ** const faultStringP); - -void -xmlrpc_parse_value_xml2(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlDataLen, - xmlrpc_mem_pool * const memPoolP, - xmlrpc_value ** const valuePP); - -#endif diff --git a/trunk/src/xmlrpc_serialize.c b/trunk/src/xmlrpc_serialize.c deleted file mode 100644 index f1679a07b..000000000 --- a/trunk/src/xmlrpc_serialize.c +++ /dev/null @@ -1,780 +0,0 @@ -/* Copyright information is at end of file */ - -/* Implementation note: - - The printf format specifiers we use appear to be entirely standard, - except for the "long long" one, which is %I64 on Windows and %lld - everywhere else. We could use the C99 standard macro PRId64 for that, - but on at least one 64-bit-long GNU compiler, PRId64 is "ld", which is - considered to be incompatible with long long. So we have XMLRPC_PRId64. -*/ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "int.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "double.h" - -#define CRLF "\015\012" -#define XML_PROLOGUE ""CRLF -#define APACHE_URL "http://ws.apache.org/xmlrpc/namespaces/extensions" -#define XMLNS_APACHE "xmlns:ex=\"" APACHE_URL "\"" - - -static void -addString(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - const char * const string) { - - XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, string, strlen(string)); -} - - - -static void -formatOut(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - const char * const formatString, - ...) { -/*---------------------------------------------------------------------------- - A lightweight print routine for use with various serialization - functions. - - Use this routine only for printing small objects -- it uses a - fixed-size internal buffer and returns an error on overflow. In - particular, do NOT use this routine to print XML-RPC string values! ------------------------------------------------------------------------------*/ - va_list args; - char buffer[128]; - int rc; - - XMLRPC_ASSERT_ENV_OK(envP); - - va_start(args, formatString); - - rc = XMLRPC_VSNPRINTF(buffer, sizeof(buffer), formatString, args); - - /* Old vsnprintf() (and Windows) fails with return value -1 if the full - string doesn't fit in the buffer. New vsnprintf() puts whatever will - fit in the buffer, and returns the length of the full string - regardless. For us, this truncation is a failure. - */ - - if (rc < 0) - xmlrpc_faultf(envP, "formatOut() overflowed internal buffer"); - else { - unsigned int const formattedLen = rc; - - if (formattedLen + 1 >= (sizeof(buffer))) - xmlrpc_faultf(envP, "formatOut() overflowed internal buffer"); - else - XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, buffer, formattedLen); - } - va_end(args); -} - - - -static void -assertValidUtf8(const char * const str ATTR_UNUSED, - size_t const len ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - Assert that the string 'str' of length 'len' is valid UTF-8. ------------------------------------------------------------------------------*/ -#if !defined NDEBUG - /* Check the assertion; if it's false, issue a message to - Standard Error, but otherwise ignore it. - */ - xmlrpc_env env; - - xmlrpc_env_init(&env); - xmlrpc_validate_utf8(&env, str, len); - if (env.fault_occurred) - fprintf(stderr, "*** xmlrpc-c WARNING ***: %s (%s)\n", - "Xmlrpc-c sending corrupted UTF-8 data to network", - env.fault_string); - xmlrpc_env_clean(&env); -#endif -} - - - -static size_t -escapedSize(const char * const chars, - size_t const len) { - - size_t size; - size_t i; - - size = 0; - for (i = 0; i < len; ++i) { - if (chars[i] == '<') - size += 4; /* < */ - else if (chars[i] == '>') - size += 4; /* > */ - else if (chars[i] == '&') - size += 5; /* & */ - else if (chars[i] == '\r') - size += 6; /* */ - else - size += 1; - } - return size; -} - - - -static void -escapeForXml(xmlrpc_env * const envP, - const char * const chars, - size_t const len, - xmlrpc_mem_block ** const outputPP) { -/*---------------------------------------------------------------------------- - Escape & and < in a UTF-8 string so as to make it suitable for the - content of an XML element. I.e. turn them into entity references - & and <. - - Also change > to >, even though not required for XML, for - symmetry. - - < etc. are known in XML as "entity references." - - Also Escape CR as . While raw CR _is_ allowed in the content - of an XML element, it has a special meaning -- it means line ending. - Our input uses LF for for line endings. Since it also means line ending - in XML, we just pass it through to our output like it were a regular - character. - - is known in XML as a "character reference." - - We assume chars[] is is ASCII. That isn't right -- we should - handle all valid UTF-8. Someday, we must do something more complex - and copy over multibyte characters verbatim. (The code here could - erroneously find that e.g. the 2nd byte of a UTF-8 character is a - CR). ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * outputP; - size_t outputSize; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(chars != NULL); - - assertValidUtf8(chars, len); - - /* Note that in UTF-8, any byte that has high bit of zero is a - character all by itself (every byte of a multi-byte UTF-8 character - has the high bit set). Also, the Unicode code points < 128 are - identical to the ASCII ones. - */ - - outputSize = escapedSize(chars, len); - - outputP = XMLRPC_MEMBLOCK_NEW(char, envP, outputSize); - if (!envP->fault_occurred) { - char * p; - size_t i; - p = XMLRPC_MEMBLOCK_CONTENTS(char, outputP); /* Start at beginning */ - - for (i = 0; i < len; i++) { - if (chars[i] == '<') { - memcpy(p, "<", 4); - p += 4; - } else if (chars[i] == '>') { - memcpy(p, ">", 4); - p += 4; - } else if (chars[i] == '&') { - memcpy(p, "&", 5); - p += 5; - } else if (chars[i] == '\r') { - memcpy(p, " ", 6); - p += 6; - } else { - /* Either a plain character or a LF line delimiter */ - *p = chars[i]; - p += 1; - } - } - *outputPP = outputP; - assert(p == XMLRPC_MEMBLOCK_CONTENTS(char, outputP) + outputSize); - - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, outputP); - } -} - - - -static void -serializeUtf8MemBlock(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_mem_block * const inputP) { -/*---------------------------------------------------------------------------- - Append the characters in *inputP to the XML stream in *outputP. - - *inputP contains Unicode characters in UTF-8. - - We assume *inputP ends with a NUL character that marks end of - string, and we ignore that. - - To the extent that *inputP contains code points that do not represent an - XML character (for example, ASCII control characters), we generate a - non-XML stream. But it is important for us to do that, because the - unfortunate way in which Xmlrpc-c defines its string type means Caller - is actually supposed to generate non-XML output sometimes. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * escapedP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(outputP != NULL); - XMLRPC_ASSERT(inputP != NULL); - - escapeForXml(envP, - XMLRPC_MEMBLOCK_CONTENTS(const char, inputP), - XMLRPC_MEMBLOCK_SIZE(const char, inputP) - 1, - /* -1 is for the terminating NUL */ - &escapedP); - if (!envP->fault_occurred) { - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(const char, escapedP); - size_t const size = XMLRPC_MEMBLOCK_SIZE(char, escapedP); - - XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, contents, size); - - XMLRPC_MEMBLOCK_FREE(const char, escapedP); - } -} - - - -static void -xmlrpc_serialize_base64_data(xmlrpc_env * const envP, - xmlrpc_mem_block * const output, - unsigned char * const data, - size_t const len) { -/*---------------------------------------------------------------------------- - Encode the 'len' bytes at 'data' in base64 ASCII and append the result to - 'output'. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * encoded; - - encoded = xmlrpc_base64_encode(envP, data, len); - if (!envP->fault_occurred) { - unsigned char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(unsigned char, encoded); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(unsigned char, encoded); - - XMLRPC_MEMBLOCK_APPEND(char, envP, output, contents, size); - - XMLRPC_MEMBLOCK_FREE(char, encoded); - } -} - - - -static void -serializeDatetime(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP) { -/*---------------------------------------------------------------------------- - Add to *outputP the content of a element to represent - the datetime value *valueP. I.e. - " ... ". ------------------------------------------------------------------------------*/ - - addString(envP, outputP, ""); - if (!envP->fault_occurred) { - char dtString[64]; - - XMLRPC_SNPRINTF(dtString, sizeof(dtString), - "%u%02u%02uT%02u:%02u:%02u", - valueP->_value.dt.Y, - valueP->_value.dt.M, - valueP->_value.dt.D, - valueP->_value.dt.h, - valueP->_value.dt.m, - valueP->_value.dt.s); - - if (valueP->_value.dt.u != 0) { - char usecString[64]; - assert(valueP->_value.dt.u < 1000000); - XMLRPC_SNPRINTF(usecString, sizeof(usecString), ".%06u", - valueP->_value.dt.u); - STRSCAT(dtString, usecString); - } - addString(envP, outputP, dtString); - - if (!envP->fault_occurred) { - addString(envP, outputP, ""); - } - } -} - - - -static void -serializeStructMember(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const memberKeyP, - xmlrpc_value * const memberValueP, - xmlrpc_dialect const dialect) { - - addString(envP, outputP, ""); - - if (!envP->fault_occurred) { - serializeUtf8MemBlock(envP, outputP, memberKeyP->blockP); - - if (!envP->fault_occurred) { - addString(envP, outputP, ""CRLF); - - if (!envP->fault_occurred) { - xmlrpc_serialize_value2(envP, outputP, memberValueP, dialect); - - if (!envP->fault_occurred) { - addString(envP, outputP, ""CRLF); - } - } - } - } -} - - - -static void -serializeStruct(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const structP, - xmlrpc_dialect const dialect) { -/*---------------------------------------------------------------------------- - Add to *outputP the content of a element to represent - the structure value *valueP. I.e. " ... ". ------------------------------------------------------------------------------*/ - addString(envP, outputP, ""CRLF); - if (!envP->fault_occurred) { - unsigned int const size = xmlrpc_struct_size(envP, structP); - if (!envP->fault_occurred) { - unsigned int i; - for (i = 0; i < size && !envP->fault_occurred; ++i) { - xmlrpc_value * memberKeyP; - xmlrpc_value * memberValueP; - - xmlrpc_struct_get_key_and_value(envP, structP, i, - &memberKeyP, &memberValueP); - if (!envP->fault_occurred) { - serializeStructMember(envP, outputP, - memberKeyP, memberValueP, dialect); - } - } - if (!envP->fault_occurred) - addString(envP, outputP, ""); - } - } -} - - - -static void -serializeArray(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP, - xmlrpc_dialect const dialect) { -/*---------------------------------------------------------------------------- - Add to *outputP the content of a element to represent - the array value *valueP. I.e. " ... ". ------------------------------------------------------------------------------*/ - int const size = xmlrpc_array_size(envP, valueP); - - if (!envP->fault_occurred) { - addString(envP, outputP, ""CRLF); - if (!envP->fault_occurred) { - int i; - /* Serialize each item. */ - for (i = 0; i < size && !envP->fault_occurred; ++i) { - xmlrpc_value * const itemP = - xmlrpc_array_get_item(envP, valueP, i); - if (!envP->fault_occurred) { - xmlrpc_serialize_value2(envP, outputP, itemP, dialect); - if (!envP->fault_occurred) - addString(envP, outputP, CRLF); - } - } - } - } - if (!envP->fault_occurred) - addString(envP, outputP, ""); -} - - - -static void -formatValueContent(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP, - xmlrpc_dialect const dialect) { -/*---------------------------------------------------------------------------- - Add to *outputP the content of a element to represent - value *valueP. E.g. "42" ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - - switch (valueP->_type) { - case XMLRPC_TYPE_INT: - formatOut(envP, outputP, "%d", valueP->_value.i); - break; - - case XMLRPC_TYPE_I8: { - const char * const elemName = - dialect == xmlrpc_dialect_apache ? "ex:i8" : "i8"; - formatOut(envP, outputP, "<%s>%" PRId64 "", - elemName, valueP->_value.i8, elemName); - } break; - - case XMLRPC_TYPE_BOOL: - formatOut(envP, outputP, "%s", - valueP->_value.b ? "1" : "0"); - break; - - case XMLRPC_TYPE_DOUBLE: { - const char * serializedValue; - xmlrpc_formatFloat(envP, valueP->_value.d, &serializedValue); - if (!envP->fault_occurred) { - addString(envP, outputP, ""); - if (!envP->fault_occurred) { - addString(envP, outputP, serializedValue); - if (!envP->fault_occurred) - addString(envP, outputP, ""); - } - xmlrpc_strfree(serializedValue); - } - } break; - - case XMLRPC_TYPE_DATETIME: - serializeDatetime(envP, outputP, valueP); - break; - - case XMLRPC_TYPE_STRING: - addString(envP, outputP, ""); - if (!envP->fault_occurred) { - serializeUtf8MemBlock(envP, outputP, valueP->blockP); - if (!envP->fault_occurred) - addString(envP, outputP, ""); - } - break; - - case XMLRPC_TYPE_BASE64: { - unsigned char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(unsigned char, valueP->blockP); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(unsigned char, valueP->blockP); - addString(envP, outputP, ""CRLF); - if (!envP->fault_occurred) { - xmlrpc_serialize_base64_data(envP, outputP, contents, size); - if (!envP->fault_occurred) - addString(envP, outputP, ""); - } - } break; - - case XMLRPC_TYPE_ARRAY: - serializeArray(envP, outputP, valueP, dialect); - break; - - case XMLRPC_TYPE_STRUCT: - serializeStruct(envP, outputP, valueP, dialect); - break; - - case XMLRPC_TYPE_C_PTR: - xmlrpc_faultf(envP, "Tried to serialize a C pointer value."); - break; - - case XMLRPC_TYPE_NIL: { - const char * const elemName = - dialect == xmlrpc_dialect_apache ? "ex:nil" : "nil"; - formatOut(envP, outputP, "<%s/>", elemName); - } break; - - case XMLRPC_TYPE_DEAD: - xmlrpc_faultf(envP, "Tried to serialize a dead value."); - break; - - default: - xmlrpc_faultf(envP, "Invalid xmlrpc_value type: %d", valueP->_type); - } -} - - - -void -xmlrpc_serialize_value2(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP, - xmlrpc_dialect const dialect) { -/*---------------------------------------------------------------------------- - Generate the XML to represent XML-RPC value 'valueP' in XML-RPC. - - Add it to *outputP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(outputP != NULL); - XMLRPC_ASSERT_VALUE_OK(valueP); - - addString(envP, outputP, ""); - - if (!envP->fault_occurred) { - formatValueContent(envP, outputP, valueP, dialect); - - if (!envP->fault_occurred) - addString(envP, outputP, ""); - } -} - - - -void -xmlrpc_serialize_value(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP) { - - xmlrpc_serialize_value2(envP, outputP, valueP, xmlrpc_dialect_i8); -} - - - -void -xmlrpc_serialize_params2(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const paramArrayP, - xmlrpc_dialect const dialect) { -/*---------------------------------------------------------------------------- - Serialize the parameter list of an XML-RPC call. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(outputP != NULL); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - - addString(envP, outputP, ""CRLF); - if (!envP->fault_occurred) { - /* Serialize each parameter. */ - int const paramCount = xmlrpc_array_size(envP, paramArrayP); - if (!envP->fault_occurred) { - int paramSeq; - for (paramSeq = 0; - paramSeq < paramCount && !envP->fault_occurred; - ++paramSeq) { - - addString(envP, outputP, ""); - if (!envP->fault_occurred) { - xmlrpc_value * const itemP = - xmlrpc_array_get_item(envP, paramArrayP, paramSeq); - if (!envP->fault_occurred) { - xmlrpc_serialize_value2(envP, outputP, itemP, dialect); - if (!envP->fault_occurred) - addString(envP, outputP, ""CRLF); - } - } - } - } - } - - if (!envP->fault_occurred) - addString(envP, outputP, ""CRLF); -} - - - -void -xmlrpc_serialize_params(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const paramArrayP) { -/*---------------------------------------------------------------------------- - Serialize the parameter list of an XML-RPC call in the original - "i8" dialect. ------------------------------------------------------------------------------*/ - xmlrpc_serialize_params2(envP, outputP, paramArrayP, xmlrpc_dialect_i8); -} - - - -/*========================================================================= -** xmlrpc_serialize_call -**========================================================================= -** Serialize an XML-RPC call. -*/ - -void -xmlrpc_serialize_call2(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_dialect const dialect) { -/*---------------------------------------------------------------------------- - Serialize an XML-RPC call of method named 'methodName' with parameter - list *paramArrayP. Use XML-RPC dialect 'dialect'. - - Append the call XML to *outputP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(outputP != NULL); - XMLRPC_ASSERT(methodName != NULL); - XMLRPC_ASSERT_VALUE_OK(paramArrayP); - - addString(envP, outputP, XML_PROLOGUE); - if (!envP->fault_occurred) { - const char * const xmlns = - dialect == xmlrpc_dialect_apache ? " " XMLNS_APACHE : ""; - formatOut(envP, outputP, ""CRLF"", xmlns); - if (!envP->fault_occurred) { - xmlrpc_mem_block * encodedP; - escapeForXml(envP, methodName, strlen(methodName), &encodedP); - if (!envP->fault_occurred) { - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, encodedP); - size_t const size = XMLRPC_MEMBLOCK_SIZE(char, encodedP); - XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, contents, size); - if (!envP->fault_occurred) { - addString(envP, outputP, ""CRLF); - if (!envP->fault_occurred) { - xmlrpc_serialize_params2(envP, outputP, paramArrayP, - dialect); - if (!envP->fault_occurred) - addString(envP, outputP, ""CRLF); - } - } - XMLRPC_MEMBLOCK_FREE(char, encodedP); - } - } - } -} - - - -void -xmlrpc_serialize_call(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - const char * const methodName, - xmlrpc_value * const paramArrayP) { - - xmlrpc_serialize_call2(envP, outputP, methodName, paramArrayP, - xmlrpc_dialect_i8); -} - - - -void -xmlrpc_serialize_response2(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP, - xmlrpc_dialect const dialect) { -/*---------------------------------------------------------------------------- - Serialize a result response to an XML-RPC call. - - The result is 'valueP'. - - Add the response XML to *outputP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(outputP != NULL); - XMLRPC_ASSERT_VALUE_OK(valueP); - - addString(envP, outputP, XML_PROLOGUE); - if (!envP->fault_occurred) { - const char * const xmlns = - dialect == xmlrpc_dialect_apache ? " " XMLNS_APACHE : ""; - formatOut(envP, outputP, - ""CRLF""CRLF"", xmlns); - if (!envP->fault_occurred) { - xmlrpc_serialize_value2(envP, outputP, valueP, dialect); - if (!envP->fault_occurred) { - addString(envP, outputP, - ""CRLF""CRLF - ""CRLF); - } - } - } -} - - - -void -xmlrpc_serialize_response(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - xmlrpc_value * const valueP) { - - xmlrpc_serialize_response2(envP, outputP, valueP, xmlrpc_dialect_i8); -} - - - -void -xmlrpc_serialize_fault(xmlrpc_env * const envP, - xmlrpc_mem_block * const outputP, - const xmlrpc_env * const faultP) { -/*---------------------------------------------------------------------------- - Serialize a fault response to an XML-RPC call. - - 'faultP' is the fault. - - Add the response XML to *outputP. ------------------------------------------------------------------------------*/ - xmlrpc_value * faultStructP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(outputP != NULL); - XMLRPC_ASSERT(faultP != NULL); - XMLRPC_ASSERT(faultP->fault_occurred); - - faultStructP = xmlrpc_build_value(envP, "{s:i,s:s}", - "faultCode", - (xmlrpc_int32) faultP->fault_code, - "faultString", faultP->fault_string); - if (!envP->fault_occurred) { - addString(envP, outputP, XML_PROLOGUE); - if (!envP->fault_occurred) { - addString(envP, outputP, ""CRLF""CRLF); - if (!envP->fault_occurred) { - xmlrpc_serialize_value(envP, outputP, faultStructP); - if (!envP->fault_occurred) { - addString(envP, outputP, - CRLF""CRLF""CRLF); - } - } - } - xmlrpc_DECREF(faultStructP); - } -} - - - -/* 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. */ diff --git a/trunk/src/xmlrpc_server_abyss.c b/trunk/src/xmlrpc_server_abyss.c deleted file mode 100644 index 47c7042aa..000000000 --- a/trunk/src/xmlrpc_server_abyss.c +++ /dev/null @@ -1,1374 +0,0 @@ -/* Copyright information is at the end of the file */ - -#include "xmlrpc_config.h" - -#define _XOPEN_SOURCE 600 /* For strdup(), sigaction */ -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ - -#include -#include -#include -#include -#include -#include -#include -#if MSVCRT -# include -# pragma comment(lib, "Ws2_32.lib") -#else -# include -# include -# include -# include -# include -#endif - -#include "bool.h" -#include "int.h" -#include "mallocvar.h" - -#include "xmlrpc-c/abyss.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/server_abyss.h" - -#include "abyss_handler.h" - - -struct xmlrpc_server_abyss { - TServer abyssServer; - TChanSwitch * chanSwitchP; - bool shutdownEnabled; - /* User wants system.shutdown to succeed */ -}; - - - -static void -dieIfFaultOccurred(xmlrpc_env * const envP) { - - if (envP->fault_occurred) { - fprintf(stderr, "Unexpected XML-RPC fault: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -static void -initAbyss(xmlrpc_env * const envP) { - - const char * error; - AbyssInit(&error); - if (error) { - xmlrpc_faultf(envP, "Failed to initialize the Abyss library. %s", - error); - xmlrpc_strfree(error); - } -} - - - -static void -termAbyss(void) { - - AbyssTerm(); -} - - - -static unsigned int globallyInitialized = 0; - /* Initialization count */ - - -void -xmlrpc_server_abyss_global_init(xmlrpc_env * const envP) { - - /* Note that this is specified as not thread safe; user calls it at - the beginning of his program, when it is only one thread. - */ - - XMLRPC_ASSERT_ENV_OK(envP); - - if (globallyInitialized == 0) - initAbyss(envP); - - ++globallyInitialized; -} - - - -void -xmlrpc_server_abyss_global_term(void) { - - /* Note that this is specified as not thread safe; user calls it at - the end of his program, when it is only one thread. - */ - - XMLRPC_ASSERT(globallyInitialized > 0); - - --globallyInitialized; - - if (globallyInitialized == 0) - termAbyss(); -} - - - -static void -validateGlobalInit(xmlrpc_env * const envP) { - - if (!globallyInitialized) - xmlrpc_faultf(envP, "libxmlrpc_server_abyss has not been globally " - "initialized. See xmlrpc_server_abyss_init()"); -} - - - -static void -processXmlrpcCall(xmlrpc_env * const envP, - void * const arg, - const char * const callXml, - size_t const callXmlLen, - TSession * const abyssSessionP, - xmlrpc_mem_block ** const responseXmlPP) { - - xmlrpc_registry * const registryP = arg; - - xmlrpc_registry_process_call2(envP, registryP, - callXml, callXmlLen, abyssSessionP, - responseXmlPP); - -} - - - -static void -setHandler(xmlrpc_env * const envP, - TServer * const srvP, - struct uriHandlerXmlrpc * const uriHandlerXmlrpcP, - size_t const xmlProcessorMaxStackSize) { - - abyss_bool success; - - xmlrpc_abyss_handler_trace( - getenv("XMLRPC_TRACE_ABYSS")); - - { - size_t const stackSize = - xmlrpc_abyss_handler_stacksize() + xmlProcessorMaxStackSize; - struct ServerReqHandler3 const handlerDesc = { - /* .term = */ &xmlrpc_termUriHandler, - /* .handleReq = */ &xmlrpc_handleIfXmlrpcReq, - /* .userdata = */ uriHandlerXmlrpcP, - /* .handleReqStackSize = */ stackSize - }; - ServerAddHandler3(srvP, &handlerDesc, &success); - } - if (!success) - xmlrpc_faultf(envP, "Abyss failed to register the Xmlrpc-c request " - "handler. ServerAddHandler3() failed."); -} - - - -static void -interpretHttpAccessControl( - const xmlrpc_server_abyss_handler_parms * const parmsP, - unsigned int const parmSize, - ResponseAccessCtl * const accessCtlP) { - - const char * allowOrigin; - bool expires; - unsigned int maxAge; - - if (parmSize >= XMLRPC_AHPSIZE(allow_origin) && parmsP->allow_origin) - allowOrigin = parmsP->allow_origin; - else - allowOrigin = NULL; - - if (parmSize >= XMLRPC_AHPSIZE(access_ctl_expires) - && parmsP->access_ctl_expires) { - expires = true; - - if (parmSize >= XMLRPC_AHPSIZE(access_ctl_max_age)) - maxAge = parmsP->access_ctl_max_age; - else - maxAge = 0; - } else { - expires = false; - maxAge = 0; /* Meaningless; just to quiet runtime memory checks */ - } - - xmlrpc_initAccessCtl(accessCtlP, allowOrigin, expires, maxAge); -} - - - -void -xmlrpc_server_abyss_set_handler3( - xmlrpc_env * const envP, - TServer * const srvP, - const xmlrpc_server_abyss_handler_parms * const parmsP, - unsigned int const parmSize) { - - struct uriHandlerXmlrpc * uriHandlerXmlrpcP; - size_t xmlProcessorMaxStackSize; - - MALLOCVAR_NOFAIL(uriHandlerXmlrpcP); - - if (!envP->fault_occurred) { - if (parmSize >= XMLRPC_AHPSIZE(xml_processor)) - uriHandlerXmlrpcP->xmlProcessor = parmsP->xml_processor; - else - xmlrpc_faultf(envP, "Parameter too short to contain the required " - "'xml_processor' member"); - } - if (!envP->fault_occurred) { - if (parmSize >= XMLRPC_AHPSIZE(xml_processor_arg)) - uriHandlerXmlrpcP->xmlProcessorArg = parmsP->xml_processor_arg; - else - xmlrpc_faultf(envP, "Parameter too short to contain the required " - "'xml_processor_arg' member"); - } - if (!envP->fault_occurred) { - if (parmSize >= XMLRPC_AHPSIZE(xml_processor_max_stack)) - xmlProcessorMaxStackSize = parmsP->xml_processor_max_stack; - else - xmlrpc_faultf(envP, "Parameter too short to contain the required " - "'xml_processor_max_stack' member"); - } - if (!envP->fault_occurred) { - if (parmSize >= XMLRPC_AHPSIZE(uri_path) && parmsP->uri_path) - uriHandlerXmlrpcP->uriPath = xmlrpc_strdupsol(parmsP->uri_path); - else - uriHandlerXmlrpcP->uriPath = xmlrpc_strdupsol("/RPC2"); - - if (parmSize >= XMLRPC_AHPSIZE(chunk_response) && - parmsP->chunk_response) - uriHandlerXmlrpcP->chunkResponse = parmsP->chunk_response; - else - uriHandlerXmlrpcP->chunkResponse = false; - - interpretHttpAccessControl(parmsP, parmSize, - &uriHandlerXmlrpcP->accessControl); - - if (envP->fault_occurred) - xmlrpc_termAccessControl(&uriHandlerXmlrpcP->accessControl); - } - if (!envP->fault_occurred) - setHandler(envP, srvP, uriHandlerXmlrpcP, xmlProcessorMaxStackSize); - - if (envP->fault_occurred) - free(uriHandlerXmlrpcP); -} - - - -void -xmlrpc_server_abyss_set_handler2( - TServer * const srvP, - const char * const uriPath, - xmlrpc_call_processor xmlProcessor, - void * const xmlProcessorArg, - size_t const xmlProcessorMaxStackSize, - xmlrpc_bool const chunkResponse) { - - xmlrpc_env env; - xmlrpc_server_abyss_handler_parms parms; - - xmlrpc_env_init(&env); - - parms.xml_processor = xmlProcessor; - parms.xml_processor_arg = xmlProcessorArg; - parms.xml_processor_max_stack = xmlProcessorMaxStackSize; - parms.uri_path = uriPath; - parms.chunk_response = chunkResponse; - - xmlrpc_server_abyss_set_handler3(&env, srvP, - &parms, XMLRPC_AHPSIZE(chunk_response)); - - if (env.fault_occurred) - abort(); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_server_abyss_set_handler(xmlrpc_env * const envP, - TServer * const srvP, - const char * const uriPath, - xmlrpc_registry * const registryP) { - - xmlrpc_server_abyss_handler_parms parms; - - parms.xml_processor = &processXmlrpcCall; - parms.xml_processor_arg = registryP; - parms.xml_processor_max_stack = xmlrpc_registry_max_stackSize(registryP); - parms.uri_path = uriPath; - - xmlrpc_server_abyss_set_handler3(envP, srvP, - &parms, XMLRPC_AHPSIZE(uri_path)); -} - - - -void -xmlrpc_server_abyss_set_default_handler(TServer * const srvP) { - - ServerDefaultHandler(srvP, xmlrpc_serverAbyssDefaultUriHandler); -} - - - -static void -setHandlersRegistry(TServer * const srvP, - const char * const uriPath, - xmlrpc_registry * const registryP, - bool const chunkResponse, - const char * const allowOrigin, - bool const expires, - unsigned int const maxAge) { - - xmlrpc_env env; - xmlrpc_server_abyss_handler_parms parms; - - xmlrpc_env_init(&env); - - parms.xml_processor = &processXmlrpcCall; - parms.xml_processor_arg = registryP; - parms.xml_processor_max_stack = xmlrpc_registry_max_stackSize(registryP), - parms.uri_path = uriPath; - parms.chunk_response = chunkResponse; - parms.allow_origin = allowOrigin; - parms.access_ctl_expires = expires; - parms.access_ctl_max_age = maxAge; - - xmlrpc_server_abyss_set_handler3( - &env, srvP, &parms, XMLRPC_AHPSIZE(access_ctl_max_age)); - - if (env.fault_occurred) - abort(); - - xmlrpc_env_clean(&env); - - xmlrpc_server_abyss_set_default_handler(srvP); -} - - - -void -xmlrpc_server_abyss_set_handlers2(TServer * const srvP, - const char * const uriPath, - xmlrpc_registry * const registryP) { - - setHandlersRegistry(srvP, uriPath, registryP, false, NULL, false, 0); -} - - - -void -xmlrpc_server_abyss_set_handlers(TServer * const srvP, - xmlrpc_registry * const registryP) { - - setHandlersRegistry(srvP, "/RPC2", registryP, false, NULL, false, 0); -} - - - -/*============================================================================ - createServer() -============================================================================*/ - -static void -setAdditionalServerParms(const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize, - TServer * const serverP) { - - if (parmSize >= XMLRPC_APSIZE(keepalive_timeout) && - parmsP->keepalive_timeout > 0) - ServerSetKeepaliveTimeout(serverP, parmsP->keepalive_timeout); - if (parmSize >= XMLRPC_APSIZE(keepalive_max_conn) && - parmsP->keepalive_max_conn > 0) - ServerSetKeepaliveMaxConn(serverP, parmsP->keepalive_max_conn); - if (parmSize >= XMLRPC_APSIZE(timeout) && - parmsP->timeout > 0) - ServerSetTimeout(serverP, parmsP->timeout); - if (parmSize >= XMLRPC_APSIZE(dont_advertise)) - ServerSetAdvertise(serverP, !parmsP->dont_advertise); - if (parmSize >= XMLRPC_APSIZE(max_conn)) { - if (parmsP->max_conn != 0) - ServerSetMaxConn(serverP, parmsP->max_conn); - } - if (parmSize >= XMLRPC_APSIZE(max_conn_backlog)) { - if (parmsP->max_conn_backlog != 0) - ServerSetMaxConnBacklog(serverP, parmsP->max_conn_backlog); - } - if (parmSize >= XMLRPC_APSIZE(max_rpc_mem)) { - if (parmsP->max_rpc_mem != 0) - ServerSetMaxSessionMem(serverP, parmsP->max_rpc_mem); - } -} - - - -static void -extractSockAddrParms(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize, - const struct sockaddr ** const sockAddrPP, - socklen_t * const sockAddrLenP, - unsigned int * const portNumberP) { -/*---------------------------------------------------------------------------- - Return the server parameters that affect the address on which the server - socket shall listen. - - There are two ways the arguments can specify this: 1) user supplies a - complete socket address, which specifies both a TCP port number and an IP - address (which determines on which interface, ergo which network, if any, - the server listens); and 2) just a TCP port number, which means he wants - to listen on all IPv4 interfaces and networks. (2) is legacy. - - If the user specifies the 'sockaddrP' and 'sockaddrlen' arguments, he gets - (1) and we ignore his 'port' argument. We return his 'sockaddrP' and - 'sockaddrlen' values as *sockAddrPP and *sockAddrLenP and nothing as - *portNumberP. - - If the user doesn't specify 'sockaddrP', he gets (2). We return NULL as - *sockAddrP and his 'port_number' argument as *portNumberP. If he doesn't - specify 'port' either, we default it to 8080. - - Specifying 'sockaddrP' and not 'sockaddrlen' is an error. - - Note that the user's socket address may indicate "any IP address." ------------------------------------------------------------------------------*/ - if (parmSize >= XMLRPC_APSIZE(sockaddr_p)) { - if (parmSize < XMLRPC_APSIZE(sockaddrlen)) - xmlrpc_faultf(envP, "You must specify 'sockaddrlen' when you " - "specify 'sockaddrP'"); - else { - *sockAddrPP = parmsP->sockaddr_p; - *sockAddrLenP = parmsP->sockaddrlen; - } - } else - *sockAddrPP = NULL; - - if (*sockAddrPP == NULL) { - unsigned int portNumber; - - if (parmSize >= XMLRPC_APSIZE(port_number)) - portNumber = parmsP->port_number; - else - portNumber = 8080; - - if (portNumber > 0xffff) - xmlrpc_faultf(envP, - "TCP port number %u exceeds the maximum possible " - "TCP port number (65535)", - portNumber); - - *portNumberP = portNumber; - } -} - - - -static void -extractServerCreateParms( - xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize, - bool * const socketBoundP, - const struct sockaddr ** const sockAddrPP, - socklen_t * const sockAddrLenP, - unsigned int * const portNumberP, - TOsSocket * const socketFdP, - const char ** const logFileNameP) { - - - if (parmSize >= XMLRPC_APSIZE(socket_bound)) - *socketBoundP = parmsP->socket_bound; - else - *socketBoundP = false; - - if (*socketBoundP) { - if (parmSize < XMLRPC_APSIZE(socket_handle)) - xmlrpc_faultf(envP, "socket_bound is true, but server parameter " - "structure does not contain socket_handle (it's too " - "short)"); - else - *socketFdP = parmsP->socket_handle; - } else { - extractSockAddrParms(envP, parmsP, parmSize, sockAddrPP, sockAddrLenP, - portNumberP); - } - if (!envP->fault_occurred) { - if (parmSize >= XMLRPC_APSIZE(log_file_name) && - parmsP->log_file_name) - *logFileNameP = strdup(parmsP->log_file_name); - else - *logFileNameP = NULL; - } -} - - - -static void -chanSwitchCreateOsSocket(TOsSocket const socketFd, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - -#if MSVCRT - ChanSwitchWinCreateWinsock(socketFd, chanSwitchPP, errorP); -#else - ChanSwitchUnixCreateFd(socketFd, chanSwitchPP, errorP); -#endif - -} - - - -static void -createChanSwitchOsSocket(xmlrpc_env * const envP, - TOsSocket const socketFd, - TChanSwitch ** const chanSwitchPP) { - - const char * error; - - chanSwitchCreateOsSocket(socketFd, chanSwitchPP, &error); - - if (error) { - xmlrpc_faultf(envP, "Unable to create Abyss channel switch out of " - "file descriptor %d. %s", socketFd, error); - xmlrpc_strfree(error); - } -} - - - -static void -chanSwitchCreateSockAddr(int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - -#if MSVCRT - ChanSwitchWinCreate2(protocolFamily, sockAddrP, sockAddrLen, - chanSwitchPP, errorP); -#else - ChanSwitchUnixCreate2(protocolFamily, sockAddrP, sockAddrLen, - chanSwitchPP, errorP); -#endif - -} - - - -static void -createChanSwitchSockAddr(xmlrpc_env * const envP, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - TChanSwitch ** const chanSwitchPP) { - - int protocolFamily; - - assert(sockAddrP); - - switch (sockAddrP->sa_family) { - case AF_INET: - protocolFamily = PF_INET; - break; - case AF_INET6: - protocolFamily = PF_INET6; - break; - default: - xmlrpc_faultf(envP, "Unknown socket address family %d. " - "We know only AF_INET and AF_INET6.", - sockAddrP->sa_family); - } - - if (!envP->fault_occurred) { - const char * error; - - chanSwitchCreateSockAddr(protocolFamily, sockAddrP, sockAddrLen, - chanSwitchPP, &error); - - if (error) { - xmlrpc_faultf(envP, "Unable to create Abyss channel switch " - "given the socket address. %s", error); - xmlrpc_strfree(error); - } - } -} - - - -static void -createChanSwitchIpv4Port(xmlrpc_env * const envP, - unsigned int const portNumber, - TChanSwitch ** const chanSwitchPP) { - - struct sockaddr_in sockAddr; - const char * error; - - sockAddr.sin_family = AF_INET; - sockAddr.sin_port = htons(portNumber); - sockAddr.sin_addr.s_addr = INADDR_ANY; - - chanSwitchCreateSockAddr(PF_INET, (const struct sockaddr *)&sockAddr, - sizeof(sockAddr), - chanSwitchPP, &error); - - if (error) { - xmlrpc_faultf(envP, "Unable to create Abyss channel switch " - "to listen on Port %u at any IPv4 address. %s", - portNumber, error); - xmlrpc_strfree(error); - } -} - - - -static void -createServerBare(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize, - TServer * const serverP, - TChanSwitch ** const chanSwitchPP) { -/*---------------------------------------------------------------------------- - Create a bare server. It will need further setup before it is ready - to use. ------------------------------------------------------------------------------*/ - bool socketBound; - const struct sockaddr * sockAddrP; - socklen_t sockAddrLen; - unsigned int portNumber; - TOsSocket socketFd; - const char * logFileName; - - extractServerCreateParms(envP, parmsP, parmSize, - &socketBound, - &sockAddrP, &sockAddrLen, &portNumber, &socketFd, - &logFileName); - - if (!envP->fault_occurred) { - TChanSwitch * chanSwitchP; - - if (socketBound) - createChanSwitchOsSocket(envP, socketFd, &chanSwitchP); - else { - if (sockAddrP) - createChanSwitchSockAddr(envP, sockAddrP, sockAddrLen, - &chanSwitchP); - else - createChanSwitchIpv4Port(envP, portNumber, &chanSwitchP); - } - if (!envP->fault_occurred) { - const char * error; - - ServerCreateSwitch(serverP, chanSwitchP, &error); - - if (error) { - xmlrpc_faultf(envP, "Abyss failed to create server. %s", - error); - xmlrpc_strfree(error); - } else { - *chanSwitchPP = chanSwitchP; - - ServerSetName(serverP, "XmlRpcServer"); - - if (logFileName) - ServerSetLogFileName(serverP, logFileName); - } - if (envP->fault_occurred) - ChanSwitchDestroy(chanSwitchP); - } - if (logFileName) - xmlrpc_strfree(logFileName); - } -} - - - -static const char * -uriPathParm(const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize) { - - const char * uriPath; - - if (parmSize >= XMLRPC_APSIZE(uri_path) && parmsP->uri_path) - uriPath = parmsP->uri_path; - else - uriPath = "/RPC2"; - - return uriPath; -} - - - -static bool -chunkResponseParm(const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize) { - - return - parmSize >= XMLRPC_APSIZE(chunk_response) && - parmsP->chunk_response; -} - - - -static const char * -allowOriginParm(const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize) { - - return - parmSize >= XMLRPC_APSIZE(allow_origin) ? - parmsP->allow_origin : NULL; -} - - - -static bool -expiresParm(const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize) { - - return - parmSize >= XMLRPC_APSIZE(access_ctl_expires) ? - parmsP->access_ctl_expires : false; -} - - - -static unsigned int -maxAgeParm(const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize) { - - return - parmSize >= XMLRPC_APSIZE(access_ctl_max_age) ? - parmsP->access_ctl_max_age : 0; -} - - - -static void -createServer(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize, - TServer * const abyssServerP, - TChanSwitch ** const chanSwitchPP) { - - createServerBare(envP, parmsP, parmSize, abyssServerP, chanSwitchPP); - - if (!envP->fault_occurred) { - const char * error; - - setAdditionalServerParms(parmsP, parmSize, abyssServerP); - - setHandlersRegistry(abyssServerP, uriPathParm(parmsP, parmSize), - parmsP->registryP, - chunkResponseParm(parmsP, parmSize), - allowOriginParm(parmsP, parmSize), - expiresParm(parmsP, parmSize), - maxAgeParm(parmsP, parmSize)); - - ServerInit2(abyssServerP, &error); - - if (error) { - xmlrpc_faultf(envP, error); - xmlrpc_strfree(error); - } - } -} - - - -static bool -enableShutdownParm(const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize) { - - return - parmSize >= XMLRPC_APSIZE(enable_shutdown) && - parmsP->enable_shutdown; -} - - - -static xmlrpc_server_shutdown_fn shutdownAbyss; - -static void -shutdownAbyss(xmlrpc_env * const faultP, - void * const context, - const char * const comment ATTR_UNUSED, - void * const callInfo ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - Tell Abyss to wrap up whatever it's doing and shut down. - - This is a server shutdown function to be registered in the method - registry, for use by the 'system.shutdown' system method. - - After we return, Abyss will finish up the system.shutdown and any - other connections that are in progress, then the call to - ServerRun() etc. will return. - - *faultP is the result of the shutdown request, not whether we - succeeded or failed. We are not allowed to fail. ------------------------------------------------------------------------------*/ - xmlrpc_server_abyss_t * const serverP = context; - - xmlrpc_env_init(faultP); - - if (!serverP->shutdownEnabled) - xmlrpc_env_set_fault_formatted( - faultP, XMLRPC_REQUEST_REFUSED_ERROR, - "Shutdown by client is disabled on this server."); - else - ServerTerminate(&serverP->abyssServer); -} - - - -/*============================================================================= - xmlrpc_server_abyss object methods -=============================================================================*/ - -void -xmlrpc_server_abyss_create(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize, - xmlrpc_server_abyss_t ** const serverPP) { - - xmlrpc_server_abyss_t * serverP; - - XMLRPC_ASSERT_ENV_OK(envP); - - validateGlobalInit(envP); - - if (!envP->fault_occurred) { - if (parmSize < XMLRPC_APSIZE(registryP)) - xmlrpc_faultf(envP, - "You must specify members at least up through " - "'registryP' in the server parameters argument. " - "That would mean the parameter size would be >= %u " - "but you specified a size of %u", - (unsigned)XMLRPC_APSIZE(registryP), parmSize); - else { - MALLOCVAR(serverP); - - if (serverP == NULL) - xmlrpc_faultf(envP, "Unable to allocate memory for " - "server descriptor."); - else { - createServer(envP, parmsP, parmSize, - &serverP->abyssServer, &serverP->chanSwitchP); - - if (!envP->fault_occurred) { - serverP->shutdownEnabled = - enableShutdownParm(parmsP, parmSize); - - xmlrpc_registry_set_shutdown( - parmsP->registryP, &shutdownAbyss, serverP); - - if (envP->fault_occurred) - free(serverP); - else - *serverPP = serverP; - } - } - } - } -} - - - -void -xmlrpc_server_abyss_destroy(xmlrpc_server_abyss_t * const serverP) { - - XMLRPC_ASSERT(globallyInitialized); - - ServerFree(&serverP->abyssServer); - - if (serverP->chanSwitchP) - ChanSwitchDestroy(serverP->chanSwitchP); - - free(serverP); -} - - - -void -xmlrpc_server_abyss_use_sigchld(xmlrpc_server_abyss_t * const serverP) { - - ServerUseSigchld(&serverP->abyssServer); -} - - - -void -xmlrpc_server_abyss_run_server(xmlrpc_env * const envP ATTR_UNUSED, - xmlrpc_server_abyss_t * const serverP) { - - ServerRun(&serverP->abyssServer); -} - - - -void -xmlrpc_server_abyss_terminate( - xmlrpc_env * const envP ATTR_UNUSED, - xmlrpc_server_abyss_t * const serverP) { - - ServerTerminate(&serverP->abyssServer); -} - - - -void -xmlrpc_server_abyss_reset_terminate( - xmlrpc_env * const envP ATTR_UNUSED, - xmlrpc_server_abyss_t * const serverP) { - - ServerResetTerminate(&serverP->abyssServer); -} - - - -static void -sigchld(int const signalClass ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - This is a signal handler for a SIGCHLD signal (which informs us that - one of our child processes has terminated). - - The only child processes we have are those that belong to the Abyss - server (and then only if the Abyss server was configured to use - forking as a threading mechanism), so we respond by passing the - signal on to the Abyss server. And reaping the dead child. ------------------------------------------------------------------------------*/ -#if !MSVCRT - /* Reap zombie children / report to Abyss until there aren't any more. */ - - bool childrenLeft; - bool error; - - assert(signalClass == SIGCHLD); - - error = false; - childrenLeft = true; /* initial assumption */ - - /* Reap defunct children until there aren't any more. */ - while (childrenLeft && !error) { - int status; - pid_t pid; - - pid = waitpid((pid_t) -1, &status, WNOHANG); - - if (pid == 0) - childrenLeft = false; - else if (pid < 0) { - /* because of ptrace */ - if (errno != EINTR) - error = true; - } else - ServerHandleSigchld(pid); - } -#endif /* MSVCRT */ -} - - -struct xmlrpc_server_abyss_sig { - - /* A description of the state of the process' signal handlers before - functions in this library messed with them; useful for restoring - them later. - */ -#if MSVCRT - int dummy; -#else - struct sigaction pipe; - struct sigaction chld; -#endif -}; - - - -static void -setupSignalHandlers(xmlrpc_server_abyss_sig * const oldHandlersP) { -#if !MSVCRT - struct sigaction mysigaction; - - sigemptyset(&mysigaction.sa_mask); - mysigaction.sa_flags = 0; - - /* This signal indicates connection closed in the middle */ - mysigaction.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &mysigaction, &oldHandlersP->pipe); - - /* This signal indicates a child process (request handler) has died */ - mysigaction.sa_handler = sigchld; - sigaction(SIGCHLD, &mysigaction, &oldHandlersP->chld); -#endif -} - - - -static void -restoreSignalHandlers(const xmlrpc_server_abyss_sig * const oldHandlersP) { -#if !MSVCRT - sigaction(SIGPIPE, &oldHandlersP->pipe, NULL); - sigaction(SIGCHLD, &oldHandlersP->chld, NULL); - -#endif -} - - - -void -xmlrpc_server_abyss_setup_sig( - xmlrpc_env * const envP, - xmlrpc_server_abyss_t * const serverP, - xmlrpc_server_abyss_sig ** const oldHandlersPP) { - - xmlrpc_server_abyss_sig * oldHandlersP; - - XMLRPC_ASSERT_ENV_OK(envP); - - validateGlobalInit(envP); - - if (!envP->fault_occurred) { - MALLOCVAR(oldHandlersP); - - if (oldHandlersP == NULL) - xmlrpc_faultf(envP, "Unable to allocate memory to save signal " - "handling state."); - else { - setupSignalHandlers(oldHandlersP); - - xmlrpc_server_abyss_use_sigchld(serverP); - } - if (oldHandlersPP) - *oldHandlersPP = oldHandlersP; - else - free(oldHandlersP); - } -} - - - -void -xmlrpc_server_abyss_restore_sig( - const xmlrpc_server_abyss_sig * const oldHandlersP) { - - restoreSignalHandlers(oldHandlersP); -} - - - -static void -runServerDaemon(TServer * const serverP, - runfirstFn const runfirst, - void * const runfirstArg) { - - xmlrpc_server_abyss_sig oldHandlers; - - setupSignalHandlers(&oldHandlers); - - ServerUseSigchld(serverP); - - ServerDaemonize(serverP); - - /* We run the user supplied runfirst after forking, but before accepting - connections (helpful when running with threads) - */ - if (runfirst) - runfirst(runfirstArg); - - ServerRun(serverP); - - restoreSignalHandlers(&oldHandlers); -} - - - -static void -oldHighLevelAbyssRun(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize) { -/*---------------------------------------------------------------------------- - This is the old deprecated interface, where the caller of the - xmlrpc_server_abyss API supplies an Abyss configuration file and - we use it to daemonize (fork into the background, chdir, set uid, etc.) - and run the Abyss server. - - The new preferred interface, implemented by normalLevelAbyssRun(), - instead lets Caller set up the process environment himself and pass - Abyss parameters in memory. That's a more conventional and - flexible API. ------------------------------------------------------------------------------*/ - TServer server; - abyss_bool success; - - success = ServerCreate(&server, "XmlRpcServer", 8080, DEFAULT_DOCS, NULL); - - if (!success) - xmlrpc_faultf(envP, "Failed to create Abyss server object"); - else { - runfirstFn runfirst; - void * runfirstArg; - - assert(parmSize >= XMLRPC_APSIZE(config_file_name)); - - ConfReadServerFile(parmsP->config_file_name, &server); - - assert(parmSize >= XMLRPC_APSIZE(registryP)); - - setHandlersRegistry(&server, "/RPC2", parmsP->registryP, false, NULL, - false, 0); - - ServerInit(&server); - - if (parmSize >= XMLRPC_APSIZE(runfirst_arg)) { - runfirst = parmsP->runfirst; - runfirstArg = parmsP->runfirst_arg; - } else { - runfirst = NULL; - runfirstArg = NULL; - } - runServerDaemon(&server, runfirst, runfirstArg); - - ServerFree(&server); - } -} - - - -static void -normalLevelAbyssRun(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize) { - - xmlrpc_server_abyss_t * serverP; - - xmlrpc_server_abyss_create(envP, parmsP, parmSize, &serverP); - - if (!envP->fault_occurred) { - xmlrpc_server_abyss_sig * oldHandlersP; - - xmlrpc_server_abyss_setup_sig(envP, serverP, &oldHandlersP); - - if (!envP->fault_occurred) { - xmlrpc_server_abyss_run_server(envP, serverP); - - xmlrpc_server_abyss_restore_sig(oldHandlersP); - - free(oldHandlersP); - } - xmlrpc_server_abyss_destroy(serverP); - } -} - - - -void -xmlrpc_server_abyss(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parmSize) { -/*---------------------------------------------------------------------------- - Note that this is not re-entrant and not thread-safe, because of the - global library initialization. If you want to run a server inside - a thread of a multi-threaded program, use - xmlrpc_server_abyss_create() instead. As required by that - subroutine, your program will contain a call to - xmlrpc_server_abyss_global_init() early in your program, when it is only - one thread. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - - xmlrpc_server_abyss_global_init(envP); - - if (!envP->fault_occurred) { - if (parmSize < XMLRPC_APSIZE(registryP)) - xmlrpc_faultf(envP, - "You must specify members at least up through " - "'registryP' in the server parameters argument. " - "That would mean the parameter size would be >= %u " - "but you specified a size of %u", - (unsigned)XMLRPC_APSIZE(registryP), parmSize); - else { - if (parmsP->config_file_name) - oldHighLevelAbyssRun(envP, parmsP, parmSize); - else - normalLevelAbyssRun(envP, parmsP, parmSize); - } - xmlrpc_server_abyss_global_term(); - } -} - - - -/*========================================================================= - XML-RPC Server Method Registry - - This is an old deprecated form of the server facilities that uses - global variables. -=========================================================================*/ - -/* These global variables must be treated as read-only after the - server has started. -*/ - -static TServer globalSrv; - /* When you use the old interface (xmlrpc_server_abyss_init(), etc.), - this is the Abyss server to which they refer. Obviously, there can be - only one Abyss server per program using this interface. - */ - -static xmlrpc_registry * builtin_registryP; - - - -void -xmlrpc_server_abyss_init_registry(void) { - - /* This used to just create the registry and Caller would be - responsible for adding the handlers that use it. - - But that isn't very modular -- the handlers and registry go - together; there's no sense in using the built-in registry and - not the built-in handlers because if you're custom building - something, you can just make your own regular registry. So now - we tie them together, and we don't export our handlers. - */ - xmlrpc_env env; - - xmlrpc_env_init(&env); - builtin_registryP = xmlrpc_registry_new(&env); - dieIfFaultOccurred(&env); - xmlrpc_env_clean(&env); - - setHandlersRegistry(&globalSrv, "/RPC2", builtin_registryP, false, NULL, - false, 0); -} - - - -xmlrpc_registry * -xmlrpc_server_abyss_registry(void) { - - /* This is highly deprecated. If you want to mess with a registry, - make your own with xmlrpc_registry_new() -- don't mess with the - internal one. - */ - return builtin_registryP; -} - - - -/* A quick & easy shorthand for adding a method. */ -void -xmlrpc_server_abyss_add_method(char * const method_name, - xmlrpc_method const method, - void * const user_data) { - xmlrpc_env env; - - xmlrpc_env_init(&env); - xmlrpc_registry_add_method(&env, builtin_registryP, NULL, method_name, - method, user_data); - dieIfFaultOccurred(&env); - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_server_abyss_add_method_w_doc(char * const method_name, - xmlrpc_method const method, - void * const user_data, - char * const signature, - char * const help) { - - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_registry_add_method_w_doc( - &env, builtin_registryP, NULL, method_name, - method, user_data, signature, help); - dieIfFaultOccurred(&env); - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_server_abyss_init(int const flags ATTR_UNUSED, - const char * const config_file) { - - abyss_bool success; - - success = ServerCreate(&globalSrv, "XmlRpcServer", 8080, - DEFAULT_DOCS, NULL); - - if (!success) - abort(); - else { - ConfReadServerFile(config_file, &globalSrv); - - xmlrpc_server_abyss_init_registry(); - /* Installs /RPC2 handler and default handler that use the - built-in registry. - */ - - ServerInit(&globalSrv); - } -} - - - -void -xmlrpc_server_abyss_run_first(runfirstFn const runfirst, - void * const runfirstArg) { - - runServerDaemon(&globalSrv, runfirst, runfirstArg); -} - - - -void -xmlrpc_server_abyss_run(void) { - runServerDaemon(&globalSrv, NULL, NULL); -} - - - -/* -** Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -** There is more copyright information in the bottom half of this file. -** Please see it for more details. -*/ diff --git a/trunk/src/xmlrpc_server_cgi.c b/trunk/src/xmlrpc_server_cgi.c deleted file mode 100644 index 00ca5042f..000000000 --- a/trunk/src/xmlrpc_server_cgi.c +++ /dev/null @@ -1,331 +0,0 @@ -/* Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -#include "xmlrpc_config.h" - -#include -#include -#include - -/* Windows NT stdout binary mode fix. */ -#if MSVCRT -#include -#include -#endif - -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/server_cgi.h" - - -/*========================================================================= -** Output Routines -**========================================================================= -** These routines send various kinds of responses to the server. -*/ - -static void -send_xml(const char * const xml_data, - size_t const xml_len) { -#if MSVCRT - _setmode(_fileno(stdout), _O_BINARY); -#endif - /* Send our CGI headers back to the server. - ** XXX - Coercing 'size_t' to 'unsigned long' might be unsafe under - ** really weird circumstances. */ - fprintf(stdout, "Status: 200 OK\n"); - /* Handle authentication cookie being sent back. */ - if (getenv("HTTP_COOKIE_AUTH") != NULL) - fprintf(stdout, "Set-Cookie: auth=%s\n", getenv("HTTP_COOKIE_AUTH")); - fprintf(stdout, "Content-type: text/xml; charset=\"utf-8\"\n"); - fprintf(stdout, "Content-length: %ld\n\n", (unsigned long) xml_len); - - /* Blast out our data. */ - fwrite(xml_data, sizeof(char), xml_len, stdout); -} - - - -static void -send_error(int const code, - const char * const message, - xmlrpc_env * const env) { - -#if MSVCRT - _setmode(_fileno(stdout), _O_BINARY); -#endif - /* Send an error header. */ - fprintf(stdout, "Status: %d %s\n", code, message); - fprintf(stdout, "Content-type: text/html\n\n"); - - /* Send an error message. */ - fprintf(stdout, "%d %s\n", code, message); - fprintf(stdout, "

%d %s

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

An error occurred processing your request.

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

XML-RPC Fault #%d: %s

\n", - env->fault_code, env->fault_string); -} - - -/*========================================================================= -** die_if_fault_occurred -**========================================================================= -** Certain kinds of errors aren't worth the trouble of generating -** an XML-RPC fault. For these, we just send status 500 to our web server -** and log the fault to our server log. -*/ - -static void -die_if_fault_occurred(xmlrpc_env * const env) { - if (env->fault_occurred) { - fprintf(stderr, "Unexpected XML-RPC fault: %s (%d)\n", - env->fault_string, env->fault_code); - send_error(500, "Internal Server Error", env); - exit(1); - } -} - - -/*========================================================================= -** Initialization, Cleanup & Method Registry -**========================================================================= -** These are all related, so we group them together. -*/ - -static xmlrpc_registry * globalRegistryP; - -/*========================================================================= -** get_body -**========================================================================= -** Slurp the body of the request into an xmlrpc_mem_block. -*/ - -static xmlrpc_mem_block * -get_body(xmlrpc_env * const env, - size_t const length) { - - xmlrpc_mem_block *result; - char *contents; - size_t count; - - XMLRPC_ASSERT_ENV_OK(env); - - /* Error-handling preconditions. */ - result = NULL; - -#if MSVCRT - /* Fix from Jeff Stewart: NT opens stdin and stdout in text mode - by default, badly confusing our length calculations. So we need - to set the file handle to binary. - */ - _setmode(_fileno(stdin), _O_BINARY); -#endif - /* XXX - Puke if length is too big. */ - - /* Allocate our memory block. */ - result = xmlrpc_mem_block_new(env, length); - XMLRPC_FAIL_IF_FAULT(env); - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, result); - - /* Get our data off the network. - ** XXX - Coercing 'size_t' to 'unsigned long' might be unsafe under - ** really weird circumstances. */ - count = fread(contents, sizeof(char), length, stdin); - if (count < length) - XMLRPC_FAIL2(env, XMLRPC_INTERNAL_ERROR, - "Expected %ld bytes, received %ld", - (unsigned long) length, (unsigned long) count); - - cleanup: - if (env->fault_occurred) { - if (result) - xmlrpc_mem_block_free(result); - return NULL; - } - return result; -} - - - -void -xmlrpc_server_cgi_process_call(xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Get the XML-RPC call from Standard Input and environment variables, - parse it, find the right method, call it, prepare an XML-RPC - response with the result, and write it to Standard Output. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - char *method, *type, *length_str; - int length; - xmlrpc_mem_block *input, *output; - char *input_data, *output_data; - size_t input_size, output_size; - int code; - char *message; - - /* Error-handling preconditions. */ - xmlrpc_env_init(&env); - input = output = NULL; - - /* Set up a default error message. */ - code = 500; message = "Internal Server Error"; - - /* Get our HTTP information from the environment. */ - method = getenv("REQUEST_METHOD"); - type = getenv("CONTENT_TYPE"); - length_str = getenv("CONTENT_LENGTH"); - - /* Perform some sanity checks. */ - if (!method || !xmlrpc_streq(method, "POST")) { - code = 405; message = "Method Not Allowed"; - XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Expected HTTP method POST"); - } - if (!type || !xmlrpc_strneq(type, "text/xml", strlen("text/xml"))) { - char *template = "Expected content type: \"text/xml\", received: \"%s\""; - size_t err_len = strlen(template) + strlen(type) + 1; - char *err = malloc(err_len); - - XMLRPC_SNPRINTF(err, err_len, template, type); - code = 400; message = "Bad Request"; - XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, err); - free(err); - } - if (!length_str) { - code = 411; message = "Length Required"; - XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Content-length required"); - } - - /* Get our content length. */ - length = atoi(length_str); - if (length <= 0) { - code = 400; message = "Bad Request"; - XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Content-length must be > 0"); - } - - /* SECURITY: Make sure our content length is legal. - ** XXX - We can cast 'input_len' because we know it's >= 0, yes? */ - if ((size_t) length > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) { - code = 400; message = "Bad Request"; - XMLRPC_FAIL(&env, XMLRPC_LIMIT_EXCEEDED_ERROR, - "XML-RPC request too large"); - } - - /* Get our body. */ - input = get_body(&env, length); - XMLRPC_FAIL_IF_FAULT(&env); - input_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, input); - input_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, input); - - /* Process our call. */ - xmlrpc_registry_process_call2(&env, registryP, - input_data, input_size, NULL, &output); - XMLRPC_FAIL_IF_FAULT(&env); - output_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output); - output_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); - - /* Send our data. */ - send_xml(output_data, output_size); - - cleanup: - if (input) - xmlrpc_mem_block_free(input); - if (output) - xmlrpc_mem_block_free(output); - - if (env.fault_occurred) - send_error(code, message, &env); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_cgi_init(int const flags ATTR_UNUSED) { - xmlrpc_env env; - - xmlrpc_env_init(&env); - globalRegistryP = xmlrpc_registry_new(&env); - die_if_fault_occurred(&env); - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_cgi_cleanup(void) { - xmlrpc_registry_free(globalRegistryP); -} - - - -xmlrpc_registry * -xmlrpc_cgi_registry(void) { - return globalRegistryP; -} - - - -void -xmlrpc_cgi_add_method(const char * const method_name, - xmlrpc_method const method, - void * const user_data) { - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_registry_add_method(&env, globalRegistryP, NULL, method_name, - method, user_data); - die_if_fault_occurred(&env); - xmlrpc_env_clean(&env); -} - - - -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) { - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_registry_add_method_w_doc(&env, globalRegistryP, NULL, method_name, - method, user_data, signature, help); - die_if_fault_occurred(&env); - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_cgi_process_call(void) { - - xmlrpc_server_cgi_process_call(globalRegistryP); -} diff --git a/trunk/src/xmlrpc_server_info.c b/trunk/src/xmlrpc_server_info.c deleted file mode 100644 index 2e06c025d..000000000 --- a/trunk/src/xmlrpc_server_info.c +++ /dev/null @@ -1,350 +0,0 @@ -/*============================================================================= - xmlrpc_server_info -=============================================================================== - The xmlrpc_server_info class. - - By Bryan Henderson, San Jose CA 2007.10.17. - - Contributed to the public domain by its author - - The xmlrpc_server_info class was originally just supposed to be - information about an HTTP server, hence the name. But we think of it - now as a generic carriage parameter, as in the C++ library. In - the future, it should be a union or maybe contain an opaque pointer - to the carriage parameter for a particular kind of transport. That - way, the client XML transports can be more than just HTTP XML - transports. -=============================================================================*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include - -#include "bool.h" -#include "mallocvar.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/client_int.h" - - - -xmlrpc_server_info * -xmlrpc_server_info_new(xmlrpc_env * const envP, - const char * const serverUrl) { - - xmlrpc_server_info * serverInfoP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverUrl); - - MALLOCVAR(serverInfoP); - if (serverInfoP == NULL) - xmlrpc_faultf(envP, "Couldn't allocate memory for xmlrpc_server_info"); - else { - serverInfoP->serverUrl = strdup(serverUrl); - if (serverInfoP->serverUrl == NULL) - xmlrpc_faultf(envP, "Couldn't allocate memory for server URL"); - else { - serverInfoP->allowedAuth.basic = false; - serverInfoP->allowedAuth.digest = false; - serverInfoP->allowedAuth.gssnegotiate = false; - serverInfoP->allowedAuth.ntlm = false; - serverInfoP->userNamePw = NULL; - serverInfoP->basicAuthHdrValue = NULL; - if (envP->fault_occurred) - xmlrpc_strfree(serverInfoP->serverUrl); - } - if (envP->fault_occurred) - free(serverInfoP); - } - return serverInfoP; -} - - - -static void -copyUserNamePw(xmlrpc_env * const envP, - const char * const src, - const char ** const dstP) { - - if (src == NULL) - *dstP = NULL; - else { - *dstP = strdup(src); - if (*dstP == NULL) - xmlrpc_faultf(envP, "Couldn't allocate memory for user name/pw"); - } -} - - - -static void -freeIfNonNull(const char * const arg) { - - if (arg) - xmlrpc_strfree(arg); -} - - - -static void -copyBasicAuthHdrValue(xmlrpc_env * const envP, - const char * const src, - const char ** const dstP) { - - if (src == NULL) - *dstP = NULL; - else { - *dstP = strdup(src); - if (*dstP == NULL) - xmlrpc_faultf(envP, "Couldn't allocate memory " - "for authentication header value"); - } -} - - - -static void -copyServerInfoContent(xmlrpc_env * const envP, - xmlrpc_server_info * const dstP, - const xmlrpc_server_info * const srcP) { - - dstP->serverUrl = strdup(srcP->serverUrl); - if (dstP->serverUrl == NULL) - xmlrpc_faultf(envP, "Couldn't allocate memory for server URL"); - else { - copyUserNamePw(envP, srcP->userNamePw, &dstP->userNamePw); - - if (!envP->fault_occurred) { - copyBasicAuthHdrValue(envP, srcP->basicAuthHdrValue, - &dstP->basicAuthHdrValue); - - if (!envP->fault_occurred) { - dstP->allowedAuth.basic = - srcP->allowedAuth.basic; - dstP->allowedAuth.digest = - srcP->allowedAuth.digest; - dstP->allowedAuth.gssnegotiate = - srcP->allowedAuth.gssnegotiate; - dstP->allowedAuth.ntlm = - srcP->allowedAuth.ntlm; - - if (envP->fault_occurred) - freeIfNonNull(dstP->basicAuthHdrValue); - } - if (envP->fault_occurred) - freeIfNonNull(dstP->userNamePw); - } - if (envP->fault_occurred) - xmlrpc_strfree(dstP->serverUrl); - } -} - - - -xmlrpc_server_info * -xmlrpc_server_info_copy(xmlrpc_env * const envP, - xmlrpc_server_info * const srcP) { - - xmlrpc_server_info * serverInfoP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(srcP); - - MALLOCVAR(serverInfoP); - if (serverInfoP == NULL) - xmlrpc_faultf(envP, - "Couldn't allocate memory for xmlrpc_server_info"); - else { - copyServerInfoContent(envP, serverInfoP, srcP); - - if (envP->fault_occurred) - free(serverInfoP); - } - return serverInfoP; -} - - - -void -xmlrpc_server_info_free(xmlrpc_server_info * const serverInfoP) { - - XMLRPC_ASSERT_PTR_OK(serverInfoP); - XMLRPC_ASSERT(serverInfoP->serverUrl != XMLRPC_BAD_POINTER); - - if (serverInfoP->userNamePw) - xmlrpc_strfree(serverInfoP->userNamePw); - serverInfoP->userNamePw = XMLRPC_BAD_POINTER; - - if (serverInfoP->basicAuthHdrValue) - xmlrpc_strfree(serverInfoP->basicAuthHdrValue); - serverInfoP->basicAuthHdrValue = XMLRPC_BAD_POINTER; - - xmlrpc_strfree(serverInfoP->serverUrl); - serverInfoP->serverUrl = XMLRPC_BAD_POINTER; - - free(serverInfoP); -} - - - -void -xmlrpc_server_info_set_user(xmlrpc_env * const envP, - xmlrpc_server_info * const serverInfoP, - const char * const username, - const char * const password) { - - const char * userNamePw; - xmlrpc_mem_block * userNamePw64; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverInfoP); - XMLRPC_ASSERT_PTR_OK(username); - XMLRPC_ASSERT_PTR_OK(password); - - xmlrpc_asprintf(&userNamePw, "%s:%s", username, password); - - userNamePw64 = - xmlrpc_base64_encode_without_newlines(envP, - (unsigned char*) userNamePw, - strlen(userNamePw)); - if (!envP->fault_occurred) { - const char * const data = XMLRPC_MEMBLOCK_CONTENTS(char, userNamePw64); - size_t const len = XMLRPC_MEMBLOCK_SIZE(char, userNamePw64); - const char * const authType = "Basic "; - - char * hdrValue; - - hdrValue = malloc(strlen(authType) + len + 1); - if (hdrValue == NULL) - xmlrpc_faultf(envP, "Could not allocate memory to store " - "authorization header value."); - else { - strcpy(hdrValue, authType); - strncat(hdrValue, data, len); - - if (serverInfoP->basicAuthHdrValue) - xmlrpc_strfree(serverInfoP->basicAuthHdrValue); - - serverInfoP->basicAuthHdrValue = hdrValue; - } - XMLRPC_MEMBLOCK_FREE(char, userNamePw64); - } - if (serverInfoP->userNamePw) - xmlrpc_strfree(serverInfoP->userNamePw); - - serverInfoP->userNamePw = userNamePw; -} - - - -void -xmlrpc_server_info_set_basic_auth(xmlrpc_env * const envP, - xmlrpc_server_info * const serverInfoP, - const char * const username, - const char * const password) { - - xmlrpc_server_info_set_user(envP, serverInfoP, username, password); - - if (!envP->fault_occurred) { - serverInfoP->allowedAuth.basic = true; - serverInfoP->allowedAuth.digest = false; - serverInfoP->allowedAuth.gssnegotiate = false; - serverInfoP->allowedAuth.ntlm = false; - } -} - - - -void -xmlrpc_server_info_allow_auth_basic(xmlrpc_env * const envP, - xmlrpc_server_info * const sP) { - - if (sP->userNamePw == NULL) - xmlrpc_faultf(envP, "You must set username/password with " - "xmlrpc_server_info_set_user()"); - else - sP->allowedAuth.basic = true; -} - - - -void -xmlrpc_server_info_disallow_auth_basic( - xmlrpc_env * const envP ATTR_UNUSED, - xmlrpc_server_info * const sP) { - - sP->allowedAuth.basic = false; -} - - - -void -xmlrpc_server_info_allow_auth_digest(xmlrpc_env * const envP, - xmlrpc_server_info * const sP) { - - if (sP->userNamePw == NULL) - xmlrpc_faultf(envP, "You must set username/password with " - "xmlrpc_server_info_set_user()"); - else - sP->allowedAuth.digest = true; -} - - - -void -xmlrpc_server_info_disallow_auth_digest( - xmlrpc_env * const envP ATTR_UNUSED, - xmlrpc_server_info * const sP) { - - sP->allowedAuth.digest = false; -} - - - -void -xmlrpc_server_info_allow_auth_negotiate(xmlrpc_env * const envP, - xmlrpc_server_info * const sP) { - - if (sP->userNamePw == NULL) - xmlrpc_faultf(envP, "You must set username/password with " - "xmlrpc_server_info_set_user()"); - else - sP->allowedAuth.gssnegotiate = true; -} - - - -void -xmlrpc_server_info_disallow_auth_negotiate( - xmlrpc_env * const envP ATTR_UNUSED, - xmlrpc_server_info * const sP) { - - sP->allowedAuth.gssnegotiate = false; -} - - - -void -xmlrpc_server_info_allow_auth_ntlm(xmlrpc_env * const envP, - xmlrpc_server_info * const sP) { - - if (sP->userNamePw == NULL) - xmlrpc_faultf(envP, "You must set username/password with " - "xmlrpc_server_info_set_user()"); - else - sP->allowedAuth.ntlm = true; -} - - - -void -xmlrpc_server_info_disallow_auth_ntlm( - xmlrpc_env * const envP ATTR_UNUSED, - xmlrpc_server_info * const sP) { - - sP->allowedAuth.ntlm = true; -} diff --git a/trunk/src/xmlrpc_server_w32httpsys.c b/trunk/src/xmlrpc_server_w32httpsys.c deleted file mode 100644 index 7e96d208b..000000000 --- a/trunk/src/xmlrpc_server_w32httpsys.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* Copyright information is at end of file. */ - -/* 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 XML-RPC server program, it is safe to exclude the - xmlrpc_server_w32httpsys.c file from the xmlrpc project and you will not - have this dependency. 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 UNICODE -#define UNICODE -#endif - -#ifndef _UNICODE -#define _UNICODE -#endif - -/* Declare that we require the Windows XP SP2 or better version of the - interface to Windows. - - Microsoft recommends - (http://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx) defining - NTDDI_VERSION instead of _WIN32_WINNT for this purpose, but as it was - invented recently, it's pretty useless. Windows header files from old - Windows SDKs won't know what to do with it. -*/ -#define _WIN32_WINNT 0x0502 - -/* See compilation note above if the compiler doesn't find this header file */ -#include -#include - -#include "xmlrpc_config.h" -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "xmlrpc-c/server_w32httpsys.h" -#include "version.h" - -#pragma comment( lib, "httpapi" ) -#pragma message( "Compiling HTTPS server ..." ) - -/* XXX - This variable is *not* currently threadsafe. Once the server has -** been started, it must be treated as read-only. */ -static xmlrpc_registry *global_registryP; - -//set TRUE if you want a log -static BOOL g_bDebug; -//set log filename -static char g_fLogFile[MAX_PATH]; -//do you want OutputDebugString() to be called? -static BOOL g_bDebugString; - -// -// Macros. -// -#define INITIALIZE_HTTP_RESPONSE( resp, status, reason ) \ - do \ - { \ - RtlZeroMemory( (resp), sizeof(*(resp)) ); \ - (resp)->StatusCode = (status); \ - (resp)->pReason = (reason); \ - (resp)->ReasonLength = (USHORT) strlen(reason); \ - } while (FALSE) - - -#define ADD_KNOWN_HEADER(Response, HeaderId, RawValue) \ - do \ - { \ - (Response).Headers.KnownHeaders[(HeaderId)].pRawValue = (RawValue); \ - (Response).Headers.KnownHeaders[(HeaderId)].RawValueLength = \ - (USHORT) strlen(RawValue); \ - } while(FALSE) - -#define ALLOC_MEM(cb) HeapAlloc(GetProcessHeap(), 0, (cb)) -#define FREE_MEM(ptr) HeapFree(GetProcessHeap(), 0, (ptr)) - -// -// Prototypes for Internal Functions. -// -DWORD -DoReceiveRequests( - HANDLE hReqQueue, - const xmlrpc_server_httpsys_parms * const parmsP - ); - -DWORD -SendHttpResponse( - IN HANDLE hReqQueue, - IN PHTTP_REQUEST pRequest, - IN USHORT StatusCode, - IN PSTR pReason, - IN PSTR pEntity - ); - -DWORD -SendHttpResponseAuthRequired( - IN HANDLE hReqQueue, - IN PHTTP_REQUEST pRequest - ); - -void -processRPCCall( - xmlrpc_env * const envP, - IN HANDLE hReqQueue, - IN PHTTP_REQUEST pRequest - ); - -__inline void TraceA(const char *format, ...); -__inline void TraceW(const wchar_t *format, ...); - - -// -// External Function Implementation. -// - -void -xmlrpc_server_httpsys( - xmlrpc_env * const envP, - const xmlrpc_server_httpsys_parms * const parmsP, - unsigned int const parm_size - ) -{ - ULONG retCode; - HANDLE hReqQueue = NULL; - HTTPAPI_VERSION HttpApiVersion = HTTPAPI_VERSION_1; - WCHAR wszURL[35]; - - XMLRPC_ASSERT_ENV_OK(envP); - - if (parm_size < XMLRPC_HSSIZE(authfn)) - { - xmlrpc_faultf(envP, - "You must specify members at least up through " - "'authfn' in the server parameters argument. " - "That would mean the parameter size would be >= %u " - "but you specified a size of %u", - XMLRPC_HSSIZE(authfn), parm_size); - return; - } - - //Set logging options - if (parmsP->logLevel>0) - g_bDebug=TRUE; - else - g_bDebug=FALSE; - - if (parmsP->logLevel>1) - g_bDebugString=TRUE; - else - g_bDebugString=FALSE; - - if (!parmsP->logFile) - g_bDebug=FALSE; - else - StringCchPrintfA(g_fLogFile,MAX_PATH,parmsP->logFile); - - //construct the URL we are listening on - if (parmsP->useSSL!=0) - StringCchPrintf(wszURL,35,L"https://+:%u/RPC2",parmsP->portNum); - else - StringCchPrintf(wszURL,35,L"http://+:%u/RPC2",parmsP->portNum); - - global_registryP = parmsP->registryP; - - // Initialize HTTP APIs. - retCode = HttpInitialize(HttpApiVersion, - HTTP_INITIALIZE_SERVER, // Flags - NULL // Reserved - ); - if (retCode != NO_ERROR) - { - xmlrpc_faultf(envP, "HttpInitialize failed with %lu", - retCode); - return; - } - - // Create a Request Queue Handle - retCode = HttpCreateHttpHandle(&hReqQueue, // Req Queue - 0 // Reserved - ); - if (retCode != NO_ERROR) - { - xmlrpc_faultf(envP, "HttpCreateHttpHandle failed with %lu", retCode); - goto CleanUp; - } - - retCode = HttpAddUrl(hReqQueue, // Req Queue - wszURL, // Fully qualified URL - NULL // Reserved - ); - - if (retCode != NO_ERROR) - { - xmlrpc_faultf(envP, "HttpAddUrl failed with %lu", retCode); - goto CleanUp; - } - - TraceW(L"we are listening for requests on the following url: %ws", - wszURL); - - // Loop while receiving requests - for(;;) - { - TraceW(L"Calling DoReceiveRequests()"); - retCode = DoReceiveRequests(hReqQueue, parmsP); - if(NO_ERROR == retCode) - { - TraceW(L"DoReceiveRequests() returned NO_ERROR, breaking"); - break; - } - } - -CleanUp: - - TraceW(L"Tearing down the server.", wszURL); - - // Call HttpRemoveUrl for the URL that we added. - HttpRemoveUrl( hReqQueue, wszURL ); - - // Close the Request Queue handle. - if(hReqQueue) - CloseHandle(hReqQueue); - - // Call HttpTerminate. - HttpTerminate(HTTP_INITIALIZE_SERVER, NULL); - return; -} - -// -// Internal Function Implementations. -// - -__inline void TraceA(const char *format, ...) -{ - if(g_bDebug) - { - if (format) - { - va_list arglist; - char str[4096]; - - va_start(arglist, format); - StringCchVPrintfA(str, sizeof(str), format, arglist); - StringCbCatA(str, sizeof(str), "\n"); - if (g_fLogFile) - { - FILE *fout = fopen(g_fLogFile, "a+t"); - if (fout) - { - fprintf(fout, str); - fclose(fout); - } - } - - printf(str); - - if (g_bDebugString) - { - - OutputDebugStringA(str); - } - - va_end(arglist); - } - } -} - -__inline void TraceW(const wchar_t *format, ...) -{ - if(g_bDebug) - { - if (format) - { - va_list arglist; - wchar_t str[4096]; - - va_start(arglist, format); - StringCchVPrintfW(str, 4096, format, arglist); - StringCbCatW(str, sizeof(str), L"\n"); - if (g_fLogFile) - { - FILE *fout = fopen(g_fLogFile, "a+t"); - if (fout) - { - fwprintf(fout, str); - fclose(fout); - } - } - - wprintf(str); - - if (g_bDebugString) - { - OutputDebugStringW(str); - } - - va_end(arglist); - } - } -} - -/* - * This is a blocking function that merely sits on the request queue - * for our URI and processes them one at a time. Once a request comes - * in, we check it for content-type, content-length, and verb. As long - * as the initial validations are done, we pass the request to the - * processRPCCall() function, which collects the body of the request - * and processes it. If we get an error back other than network type, - * we are responsible for notifing the client. - */ -DWORD -DoReceiveRequests( - IN HANDLE hReqQueue, - const xmlrpc_server_httpsys_parms * const parmsP - ) -{ - ULONG result; - HTTP_REQUEST_ID requestId; - DWORD bytesRead; - PHTTP_REQUEST pRequest; - PCHAR pRequestBuffer; - ULONG RequestBufferLength; - xmlrpc_env env; - char szHeaderBuf[255]; - long lContentLength; - - // Allocate a 2K buffer. Should be good for most requests, we'll grow - // this if required. We also need space for a HTTP_REQUEST structure. - RequestBufferLength = sizeof(HTTP_REQUEST) + 2048; - pRequestBuffer = (PCHAR) ALLOC_MEM( RequestBufferLength ); - if (pRequestBuffer == NULL) - { - return ERROR_NOT_ENOUGH_MEMORY; - } - - pRequest = (PHTTP_REQUEST)pRequestBuffer; - - // Wait for a new request -- This is indicated by a NULL request ID. - HTTP_SET_NULL_ID( &requestId ); - for(;;) - { - RtlZeroMemory(pRequest, RequestBufferLength); - - result = HttpReceiveHttpRequest( - hReqQueue, // Req Queue - requestId, // Req ID - 0, // Flags - pRequest, // HTTP request buffer - RequestBufferLength,// req buffer length - &bytesRead, // bytes received - NULL // LPOVERLAPPED - ); - - if(NO_ERROR == result) - { - // Got a request with a filled buffer. - switch(pRequest->Verb) - { - case HttpVerbPOST: - - TraceW(L"Got a POST request for %ws", - pRequest->CookedUrl.pFullUrl); - - //Check if we need use authorization. - if(parmsP->authfn) - { - xmlrpc_env_init(&env); - if(pRequest->Headers.KnownHeaders[ - HttpHeaderAuthorization].RawValueLength - < 6) - { - xmlrpc_env_set_fault( - &env, XMLRPC_REQUEST_REFUSED_ERROR, - "Authorization header too short."); - } - else - { - //unencode the headers - if(_strnicmp( - "basic", - pRequest->Headers.KnownHeaders[ - HttpHeaderAuthorization].pRawValue,5) - !=0) - { -#ifndef NDEBUG - PCHAR pTmp = (PCHAR) - ALLOC_MEM(pRequest->Headers.KnownHeaders[ - HttpHeaderAuthorization - ].RawValueLength + 1 ); - if( pTmp ) { - strncpy(pTmp, - pRequest->Headers.KnownHeaders[ - HttpHeaderAuthorization - ].pRawValue, - pRequest->Headers.KnownHeaders[ - HttpHeaderAuthorization - ].RawValueLength ); - pTmp[pRequest->Headers.KnownHeaders[ - HttpHeaderAuthorization - ].RawValueLength] = 0; - TraceA("Got HEADER [%s]",pTmp); - FREE_MEM(pTmp); - } -#endif /* #ifndef NDEBUG */ - xmlrpc_env_set_fault( - &env, XMLRPC_REQUEST_REFUSED_ERROR, - "Authorization header does not start " - "with type 'basic'!"); - } - else - { - xmlrpc_mem_block * decoded; - - decoded = - xmlrpc_base64_decode( - &env, - pRequest->Headers.KnownHeaders[ - HttpHeaderAuthorization - ].pRawValue+6, - pRequest->Headers.KnownHeaders[ - HttpHeaderAuthorization - ].RawValueLength-6); - if(!env.fault_occurred) - { - char *pDecodedStr; - char *pUser; - char *pPass; - char *pColon; - - pDecodedStr = (char*) - malloc(xmlrpc_mem_block_size(decoded)+1); - memcpy(pDecodedStr, - xmlrpc_mem_block_contents(decoded), - xmlrpc_mem_block_size(decoded)); - pDecodedStr[xmlrpc_mem_block_size(decoded)]='\0'; - pUser = pPass = pDecodedStr; - pColon=strchr(pDecodedStr,':'); - if(pColon) - { - *pColon='\0'; - pPass=pColon+1; - //The authfn should set env to - //fail if auth is denied. - parmsP->authfn(&env,pUser,pPass); - } - else - { - xmlrpc_env_set_fault( - &env, - XMLRPC_REQUEST_REFUSED_ERROR, - "Decoded auth not of the correct " - "format."); - } - free(pDecodedStr); - } - if(decoded) - XMLRPC_MEMBLOCK_FREE(char, decoded); - } - } - if(env.fault_occurred) - { - //request basic authorization, as the user - //did not provide it. - xmlrpc_env_clean(&env); - TraceW(L"POST request did not provide valid " - L"authorization header."); - result = - SendHttpResponseAuthRequired( hReqQueue, - pRequest); - break; - } - xmlrpc_env_clean(&env); - } - - //Check content type to make sure it is text/xml. - memcpy(szHeaderBuf, - pRequest->Headers.KnownHeaders[ - HttpHeaderContentType - ].pRawValue, - pRequest->Headers.KnownHeaders[ - HttpHeaderContentType - ].RawValueLength); - szHeaderBuf[pRequest->Headers.KnownHeaders[ - HttpHeaderContentType - ].RawValueLength] = '\0'; - if (_stricmp(szHeaderBuf,"text/xml")!=0) - { - //We handle only text/xml data. Anything else - //is not valid. - TraceW(L"POST request had an unrecognized " - L"content-type: %s", szHeaderBuf); - result = SendHttpResponse( - hReqQueue, - pRequest, - 400, - "Bad Request", - NULL - ); - break; - } - - //Check content length to make sure it exists and - //is not too big. - memcpy(szHeaderBuf, - pRequest->Headers.KnownHeaders[ - HttpHeaderContentLength - ].pRawValue, - pRequest->Headers.KnownHeaders[ - HttpHeaderContentLength - ].RawValueLength); - szHeaderBuf[pRequest->Headers.KnownHeaders[ - HttpHeaderContentLength - ].RawValueLength]='\0'; - lContentLength = atol(szHeaderBuf); - if (lContentLength<=0) - { - //Make sure a content length was supplied. - TraceW(L"POST request did not include a " - L"content-length", szHeaderBuf); - result = SendHttpResponse( - hReqQueue, - pRequest, - 411, - "Length Required", - NULL - ); - break; - } - if((size_t) lContentLength > - xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) - { - //Content-length is too big for us to handle - TraceW(L"POST request content-length is too big " - L"for us to handle: %d bytes", - lContentLength); - result = SendHttpResponse( - hReqQueue, - pRequest, - 500, - "content-length too large", - NULL - ); - break; - } - - //our initial validations of POST, content-type, - //and content-length all check out. Collect and - //pass the complete buffer to the XMLRPC-C library - - xmlrpc_env_init(&env); - processRPCCall(&env,hReqQueue, pRequest); - if (env.fault_occurred) - { - //if we fail and it is anything other than a - //network error, we should return a failure - //response to the client. - if (env.fault_code != XMLRPC_NETWORK_ERROR) - { - if (env.fault_string) - result = SendHttpResponse( - hReqQueue, - pRequest, - 500, - env.fault_string, - NULL - ); - else - result = SendHttpResponse( - hReqQueue, - pRequest, - 500, - "Unknown Error", - NULL - ); - } - } - - xmlrpc_env_clean(&env); - break; - - default: - //We handle only POST data. Anything else is not valid. - TraceW(L"Got an unrecognized Verb request for URI %ws", - pRequest->CookedUrl.pFullUrl); - - result = SendHttpResponse( - hReqQueue, - pRequest, - 405, - "Method Not Allowed", - NULL - ); - break; - } - if(result != NO_ERROR) - { - break; - } - - // Reset the Request ID so that we pick up the next request. - HTTP_SET_NULL_ID( &requestId ); - } - else if(result == ERROR_MORE_DATA) - { - // The input buffer was too small to hold the request headers - // We have to allocate more buffer & call the API again. - // - // When we call the API again, we want to pick up the request - // that just failed. This is done by passing a RequestID. - // This RequestID is picked from the old buffer. - requestId = pRequest->RequestId; - - // Free the old buffer and allocate a new one. - RequestBufferLength = bytesRead; - FREE_MEM( pRequestBuffer ); - pRequestBuffer = (PCHAR) ALLOC_MEM( RequestBufferLength ); - - if (pRequestBuffer == NULL) - { - result = ERROR_NOT_ENOUGH_MEMORY; - break; - } - - pRequest = (PHTTP_REQUEST)pRequestBuffer; - - } - else if(ERROR_CONNECTION_INVALID == result && - !HTTP_IS_NULL_ID(&requestId)) - { - // The TCP connection got torn down by the peer when we were - // trying to pick up a request with more buffer. We'll just move - // onto the next request. - HTTP_SET_NULL_ID( &requestId ); - } - else - { - break; - } - - } // for(;;) - - if(pRequestBuffer) - { - FREE_MEM( pRequestBuffer ); - } - - return result; -} - -/* - * SendHttpResponse sends a text/html content type back with - * the user specified status code and reason. Used for returning - * errors to clients. - */ -DWORD -SendHttpResponse( - IN HANDLE hReqQueue, - IN PHTTP_REQUEST pRequest, - IN USHORT StatusCode, - IN PSTR pReason, - IN PSTR pEntityString - ) -{ - HTTP_RESPONSE response; - HTTP_DATA_CHUNK dataChunk; - DWORD result; - DWORD bytesSent; - CHAR szServerHeader[20]; - - // Initialize the HTTP response structure. - INITIALIZE_HTTP_RESPONSE(&response, StatusCode, pReason); - - ADD_KNOWN_HEADER(response, HttpHeaderContentType, "text/html"); - - StringCchPrintfA(szServerHeader, sizeof(szServerHeader), "Xmlrpc-c/%s", - XMLRPC_C_VERSION); - ADD_KNOWN_HEADER(response, HttpHeaderServer, szServerHeader); - - if(pEntityString) - { - // Add an entity chunk - dataChunk.DataChunkType = HttpDataChunkFromMemory; - dataChunk.FromMemory.pBuffer = pEntityString; - dataChunk.FromMemory.BufferLength = (ULONG) strlen(pEntityString); - - response.EntityChunkCount = 1; - response.pEntityChunks = &dataChunk; - } - - // Since we are sending all the entity body in one call, we don't have - // to specify the Content-Length. - result = HttpSendHttpResponse( - hReqQueue, // ReqQueueHandle - pRequest->RequestId, // Request ID - 0, // Flags - &response, // HTTP response - NULL, // pReserved1 - &bytesSent, // bytes sent (OPTIONAL) - NULL, // pReserved2 (must be NULL) - 0, // Reserved3 (must be 0) - NULL, // LPOVERLAPPED (OPTIONAL) - NULL // pReserved4 (must be NULL) - ); - - if(result != NO_ERROR) - { - TraceW(L"HttpSendHttpResponse failed with %lu", result); - } - - return result; -} - -/* SendHttpResponseAuthRequired sends a 401 status code requesting - * authorization - */ - -DWORD -SendHttpResponseAuthRequired( - IN HANDLE hReqQueue, - IN PHTTP_REQUEST pRequest - ) -{ - HTTP_RESPONSE response; - DWORD result; - DWORD bytesSent; - CHAR szServerHeader[20]; - - // Initialize the HTTP response structure. - INITIALIZE_HTTP_RESPONSE(&response, 401, "Authentication Required"); - - // Add the WWW_Authenticate header. - ADD_KNOWN_HEADER(response, HttpHeaderWwwAuthenticate, - "Basic realm=\"xmlrpc\""); - - StringCchPrintfA(szServerHeader, sizeof(szServerHeader), "Xmlrpc-c/%s", - XMLRPC_C_VERSION); - ADD_KNOWN_HEADER(response, HttpHeaderServer, szServerHeader); - - // Since we are sending all the entity body in one call, we don't have - // to specify the Content-Length. - result = HttpSendHttpResponse( - hReqQueue, // ReqQueueHandle - pRequest->RequestId, // Request ID - 0, // Flags - &response, // HTTP response - NULL, // pReserved1 - &bytesSent, // bytes sent (OPTIONAL) - NULL, // pReserved2 (must be NULL) - 0, // Reserved3 (must be 0) - NULL, // LPOVERLAPPED (OPTIONAL) - NULL // pReserved4 (must be NULL) - ); - - if(result != NO_ERROR) - { - TraceW(L"SendHttpResponseAuthRequired failed with %lu", result); - } - - return result; -} - -/* - * processRPCCall() is called after some validations. The assumption is that - * the request is an HTTP post of content-type text/xml with a content-length - * that is less than the maximum the library can handle. - * - * The caller should check the error status, and if the error was other than - * a network type, respond back to the client to let them know the call failed. - */ -void -processRPCCall( - xmlrpc_env * const envP, - IN HANDLE hReqQueue, - IN PHTTP_REQUEST pRequest - ) -{ - HTTP_RESPONSE response; - DWORD result; - DWORD bytesSent; - PUCHAR pEntityBuffer; - ULONG EntityBufferLength; - ULONG BytesRead; -#define MAX_ULONG_STR ((ULONG) sizeof("4294967295")) - CHAR szContentLength[MAX_ULONG_STR]; - CHAR szServerHeader[20]; - HTTP_DATA_CHUNK dataChunk; - ULONG TotalBytesRead = 0; - xmlrpc_mem_block * body; - xmlrpc_mem_block * output; - - BytesRead = 0; - body = NULL; - output = NULL; - - // Allocate some space for an entity buffer. - EntityBufferLength = 2048; - pEntityBuffer = (PUCHAR) ALLOC_MEM( EntityBufferLength ); - if (pEntityBuffer == NULL) - { - xmlrpc_faultf(envP, "Out of Memory"); - goto Done; - } - - // NOTE: If we had passed the HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY - // flag with HttpReceiveHttpRequest(), the entity would have - // been a part of HTTP_REQUEST (using the pEntityChunks field). - // Since we have not passed that flag, we can be assured that - // there are no entity bodies in HTTP_REQUEST. - if(pRequest->Flags & HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS) - { - //Allocate some space for an XMLRPC memory block. - body = xmlrpc_mem_block_new(envP, 0); - if (envP->fault_occurred) - goto Done; - - // The entity body can be sent over multiple calls. Let's collect all - // of these in a buffer and send the buffer to the xmlrpc-c library - do - { - // Read the entity chunk from the request. - BytesRead = 0; - result = HttpReceiveRequestEntityBody( - hReqQueue, - pRequest->RequestId, - 0, - pEntityBuffer, - EntityBufferLength, - &BytesRead, - NULL - ); - switch(result) - { - case NO_ERROR: - if(BytesRead != 0) - { - XMLRPC_MEMBLOCK_APPEND(char, envP, body, - pEntityBuffer, BytesRead); - if(envP->fault_occurred) - goto Done; - } - break; - - case ERROR_HANDLE_EOF: - // We have read the last request entity body. We can now - // process the suppossed XMLRPC data. - if(BytesRead != 0) - { - XMLRPC_MEMBLOCK_APPEND(char, envP, body, - pEntityBuffer, BytesRead); - if(envP->fault_occurred) - goto Done; - } - - // We will send the response over multiple calls. - // This is achieved by passing the - // HTTP_SEND_RESPONSE_FLAG_MORE_DATA flag. - - // NOTE: Since we are accumulating the TotalBytesRead in - // a ULONG, this will not work for entity bodies that - // are larger than 4 GB. To work with large entity - // bodies, we would have to use a ULONGLONG. - TraceA("xmlrpc_server RPC2 handler processing " - "RPC request."); - - // Process the RPC. - xmlrpc_registry_process_call2( - envP, global_registryP, - XMLRPC_MEMBLOCK_CONTENTS(char, body), - XMLRPC_MEMBLOCK_SIZE(char, body), - NULL, - &output); - if (envP->fault_occurred) - goto Done; - - // Initialize the HTTP response structure. - INITIALIZE_HTTP_RESPONSE(&response, 200, "OK"); - - //Add the content-length - StringCchPrintfA(szContentLength,MAX_ULONG_STR, "%lu", - XMLRPC_MEMBLOCK_SIZE(char, output)); - ADD_KNOWN_HEADER( - response, - HttpHeaderContentLength, - szContentLength ); - - //Add the content-type - ADD_KNOWN_HEADER(response, HttpHeaderContentType, - "text/xml"); - - StringCchPrintfA(szServerHeader, sizeof(szServerHeader), - "Xmlrpc-c/%s", XMLRPC_C_VERSION); - ADD_KNOWN_HEADER(response, HttpHeaderServer, - szServerHeader); - - //send the response - result = HttpSendHttpResponse( - hReqQueue, // ReqQueueHandle - pRequest->RequestId, // Request ID - HTTP_SEND_RESPONSE_FLAG_MORE_DATA, - &response, // HTTP response - NULL, // pReserved1 - &bytesSent, // bytes sent (optional) - NULL, // pReserved2 - 0, // Reserved3 - NULL, // LPOVERLAPPED - NULL // pReserved4 - ); - if(result != NO_ERROR) - { - TraceW(L"HttpSendHttpResponse failed with %lu", - result); - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NETWORK_ERROR, - "HttpSendHttpResponse failed with %lu", result); - goto Done; - } - - // Send entity body from a memory chunk. - dataChunk.DataChunkType = HttpDataChunkFromMemory; - dataChunk.FromMemory.BufferLength = - (ULONG)XMLRPC_MEMBLOCK_SIZE(char, output); - dataChunk.FromMemory.pBuffer = - XMLRPC_MEMBLOCK_CONTENTS(char, output); - - result = HttpSendResponseEntityBody( - hReqQueue, - pRequest->RequestId, - 0, // This is the last send. - 1, // Entity Chunk Count. - &dataChunk, - NULL, - NULL, - 0, - NULL, - NULL - ); - if(result != NO_ERROR) - { - TraceW(L"HttpSendResponseEntityBody failed " - L"with %lu", result); - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NETWORK_ERROR, - "HttpSendResponseEntityBody failed with %lu", - result); - goto Done; - } - goto Done; - break; - default: - TraceW(L"HttpReceiveRequestEntityBody failed with %lu", - result); - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NETWORK_ERROR, - "HttpReceiveRequestEntityBody failed " - "with %lu", result); - goto Done; - } - } while(TRUE); - } - else - { - // This request does not have an entity body. - TraceA("Received a bad request (no body in HTTP post)."); - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_PARSE_ERROR, - "Bad POST request (no body)"); - goto Done; - } - -Done: - - if(pEntityBuffer) - FREE_MEM(pEntityBuffer); - - if(output) - XMLRPC_MEMBLOCK_FREE(char, output); - - if(body) - XMLRPC_MEMBLOCK_FREE(char, body); - - return; -} - - - -/* 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. */ - diff --git a/trunk/src/xmlrpc_string.c b/trunk/src/xmlrpc_string.c deleted file mode 100644 index e6e007166..000000000 --- a/trunk/src/xmlrpc_string.c +++ /dev/null @@ -1,993 +0,0 @@ -/*============================================================================= - xmlrpc_string -=============================================================================== - Routines for the "string" type of xmlrpc_value. - - By Bryan Henderson. - - Contributed to the public domain by its author. -=============================================================================*/ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include - -#include "bool.h" -#include "mallocvar.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "xmlrpc-c/string_int.h" -#include "xmlrpc-c/util.h" - - - -void -xmlrpc_destroyString(xmlrpc_value * const valueP) { - - if (valueP->_wcs_block) - xmlrpc_mem_block_free(valueP->_wcs_block); - - xmlrpc_mem_block_free(valueP->blockP); -} - - - -static void -verifyNoNulls(xmlrpc_env * const envP, - const char * const contents, - unsigned int const len) { -/*---------------------------------------------------------------------------- - Verify that the character array 'contents', which is 'len' bytes long, - does not contain any NUL characters, which means it can be made into - a passable ASCIIZ string just by adding a terminating NUL. - - Fail if the array contains a NUL. ------------------------------------------------------------------------------*/ - unsigned int i; - - for (i = 0; i < len && !envP->fault_occurred; ++i) - if (contents[i] == '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, - "String must not contain NUL characters"); -} - - - -#if HAVE_UNICODE_WCHAR - -static void -verifyNoNullsW(xmlrpc_env * const envP, - const wchar_t * const contents, - unsigned int const len) { -/*---------------------------------------------------------------------------- - Same as verifyNoNulls(), but for wide characters. ------------------------------------------------------------------------------*/ - unsigned int i; - - for (i = 0; i < len && !envP->fault_occurred; i++) - if (contents[i] == '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, - "String must not contain NUL characters"); -} -#endif - - - -static void -validateStringType(xmlrpc_env * const envP, - const xmlrpc_value * const valueP) { - - if (valueP->_type != XMLRPC_TYPE_STRING) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " - "string type was expected.", - xmlrpc_type_name(valueP->_type)); - } -} - - - -static void -accessStringValue(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const char ** const contentsP) { - - validateStringType(envP, valueP); - if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); - size_t const len = size - 1; - /* The memblock has a null character added to the end */ - - verifyNoNulls(envP, contents, len); - - *lengthP = len; - *contentsP = contents; - } -} - - - -void -xmlrpc_read_string(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP) { -/*---------------------------------------------------------------------------- - Read the value of an XML-RPC string as an ASCIIZ string, with - LF for line delimiters. - - Return the string in newly malloc'ed storage that Caller must free. - - Fail if the string contains null characters (which means it wasn't - really a string, but XML-RPC doesn't seem to understand what a string - is, and such values are possible). ------------------------------------------------------------------------------*/ - size_t length; - const char * contents; - - accessStringValue(envP, valueP, &length, &contents); - - if (!envP->fault_occurred) { - char * stringValue; - - MALLOCARRAY(stringValue, length + 1); - if (stringValue == NULL) - xmlrpc_faultf(envP, "Unable to allocate space " - "for %u-character string", (unsigned)length); - else { - memcpy(stringValue, contents, length); - stringValue[length] = '\0'; - - *stringValueP = stringValue; - } - } -} - - - -static unsigned int -lineDelimCount(const char * const start, - const char * const end) { - - unsigned int count; - const char * p; - - for (p = start, count = 0; p < end; ) { - const char * const nlPos = memchr(p, '\n', end-p); - if (nlPos) { - ++count; - p = nlPos + 1; - } else - p = end; - } - - return count; -} - - - -static void -copyAndConvertLfToCrlf(xmlrpc_env * const envP, - size_t const srcLen, - const char * const src, - size_t * const dstLenP, - const char ** const dstP) { - - const char * const srcEnd = src + srcLen; - unsigned int const nLineDelim = lineDelimCount(src, srcEnd); - size_t const dstLen = srcLen + nLineDelim; - char * dst; - - MALLOCARRAY(dst, dstLen + 1); - if (dst == NULL) - xmlrpc_faultf(envP, "Unable to allocate space " - "for %u-character string", (unsigned)dstLen + 1); - else { - const char * p; /* source pointer */ - char * q; /* destination pointer */ - - for (p = &src[0], q = &dst[0]; p < srcEnd; ++p) { - if (*p == '\n') - *q++ = '\r'; - - *q++ = *p; - } - XMLRPC_ASSERT(q == dst + dstLen); - - *q = '\0'; - - *dstP = dst; - *dstLenP = dstLen; - } -} - - - -void -xmlrpc_read_string_crlf(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP) { -/*---------------------------------------------------------------------------- - Same as xmlrpc_read_string(), but return CRLF instead of LF for - line delimiters. ------------------------------------------------------------------------------*/ - size_t length; - const char * contents; - - accessStringValue(envP, valueP, &length, &contents); - - if (!envP->fault_occurred) { - size_t stringLen; - - copyAndConvertLfToCrlf(envP, length, contents, - &stringLen, stringValueP); - } -} - - - -void -xmlrpc_read_string_old(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP) { -/*---------------------------------------------------------------------------- - Like xmlrpc_read_string(), except it returns as *stringValueP a pointer - into memory owned by *valueP, rather than new memory to be owned by - Caller. - - This is for internal use; it's necessary to implement the deprecated - xmlrpc_parse_value(), which also returns pointers to someone else's - storage. ------------------------------------------------------------------------------*/ - size_t length; - accessStringValue(envP, valueP, &length, stringValueP); -} - - - -void -xmlrpc_read_string_lp(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const char ** const stringValueP) { - - validateStringType(envP, valueP); - if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); - - char * stringValue; - - stringValue = malloc(size); - if (stringValue == NULL) - xmlrpc_faultf(envP, "Unable to allocate %u bytes for string.", - (unsigned int)size); - else { - memcpy(stringValue, contents, size); - *stringValueP = stringValue; - *lengthP = size - 1; /* Size includes terminating NUL */ - } - } -} - - - -void -xmlrpc_read_string_lp_crlf(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const char ** const stringValueP) { - - validateStringType(envP, valueP); - if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); /* Includes NUL */ - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); - - copyAndConvertLfToCrlf(envP, size-1, contents, - lengthP, stringValueP); - } -} - - - -void -xmlrpc_read_string_lp_old(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - size_t * const lengthP, - const char ** const stringValueP) { -/*---------------------------------------------------------------------------- - This is to xmlrpc_read_string_lp() as xmlrpc_read_string_old() is - to xmlrpc_read_string(). ------------------------------------------------------------------------------*/ - validateStringType(envP, valueP); - if (!envP->fault_occurred) { - *lengthP = XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP) - 1; - *stringValueP = XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); - } -} - - - -static __inline__ void -setupWcsBlock(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { -/*---------------------------------------------------------------------------- - Add a wcs block (wchar_t string) to the indicated xmlrpc_value if it - doesn't have one already. ------------------------------------------------------------------------------*/ - if (!valueP->_wcs_block) { - char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); - size_t const len = - XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP) - 1; - valueP->_wcs_block = - xmlrpc_utf8_to_wcs(envP, contents, len + 1); - } -} - - - -#if HAVE_UNICODE_WCHAR - -static void -accessStringValueW(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - size_t * const lengthP, - const wchar_t ** const stringValueP) { - - validateStringType(envP, valueP); - if (!envP->fault_occurred) { - setupWcsBlock(envP, valueP); - - if (!envP->fault_occurred) { - wchar_t * const wcontents = - XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); - size_t const len = - XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block) - 1; - - verifyNoNullsW(envP, wcontents, len); - - *lengthP = len; - *stringValueP = wcontents; - } - } -} - - - -void -xmlrpc_read_string_w(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const wchar_t ** const stringValueP) { - - size_t length; - const wchar_t * wcontents; - - accessStringValueW(envP, valueP, &length, &wcontents); - - if (!envP->fault_occurred) { - wchar_t * stringValue; - MALLOCARRAY(stringValue, length + 1); - if (stringValue == NULL) - xmlrpc_faultf(envP, "Unable to allocate space for %u-byte string", - (unsigned)length); - else { - memcpy(stringValue, wcontents, length * sizeof(wchar_t)); - stringValue[length] = '\0'; - - *stringValueP = stringValue; - } - } -} - - - -static unsigned int -lineDelimCountW(const wchar_t * const start, - const wchar_t * const end) { - - unsigned int count; - const wchar_t * p; - - count = 0; - p = start; - - while (p && p < end) { - /* We used to use memchr(), but Windows doesn't have it */ - p = wcsstr(p, L"\n"); - if (p && p < end) { - ++count; /* count the newline */ - ++p; /* skip the newline */ - } - } - - return count; -} - - - -static void -wCopyAndConvertLfToCrlf(xmlrpc_env * const envP, - size_t const srcLen, - const wchar_t * const src, - size_t * const dstLenP, - const wchar_t ** const dstP) { - - const wchar_t * const srcEnd = src + srcLen; - unsigned int const nLineDelim = lineDelimCountW(src, srcEnd); - size_t const dstLen = srcLen + nLineDelim; - wchar_t * dst; - - MALLOCARRAY(dst, dstLen + 1); - if (dst == NULL) - xmlrpc_faultf(envP, "Unable to allocate space " - "for %u-character string", (unsigned)dstLen + 1); - else { - const wchar_t * p; /* source pointer */ - wchar_t * q; /* destination pointer */ - - for (p = &src[0], q = &dst[0]; p < srcEnd; ++p) { - if (*p == '\n') - *q++ = '\r'; - - *q++ = *p; - } - XMLRPC_ASSERT(q == dst + dstLen); - - *q = '\0'; - - *dstP = dst; - *dstLenP = dstLen; - } -} - - - -void -xmlrpc_read_string_w_crlf(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const wchar_t ** const stringValueP) { - - size_t size; - const wchar_t * contents; - - accessStringValueW(envP, valueP, &size, &contents); - - if (!envP->fault_occurred) { - size_t stringLen; - - wCopyAndConvertLfToCrlf(envP, size, contents, - &stringLen, stringValueP); - } -} - - - -void -xmlrpc_read_string_w_old(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const wchar_t ** const stringValueP) { -/*---------------------------------------------------------------------------- - This is to xmlrpc_read_string_w() as xmlrpc_read_string_old() is - to xmlrpc_read_string(). ------------------------------------------------------------------------------*/ - size_t length; - - accessStringValueW(envP, valueP, &length, stringValueP); -} - - - -void -xmlrpc_read_string_w_lp(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - size_t * const lengthP, - const wchar_t ** const stringValueP) { - - validateStringType(envP, valueP); - if (!envP->fault_occurred) { - setupWcsBlock(envP, valueP); - - if (!envP->fault_occurred) { - wchar_t * const wcontents = - XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block); - - wchar_t * stringValue; - - MALLOCARRAY(stringValue, size); - if (stringValue == NULL) - xmlrpc_faultf(envP, - "Unable to allocate space for %u-byte string", - (unsigned int)size); - else { - memcpy(stringValue, wcontents, size * sizeof(wchar_t)); - - *lengthP = size - 1; /* size includes terminating NUL */ - *stringValueP = stringValue; - } - } - } -} - - - -void -xmlrpc_read_string_w_lp_crlf(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - size_t * const lengthP, - const wchar_t ** const stringValueP) { - - validateStringType(envP, valueP); - if (!envP->fault_occurred) { - setupWcsBlock(envP, valueP); - - if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block); - wchar_t * const wcontents = - XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); - - wCopyAndConvertLfToCrlf(envP, size-1, wcontents, - lengthP, 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) { -/*---------------------------------------------------------------------------- - This is to xmlrpc_read_string_w_lp() as xmlrpc_read_string_old() is - to xmlrpc_read_string(). ------------------------------------------------------------------------------*/ - validateStringType(envP, valueP); - if (!envP->fault_occurred) { - setupWcsBlock(envP, valueP); - - if (!envP->fault_occurred) { - wchar_t * const wcontents = - XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block); - - *lengthP = size - 1; /* size includes terminating NUL */ - *stringValueP = wcontents; - } - } -} -#endif /* HAVE_UNICODE_WCHAR */ - - - -void -xmlrpc_string_validate(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { -/*---------------------------------------------------------------------------- - Validate that *valueP is not the kind of value that would serialize into - invalid XML. - - To wit, the string does not contain any characters that are not valid XML - characters, which means it does not contain ASCII control characters - other than carriage return, line feed, and tab. - - Xmlrpc-c has the odd function, because of mistakes that were made in the - early days of XML-RPC, that it is possible to cause it to generate an - XML-RPC call or response that is invalid XML, which you do with a string - value which contains things other than XML characters. But it's a really - bad idea to exercise that option, so code that constructs string values can - use this function to ensure that it does not. See the discussion of the - string data type in the Xmlrpc-c user's guide for a detailed explanation of - this issue. ------------------------------------------------------------------------------*/ - enum {LF = 0x0a, CR = 0x0d, TAB = 0x08}; - - size_t length; - const char * contents; - - accessStringValue(envP, valueP, &length, &contents); - - if (!envP->fault_occurred) { - unsigned int i; - for (i = 0; i < length && !envP->fault_occurred; ++i) { - char const c = contents[i]; - if (iscntrl(c) && c != LF && c != CR && c != TAB) - xmlrpc_faultf(envP, "String contains an invalid value " - "(Not a Unicode codepoint for a legal XML " - "character) x%02x at position %u", - c, i); - } - } -} - - - -static void -copyLines(xmlrpc_env * const envP, - const char * const src, - size_t const srcLen, - xmlrpc_mem_block ** const dstPP) { -/*---------------------------------------------------------------------------- - Generate the internal representation of string xmlrpc_value contents for - string 'src', which is 'srcLen' characters long and has lines separated by - LF, CR, and/or CRLF. Return it as a new xmlrpc_mem_block at *dstPP. - - Note that the source format differs from the destination format in - that in the destination format, lines are separated only by newline - (LF). - - It is tempting to believe that if we just put the user's line - delimiters in the xmlrpc_value here (i.e. where user has CRLF, the - xmlrpc_value also has CRLF), the user's line delimiters would go - all the way across to the XML-RPC partner. But that won't work, - because the XML processor on the other side will, following Section - 2.11 of the XML spec, normalize all line endings to LF anyhow. So - then you might ask, why do we bother to do all the work to convert - them here? Because: besides just being logically cleaner, this way - xmlrpc_read_string() gets the proper value -- the same one the - XML-RPC partner would see. ------------------------------------------------------------------------------*/ - /* Destination format is sometimes smaller than source (because - CRLF turns into LF), but never smaller. So we allocate - destination space equal to source size (plus one for - terminating NUL), but don't necessarily use it all. - */ - - /* To convert LF, CR, and CRLF to LF, all we have to do is - copy everything up to a CR verbatim, then insert an LF and - skip the CR and any following LF, and repeat. - */ - - xmlrpc_mem_block * dstP; - - dstP = XMLRPC_MEMBLOCK_NEW(char, envP, srcLen + 1); - - if (!envP->fault_occurred) { - const char * const srcEnd = &src[srcLen]; - char * const contents = XMLRPC_MEMBLOCK_CONTENTS(char, dstP); - - const char * srcCursor; - char * dstCursor; - - for (srcCursor = &src[0], dstCursor = &contents[0]; - srcCursor < srcEnd;) { - - char * const crPos = memchr(srcCursor, '\r', srcEnd - srcCursor); - - if (crPos) { - size_t const copyLen = crPos - srcCursor; - memcpy(dstCursor, srcCursor, copyLen); - srcCursor += copyLen; - dstCursor += copyLen; - - *(dstCursor++) = '\n'; - - XMLRPC_ASSERT(*srcCursor == '\r'); - ++srcCursor; /* Move past CR */ - if (*srcCursor == '\n') - ++srcCursor; /* Move past LF */ - } else { - size_t const remainingLen = srcEnd - srcCursor; - memcpy(dstCursor, srcCursor, remainingLen); - srcCursor += remainingLen; - dstCursor += remainingLen; - } - } - - *dstCursor++ = '\0'; - - XMLRPC_ASSERT((unsigned)(dstCursor - &contents[0]) <= srcLen + 1); - - XMLRPC_MEMBLOCK_RESIZE(char, envP, dstP, dstCursor - &contents[0]); - - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, dstP); - } - *dstPP = dstP; -} - - - -static void -copySimple(xmlrpc_env * const envP, - const char * const src, - size_t const srcLen, - xmlrpc_mem_block ** const dstPP) { -/*---------------------------------------------------------------------------- - Generate the internal representation of string xmlrpc_value contents for - string 'src', which is 'srcLen' characters long and, conveniently enough, - has the exact same format as the internal representation. - - To wit, 'src' has lines separated by LFs only -- no CR or CRLF. - - Return it as a new xmlrpc_mem_block at *dstPP. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * dstP; - - dstP = XMLRPC_MEMBLOCK_NEW(char, envP, srcLen + 1); - - if (!envP->fault_occurred) { - char * const contents = XMLRPC_MEMBLOCK_CONTENTS(char, dstP); - - memcpy(contents, src, srcLen); - contents[srcLen] = '\0'; - } - *dstPP = dstP; -} - - - -enum crTreatment { CR_IS_LINEDELIM, CR_IS_CHAR }; - -static void -stringNew(xmlrpc_env * const envP, - size_t const length, - const char * const value, - enum crTreatment const crTreatment, - xmlrpc_value ** const valPP) { - - xmlrpc_value * valP; - - xmlrpc_validate_utf8(envP, value, length); - - if (!envP->fault_occurred) { - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_STRING; - valP->_wcs_block = NULL; - - /* Note that copyLines() works for strings with no CRs, but - it's slower. - */ - if (memchr(value, '\r', length) && crTreatment == CR_IS_LINEDELIM) - copyLines(envP, value, length, &valP->blockP); - else - copySimple(envP, value, length, &valP->blockP); - - if (envP->fault_occurred) - free(valP); - else - *valPP = valP; - } - } -} - - - -xmlrpc_value * -xmlrpc_string_new_lp(xmlrpc_env * const envP, - size_t const length, - const char * const value) { - - xmlrpc_value * retval; - stringNew(envP, length, value, CR_IS_LINEDELIM, &retval); - return retval; -} - - - -xmlrpc_value * -xmlrpc_string_new_lp_cr(xmlrpc_env * const envP, - size_t const length, - const char * const value) { - - xmlrpc_value * retval; - stringNew(envP, length, value, CR_IS_CHAR, &retval); - return retval; -} - - - -xmlrpc_value * -xmlrpc_string_new(xmlrpc_env * const envP, - const char * const value) { - - xmlrpc_value * retval; - stringNew(envP, strlen(value), value, CR_IS_LINEDELIM, &retval); - return retval; -} - - - -xmlrpc_value * -xmlrpc_string_new_cr(xmlrpc_env * const envP, - const char * const value) { - - xmlrpc_value * retval; - stringNew(envP, strlen(value), value, CR_IS_CHAR, &retval); - return retval; -} - - - -xmlrpc_value * -xmlrpc_string_new_va(xmlrpc_env * const envP, - const char * const format, - va_list args) { - - const char * formattedString; - xmlrpc_value * retvalP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(format != NULL); - - xmlrpc_vasprintf(&formattedString, format, args); - - if (xmlrpc_strnomem(formattedString)) { - xmlrpc_faultf(envP, "Out of memory building formatted string"); - retvalP = NULL; /* defeat compiler warning */ - } else - retvalP = xmlrpc_string_new(envP, formattedString); - - xmlrpc_strfree(formattedString); - - return retvalP; -} - - - -xmlrpc_value * -xmlrpc_string_new_f(xmlrpc_env * const envP, - const char * const format, - ...) { - - va_list args; - xmlrpc_value * retval; - - va_start(args, format); - - retval = xmlrpc_string_new_va(envP, format, args); - - va_end(args); - - return retval; -} - - - -#if HAVE_UNICODE_WCHAR - -static void -stringWNew(xmlrpc_env * const envP, - size_t const length, - const wchar_t * const value, - enum crTreatment const crTreatment, - xmlrpc_value ** const valPP) { - - xmlrpc_mem_block * utf8P; - - utf8P = xmlrpc_wcs_to_utf8(envP, value, length); - if (!envP->fault_occurred) { - char * const utf8_value = XMLRPC_MEMBLOCK_CONTENTS(char, utf8P); - size_t const utf8_len = XMLRPC_MEMBLOCK_SIZE(char, utf8P); - - if (!envP->fault_occurred) { - stringNew(envP, utf8_len, utf8_value, crTreatment, valPP); - - XMLRPC_MEMBLOCK_FREE(char, utf8P); - } - } -} - - - -xmlrpc_value * -xmlrpc_string_w_new_lp(xmlrpc_env * const envP, - size_t const length, - const wchar_t * const value) { - - xmlrpc_value * valP; - stringWNew(envP, length, value, CR_IS_LINEDELIM, &valP); - return valP; -} - - - - -xmlrpc_value * -xmlrpc_string_w_new_lp_cr(xmlrpc_env * const envP, - size_t const length, - const wchar_t * const value) { - - xmlrpc_value * valP; - stringWNew(envP, length, value, CR_IS_CHAR, &valP); - return valP; -} - - - - -xmlrpc_value * -xmlrpc_string_w_new(xmlrpc_env * const envP, - const wchar_t * const value) { - - xmlrpc_value * valP; - stringWNew(envP, wcslen(value), value, CR_IS_LINEDELIM, &valP); - return valP; -} - - - -xmlrpc_value * -xmlrpc_string_w_new_cr(xmlrpc_env * const envP, - const wchar_t * const value) { - - xmlrpc_value * valP; - stringWNew(envP, wcslen(value), value, CR_IS_CHAR, &valP); - return valP; -} - - - -#endif /* HAVE_UNICODE_WCHAR */ - - - -xmlrpc_value * -xmlrpc_string_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * valP; - - if (valueP->_type != XMLRPC_TYPE_STRING) { - xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, - "Value is not a string. " - "It is type #%d", valueP->_type); - valP = NULL; - } else { - xmlrpc_createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_STRING; - - valP->blockP = - xmlrpc_mem_block_new(envP, - xmlrpc_mem_block_size(valueP->blockP)); - - if (!envP->fault_occurred) { - memcpy(xmlrpc_mem_block_contents(valP->blockP), - xmlrpc_mem_block_contents(valueP->blockP), - xmlrpc_mem_block_size(valueP->blockP)); - } - } - if (!envP->fault_occurred) { - if (valueP->_wcs_block) { - valP->_wcs_block = - xmlrpc_mem_block_new( - envP, - xmlrpc_mem_block_size(valueP->_wcs_block)); - - if (!envP->fault_occurred) { - memcpy(xmlrpc_mem_block_contents(valP->_wcs_block), - xmlrpc_mem_block_contents(valueP->_wcs_block), - xmlrpc_mem_block_size(valueP->_wcs_block)); - } - } else - valP->_wcs_block = NULL; - } - } - return valP; -} - - - diff --git a/trunk/src/xmlrpc_struct.c b/trunk/src/xmlrpc_struct.c deleted file mode 100644 index d5606906b..000000000 --- a/trunk/src/xmlrpc_struct.c +++ /dev/null @@ -1,711 +0,0 @@ -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/base_int.h" -#include "int.h" - -#define KEY_ERROR_BUFFER_SZ (32) - - - -static uint32_t -hashStructKey(const char * const key, - size_t const keyLen) { - - uint32_t hash; - size_t i; - - XMLRPC_ASSERT(key != NULL); - - /* This is the Bernstein hash, optimized for lower case ASCII - keys. Note that the bytes of such a key differ only in their - lower 5 bits. - */ - for (hash = 0, i = 0; i < keyLen; ++i) - hash = hash + key[i] + (hash << 5); - - return hash; -} - - - -static void -changeMemberValue(xmlrpc_value * const structP, - unsigned int const mbrIndex, - xmlrpc_value * const newValueP) { -/*---------------------------------------------------------------------------- - Change the value of an existing member. (But be careful--the original and - new values might be the same object, so watch the order of INCREF and DECREF - calls!) ------------------------------------------------------------------------------*/ - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); - _struct_member * const memberP = &members[mbrIndex]; - xmlrpc_value * const oldValueP = memberP->value; - - /* Juggle our references. */ - memberP->value = newValueP; - xmlrpc_INCREF(memberP->value); - xmlrpc_DECREF(oldValueP); -} - - - -static void -addNewMember(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyvalP, - xmlrpc_value * const valueP) { -/*---------------------------------------------------------------------------- - Add a new member. Assume no member already exists with this key. ------------------------------------------------------------------------------*/ - const char * const key = - XMLRPC_MEMBLOCK_CONTENTS(char, keyvalP->blockP); - size_t const keyLen = - XMLRPC_MEMBLOCK_SIZE(char, keyvalP->blockP) - 1; - - _struct_member newMember; - - newMember.keyHash = hashStructKey(key, keyLen); - newMember.key = keyvalP; - newMember.value = valueP; - - XMLRPC_MEMBLOCK_APPEND(_struct_member, envP, structP->blockP, - &newMember, 1); - - if (!envP->fault_occurred) { - xmlrpc_INCREF(keyvalP); - xmlrpc_INCREF(valueP); - } -} - - - -void -xmlrpc_destroyStruct(xmlrpc_value * const structP) { -/*---------------------------------------------------------------------------- - Dispose of the contents of struct *structP (but not the struct value - itself). The value is not valid after this. ------------------------------------------------------------------------------*/ - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); - - unsigned int i; - - for (i = 0; i < size; ++i) { - xmlrpc_DECREF(members[i].key); - xmlrpc_DECREF(members[i].value); - } - XMLRPC_MEMBLOCK_FREE(_struct_member, structP->blockP); -} - - - -/*========================================================================= -** xmlrpc_struct_new -**========================================================================= -** Create a new value. The corresponding destructor code -** currently lives in xmlrpc_DECREF. -** -** We store the individual members in an array of _struct_member. This -** contains a key, a hash code, and a value. We look up keys by doing -** a linear search of the hash codes. -*/ - -xmlrpc_value * -xmlrpc_struct_new(xmlrpc_env * const envP) { - - xmlrpc_value * valP; - - XMLRPC_ASSERT_ENV_OK(envP); - - xmlrpc_createXmlrpcValue(envP, &valP); - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_STRUCT; - - valP->blockP = XMLRPC_MEMBLOCK_NEW(_struct_member, envP, 0); - - if (envP->fault_occurred) - free(valP); - } - return valP; -} - - - -xmlrpc_value * -xmlrpc_struct_new_value(xmlrpc_env * const envP, - xmlrpc_value * const valueP) { - - xmlrpc_value * structP; - - if (valueP->_type != XMLRPC_TYPE_STRUCT) { - xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, - "Value is not a structure. " - "It is type #%d", valueP->_type); - structP = NULL; - } else { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, structP->blockP); - - xmlrpc_createXmlrpcValue(envP, &structP); - if (!envP->fault_occurred) { - structP->_type = XMLRPC_TYPE_STRUCT; - - structP->blockP = XMLRPC_MEMBLOCK_NEW(xmlrpc_value *, envP, 0); - - if (envP->fault_occurred) - free(structP); - else { - _struct_member * const srcMemberList = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, valueP->blockP); - - unsigned int i; - - for (i = 0; i < size && !envP->fault_occurred; ++i) { - const _struct_member * const thisMemberP = - &srcMemberList[i]; - - xmlrpc_value * keyValP = - xmlrpc_string_new_value(envP, thisMemberP->key); - if (!envP->fault_occurred) { - xmlrpc_value * valueP = - xmlrpc_value_new(envP, thisMemberP->value); - - if (!envP->fault_occurred) { - addNewMember(envP, structP, keyValP, valueP); - - xmlrpc_DECREF(valueP); - } - xmlrpc_DECREF(keyValP); - } - } - if (envP->fault_occurred) - xmlrpc_destroyStruct(structP); - } - - if (envP->fault_occurred) - free(structP); - } - } - return structP; -} - - - -/*========================================================================= -** xmlrpc_struct_size -**========================================================================= -** Return the number of key-value pairs contained in the struct. If the -** value is not a struct, return -1 and set a fault. -*/ - -int -xmlrpc_struct_size(xmlrpc_env * const envP, - xmlrpc_value * const structP) { - - int retval; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - - if (structP->_type != XMLRPC_TYPE_STRUCT) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", - structP->_type); - retval = -1; - } else { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); - - assert((size_t)(int)size == size); - /* Because structs are defined to have few enough members */ - - retval = (int)size; - } - return retval; -} - - - -static void -findMember(xmlrpc_value * const structP, - const char * const key, - size_t const keyLen, - bool * const foundP, - unsigned int * const indexP) { - - size_t size, i; - uint32_t searchHash; - _struct_member * contents; /* array */ - bool found; - size_t foundIndex; /* Meaningful only when 'found' is true */ - - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT(key != NULL); - foundIndex = 0; /* defeat used-before-set compiler warning */ - - /* Look for our key. */ - searchHash = hashStructKey(key, keyLen); - size = XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); - contents = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); - for (i = 0, found = false; i < size && !found; ++i) { - if (contents[i].keyHash == searchHash) { - xmlrpc_value * const keyvalP = contents[i].key; - const char * const keystr = - XMLRPC_MEMBLOCK_CONTENTS(char, keyvalP->blockP); - size_t const keystrSize = - XMLRPC_MEMBLOCK_SIZE(char, keyvalP->blockP)-1; - if (keystrSize == keyLen && memcmp(key, keystr, keyLen) == 0) { - found = true; - foundIndex = i; - } - } - } - if (found) { - assert((size_t)(int)foundIndex == foundIndex); - /* Definition of structure says it has few enough members */ - - if (indexP) - *indexP = foundIndex; - } - *foundP = found; -} - - - -/*========================================================================= -** xmlrpc_struct_has_key -**========================================================================= -*/ - -int -xmlrpc_struct_has_key(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key) { - - XMLRPC_ASSERT(key != NULL); - return xmlrpc_struct_has_key_n(envP, strctP, key, strlen(key)); -} - - - -int -xmlrpc_struct_has_key_n(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - size_t const keyLen) { - int retval; - - /* Suppress a compiler warning about uninitialized variables. */ - retval = 0; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT(key != NULL); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault(envP, XMLRPC_TYPE_ERROR, - "Value is not a struct"); - else { - bool found; - - findMember(structP, key, keyLen, &found, NULL); - - retval = found ? 1 : 0; - } - return retval; -} - - - -/*========================================================================= -** xmlrpc_struct_find_value... -**========================================================================= -** These functions look up a specified key value in a specified struct. -** If it exists, they return the value of the struct member. If not, -** they return a NULL to indicate such. -*/ - -/* It would be a nice extension to be able to look up a key that is - not a text string. -*/ - -void -xmlrpc_struct_find_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Given a key, retrieve a value from the struct. If the key is not - present, return NULL as *valuePP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_PTR_OK(key); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", - structP->_type); - else { - bool found; - unsigned int index; - - /* Get our member index. */ - findMember(structP, key, strlen(key), &found, &index); - if (!found) - *valuePP = NULL; - else { - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); - *valuePP = members[index].value; - - XMLRPC_ASSERT_VALUE_OK(*valuePP); - - xmlrpc_INCREF(*valuePP); - } - } -} - - - -void -xmlrpc_struct_find_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Given a key, retrieve a value from the struct. If the key is not - present, return NULL as *valuePP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_VALUE_OK(keyP); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", - structP->_type); - else { - if (keyP->_type != XMLRPC_TYPE_STRING) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Key value is not a string. " - "It is type #%d", - keyP->_type); - else { - bool found; - unsigned int index; - - /* Get our member index. */ - findMember(structP, - XMLRPC_MEMBLOCK_CONTENTS(char, keyP->blockP), - XMLRPC_MEMBLOCK_SIZE(char, keyP->blockP)-1, - &found, &index); - if (!found) - *valuePP = NULL; - else { - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); - *valuePP = members[index].value; - - XMLRPC_ASSERT_VALUE_OK(*valuePP); - - xmlrpc_INCREF(*valuePP); - } - } - } -} - - - -/*========================================================================= -** xmlrpc_struct_read_value... -**========================================================================= -** These fail if no member with the specified key exists. -** Otherwise, they are the same as xmlrpc_struct_find_value... -*/ - -void -xmlrpc_struct_read_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP) { - - xmlrpc_struct_find_value_v(envP, structP, keyP, valuePP); - - if (!envP->fault_occurred) { - if (*valuePP == NULL) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "No member of struct has key '%.*s'", - (int)XMLRPC_MEMBLOCK_SIZE(char, keyP->blockP), - XMLRPC_MEMBLOCK_CONTENTS(char, keyP->blockP)); - } - } -} - - - -void -xmlrpc_struct_read_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - xmlrpc_value ** const valuePP) { - - xmlrpc_struct_find_value(envP, structP, key, valuePP); - - if (!envP->fault_occurred) { - if (*valuePP == NULL) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "No member of struct has key '%s'", - key); - /* We should fix the error message to format the key for display */ - } - } -} - - - -/*========================================================================= -** xmlrpc_struct_get_value... -**========================================================================= -** These are for backward compatibility. They used to be the only ones. -** They're deprecated because they don't acquire a reference to the -** value they return. -*/ - -xmlrpc_value * -xmlrpc_struct_get_value_n(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - size_t const keyLen) { - - xmlrpc_value * retval; - xmlrpc_value * keyP; /* 'key' as an XML-RPC string */ - - keyP = xmlrpc_string_new_lp(envP, keyLen, key); - if (!envP->fault_occurred) { - xmlrpc_struct_find_value_v(envP, structP, keyP, &retval); - - if (!envP->fault_occurred) { - if (retval == NULL) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, - "No member of struct has key '%.*s'", - (int)keyLen, key); - /* We should fix the error message to format the key - for display */ - } else - /* For backward compatibility. */ - xmlrpc_DECREF(retval); - } - xmlrpc_DECREF(keyP); - } - return retval; -} - - - -xmlrpc_value * -xmlrpc_struct_get_value(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key) { - - XMLRPC_ASSERT(key != NULL); - return xmlrpc_struct_get_value_n(envP, strctP, key, strlen(key)); -} - - - -/*========================================================================= -** xmlrpc_struct_set_value -**========================================================================= -*/ - -void -xmlrpc_struct_set_value(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - xmlrpc_value * const valueP) { - - XMLRPC_ASSERT(key != NULL); - xmlrpc_struct_set_value_n(envP, strctP, key, strlen(key), valueP); -} - - - -void -xmlrpc_struct_set_value_n(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - size_t const keyLen, - xmlrpc_value * const valueP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(key != NULL); - - if (xmlrpc_value_type(strctP) != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, - "Trying to set value in something not a struct. " - "Type is %d; struct is %d", - xmlrpc_value_type(strctP), XMLRPC_TYPE_STRUCT); - else { - xmlrpc_value * keyvalP; /* 'key' as an XML-RPC string */ - - keyvalP = xmlrpc_string_new_lp(envP, keyLen, key); - if (!envP->fault_occurred) - xmlrpc_struct_set_value_v(envP, strctP, keyvalP, valueP); - - xmlrpc_DECREF(keyvalP); - } -} - - - -void -xmlrpc_struct_set_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyvalP, - xmlrpc_value * const valueP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_VALUE_OK(keyvalP); - XMLRPC_ASSERT_VALUE_OK(valueP); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault(envP, XMLRPC_TYPE_ERROR, - "Value is not a struct"); - else if (keyvalP->_type != XMLRPC_TYPE_STRING) - xmlrpc_env_set_fault(envP, XMLRPC_TYPE_ERROR, - "Key value is not a string"); - else { - const char * const key = - XMLRPC_MEMBLOCK_CONTENTS(char, keyvalP->blockP); - size_t const keyLen = - XMLRPC_MEMBLOCK_SIZE(char, keyvalP->blockP) - 1; - - bool found; - unsigned int index; - - findMember(structP, key, keyLen, &found, &index); - - if (found) - changeMemberValue(structP, index, valueP); - else - addNewMember(envP, structP, keyvalP, valueP); - } -} - - - -/* Note that the order of keys and values is undefined, and may change - when you modify the struct. -*/ - -void -xmlrpc_struct_read_member(xmlrpc_env * const envP, - xmlrpc_value * const structP, - unsigned int const index, - xmlrpc_value ** const keyvalP, - xmlrpc_value ** const valueP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_PTR_OK(keyvalP); - XMLRPC_ASSERT_PTR_OK(valueP); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Attempt to read a struct member " - "of something that is not a struct"); - else { - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); - - if (index >= size) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Index %u is beyond the end of " - "the %u-member structure", index, (unsigned int)size); - else { - _struct_member * const memberP = &members[index]; - *keyvalP = memberP->key; - xmlrpc_INCREF(memberP->key); - *valueP = memberP->value; - xmlrpc_INCREF(memberP->value); - } - } -} - - - -void -xmlrpc_struct_get_key_and_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - int const index, - xmlrpc_value ** const keyvalP, - xmlrpc_value ** const valueP) { -/*---------------------------------------------------------------------------- - Same as xmlrpc_struct_read_member(), except doesn't take a reference - to the returned value. - - This is obsolete. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_PTR_OK(keyvalP); - XMLRPC_ASSERT_PTR_OK(valueP); - - if (index < 0) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Index %d is negative.", index); - else { - xmlrpc_struct_read_member(envP, structP, index, keyvalP, valueP); - if (!envP->fault_occurred) { - xmlrpc_DECREF(*keyvalP); - xmlrpc_DECREF(*valueP); - } - } - if (envP->fault_occurred) { - *keyvalP = NULL; - *valueP = NULL; - } -} - - - -/* 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. */ - diff --git a/trunk/srcdir.mk.in b/trunk/srcdir.mk.in deleted file mode 100644 index d389df1b6..000000000 --- a/trunk/srcdir.mk.in +++ /dev/null @@ -1 +0,0 @@ -SRCDIR=@abs_srcdir@ diff --git a/trunk/stamp-h.in b/trunk/stamp-h.in deleted file mode 100644 index 9788f7023..000000000 --- a/trunk/stamp-h.in +++ /dev/null @@ -1 +0,0 @@ -timestamp diff --git a/trunk/test/Makefile b/trunk/test/Makefile deleted file mode 100644 index 4fce824c7..000000000 --- a/trunk/test/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - SRCDIR := $(call updir,$(CURDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := test - -include $(BLDDIR)/config.mk - -SUBDIRS = cpp - -XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test - -LDADD_CGI_SERVER = \ - $(shell $(XMLRPC_C_CONFIG) cgi-server --ldadd) - -default: all - -INCLUDES = -I$(BLDDIR) -Isrcdir/include -Isrcdir/lib/util/include \ - -PROGS = test cgitest1 - -all: $(PROGS) $(SUBDIRS:%=%/all) - -TEST_OBJS = \ - testtool.o \ - test.o \ - cgi.o \ - memblock.o \ - method_registry.o \ - parse_xml.o \ - serialize.o \ - serialize_value.o \ - value.o \ - value_datetime.o \ - xml_data.o \ - -ifeq ($(MUST_BUILD_CLIENT),yes) - TEST_OBJS += client.o - LIBXMLRPC_CLIENT_DEP = $(LIBXMLRPC_CLIENT_A) - LDADD_CLIENT = $(shell $(XMLRPC_C_CONFIG) client --ldadd) -else - TEST_OBJS += client_dummy.o - LIBXMLRPC_CLIENT_DEP = - LDADD_CLIENT = -endif - -ifeq ($(ENABLE_ABYSS_SERVER),yes) - TEST_OBJS += abyss.o server_abyss.o - LIBXMLRPC_ABYSS_DEP = $(LIBXMLRPC_ABYSS_A) - LIBXMLRPC_SERVER_ABYSS_DEP = $(LIBXMLRPC_ABYSS_A) - LDADD_ABYSS_SERVER = \ - $(shell $(XMLRPC_C_CONFIG) abyss-server --ldadd) -else - TEST_OBJS += abyss_dummy.o server_abyss_dummy.o - LIBXMLRPC_ABYSS_DEP = - LIBXMLRPC_SERVER_ABYSS_DEP = - LDADD_ABYSS_SERVER = -endif - -include $(SRCDIR)/common.mk - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -test: \ - $(XMLRPC_C_CONFIG) \ - $(TEST_OBJS) $(LIBXMLRPC_A) $(LIBXMLRPC_UTIL_A) \ - $(LIBXMLRPC_SERVER_A) $(LIBXMLRPC_SERVER_ABYSS_DEP) $(LIBXMLRPC_XML) \ - $(LIBXMLRPC_CLIENT_DEP) $(LIBXMLRPC_ABYSS_DEP) \ - $(LIBXMLRPC_XMLPARSE_A) $(LIBXMLRPC_XMLTOK_A) \ - $(CASPRINTF) - $(CCLD) -o $@ $(LDFLAGS_ALL) \ - $(TEST_OBJS) $(LDADD_CLIENT) $(LDADD_ABYSS_SERVER) $(CASPRINTF) - -CGITEST1_OBJS = cgitest1.o testtool.o - -cgitest1: $(CGITEST1_OBJS) $(LIBXMLRPC_SERVER_A) $(LIBXMLRPC_SERVER_CGI_A) \ - $(LIBXMLRPC_A) $(LIBXMLRPC_UTIL_A) $(LIBXMLRPC_XML) - $(CCLD) -o $@ $(CGITEST1_OBJS) $(LDFLAGS_ALL) $(LDADD_CGI_SERVER) - -OBJS = $(TEST_OBJS) cgitest1.o - -$(OBJS):%.o:%.c - $(CC) -c $(INCLUDES) $(CFLAGS_ALL) $< - -# Note the difference between 'check' and 'runtests'. 'check' means to check -# our own correctness. 'runtests' means to run the tests that check our -# parent's correctness - -.PHONY: check -check: - -.PHONY: runtests_local -runtests_local: test cgitest1 - ./test - -.PHONY: runtests -runtests: runtests_local cpp/runtests - -cpp/runtests: FORCE - $(MAKE) -C $(dir $@) $(notdir $@) - -.PHONY: install -install: - -.PHONY: uninstall -uninstall: - -.PHONY: clean clean-local distclean -clean: clean-common clean-local -clean-local: $(SUBDIRS:%=%/clean) - rm -f $(PROGS) - -distclean: clean $(SUBDIRS:%=%/distclean) distclean-common - -.PHONY: dep -dep: dep-common $(SUBDIRS:%=%/dep) - -include depend.mk diff --git a/trunk/test/abyss.c b/trunk/test/abyss.c deleted file mode 100644 index 84c5cb1d6..000000000 --- a/trunk/test/abyss.c +++ /dev/null @@ -1,416 +0,0 @@ -/* None of the tests in here rely on a client existing, or even a network - connection. We should figure out how to create a test client and do - such tests. -*/ -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ - -#include "unistdx.h" -#include -#ifndef _WIN32 -#include -#include -#endif -#include -#include - -#include "xmlrpc_config.h" - -#include "int.h" -#include "casprintf.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "xmlrpc-c/abyss.h" - -#include "testtool.h" - -#include "abyss.h" - - - -static void -bindSocketToPort(int const fd, - uint16_t const portNumber) { - - struct sockaddr_in name; - int rc; - - name.sin_family = AF_INET; - name.sin_port = htons(portNumber); - name.sin_addr.s_addr = INADDR_ANY; - - rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); - if (rc != 0) - fprintf(stderr, "bind() of %d failed, errno=%d (%s)", - fd, errno, strerror(errno)); - - TEST(rc == 0); -} - - - -static void -chanSwitchCreateFd(int const fd, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - -#ifdef _WIN32 - ChanSwitchWinCreateWinsock(fd, chanSwitchPP, errorP); -#else - ChanSwitchUnixCreateFd(fd, chanSwitchPP, errorP); -#endif -} - - - -static void -closesock(int const fd) { -#ifdef _WIN32 - closesocket(fd); -#else - close(fd); -#endif -} - - - -static void -chanSwitchCreate(uint16_t const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - -#ifdef _WIN32 - ChanSwitchWinCreate(portNumber, chanSwitchPP, errorP); -#else - ChanSwitchUnixCreate(portNumber, chanSwitchPP, errorP); -#endif -} - - - -static void -chanSwitchCreate2(int const protocolFamily, - const struct sockaddr * const sockAddrP, - socklen_t const sockAddrLen, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - -#ifdef _WIN32 - ChanSwitchWinCreate2(protocolFamily, sockAddrP, sockAddrLen, - chanSwitchPP, errorP); -#else - ChanSwitchUnixCreate2(protocolFamily, sockAddrP, sockAddrLen, - chanSwitchPP, errorP); -#endif -} - - - -static void -chanSwitchCreateIpV6(uint16_t const portNumber, - TChanSwitch ** const chanSwitchPP, - const char ** const errorP) { - -#ifndef _WIN32 - ChanSwitchUnixCreateIpV6Port(portNumber, chanSwitchPP, errorP); -#endif -} - - - -static void -channelCreateFd(int const fd, - TChannel ** const channelPP, - const char ** const errorP) { - -#ifdef _WIN32 - struct abyss_win_chaninfo * channelInfoP; - ChannelWinCreateWinsock(fd, channelPP, &channelInfoP, errorP); -#else - struct abyss_unix_chaninfo * channelInfoP; - ChannelUnixCreateFd(fd, channelPP, &channelInfoP, errorP); -#endif -} - - - -static void -testChanSwitchOsSocket(void) { - - XMLRPC_SOCKET rc; - - rc = socket(AF_INET, SOCK_STREAM, 0); - if (rc < 0) { - fprintf(stderr, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - abort(); - } else { - int const fd = rc; - - TChanSwitch * chanSwitchP; - TServer server; - const char * error; - - bindSocketToPort(fd, 8080); - - chanSwitchCreateFd(fd, &chanSwitchP, &error); - - TEST_NULL_STRING(error); - - ServerCreateSwitch(&server, chanSwitchP, &error); - - TEST_NULL_STRING(error); - - ServerFree(&server); - - ChanSwitchDestroy(chanSwitchP); - - closesock(fd); - } -} - - - -static void -testChanSwitchSockAddr(void) { - - TServer server; - TChanSwitch * chanSwitchP; - const char * error; - - struct sockaddr_in sockAddr; - - sockAddr.sin_family = AF_INET; - sockAddr.sin_port = htons(8080); - sockAddr.sin_addr = test_ipAddrFromDecimal(127, 0, 0, 1); - - chanSwitchCreate2(PF_INET, - (const struct sockaddr *) &sockAddr, sizeof(sockAddr), - &chanSwitchP, &error); - - TEST_NULL_STRING(error); - - ServerCreateSwitch(&server, chanSwitchP, &error); - - TEST_NULL_STRING(error); - - ServerFree(&server); - - ChanSwitchDestroy(chanSwitchP); -} - - - -static void -testChanSwitch(void) { - - TServer server; - TChanSwitch * chanSwitchP; - const char * error; - - chanSwitchCreate(8080, &chanSwitchP, &error); - - TEST_NULL_STRING(error); - - ServerCreateSwitch(&server, chanSwitchP, &error); - - TEST_NULL_STRING(error); - - ServerFree(&server); - - ChanSwitchDestroy(chanSwitchP); - -#ifndef _WIN32 - chanSwitchCreateIpV6(8080, &chanSwitchP, &error); - - TEST_NULL_STRING(error); - - ChanSwitchDestroy(chanSwitchP); - - testChanSwitchSockAddr(); - - testChanSwitchOsSocket(); -#endif -} - - - -static void -testChannel(void) { - - XMLRPC_SOCKET rc; - - rc = socket(AF_INET, SOCK_STREAM, 0); - if (rc < 0) { - fprintf(stderr, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - abort(); - } else { - int const fd = rc; - - TChannel * channelP; - const char * error; - - channelCreateFd(fd, &channelP, &error); - - TEST(error); - - TEST(strstr(error, "not in connected")); - - strfree(error); - } -} - - - -static void -testOsSocket(void) { - - XMLRPC_SOCKET rc; - - rc = socket(AF_INET, SOCK_STREAM, 0); - if (rc < 0) { - fprintf(stderr, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - abort(); - } else { - int const fd = rc; - - TServer server; - abyss_bool success; - - bindSocketToPort(fd, 8080); - - success = ServerCreateSocket(&server, NULL, fd, NULL, NULL); - - TEST(success); - - ServerFree(&server); - - closesock(fd); - } -} - - - -static void -testSocket(void) { - -#ifndef _WIN32 - int rc; - - rc = socket(AF_INET, SOCK_STREAM, 0); - if (rc < 0) { - fprintf(stderr, "socket() failed with errno %d (%s)", - errno, strerror(errno)); - abort(); - } else { - int const fd = rc; - - TSocket * socketP; - TServer server; - const char * error; - - SocketUnixCreateFd(fd, &socketP); - - TEST(socketP != NULL); - - ServerCreateSocket2(&server, socketP, &error); - - TEST(!error); - - ServerFree(&server); - - SocketDestroy(socketP); - - close(fd); - } -#endif -} - - - -static void -testServerCreate(void) { - - TServer server; - abyss_bool success; - - success = ServerCreate(&server, NULL, 8080, NULL, NULL); - TEST(success); - ServerInit(&server); - ServerFree(&server); - - success = ServerCreate(&server, "myserver", 8080, - "/tmp/docroot", "/tmp/logfile"); - TEST(success); - ServerInit(&server); - ServerFree(&server); - - success = ServerCreateNoAccept(&server, NULL, NULL, NULL); - TEST(success); - ServerFree(&server); - - { - TChanSwitch * chanSwitchP; - const char * error; - - chanSwitchCreate(8080, &chanSwitchP, &error); - - TEST_NULL_STRING(error); - - ServerCreateSwitch(&server, chanSwitchP, &error); - - TEST_NULL_STRING(error); - - ServerSetName(&server, "/tmp/docroot"); - ServerSetLogFileName(&server, "/tmp/logfile"); - ServerSetKeepaliveTimeout(&server, 50); - ServerSetKeepaliveMaxConn(&server, 5); - ServerSetTimeout(&server, 75); - ServerSetAdvertise(&server, 1); - ServerSetAdvertise(&server, 0); - - ServerInit(&server); - - ServerFree(&server); - - ChanSwitchDestroy(chanSwitchP); - } -} - - - -void -test_abyss(void) { - - const char * error; - - printf("Running Abyss server tests...\n"); - - AbyssInit(&error); - TEST_NULL_STRING(error); - - ChanSwitchInit(&error); - TEST_NULL_STRING(error); - - ChannelInit(&error); - TEST_NULL_STRING(error); - - testChanSwitch(); - - testChannel(); - - testOsSocket(); - - testSocket(); - - testServerCreate(); - - ChannelTerm(); - ChanSwitchTerm(); - AbyssTerm(); - - printf("\n"); - printf("Abyss server tests done.\n"); -} - diff --git a/trunk/test/abyss.h b/trunk/test/abyss.h deleted file mode 100644 index 64e8afbba..000000000 --- a/trunk/test/abyss.h +++ /dev/null @@ -1,2 +0,0 @@ -void -test_abyss(void); diff --git a/trunk/test/abyss_dummy.c b/trunk/test/abyss_dummy.c deleted file mode 100644 index 192844dff..000000000 --- a/trunk/test/abyss_dummy.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#include "abyss.h" - - - -void -test_abyss(void) { - - printf("Running dummy Abyss test."); - - printf("\n"); - printf("Abyss server tests done.\n"); -} diff --git a/trunk/test/cgi.c b/trunk/test/cgi.c deleted file mode 100644 index 18dfa9bcf..000000000 --- a/trunk/test/cgi.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include - -#include "xmlrpc_config.h" - -#include "testtool.h" -#include "cgi.h" - -static const char cgiResponse1[] = - "....Status: 200 OK\n" - "Content-type: text/xml; charset=\"utf-8\"\n" - "Content-length: 141\n" - "\n" - "\r\n" - "\r\n" - "\r\n" - "12\r\n" - "\r\n" - "\r\n"; - - -#define TESTDATA_DIR "data" -#define DIRSEP DIRECTORY_SEPARATOR - -void -test_server_cgi(void) { -/*---------------------------------------------------------------------------- - Here, we pretend to be a web server when someone has requested a POST - to the CGI script "cgitest1". ------------------------------------------------------------------------------*/ - FILE * cgiOutputP; - - printf("Running CGI tests...\n"); - - cgiOutputP = popen("REQUEST_METHOD=POST " - "CONTENT_TYPE=text/xml " - "CONTENT_LENGTH=211 " - "./cgitest1 " - "<" - TESTDATA_DIR DIRSEP "sample_add_call.xml", - "r"); - - if (cgiOutputP == NULL) - TEST_ERROR("Unable to run 'cgitest' program."); - else { - unsigned char cgiResponse[4096]; - size_t bytesRead; - - bytesRead = fread(cgiResponse, 1, sizeof(cgiResponse), cgiOutputP); - - TEST(bytesRead == strlen(cgiResponse1)); - - TEST(memcmp(cgiResponse, cgiResponse1, bytesRead) == 0); - } - fclose(cgiOutputP); - printf("\n"); - printf("CGI tests done.\n"); -} diff --git a/trunk/test/cgi.h b/trunk/test/cgi.h deleted file mode 100644 index 4e2de991c..000000000 --- a/trunk/test/cgi.h +++ /dev/null @@ -1,2 +0,0 @@ -void -test_server_cgi(void); diff --git a/trunk/test/cgitest1.c b/trunk/test/cgitest1.c deleted file mode 100644 index ce758b11d..000000000 --- a/trunk/test/cgitest1.c +++ /dev/null @@ -1,79 +0,0 @@ -/*============================================================================ - Act like a CGI script -- read POST data from Standard Input, interpret - it as an XML-RPC call, and write an XML-RPC response to Standard Output. - - This is for use by a test program. -============================================================================*/ - -#include -#include -#include -#include - -#include "xmlrpc_config.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "xmlrpc-c/server_cgi.h" - -#include "testtool.h" - - -int total_tests; -int total_failures; - - - -static xmlrpc_value * -sample_add(xmlrpc_env * const env, - xmlrpc_value * const param_array, - void * const user_data ATTR_UNUSED) { - - xmlrpc_int32 x, y, z; - - /* Parse our argument array. */ - xmlrpc_decompose_value(env, param_array, "(ii)", &x, &y); - if (env->fault_occurred) - return NULL; - - /* Add our two numbers. */ - z = x + y; - - /* Return our result. */ - return xmlrpc_build_value(env, "i", z); -} - - - -int -main(int argc ATTR_UNUSED, - char ** argv ATTR_UNUSED) { - - xmlrpc_env env; - xmlrpc_registry * registryP; - xmlrpc_value * argArrayP; - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - TEST(registryP != NULL); - TEST_NO_FAULT(&env); - - xmlrpc_registry_add_method(&env, registryP, NULL, "sample.add", - sample_add, NULL); - TEST_NO_FAULT(&env); - - argArrayP = xmlrpc_build_value(&env, "(ii)", - (xmlrpc_int32) 25, (xmlrpc_int32) 17); - TEST_NO_FAULT(&env); - - /* The following reads from Standard Input and writes to Standard - Output - */ - xmlrpc_server_cgi_process_call(registryP); - - xmlrpc_DECREF(argArrayP); - xmlrpc_registry_free(registryP); - - return 0; -} diff --git a/trunk/test/client.c b/trunk/test/client.c deleted file mode 100644 index f3fc80ff1..000000000 --- a/trunk/test/client.c +++ /dev/null @@ -1,508 +0,0 @@ -#include -#include -#include -#include - -#include "xmlrpc_config.h" -#include "transport_config.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/transport.h" - -#include "bool.h" -#include "testtool.h" -#include "client.h" - - - -static void -testVersion(void) { - - unsigned int major, minor, point; - - xmlrpc_client_version(&major, &minor, &point); - -#ifndef _WIN32 - /* xmlrpc_client_version_major, etc. are not exported from a Windows DLL */ - - TEST(major == xmlrpc_client_version_major); - TEST(minor == xmlrpc_client_version_minor); - TEST(point == xmlrpc_client_version_point); -#endif -} - - - -static void -testGlobalConst(void) { - - xmlrpc_env env; - xmlrpc_env_init(&env); - - xmlrpc_client_setup_global_const(&env); - TEST_NO_FAULT(&env); - - xmlrpc_client_teardown_global_const(); - - xmlrpc_client_setup_global_const(&env); - TEST_NO_FAULT(&env); - xmlrpc_client_setup_global_const(&env); - TEST_NO_FAULT(&env); - - xmlrpc_client_teardown_global_const(); - xmlrpc_client_teardown_global_const(); - - xmlrpc_env_clean(&env); -} - - - -static xmlrpc_progress_fn myProgress; - -static void -myProgress(void * const userHandle, - struct xmlrpc_progress_data const data) { - - printf("Progress of %p: %f, %f, %f, %f\n", - userHandle, - data.call.total, - data.call.now, - data.response.total, - data.response.now); -} - - - -static void -testCreateCurlParms(void) { - -#if MUST_BUILD_CURL_CLIENT - - xmlrpc_env env; - xmlrpc_client * clientP; - struct xmlrpc_clientparms clientParms1; - struct xmlrpc_curl_xportparms curlTransportParms1; - - xmlrpc_env_init(&env); - - clientParms1.transport = "curl"; - clientParms1.transportparmsP = &curlTransportParms1; - - curlTransportParms1.network_interface = "eth0"; - clientParms1.transportparm_size = XMLRPC_CXPSIZE(network_interface); - xmlrpc_client_create(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparm_size), - &clientP); - TEST_NO_FAULT(&env); - xmlrpc_client_destroy(clientP); - - curlTransportParms1.no_ssl_verifypeer = 1; - curlTransportParms1.no_ssl_verifyhost = 1; - clientParms1.transportparm_size = XMLRPC_CXPSIZE(no_ssl_verifyhost); - xmlrpc_client_create(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparm_size), - &clientP); - TEST_NO_FAULT(&env); - xmlrpc_client_destroy(clientP); - - curlTransportParms1.user_agent = "testprog/1.0"; - clientParms1.transportparm_size = XMLRPC_CXPSIZE(user_agent); - xmlrpc_client_create(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparm_size), - &clientP); - TEST_NO_FAULT(&env); - xmlrpc_client_destroy(clientP); - - curlTransportParms1.ssl_cert = NULL; - curlTransportParms1.sslcerttype = NULL; - curlTransportParms1.sslcertpasswd = NULL; - curlTransportParms1.sslkey = NULL; - curlTransportParms1.sslkeytype = NULL; - curlTransportParms1.sslkeypasswd = NULL; - curlTransportParms1.sslengine = NULL; - curlTransportParms1.sslengine_default = false; - curlTransportParms1.sslversion = XMLRPC_SSLVERSION_DEFAULT; - curlTransportParms1.cainfo = NULL; - curlTransportParms1.capath = NULL; - curlTransportParms1.randomfile = NULL; - curlTransportParms1.egdsocket = NULL; - curlTransportParms1.ssl_cipher_list = NULL; - curlTransportParms1.timeout = 0; - curlTransportParms1.dont_advertise = 1; - curlTransportParms1.proxy = NULL; - curlTransportParms1.proxy_port = 0; - curlTransportParms1.proxy_type = XMLRPC_HTTPPROXY_HTTP; - curlTransportParms1.proxy_auth = XMLRPC_HTTPAUTH_NONE; - curlTransportParms1.proxy_userpwd = "mypassword"; - curlTransportParms1.gssapi_delegation = 1; - curlTransportParms1.referer = "myreferer"; - curlTransportParms1.connect_timeout = 0; - - clientParms1.transportparm_size = XMLRPC_CXPSIZE(referer); - xmlrpc_client_create(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparm_size), - &clientP); - TEST_NO_FAULT(&env); - xmlrpc_client_destroy(clientP); - - xmlrpc_env_clean(&env); -#endif /* MUST_BUILD_CURL_CLIENT */ -} - - - -static void -testCreateSeparateXport(void) { - -#if MUST_BUILD_CURL_CLIENT - xmlrpc_env env; - xmlrpc_client * clientP; - struct xmlrpc_clientparms clientParms1; - struct xmlrpc_curl_xportparms curlTransportParms1; - struct xmlrpc_client_transport * transportP; - - xmlrpc_env_init(&env); - - xmlrpc_curl_transport_ops.create( - &env, 0, "", "", &curlTransportParms1, 0, - &transportP); - - TEST_NO_FAULT(&env); - - clientParms1.transport = NULL; - clientParms1.transportparmsP = NULL; - clientParms1.transportparm_size = 0; - clientParms1.transportOpsP = NULL; - clientParms1.transportP = NULL; - - xmlrpc_client_create(&env, 0, "", "", - &clientParms1, XMLRPC_CPSIZE(transportP), - &clientP); - TEST_NO_FAULT(&env); - - xmlrpc_client_destroy(clientP); - - clientParms1.transport = "curl"; - clientParms1.transportparmsP = &curlTransportParms1; - clientParms1.transportparm_size = 0; - clientParms1.transportOpsP = NULL; - clientParms1.transportP = NULL; - - xmlrpc_client_create(&env, 0, "", "", - &clientParms1, XMLRPC_CPSIZE(transportP), - &clientP); - TEST_NO_FAULT(&env); - - xmlrpc_client_destroy(clientP); - - clientParms1.transportP = transportP; - xmlrpc_client_create(&env, 0, "", "", - &clientParms1, XMLRPC_CPSIZE(transportP), - &clientP); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - /* Both transportP and transport specified */ - - clientParms1.transport = NULL; - clientParms1.transportparmsP = NULL; - clientParms1.transportparm_size = 0; - clientParms1.transportOpsP = &xmlrpc_curl_transport_ops; - clientParms1.transportP = transportP; - - xmlrpc_client_create(&env, 0, "", "", - &clientParms1, XMLRPC_CPSIZE(transportOpsP), - &clientP); - - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - /* transportOpsP but no transportP */ - - xmlrpc_client_create(&env, 0, "", "", - &clientParms1, XMLRPC_CPSIZE(transportP), - &clientP); - - TEST_NO_FAULT(&env); - - xmlrpc_client_destroy(clientP); - - xmlrpc_curl_transport_ops.destroy(transportP); - - xmlrpc_env_clean(&env); - -#endif /* MUST_BUILD_CURL_CLIENT */ -} - - - -static void -testCreateDestroy(void) { - - xmlrpc_env env; - xmlrpc_client * clientP; - struct xmlrpc_clientparms clientParms1; - struct xmlrpc_curl_xportparms curlTransportParms1; - int interrupt; - - xmlrpc_env_init(&env); - - xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - /* Didn't set up global const */ - - xmlrpc_client_setup_global_const(&env); - TEST_NO_FAULT(&env); - - xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP); - TEST_NO_FAULT(&env); - xmlrpc_client_destroy(clientP); - - xmlrpc_client_create(&env, 0, "testprog", "1.0", &clientParms1, 0, - &clientP); - TEST_NO_FAULT(&env); - xmlrpc_client_destroy(clientP); - - clientParms1.transport = "curl"; - xmlrpc_client_create(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transport), &clientP); - TEST_NO_FAULT(&env); - xmlrpc_client_destroy(clientP); - - clientParms1.transportparmsP = NULL; - xmlrpc_client_create(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparmsP), - &clientP); - TEST_NO_FAULT(&env); - xmlrpc_client_destroy(clientP); - - clientParms1.transportOpsP = NULL; - clientParms1.transportP = NULL; - clientParms1.dialect = xmlrpc_dialect_apache; - clientParms1.progressFn = &myProgress; - xmlrpc_client_create(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(progressFn), - &clientP); - TEST_NO_FAULT(&env); - xmlrpc_client_destroy(clientP); - - clientParms1.transportparmsP = &curlTransportParms1; - - xmlrpc_client_create(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparmsP), - &clientP); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - clientParms1.transportparm_size = 0; - xmlrpc_client_create(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparm_size), - &clientP); - TEST_NO_FAULT(&env); - - xmlrpc_client_set_interrupt(clientP, &interrupt); - xmlrpc_client_set_interrupt(clientP, NULL); - - xmlrpc_client_destroy(clientP); - - testCreateCurlParms(); - - testCreateSeparateXport(); - - xmlrpc_client_teardown_global_const(); - - xmlrpc_env_clean(&env); -} - - - -static void -testSynchCall(void) { - - xmlrpc_env env; - xmlrpc_client * clientP; - xmlrpc_value * resultP; - xmlrpc_value * emptyArrayP; - xmlrpc_server_info * noSuchServerInfoP; - - xmlrpc_env_init(&env); - - emptyArrayP = xmlrpc_array_new(&env); - TEST_NO_FAULT(&env); - - xmlrpc_client_setup_global_const(&env); - TEST_NO_FAULT(&env); - - xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP); - TEST_NO_FAULT(&env); - - noSuchServerInfoP = xmlrpc_server_info_new(&env, "nosuchserver"); - TEST_NO_FAULT(&env); - - xmlrpc_client_call2(&env, clientP, noSuchServerInfoP, "nosuchmethod", - emptyArrayP, &resultP); - TEST_FAULT(&env, XMLRPC_NETWORK_ERROR); /* No such server */ - - xmlrpc_client_call2f(&env, clientP, "nosuchserver", "nosuchmethod", - &resultP, "(i)", 7); - TEST_FAULT(&env, XMLRPC_NETWORK_ERROR); /* No such server */ - - xmlrpc_server_info_free(noSuchServerInfoP); - - xmlrpc_client_destroy(clientP); - - xmlrpc_DECREF(emptyArrayP); - - xmlrpc_client_teardown_global_const(); - - xmlrpc_env_clean(&env); -} - - - -static void -testInitCleanup(void) { - - xmlrpc_env env; - struct xmlrpc_clientparms clientParms1; - struct xmlrpc_curl_xportparms curlTransportParms1; - - xmlrpc_env_init(&env); - - xmlrpc_client_init2(&env, 0, "testprog", "1.0", NULL, 0); - TEST_NO_FAULT(&env); - xmlrpc_client_cleanup(); - - xmlrpc_client_init2(&env, 0, "testprog", "1.0", &clientParms1, 0); - TEST_NO_FAULT(&env); - xmlrpc_client_cleanup(); - - clientParms1.transport = "curl"; - xmlrpc_client_init2(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transport)); - TEST_NO_FAULT(&env); - xmlrpc_client_cleanup(); - - clientParms1.transportparmsP = NULL; - xmlrpc_client_init2(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparmsP)); - TEST_NO_FAULT(&env); - xmlrpc_client_cleanup(); - - clientParms1.transportparmsP = &curlTransportParms1; - - /* Fails because we didn't include transportparm_size: */ - xmlrpc_client_init2(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparmsP)); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - clientParms1.transportparm_size = 0; - xmlrpc_client_init2(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparm_size)); - TEST_NO_FAULT(&env); - xmlrpc_client_cleanup(); - - curlTransportParms1.network_interface = "eth0"; - clientParms1.transportparm_size = XMLRPC_CXPSIZE(network_interface); - xmlrpc_client_init2(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparm_size)); - TEST_NO_FAULT(&env); - xmlrpc_client_cleanup(); - - curlTransportParms1.no_ssl_verifypeer = 1; - curlTransportParms1.no_ssl_verifyhost = 1; - clientParms1.transportparm_size = XMLRPC_CXPSIZE(no_ssl_verifyhost); - xmlrpc_client_init2(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparm_size)); - TEST_NO_FAULT(&env); - xmlrpc_client_cleanup(); - - curlTransportParms1.user_agent = "testprog/1.0"; - clientParms1.transportparm_size = XMLRPC_CXPSIZE(user_agent); - xmlrpc_client_init2(&env, 0, "testprog", "1.0", - &clientParms1, XMLRPC_CPSIZE(transportparm_size)); - TEST_NO_FAULT(&env); - xmlrpc_client_cleanup(); - - xmlrpc_client_init(0, "testprog", "1.0"); - TEST_NO_FAULT(&env); - xmlrpc_client_cleanup(); - - xmlrpc_env_clean(&env); -} - - - -static void -testServerInfo(void) { - - xmlrpc_env env; - xmlrpc_server_info * serverInfoP; - xmlrpc_server_info * serverInfo2P; - - printf(" Running serverInfo tests...\n"); - - xmlrpc_env_init(&env); - - serverInfoP = xmlrpc_server_info_new(&env, "testurl"); - TEST_NO_FAULT(&env); - - serverInfo2P = xmlrpc_server_info_copy(&env, serverInfoP); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_free(serverInfo2P); - - /* Fails because we haven't set user/password yet: */ - xmlrpc_server_info_allow_auth_basic(&env, serverInfoP); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_server_info_set_basic_auth(&env, serverInfoP, - "username", "password"); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_set_user(&env, serverInfoP, "username", "password"); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_allow_auth_basic(&env, serverInfoP); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_disallow_auth_basic(&env, serverInfoP); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_allow_auth_digest(&env, serverInfoP); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_disallow_auth_digest(&env, serverInfoP); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_allow_auth_negotiate(&env, serverInfoP); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_disallow_auth_negotiate(&env, serverInfoP); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_allow_auth_ntlm(&env, serverInfoP); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_disallow_auth_ntlm(&env, serverInfoP); - TEST_NO_FAULT(&env); - - xmlrpc_server_info_free(serverInfoP); - - xmlrpc_env_clean(&env); -} - - - -void -test_client(void) { - - printf("Running client tests."); - - testVersion(); - testGlobalConst(); - testCreateDestroy(); - testInitCleanup(); - printf("\n"); - testServerInfo(); - testSynchCall(); - - printf("\n"); - printf("Client tests done.\n"); -} diff --git a/trunk/test/client.h b/trunk/test/client.h deleted file mode 100644 index 272761702..000000000 --- a/trunk/test/client.h +++ /dev/null @@ -1,2 +0,0 @@ -void -test_client(void); diff --git a/trunk/test/client_dummy.c b/trunk/test/client_dummy.c deleted file mode 100644 index 6377fb85e..000000000 --- a/trunk/test/client_dummy.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#include "client.h" - - - -void -test_client(void) { - - printf("Running dummy client test."); - - printf("\n"); - printf("Client tests done.\n"); -} diff --git a/trunk/test/cpp/Makefile b/trunk/test/cpp/Makefile deleted file mode 100644 index 7e57d36b5..000000000 --- a/trunk/test/cpp/Makefile +++ /dev/null @@ -1,134 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - testDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(testDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := test/cpp - -include $(BLDDIR)/config.mk - -PROGS = test - -default: all - -all: $(PROGS) - -XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test - -LIBS := - -LIBS += $(SOCKETLIBOPT) $(THREAD_LIBS) - -INCLUDES = -Isrcdir/include -I$(BLDDIR) -Isrcdir -Isrcdir/lib/util/include - -# This 'common.mk' dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/common.mk: srcdir blddir - -include $(SRCDIR)/common.mk - -TEST_OBJS = \ - test.o \ - base64.o \ - registry.o \ - server_pstream.o \ - tools.o \ - value.o \ - xml.o \ - -ifeq ($(MUST_BUILD_CLIENT),yes) - TEST_OBJS += testclient.o - LIBS += $(shell $(XMLRPC_C_CONFIG) client --ldadd) -else - TEST_OBJS += testclient_dummy.o -endif - -ifeq ($(ENABLE_ABYSS_SERVER),yes) - TEST_OBJS += abyss.o server_abyss.o - LIBS += $(shell $(XMLRPC_C_CONFIG) abyss-server --ldadd) -else - TEST_OBJS += abyss_dummy.o server_abyss_dummy.o -endif - -#----------------------------------------------------------------------------- -# TEST_LIBS -#----------------------------------------------------------------------------- -TEST_LIBS = -ifeq ($(ENABLE_ABYSS_SERVER),yes) - TEST_LIBS += $(LIBXMLRPC_SERVER_ABYSSPP_A) -endif -TEST_LIBS += $(LIBXMLRPC_SERVER_PSTREAMPP_A) -TEST_LIBS += $(LIBXMLRPC_SERVERPP_A) -ifeq ($(MUST_BUILD_CLIENT),yes) - TEST_LIBS += $(LIBXMLRPC_CLIENTPP_A) $(LIBXMLRPC_CLIENT_A) -endif -TEST_LIBS += $(LIBXMLRPCPP_A) -TEST_LIBS += $(LIBXMLRPC_CPP_A) -ifeq ($(ENABLE_ABYSS_SERVER),yes) - TEST_LIBS += $(LIBXMLRPC_SERVER_ABYSS_A) -endif -TEST_LIBS += $(LIBXMLRPC_SERVER_A) -TEST_LIBS += $(LIBXMLRPC_A) -ifeq ($(ENABLE_ABYSS_SERVER),yes) - TEST_LIBS += $(LIBXMLRPC_ABYSS_A) - TEST_LIBS += $(LIBXMLRPC_ABYSSPP_A) -endif -TEST_LIBS += $(LIBXMLRPC_PACKETSOCKET_A) -TEST_LIBS += $(LIBXMLRPC_UTILPP_A) -TEST_LIBS += $(LIBXMLRPC_UTIL_A) -ifeq ($(MSVCRT),yes) - TEST_LIBS += socketpair.o -endif -ifneq ($(ENABLE_LIBXML2_BACKEND),yes) - # We're using the internal Expat XML parser - TEST_LIBS += $(LIBXMLRPC_XMLPARSE_A) - TEST_LIBS += $(LIBXMLRPC_XMLTOK_A) -endif - -ifneq ($(ENABLE_LIBXML2_BACKEND),yes) - # We're using the internal Expat XML parser - LIB_XML = - registry.o: D_INTERNAL_EXPAT=-DINTERNAL_EXPAT -else - LIB_XML = $(shell xml2-config --libs) -endif - -test: $(TEST_OBJS) $(TEST_LIBS) - $(CXXLD) -o $@ $(LDFLAGS_ALL) $^ $(LIB_XML) $(LIBS) - -%.o:%.cpp - $(CXX) -c $(INCLUDES) $(CXXFLAGS_ALL) $(D_INTERNAL_EXPAT) $< - -socketpair.o: $(SRCDIR)/Windows/socketpair.cpp - $(CXX) -c $(INCLUDES) $(CXXFLAGS_ALL) $(D_INTERNAL_EXPAT) $< - -# Note the difference between 'check' and 'runtests'. 'check' means to check -# our own correctness. 'runtests' means to run the tests that check our -# parent's correctness - -.PHONY: check -check: - -.PHONY: runtests -runtests: test - ./test - -.PHONY: install -install: - -.PHONY: uninstall -uninstall: - -.PHONY: clean clean-local distclean -clean: clean-common clean-local -clean-local: - rm -f $(PROGS) - -distclean: clean distclean-common - -.PHONY: dep -dep: dep-common - -include depend.mk diff --git a/trunk/test/cpp/abyss.cpp b/trunk/test/cpp/abyss.cpp deleted file mode 100644 index 473670505..000000000 --- a/trunk/test/cpp/abyss.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/*============================================================================= - abyss -=============================================================================== - Test the Abyss server C++ facilities of XML-RPC for C/C++. - -=============================================================================*/ -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ - -#include - -using namespace std; - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/AbyssServer.hpp" -#include "xmlrpc-c/AbyssEnvironment.hpp" -#include "xmlrpc-c/AbyssChanSwitch.hpp" -#ifdef _WIN32 -#include "xmlrpc-c/AbyssChanSwitchWin.hpp" -#else -#include "xmlrpc-c/AbyssChanSwitchUnix.hpp" -#endif - -using namespace xmlrpc_c; - -#include "tools.hpp" -#include "abyss.hpp" - - - -// We need 'global' because methods of class addHandlerTestSuite call -// functions in the Abyss C library. By virtue of global's static -// storage class, the program loader will call its constructor and -// destructor and thus initialize and terminate the Abyss C library. - -static const AbyssEnvironment global; - -namespace { - - - -class addHandlerTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "addHandlerTestSuite"; - } - virtual void runtests(unsigned int const) { - - class AbyssReqHandler_Test : public AbyssServer::ReqHandler { - public: - AbyssReqHandler_Test() {} - - void - handleRequest(AbyssServer::Session * const , - bool * const ) {} - }; - -#ifdef _WIN32 - AbyssChanSwitchWin chanSwitch(8080); -#else - AbyssChanSwitchUnix chanSwitch(8080); -#endif - - AbyssServer abyssServer(&chanSwitch); - - AbyssReqHandler_Test abyssReqHandler; - - abyssServer.addRequestHandler(&abyssReqHandler); - } -}; - - - -class createTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "createTestSuite"; - } - virtual void runtests(unsigned int const) { -#ifdef _WIN32 - AbyssChanSwitchWin chanSwitch(8080); -#else - AbyssChanSwitchUnix chanSwitch(8080); -#endif - AbyssServer abyssServer(&chanSwitch); - - } -}; - - - -} // namespace - - - -string -abyssTestSuite::suiteName() { - return "abyssTestSuite"; -} - - -void -abyssTestSuite::runtests(unsigned int const indentation) { - - createTestSuite().run(indentation+1); - - addHandlerTestSuite().run(indentation+1); -} - - - diff --git a/trunk/test/cpp/abyss.hpp b/trunk/test/cpp/abyss.hpp deleted file mode 100644 index 88c054baf..000000000 --- a/trunk/test/cpp/abyss.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "tools.hpp" - -class abyssTestSuite : public testSuite { - -public: - virtual std::string suiteName(); - virtual void runtests(unsigned int const); -}; diff --git a/trunk/test/cpp/abyss_dummy.cpp b/trunk/test/cpp/abyss_dummy.cpp deleted file mode 100644 index 0482370a4..000000000 --- a/trunk/test/cpp/abyss_dummy.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/*============================================================================= - abyss_dummy -=============================================================================== - This is a substitute for abyss.cpp, for use in a test program that is - not linked with the Abyss libraries. - - It simply passes the test. -=============================================================================*/ - -#include -#include - -#include "tools.hpp" -#include "abyss.hpp" - -using namespace std; - -string -abyssTestSuite::suiteName() { - return "abyssTestSuite"; -} - - -void -abyssTestSuite::runtests(unsigned int const indentation) { - - cout << string((indentation+1)*2, ' ') - << "Running dummy test." << endl; -} diff --git a/trunk/test/cpp/base64.cpp b/trunk/test/cpp/base64.cpp deleted file mode 100644 index 17e4e780b..000000000 --- a/trunk/test/cpp/base64.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "xmlrpc-c/base64.hpp" - -#include "tools.hpp" - -#include "base64.hpp" - -using namespace xmlrpc_c; -using namespace std; - - - -string -base64TestSuite::suiteName() { - return "base64TestSuite"; -} - - - -void -base64TestSuite::runtests(unsigned int const) { - - unsigned char const bytes0Data[] = "This is a test"; - - vector bytes0(&bytes0Data[0], - &bytes0Data[sizeof(bytes0Data)]); - - string const base64_0("VGhpcyBpcyBhIHRlc3QA"); - - string const expectedBase64_0(base64_0 + "\r\n"); - - TEST(base64FromBytes(bytes0) == expectedBase64_0); - - TEST(bytesFromBase64(base64_0) == bytes0); - - unsigned char const bytes1Data[] = {0x80, 0xff}; - - vector bytes1(&bytes1Data[0], - &bytes1Data[sizeof(bytes1Data)]); - - string const base64_1("gP8="); - - string const expectedBase64_1(base64_1 + "\r\n"); - - TEST(base64FromBytes(bytes1) == expectedBase64_1); - - TEST(bytesFromBase64(base64_1) == bytes1); - -} diff --git a/trunk/test/cpp/base64.hpp b/trunk/test/cpp/base64.hpp deleted file mode 100644 index 72ee02d93..000000000 --- a/trunk/test/cpp/base64.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "tools.hpp" - -class base64TestSuite : public testSuite { - -public: - virtual std::string suiteName(); - virtual void runtests(unsigned int const indentation); -}; - diff --git a/trunk/test/cpp/registry.cpp b/trunk/test/cpp/registry.cpp deleted file mode 100644 index 0eb7d37c7..000000000 --- a/trunk/test/cpp/registry.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/*============================================================================= - registry -=============================================================================== - Test the method registry (server) C++ facilities of XML-RPC for C/C++. - -=============================================================================*/ - -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/registry.hpp" - -#include "tools.hpp" -#include "registry.hpp" - -using namespace xmlrpc_c; -using namespace std; - - - -namespace { - -static string const -xmlPrologue("\r\n"); - -static string const -apacheUrl("http://ws.apache.org/xmlrpc/namespaces/extensions"); - -static string const -xmlnsApache("xmlns:ex=\"" + apacheUrl + "\""); - - -string const noElementFoundXml( - xmlPrologue + - "\r\n" - "\r\n" - "\r\n" - "faultCode\r\n" - "-503\r\n" - "faultString\r\n" - "Call XML not a proper XML-RPC call. " - "Call is not valid XML. no element found" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - ); - -string const invalidXMLCall( - xmlPrologue + - "\r\n" - "\r\n" - "\r\n" - "faultCode\r\n" - "-503\r\n" - "faultString\r\n" - "Call XML not a proper XML-RPC call. " - "Call is not valid XML. XML parsing failed" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - ); - -string const sampleAddGoodCallXml( - xmlPrologue + - "\r\n" - "sample.add\r\n" - "\r\n" - "5\r\n" - "7\r\n" - "\r\n" - "\r\n" - ); - -string const sampleAddGoodResponseXml( - xmlPrologue + - "\r\n" - "\r\n" - "12\r\n" - "\r\n" - "\r\n" - ); - - -string const sampleAddBadCallXml( - xmlPrologue + - "\r\n" - "sample.add\r\n" - "\r\n" - "5\r\n" - "\r\n" - "\r\n" - ); - -string const sampleAddBadResponseXml( - xmlPrologue + - "\r\n" - "\r\n" - "\r\n" - "faultCode\r\n" - "-501\r\n" - "faultString\r\n" - "Not enough parameters\r\n" - "\r\n" - "\r\n" - "\r\n" - ); - -string const testCallInfoCallXml( - xmlPrologue + - "\r\n" - "test.callinfo\r\n" - "\r\n" - "\r\n" - "\r\n" - ); - -string const testCallInfoResponseXml( - xmlPrologue + - "\r\n" - "\r\n" - "this is a test callInfo" - "\r\n" - "\r\n" - "\r\n" - ); - -string const nonexistentMethodCallXml( - xmlPrologue + - "\r\n" - "nosuchmethod\r\n" - "\r\n" - "5\r\n" - "7\r\n" - "\r\n" - "\r\n" - ); - -string const nonexistentMethodYesDefResponseXml( - xmlPrologue + - "\r\n" - "\r\n" - "no such method: nosuchmethod" - "\r\n" - "\r\n" - "\r\n" - ); - -string const nonexistentMethodNoDefResponseXml( - xmlPrologue + - "\r\n" - "\r\n" - "\r\n" - "faultCode\r\n" - "-506\r\n" - "faultString\r\n" - "Method 'nosuchmethod' not defined" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - ); - - - -string const echoI8ApacheCall( - xmlPrologue + - "\r\n" - "echo\r\n" - "\r\n" - "5\r\n" - "\r\n" - "\r\n" - ); - -string const echoI8ApacheResponse( - xmlPrologue + - "\r\n" - "\r\n" - "5\r\n" - "\r\n" - "\r\n" - ); - -string const echoNilApacheCall( - xmlPrologue + - "\r\n" - "echo\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - ); - -string const echoNilApacheResponse( - xmlPrologue + - "\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n" - ); - - -class callInfo_test : public callInfo { - -public: - callInfo_test() : data("this is a test callInfo") {} - - callInfo_test(string const& data) : data(data) {}; - - string data; -}; - - - -class sampleAddMethod : public method { -public: - sampleAddMethod() { - this->_signature = "i:ii"; - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = value_int(addend + adder); - } -}; - - - -class sampleAddMethod2 : public method2 { -public: - sampleAddMethod2() { - this->_signature = "i:ii"; - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - const callInfo * const, - value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = value_int(addend + adder); - } -}; - - - -class testCallInfoMethod : public method2 { -public: - testCallInfoMethod() { - this->_signature = "s:"; - } - void - execute(xmlrpc_c::paramList const& paramList, - const callInfo * const callInfoPtr, - value * const retvalP) { - - const callInfo_test * const callInfoP( - dynamic_cast(callInfoPtr)); - - TEST(callInfoP != NULL); - - paramList.verifyEnd(0); - - *retvalP = value_string(callInfoP->data); - } -}; - - - -class nameMethod : public defaultMethod { - - void - execute(string const& methodName, - xmlrpc_c::paramList const& , // paramList - value * const retvalP) { - - *retvalP = value_string(string("no such method: ") + methodName); - } -}; - - - -class echoMethod : public method { -public: - void - execute(xmlrpc_c::paramList const& paramList, - value * const retvalP) { - - paramList.verifyEnd(1); - - *retvalP = paramList[0]; - } -}; - - - -static void -testEmptyXmlDocCall(xmlrpc_c::registry const& myRegistry) { - - string response; - myRegistry.processCall("", &response); - -#ifdef INTERNAL_EXPAT - TEST(response == noElementFoundXml); -#else - // This is what we get with libxml2 - TEST(response == invalidXMLCall); -#endif -} - - - -class registryRegMethodTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "registryRegMethodTestSuite"; - } - virtual void runtests(unsigned int const) { - - xmlrpc_c::registry myRegistry; - - sampleAddMethod m; - - myRegistry.addMethod("xyz", &m); - - myRegistry.addMethod("sample.add", - xmlrpc_c::methodPtr(new sampleAddMethod)); - - myRegistry.disableIntrospection(); - testEmptyXmlDocCall(myRegistry); - { - string response; - myRegistry.processCall(sampleAddGoodCallXml, &response); - TEST(response == sampleAddGoodResponseXml); - } - { - string response; - myRegistry.processCall(sampleAddBadCallXml, &response); - TEST(response == sampleAddBadResponseXml); - } - { - string response; - callInfo const callInfo; - myRegistry.processCall(sampleAddBadCallXml, &callInfo, &response); - TEST(response == sampleAddBadResponseXml); - } - } -}; - - - -class registryDefaultMethodTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "registryDefaultMethodTestSuite"; - } - virtual void runtests(unsigned int const) { - - xmlrpc_c::registry myRegistry; - - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - - { - string response; - myRegistry.processCall(sampleAddGoodCallXml, &response); - TEST(response == sampleAddGoodResponseXml); - } - { - string response; - myRegistry.processCall(nonexistentMethodCallXml, &response); - TEST(response == nonexistentMethodNoDefResponseXml); - } - // We're actually violating the spirit of setDefaultMethod by - // doing this to a registry that's already been used, but as long - // as it works, it's a convenient way to implement this test. - nameMethod dm; - myRegistry.setDefaultMethod(&dm); - myRegistry.setDefaultMethod(defaultMethodPtr(new nameMethod)); - - { - string response; - myRegistry.processCall(nonexistentMethodCallXml, &response); - TEST(response == nonexistentMethodYesDefResponseXml); - } - } -}; - - - -class method2TestSuite : public testSuite { - -public: - virtual string suiteName() { - return "method2TestSuite"; - } - virtual void runtests(unsigned int const) { - - xmlrpc_c::registry myRegistry; - - myRegistry.addMethod("sample.add", - xmlrpc_c::methodPtr(new sampleAddMethod2)); - - myRegistry.addMethod("test.callinfo", - xmlrpc_c::methodPtr(new testCallInfoMethod)); - - { - string response; - myRegistry.processCall(sampleAddGoodCallXml, &response); - TEST(response == sampleAddGoodResponseXml); - } - { - string response; - myRegistry.processCall(sampleAddBadCallXml, &response); - TEST(response == sampleAddBadResponseXml); - } - { - string response; - callInfo_test const callInfo; - myRegistry.processCall(testCallInfoCallXml, &callInfo, &response); - TEST(response == testCallInfoResponseXml); - } - } -}; - - - -class dialectTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "dialectTestSuite"; - } - virtual void runtests(unsigned int const) { - - registry myRegistry; - string response; - - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - myRegistry.addMethod("echo", methodPtr(new echoMethod)); - - myRegistry.setDialect(xmlrpc_dialect_i8); - - myRegistry.setDialect(xmlrpc_dialect_apache); - - myRegistry.processCall(echoI8ApacheCall, &response); - - TEST(response == echoI8ApacheResponse); - - myRegistry.processCall(echoNilApacheCall, &response); - - TEST(response == echoNilApacheResponse); - - EXPECT_ERROR( // invalid dialect - myRegistry.setDialect(static_cast(300)); - ); - } -}; - - - -class testShutdown : public xmlrpc_c::registry::shutdown { -/*---------------------------------------------------------------------------- - This class is logically local to - registryShutdownTestSuite::runtests(), but if we declare it that - way, gcc 2.95.3 fails with some bogus messages about undefined - references from random functions when we do that. ------------------------------------------------------------------------------*/ -public: - void doit(string const&, - void * const) const { - - } -}; - - - -class registryShutdownTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "registryShutdownTestSuite"; - } - virtual void runtests(unsigned int const) { - - xmlrpc_c::registry myRegistry; - - testShutdown shutdown; - - myRegistry.setShutdown(&shutdown); - } -}; - - - -} // unnamed namespace - - - -string -registryTestSuite::suiteName() { - return "registryTestSuite"; -} - - - -void -registryTestSuite::runtests(unsigned int const indentation) { - - { - registryPtr myRegistryP(new registry); - - myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); - } - - registryRegMethodTestSuite().run(indentation+1); - - registryDefaultMethodTestSuite().run(indentation+1); - - method2TestSuite().run(indentation+1); - - registry myRegistry; - - myRegistry.disableIntrospection(); - - dialectTestSuite().run(indentation+1); - - registryShutdownTestSuite().run(indentation+1); - - TEST(myRegistry.maxStackSize() >= 256); - -} diff --git a/trunk/test/cpp/registry.hpp b/trunk/test/cpp/registry.hpp deleted file mode 100644 index b8614257d..000000000 --- a/trunk/test/cpp/registry.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "tools.hpp" - -class registryTestSuite : public testSuite { - -public: - virtual std::string suiteName(); - virtual void runtests(unsigned int const indentation); -}; - diff --git a/trunk/test/cpp/server_abyss.cpp b/trunk/test/cpp/server_abyss.cpp deleted file mode 100644 index c1b449952..000000000 --- a/trunk/test/cpp/server_abyss.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/*============================================================================= - server_abyss -=============================================================================== - Test the Abyss XML-RPC server C++ facilities of XML-RPC for C/C++. - -=============================================================================*/ -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef WIN32 - #include -#else - #include - #include - #include - #include -#endif - -using namespace std; - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/registry.hpp" -#include "xmlrpc-c/server_abyss.hpp" -#include "xmlrpc-c/abyss.h" - -using namespace xmlrpc_c; - -#include "tools.hpp" -#include "server_abyss.hpp" - - - -namespace { - -static void -closesock(int const fd) { -#ifdef WIN32 - closesocket(fd); -#else - close(fd); -#endif -} - - - -static sockaddr_in -localhostSockAddr(short const portNumber) { - - struct sockaddr_in retval; - - retval.sin_family = AF_INET; - retval.sin_port = htons(portNumber); - retval.sin_addr = test_ipAddrFromDecimal(127, 0, 0, 1); - - return retval; -} - - - -class boundSocket { - -public: - boundSocket(short const portNumber) { - this->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - - if (this->fd < 0) - throwf("socket() failed. errno=%d (%s)", - errno, strerror(errno)); - - struct sockaddr_in sockAddr; - int rc; - - sockAddr.sin_family = AF_INET; - sockAddr.sin_port = htons(portNumber); - sockAddr.sin_addr.s_addr = 0; - - rc = bind(this->fd, (struct sockaddr *)&sockAddr, sizeof(sockAddr)); - - if (rc != 0) { - closesock(this->fd); - throwf("Couldn't bind. bind() failed with errno=%d (%s)", - errno, strerror(errno)); - } - } - - ~boundSocket() { - closesock(this->fd); - } - - XMLRPC_SOCKET fd; -}; - - - -class sampleAddMethod : public method { -public: - sampleAddMethod() { - this->_signature = "i:ii"; - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = value_int(addend + adder); - } -}; - - - -// We need 'global' because methods of class addHandlerTestSuite call -// functions in the Abyss C library. By virtue of global's static -// storage class, the program loader will call its constructor and -// destructor and thus initialize and terminate the Abyss C library. - -static class abyssGlobalState { -public: - abyssGlobalState() { - const char * error; - AbyssInit(&error); - if (error) { - string const e(error); - free(const_cast(error)); - throwf("AbyssInit() failed. %s", e.c_str()); - } - } - ~abyssGlobalState() { - AbyssTerm(); - } -} const global; - - - -class addHandlerTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "addHandlerTestSuite"; - } - virtual void runtests(unsigned int const) { - TServer abyssServer; - - ServerCreate(&abyssServer, "testserver", 8080, NULL, NULL); - - registry myRegistry; - - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - - registryPtr myRegistryP(new registry); - - myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); - - server_abyss_set_handlers(&abyssServer, myRegistry); - - server_abyss_set_handlers(&abyssServer, &myRegistry); - - server_abyss_set_handlers(&abyssServer, myRegistryP); - - server_abyss_set_handlers(&abyssServer, myRegistry, "/RPC3"); - - server_abyss_set_handlers(&abyssServer, &myRegistry, "/RPC3"); - - server_abyss_set_handlers(&abyssServer, myRegistryP, "/RPC3"); - - ServerFree(&abyssServer); - } -}; - - - -class setShutdownTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "setShutdownTestSuite"; - } - virtual void runtests(unsigned int const) { - - registry myRegistry; - - serverAbyss myServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - .portNumber(12345) - ); - - serverAbyss::shutdown shutdown(&myServer); - - myRegistry.setShutdown(&shutdown); - } -}; - - - -class createTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "createTestSuite"; - } - virtual void runtests(unsigned int const) { - - registry myRegistry; - - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - - registryPtr myRegistryP(new registry); - - myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); - - struct sockaddr_in const sockAddr(localhostSockAddr(8080)); - const struct sockaddr * const sockAddrP( - (const struct sockaddr *)&sockAddr); - - EXPECT_ERROR( // No registry - serverAbyss::constrOpt opt; - serverAbyss abyssServer(opt); - ); - EXPECT_ERROR( // Both registryP and registryPtr - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryPtr(myRegistryP) - .registryP(&myRegistry) - .portNumber(12345) - ); - ); - EXPECT_ERROR( // Both portNumber and socketFd - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - .portNumber(8080) - .socketFd(3)); - ); - - EXPECT_ERROR( // Both portNumber and sockAddrP - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - .portNumber(8080) - .sockAddrP(sockAddrP) - .sockAddrLen(sizeof(sockAddr))); - ); - - EXPECT_ERROR( // Both socketFd and sockAddrP - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - .socketFd(3) - .sockAddrP(sockAddrP) - .sockAddrLen(sizeof(sockAddr))); - ); - - EXPECT_ERROR( // sockAddrP but no sockAddrLen - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - .sockAddrP(sockAddrP)); - ); - - EXPECT_ERROR( // port number too big - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - .portNumber(65536)); - ); - - // Because of the vagaries of Abyss, construction of the following - // objects may exit the program if it detects an error, such as - // port number already in use. We need to fix Abyss some day. - - { - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - .portNumber(12345) - ); - } - { - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryPtr(myRegistryP) - .portNumber(12345) - ); - } - { - boundSocket socket(12345); - - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - .socketFd(socket.fd) - ); - } - { - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - ); - } - - { - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryPtr(myRegistryP) - .sockAddrP(sockAddrP) - .sockAddrLen(sizeof(sockAddr)) - ); - } - { - // Test all the options - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryPtr(myRegistryP) - .portNumber(12345) - .maxConn(10) - .maxConnBacklog(10) - .keepaliveTimeout(5) - .keepaliveMaxConn(4) - .timeout(20) - .dontAdvertise(true) - .uriPath("/xmlrpc") - .chunkResponse(true) - .allowOrigin("*") - .accessCtlMaxAge(42) - .logFileName("/tmp/logfile") - .serverOwnsSignals(false) - .expectSigchld(true) - ); - - } - { - serverAbyss abyssServer( - myRegistry, - 12345, // TCP port on which to listen - "/tmp/xmlrpc_log" // Log file - ); - } - } -}; - - - -class testCallInfoMethod : public method2 { -public: - void - execute(paramList const& paramList, - const callInfo * const callInfoPtr, - value * const retvalP) { - - const callInfo_serverAbyss * const callInfoP( - dynamic_cast(callInfoPtr)); - - TEST(callInfoP != NULL); - - paramList.verifyEnd(0); - - TEST(callInfoP->serverAbyssP != NULL); - TEST(callInfoP->abyssSessionP != NULL); - - *retvalP = value_nil(); - } -}; - - - -class callInfoTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "callInfoTestSuite"; - } - virtual void runtests(unsigned int const) { - - registry myRegistry; - - myRegistry.addMethod("sample.add", methodPtr(new testCallInfoMethod)); - - serverAbyss abyssServer(serverAbyss::constrOpt() - .registryP(&myRegistry) - .portNumber(12345) - ); - } -}; - - - -} // unnamed namespace - - - -string -serverAbyssTestSuite::suiteName() { - return "serverAbyssTestSuite"; -} - - -void -serverAbyssTestSuite::runtests(unsigned int const indentation) { - - addHandlerTestSuite().run(indentation+1); - - setShutdownTestSuite().run(indentation+1); - - createTestSuite().run(indentation+1); - - callInfoTestSuite().run(indentation+1); -} diff --git a/trunk/test/cpp/server_abyss.hpp b/trunk/test/cpp/server_abyss.hpp deleted file mode 100644 index 88da51594..000000000 --- a/trunk/test/cpp/server_abyss.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "tools.hpp" - -class serverAbyssTestSuite : public testSuite { - -public: - virtual std::string suiteName(); - virtual void runtests(unsigned int const); -}; diff --git a/trunk/test/cpp/server_abyss_dummy.cpp b/trunk/test/cpp/server_abyss_dummy.cpp deleted file mode 100644 index 307ac99f0..000000000 --- a/trunk/test/cpp/server_abyss_dummy.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/*============================================================================= - server_abyss_dummy -=============================================================================== - This is a substitute for server_abyss.cpp, for use in a test program that is - not linked with the Abyss XML-RPC server libraries. - - It simply passes the test. -=============================================================================*/ - -#include -#include - -#include "tools.hpp" -#include "server_abyss.hpp" - -using namespace std; - -string -serverAbyssTestSuite::suiteName() { - return "serverAbyssTestSuite"; -} - - -void -serverAbyssTestSuite::runtests(unsigned int const indentation) { - - cout << string((indentation+1)*2, ' ') - << "Running dummy test." << endl; -} diff --git a/trunk/test/cpp/server_pstream.cpp b/trunk/test/cpp/server_pstream.cpp deleted file mode 100644 index 1709bc414..000000000 --- a/trunk/test/cpp/server_pstream.cpp +++ /dev/null @@ -1,821 +0,0 @@ -/*============================================================================= - server_pstream -=============================================================================== - Test the pstream server C++ facilities of XML-RPC for C/C++. - -=============================================================================*/ - -#include "xmlrpc_config.h" - -#if MSVCRT - #include - #include -#else - #include - #include - #include - #include -#endif - -#include -#include -#include -#include - -#include "xmlrpc-c/config.h" - -#if MSVCRT - int - xmlrpc_win32_socketpair(int const domain, - int const type, - int const protocol, - SOCKET socks[2]); -#endif - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/sleep_int.h" -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/registry.hpp" -#include "xmlrpc-c/server_pstream.hpp" - -#include "tools.hpp" -#include "server_pstream.hpp" - -using namespace xmlrpc_c; -using namespace std; - - -namespace { - -static void -setNonBlocking(XMLRPC_SOCKET const socket) { - -#if MSVCRT - u_long iMode = 1; - ioctlsocket(socket, FIONBIO, &iMode); -#else - fcntl(socket, F_SETFL, O_NONBLOCK); -#endif -} - - - -#define ESC_STR "\x1B" - - -static string const -xmlPrologue("\r\n"); - -static string const -packetStart(ESC_STR "PKT"); - -static string const -packetEnd(ESC_STR "END"); - - -class callInfo_test : public callInfo { -public: - callInfo_test() : info("this is a test") {} - string const info; -}; - - - -class sampleAddMethod : public method { -public: - sampleAddMethod() { - this->_signature = "i:ii"; - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = value_int(addend + adder); - } -}; - -string const sampleAddCallXml( - xmlPrologue + - "\r\n" - "sample.add\r\n" - "\r\n" - "5\r\n" - "7\r\n" - "\r\n" - "\r\n" - ); - -string const sampleAddResponseXml( - xmlPrologue + - "\r\n" - "\r\n" - "12\r\n" - "\r\n" - "\r\n" - ); - - -class testCallInfoMethod : public method2 { - -public: - virtual void - execute(paramList const& paramList, - const callInfo * const callInfoPtr, - value * const retvalP) { - - const callInfo_test * const callInfoP( - dynamic_cast(callInfoPtr)); - - TEST(callInfoP != NULL); - - paramList.verifyEnd(0); - - TEST(callInfoP->info == string("this is a test")); - - *retvalP = value_nil(); - } -}; - -string const testCallInfoCallXml( - xmlPrologue + - "\r\n" - "test.callinfo\r\n" - "\r\n" - "\r\n" - "\r\n" - ); - -string const testCallInfoResponseXml( - xmlPrologue + - "\r\n" - "\r\n" - "" - "\r\n" - "\r\n" - "\r\n" - ); - - - -static void -waitForNetworkTransport() { -/*---------------------------------------------------------------------------- - Wait for a message to travel through the network. - - This is part of our hack to allow us to test client/server communication - without the bother of a separate thread for each. One party writes - to a socket, causing the OS to buffer the message, then the other party - reads from the socket, getting the buffered message. We never wait - to send or receive, because with only one thread to do both, we would - deadlock. Instead, we just count on the buffer being big enough. - - But on some systems, the message doesn't immediately travel like this. It - takes action by an independent thread (provided by the OS) to move the - message. In particular, we've seen this behavior on Windows (2010.10). - - So we just sleep for a small amount of time to let the message move. ------------------------------------------------------------------------------*/ - - // xmlrpc_millisecond_sleep() is allowed to return early, and on Windows - // it does that in preference to returning late insofar as the clock - // resolution doesn't allow returning at the exact time. It is rumored - // that Windows clock period may be as long as 40 milliseconds. - - xmlrpc_millisecond_sleep(50); -} - - - -class client { -/*---------------------------------------------------------------------------- - This is an object you can use as a client to test a packet stream - server. - - You attach the 'serverFd' member to your packet stream server, then - call the 'sendCall' method to send a call to your server, then call - the 'recvResp' method to get the response. - - Destroying the object closes the connection. - - We rely on typical, though unguaranteed socket function: we need to - be able to write 'contents' to the socket in a single write() - system call before the other side reads anything -- i.e. the socket - has to have a buffer that big. We do this because we're lazy; doing - it right would require forking a writer process. ------------------------------------------------------------------------------*/ -public: - - client(); - - ~client(); - - void - sendCall(string const& callBytes) const; - - void - hangup(); - - void - recvResp(string * const respBytesP) const; - - int serverFd; - -private: - - int clientFd; -}; - - - -client::client() { - - enum { - SERVER = 0, - CLIENT = 1, - }; - XMLRPC_SOCKET sockets[2]; - int rc; - - rc = XMLRPC_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, sockets); - - if (rc < 0) - throwf("Failed to create UNIX domain stream socket pair " - "as test tool. errno=%d (%s)", - errno, strerror(errno)); - else { - setNonBlocking(sockets[CLIENT]); - - this->serverFd = sockets[SERVER]; - this->clientFd = sockets[CLIENT]; - } -} - - - -client::~client() { - - XMLRPC_CLOSESOCKET(this->clientFd); - XMLRPC_CLOSESOCKET(this->serverFd); -} - - - -void -client::sendCall(string const& packetBytes) const { - - int rc; - - rc = send(this->clientFd, packetBytes.c_str(), packetBytes.length(), 0); - - waitForNetworkTransport(); - - if (rc < 0) - throwf("send() of test data to socket failed, errno=%d (%s)", - errno, strerror(errno)); - else { - unsigned int bytesWritten(rc); - - if (bytesWritten != packetBytes.length()) - throwf("Short write to socket"); - } -} - - - -void -client::hangup() { - - // Closing the socket (close()) would be a better simulation of the - // real world, and easier, but we shut down just the client->server - // half of the socket and remain open to receive an RPC response. - // That's because this test program is lazy and does the client and - // server in the same thread, depending on socket buffering on the - // receive side to provide parallelism. We need to be able to do the - // following sequence: - // - // - Client sends call - // - Client hangs up - // - Server gets call - // - Server sends response - // - Client gets response - // - Server notices hangup - - shutdown(this->clientFd, 1); // Shutdown for transmission only -} - - - -void -client::recvResp(string * const packetBytesP) const { - - char buffer[4096]; - int rc; - - waitForNetworkTransport(); - - rc = recv(this->clientFd, buffer, sizeof(buffer), 0); - - if (rc < 0) - throwf("recv() from socket failed, errno=%d (%s)", - errno, strerror(errno)); - else { - unsigned int bytesReceived(rc); - - *packetBytesP = string(buffer, bytesReceived); - } -} - - - -static void -testEmptyStream(registry const& myRegistry) { -/*---------------------------------------------------------------------------- - Here we send the pstream server an empty stream; i.e. we close the - socket from the client end without sending anything. - - This should cause the server to recognize EOF. ------------------------------------------------------------------------------*/ - - client client; - - serverPstreamConn server(serverPstreamConn::constrOpt() - .registryP(&myRegistry) - .socketFd(client.serverFd)); - - client.hangup(); - - bool eof; - server.runOnce(&eof); - - TEST(eof); -} - - - -static void -testBrokenPacket(registry const& myRegistry) { -/*---------------------------------------------------------------------------- - Here we send a stream that is not a legal packetsocket stream: it - doesn't have any control word. ------------------------------------------------------------------------------*/ - client client; - - serverPstreamConn server(serverPstreamConn::constrOpt() - .registryP(&myRegistry) - .socketFd(client.serverFd)); - - client.sendCall("junk"); - client.hangup(); - - bool eof; - - EXPECT_ERROR( - server.runOnce(&eof); - ); -} - - - -static void -testEmptyPacket(registry const& myRegistry) { -/*---------------------------------------------------------------------------- - Here we send the pstream server one empty packet. It should respond - with one packet, being an XML-RPC fault response complaining that the - call is not valid XML. ------------------------------------------------------------------------------*/ - client client; - - serverPstreamConn server(serverPstreamConn::constrOpt() - .registryP(&myRegistry) - .socketFd(client.serverFd)); - - client.sendCall(packetStart + packetEnd); - - bool eof; - server.runOnce(&eof); - - TEST(!eof); - - string response; - client.recvResp(&response); - - // We ought to validate that the response is a complaint about - // the empty call - - client.hangup(); - - server.runOnce(&eof); - - TEST(eof); -} - - - -static void -testCallInfo(client * const clientP, - serverPstreamConn * const serverP) { - - string const testCallInfoCallStream( - packetStart + testCallInfoCallXml + packetEnd - ); - - string const testCallInfoResponseStream( - packetStart + testCallInfoResponseXml + packetEnd - ); - - clientP->sendCall(testCallInfoCallStream); - - callInfo_test callInfo; - int nointerrupt(0); - bool eof; - serverP->runOnce(&callInfo, &nointerrupt, &eof); - - TEST(!eof); - - string response; - clientP->recvResp(&response); - - TEST(response == testCallInfoResponseStream); -} - - - -static void -testNormalCall(registry const& myRegistry) { - - string const sampleAddGoodCallStream( - packetStart + sampleAddCallXml + packetEnd - ); - - string const sampleAddGoodResponseStream( - packetStart + sampleAddResponseXml + packetEnd - ); - - client client; - - serverPstreamConn server(serverPstreamConn::constrOpt() - .registryP(&myRegistry) - .socketFd(client.serverFd)); - - client.sendCall(sampleAddGoodCallStream); - - bool eof; - - int interrupt(1); - server.runOnce(&interrupt, &eof); // returns without reading socket - TEST(!eof); - - server.runOnce(&eof); - - TEST(!eof); - - string response; - client.recvResp(&response); - - TEST(response == sampleAddGoodResponseStream); - - testCallInfo(&client, &server); - - client.hangup(); - - server.runOnce(&eof); - - TEST(eof); -} - - - -static void -testNoWaitCall(registry const& myRegistry) { - - string const sampleAddGoodCallStream( - packetStart + - xmlPrologue + - "\r\n" - "sample.add\r\n" - "\r\n" - "5\r\n" - "7\r\n" - "\r\n" - "\r\n" + - packetEnd - ); - - - string const sampleAddGoodResponseStream( - packetStart + - xmlPrologue + - "\r\n" - "\r\n" - "12\r\n" - "\r\n" - "\r\n" + - packetEnd - ); - - client client; - - serverPstreamConn server(serverPstreamConn::constrOpt() - .registryP(&myRegistry) - .socketFd(client.serverFd)); - - bool eof; - bool gotOne; - string response; - - server.runOnceNoWait(&eof, &gotOne); - - TEST(!eof); - TEST(!gotOne); - - server.runOnceNoWait(&eof); - - TEST(!eof); - - client.sendCall(sampleAddGoodCallStream); - - server.runOnceNoWait(&eof, &gotOne); - - TEST(!eof); - TEST(gotOne); - - client.recvResp(&response); - - TEST(response == sampleAddGoodResponseStream); - - client.sendCall(sampleAddGoodCallStream); - - server.runOnce(&eof); - - TEST(!eof); - client.recvResp(&response); - TEST(response == sampleAddGoodResponseStream); - - client.hangup(); - - server.runOnce(&eof); - - TEST(eof); -} - - - -static void -testMultiRpcRunNoRpc(registry const& myRegistry) { - - client client; - - serverPstreamConn server(serverPstreamConn::constrOpt() - .registryP(&myRegistry) - .socketFd(client.serverFd)); - - client.hangup(); - - server.run(); -} - - - -static void -testMultiRpcRunOneRpc(registry const& myRegistry) { - - string const sampleAddGoodCallStream( - packetStart + - xmlPrologue + - "\r\n" - "sample.add\r\n" - "\r\n" - "5\r\n" - "7\r\n" - "\r\n" - "\r\n" + - packetEnd - ); - - - string const sampleAddGoodResponseStream( - packetStart + - xmlPrologue + - "\r\n" - "\r\n" - "12\r\n" - "\r\n" - "\r\n" + - packetEnd - ); - - client client; - - serverPstreamConn server(serverPstreamConn::constrOpt() - .registryP(&myRegistry) - .socketFd(client.serverFd)); - - - client.sendCall(sampleAddGoodCallStream); - client.hangup(); - - int interrupt; - - interrupt = 1; - server.run(&interrupt); // Returns without reading socket - - interrupt = 0; - server.run(&interrupt); // Does the buffered RPC - - string response; - client.recvResp(&response); - - TEST(response == sampleAddGoodResponseStream); -} - - - -class serverPstreamConnTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "serverPstreamConnTestSuite"; - } - virtual void runtests(unsigned int const) { - registry myRegistry; - - myRegistry.addMethod("sample.add", - methodPtr(new sampleAddMethod)); - myRegistry.addMethod("test.callinfo", - methodPtr(new testCallInfoMethod)); - - registryPtr myRegistryP(new registry); - - myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); - - EXPECT_ERROR( // Empty options - serverPstreamConn::constrOpt opt; - serverPstreamConn server(opt); - ); - - EXPECT_ERROR( // No registry - serverPstreamConn server(serverPstreamConn::constrOpt() - .socketFd(3)); - ); - - EXPECT_ERROR( // No socket fd - serverPstreamConn server(serverPstreamConn::constrOpt() - .registryP(&myRegistry)); - ); - - testEmptyStream(myRegistry); - - testBrokenPacket(myRegistry); - - testEmptyPacket(myRegistry); - - testNormalCall(myRegistry); - - testNoWaitCall(myRegistry); - - testMultiRpcRunNoRpc(myRegistry); - - testMultiRpcRunOneRpc(myRegistry); - } -}; - - - -static void -testMultiConnInterrupt(registry const& myRegistry) { - - // We use a nonexistent file descriptor, but the server won't - // ever access it, so it won't know. - - serverPstream server(serverPstream::constrOpt() - .registryP(&myRegistry) - .socketFd(37)); - - int interrupt(1); // interrupt immediately - - server.runSerial(&interrupt); -} - - - -class derivedServer : public xmlrpc_c::serverPstream { -public: - derivedServer(serverPstream::constrOpt const& constrOpt) : - serverPstream(constrOpt), - info("this is my derived server") {} - - string const info; -}; - - - -class multiTestCallInfoMethod : public method2 { - -// The test isn't sophisticated enough actually to do an RPC, so this -// code never runs. We just want to see if it compiles. - -public: - virtual void - execute(paramList const& paramList, - const callInfo * const callInfoPtr, - value * const retvalP) { - - const callInfo_serverPstream * const callInfoP( - dynamic_cast(callInfoPtr)); - - TEST(callInfoP != NULL); - - paramList.verifyEnd(0); - - derivedServer * const derivedServerP( - dynamic_cast(callInfoP->serverP)); - - TEST(derivedServerP->info == string("this is my derived server")); - - TEST(callInfoP->clientAddr.sa_family == AF_INET); - TEST(callInfoP->clientAddrSize >= sizeof(struct sockaddr_in)); - - *retvalP = value_nil(); - } -}; - -static void -testMultiConnCallInfo() { - - registry myRegistry; - - myRegistry.addMethod("testCallInfo", - methodPtr(new multiTestCallInfoMethod)); - - derivedServer server(serverPstream::constrOpt() - .registryP(&myRegistry) - .socketFd(37)); -} - - - -class multiConnServerTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "multiConnServerTestSuite"; - } - virtual void runtests(unsigned int const) { - registry myRegistry; - - myRegistry.addMethod("sample.add", - methodPtr(new sampleAddMethod)); - - registryPtr myRegistryP(new registry); - - myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); - - EXPECT_ERROR( // Empty options - serverPstream::constrOpt opt; - serverPstream server(opt); - ); - - EXPECT_ERROR( // No registry - serverPstream server(serverPstream::constrOpt() - .socketFd(3)); - ); - - EXPECT_ERROR( // No socket fd - serverPstream server(serverPstream::constrOpt() - .registryP(&myRegistry)); - ); - - testMultiConnInterrupt(myRegistry); - - testMultiConnCallInfo(); - } -}; - - - -} // unnamed namespace - - - -string -serverPstreamTestSuite::suiteName() { - return "serverPstreamTestSuite"; -} - - -void -serverPstreamTestSuite::runtests(unsigned int const indentation) { - - serverPstreamConnTestSuite().run(indentation + 1); - - multiConnServerTestSuite().run(indentation + 1); -} - diff --git a/trunk/test/cpp/server_pstream.hpp b/trunk/test/cpp/server_pstream.hpp deleted file mode 100644 index 181658037..000000000 --- a/trunk/test/cpp/server_pstream.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "tools.hpp" - -class serverPstreamTestSuite : public testSuite { - -public: - virtual std::string suiteName(); - virtual void runtests(unsigned int const); -}; diff --git a/trunk/test/cpp/test.cpp b/trunk/test/cpp/test.cpp deleted file mode 100644 index 0546ea226..000000000 --- a/trunk/test/cpp/test.cpp +++ /dev/null @@ -1,390 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/oldcppwrapper.hpp" -#include "xmlrpc-c/registry.hpp" - -#include "base64.hpp" -#include "xml.hpp" -#include "value.hpp" -#include "testclient.hpp" -#include "registry.hpp" -#include "server_abyss.hpp" -#include "server_pstream.hpp" -#include "abyss.hpp" -#include "tools.hpp" - -using namespace xmlrpc_c; -using namespace std; - -//========================================================================= -// Test Harness -//========================================================================= -// -// There are two styles of test in here. The older ones are vaguely -// inspired by Kent Beck's book on eXtreme Programming (XP) and use -// the TEST...() macros. -// -// But this style is not really appropriate for C++. It's based on -// code that explicitly tests for errors, as one would do in C. In C++, -// it is cumbersome to catch exceptions on every call, so we don't in -// the new style. - -// And there's not much point in trying to count test successes and -// failures. Any failure is a problem, so in the new style, we just -// quit after we recognize one (again, more in line with regular exception -// throwing). With exception throwing, you can't count what _didn't_ -// cause an exception, so there's no meaningful count of test successes. -// -// To run the tests, type './cpptest'. -// To check for memory leaks, install RedHat's 'memprof' utility, and -// type 'memprof cpptest'. -// -// If you add new tests to this file, please deallocate any data -// structures you use in the appropriate fashion. This allows us to test -// various destructor code for memory leaks. - - -//========================================================================= -// Test Suites -//========================================================================= - -void -test_fault (void) { - - // Create a new fault and perform basic operations. - XmlRpcFault fault1 = XmlRpcFault(6, "Sample fault"); - TEST(fault1.getFaultCode() == 6); - TEST(fault1.getFaultString() == "Sample fault"); - - // Extract and examine the underlying xmlrpc_env struct. - xmlrpc_env *env1 = fault1.getFaultEnv(); - TEST(env1 != NULL); - TEST(env1->fault_occurred); - TEST(env1->fault_code == 6); - TEST(strcmp(env1->fault_string, "Sample fault") == 0); - - // Test our copy constructor. - XmlRpcFault fault2 = fault1; - TEST(fault2.getFaultCode() == 6); - TEST(fault2.getFaultString() == "Sample fault"); - - // Construct a fault from a pre-existing xmlrpc_env structure. - xmlrpc_env env3; - xmlrpc_env_init(&env3); - xmlrpc_env_set_fault(&env3, 7, "Another fault"); - XmlRpcFault fault3 = XmlRpcFault(&env3); - xmlrpc_env_clean(&env3); - TEST(fault3.getFaultCode() == 7); - TEST(fault3.getFaultString() == "Another fault"); - - // Attempt to construct a fault from a fault-free xmlrpc_env. - xmlrpc_env env4; - xmlrpc_env_init(&env4); - try { - XmlRpcFault fault4 = XmlRpcFault(&env4); - TEST_FAILED("Constructed invalid XmlRpcFault"); - } catch (XmlRpcFault const& fault) { - TEST_PASSED(); - TEST(fault.getFaultCode() == XMLRPC_INTERNAL_ERROR); - } - xmlrpc_env_clean(&env4); -} - - - -void test_env (void) { - - // Declare these here to prevent silly compiler warnings about - // potentially uninitialized variables. - XmlRpcEnv env1; - XmlRpcEnv env2; - - // Perform simple environment tests. - TEST(!env1.hasFaultOccurred()); - xmlrpc_env_set_fault(env1, 8, "Fault 8"); - TEST(env1.hasFaultOccurred()); - XmlRpcFault fault1 = env1.getFault(); - TEST(fault1.getFaultCode() == 8); - TEST(fault1.getFaultString() == "Fault 8"); - - // Test throwIfFaultOccurred. - try { - env2.throwIfFaultOccurred(); - TEST_PASSED(); - } catch (XmlRpcFault const&) { - TEST_FAILED("We threw a fault when one hadn't occurred"); - } - xmlrpc_env_set_fault(env2, 9, "Fault 9"); - try { - env2.throwIfFaultOccurred(); - TEST_FAILED("A fault occurred, and we didn't throw it"); - } catch (XmlRpcFault const& fault) { - TEST_PASSED(); - TEST(fault.getFaultCode() == 9); - TEST(fault.getFaultString() == "Fault 9"); - } - - // Make sure we can't get a fault if one hasn't occurred. - XmlRpcEnv env3; - try { - XmlRpcFault fault3 = env3.getFault(); - TEST_FAILED("We retrieved a non-existant fault"); - } catch (XmlRpcFault const& fault) { - TEST_PASSED(); - TEST(fault.getFaultCode() == XMLRPC_INTERNAL_ERROR); - } -} - -void test_value (void) { - XmlRpcEnv env; - - // Test basic reference counting behavior. - xmlrpc_value *v = xmlrpc_build_value(env, "i", (xmlrpc_int32) 1); - env.throwIfFaultOccurred(); - XmlRpcValue val1 = XmlRpcValue(v, XmlRpcValue::CONSUME_REFERENCE); - v = xmlrpc_build_value(env, "i", (xmlrpc_int32) 2); - env.throwIfFaultOccurred(); - XmlRpcValue val2 = v; - xmlrpc_DECREF(v); - - // Borrow a reference. - v = xmlrpc_build_value(env, "i", (xmlrpc_int32) 3); - env.throwIfFaultOccurred(); - XmlRpcValue val3 = XmlRpcValue(v, XmlRpcValue::CONSUME_REFERENCE); - xmlrpc_value *borrowed = val3.borrowReference(); - TEST(borrowed == v); - - // Make a reference. - v = xmlrpc_build_value(env, "i", (xmlrpc_int32) 4); - env.throwIfFaultOccurred(); - XmlRpcValue val4 = XmlRpcValue(v, XmlRpcValue::CONSUME_REFERENCE); - xmlrpc_value *made = val4.makeReference(); - TEST(made == v); - xmlrpc_DECREF(made); - - // Test our default constructor. - XmlRpcValue val5; - TEST(val5.getBool() == false); - - // Test our type introspection. - TEST(XmlRpcValue::makeInt(0).getType() == XMLRPC_TYPE_INT); - - // Test our basic data types. - TEST(XmlRpcValue::makeInt(30).getInt() == 30); - TEST(XmlRpcValue::makeInt(-30).getInt() == -30); - TEST(XmlRpcValue::makeBool(true).getBool() == true); - TEST(XmlRpcValue::makeBool(false).getBool() == false); - TEST(XmlRpcValue::makeDateTime("19980717T14:08:55").getRawDateTime() == - "19980717T14:08:55"); - TEST(XmlRpcValue::makeString("foo").getString() == "foo"); - TEST(XmlRpcValue::makeString("bar", 3).getString() == "bar"); - TEST(XmlRpcValue::makeString("bar", 3).getString() == "bar"); - TEST(XmlRpcValue::makeString("a\0b").getString() == string("a\0b")); - XmlRpcValue::makeArray().getArray(); - XmlRpcValue::makeStruct().getStruct(); - - // Test byte string values. - const unsigned char *b64_data; - size_t b64_len; - XmlRpcValue val6 = XmlRpcValue::makeBase64((unsigned char*) "a\0\0b", 4); - val6.getBase64(b64_data, b64_len); - TEST(b64_len == 4); - TEST(memcmp(b64_data, "a\0\0b", 4) == 0); - - // Test arrays. - XmlRpcValue array = XmlRpcValue::makeArray(); - TEST(array.arraySize() == 0); - array.arrayAppendItem(XmlRpcValue::makeString("foo")); - TEST(array.arraySize() == 1); - array.arrayAppendItem(XmlRpcValue::makeString("bar")); - TEST(array.arraySize() == 2); - TEST(array.arrayGetItem(0).getString() == "foo"); - TEST(array.arrayGetItem(1).getString() == "bar"); - - // Test structs. - XmlRpcValue strct = XmlRpcValue::makeStruct(); - TEST(strct.structSize() == 0); - strct.structSetValue("foo", XmlRpcValue::makeString("fooval")); - TEST(strct.structSize() == 1); - strct.structSetValue("bar", XmlRpcValue::makeString("barval")); - TEST(strct.structSize() == 2); - TEST(strct.structHasKey("bar")); - TEST(!strct.structHasKey("nosuch")); - for (int i = 0; i < (int)strct.structSize(); ++i) { - string key; - XmlRpcValue value; - strct.structGetKeyAndValue(i, key, value); - TEST(key + "val" == value.getString()); - } -} - - - -static void -testXmlRpcCpp() { -/*---------------------------------------------------------------------------- - Test the legacy XmlRpcCpp.cpp library ------------------------------------------------------------------------------*/ - cout << "Testing XmlRpcCpp library..." << endl; - - test_fault(); - test_env(); - test_value(); -} - - - -static void -buildParamListWithAdd(paramList * const paramListP, - time_t const timeFuture) { - - paramListP->add(value_int(7)); - paramListP->add(value_boolean(true)).add(value_double(3.14)); - time_t const timeZero(0); - paramListP->add(value_datetime(timeZero)); - paramListP->add(value_datetime(timeFuture)); - paramListP->add(value_string("hello world")); - unsigned char bytestringArray[] = {0x10, 0x11, 0x12, 0x13, 0x14}; - vector - bytestringData(&bytestringArray[0], &bytestringArray[4]); - paramListP->add(value_bytestring(bytestringData)); - vector arrayData; - arrayData.push_back(value_int(7)); - arrayData.push_back(value_double(2.78)); - arrayData.push_back(value_string("hello world")); - paramListP->add(value_array(arrayData)); - map structData; - pair member("the_integer", value_int(9)); - structData.insert(member); - paramListP->add(value_struct(structData)); - paramListP->add(value_nil()); - paramListP->add(value_i8((xmlrpc_int64)UINT_MAX + 1)); -} - - - -static void -verifyParamList(paramList const& paramList, - time_t const timeFuture) { - - TEST(paramList.size() == 11); - - TEST(paramList.getInt(0) == 7); - TEST(paramList.getInt(0, 7) == 7); - TEST(paramList.getInt(0, -5, 7) == 7); - TEST(paramList.getBoolean(1) == true); - TEST(paramList.getDouble(2) == 3.14); - TEST(paramList.getDouble(2, 1) == 3.14); - TEST(paramList.getDouble(2, 1, 4) == 3.14); - time_t const timeZero(0); - TEST(paramList.getDatetime_sec(3) == timeZero); - TEST(paramList.getDatetime_sec(3, paramList::TC_ANY) == timeZero); - TEST(paramList.getDatetime_sec(3, paramList::TC_NO_FUTURE) - == timeZero); - TEST(paramList.getDatetime_sec(4, paramList::TC_NO_PAST) - == timeFuture); - TEST(paramList.getString(5) == "hello world"); - TEST(paramList.getBytestring(6)[0] == 0x10); - TEST(paramList.getArray(7).size() == 3); - TEST(paramList.getArray(7, 3).size() == 3); - TEST(paramList.getArray(7, 1, 3).size() == 3); - paramList.getStruct(8)["the_integer"]; - paramList.getNil(9); - TEST(paramList.getI8(10) == (xmlrpc_int64)UINT_MAX + 1); - paramList.verifyEnd(11); -} - - - -class paramListTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "paramListTestSuite"; - } - virtual void runtests(unsigned int const) { - - time_t const timeFuture(time(NULL)+100); - - paramList paramList1; - TEST(paramList1.size() == 0); - - buildParamListWithAdd(¶mList1, timeFuture); - - verifyParamList(paramList1, timeFuture); - - paramList paramList2(5); - TEST(paramList2.size() == 0); - - paramList2.addc(7); - paramList2.addc(true).addc(3.14); - TEST(paramList2.size() == 3); - TEST(paramList2.getInt(0) == 7); - TEST(paramList2.getBoolean(1) == true); - TEST(paramList2.getDouble(2) == 3.14); - } -}; - -//========================================================================= -// Test Driver -//========================================================================= - -int -main(int argc, char**) { - - int retval; - - if (argc-1 > 0) { - cout << "Program takes no arguments" << endl; - exit(1); - } - - bool testsPassed; - - try { - // Add your test suites here. - base64TestSuite().run(0); - xmlTestSuite().run(0); - valueTestSuite().run(0); - paramListTestSuite().run(0); - registryTestSuite().run(0); - serverAbyssTestSuite().run(0); - serverPstreamTestSuite().run(0); - clientTestSuite().run(0); - abyssTestSuite().run(0); - - testXmlRpcCpp(); - - testsPassed = true; - } catch (error const& error) { - cout << "Unexpected error thrown: " << error.what() << endl; - testsPassed = false; - } catch (XmlRpcFault const& fault) { - cout << "Unexpected XML-RPC fault when running test suites." << endl - << "Fault #" << fault.getFaultCode() - << ": " << fault.getFaultString() << endl; - testsPassed = false; - } catch (...) { - cout << "Unexpected exception when running test suites." << endl; - testsPassed = false; - } - - if (testsPassed) { - cout << "PASSED" << endl; - retval = 0; - } else { - cout << "FAILED" << endl; - retval = 1; - } - return retval; -} diff --git a/trunk/test/cpp/testclient.cpp b/trunk/test/cpp/testclient.cpp deleted file mode 100644 index 7ad3eeef7..000000000 --- a/trunk/test/cpp/testclient.cpp +++ /dev/null @@ -1,953 +0,0 @@ -/*============================================================================= - testclient -=============================================================================== - Test the client C++ facilities of XML-RPC for C/C++. - - Contrary to what you might expect, we use the server facilities too - because we test much of the client using a simulated server, via the - "direct" client XML transport we define herein. -=============================================================================*/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "transport_config.h" -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/registry.hpp" -#include "xmlrpc-c/client.hpp" -#include "xmlrpc-c/client_simple.hpp" - -#include "tools.hpp" -#include "testclient.hpp" - -using namespace xmlrpc_c; -using namespace std; - - - -namespace { - -class sampleAddMethod : public method { -public: - sampleAddMethod() { - this->_signature = "i:ii"; - this->_help = "This method adds two integers together"; - } - void - execute(xmlrpc_c::paramList const& paramList, - value * const retvalP) { - - int const addend(paramList.getInt(0)); - int const adder(paramList.getInt(1)); - - paramList.verifyEnd(2); - - *retvalP = value_int(addend + adder); - } -}; - - - -class testApacheDialectMethod : public method { -public: - void - execute(xmlrpc_c::paramList const& paramList, - value * const retvalP) { - - paramList.getNil(0); - - paramList.verifyEnd(1); - - *retvalP = value_i8(7ll); - } -}; - - - -class carriageParm_direct : public carriageParm { -public: - carriageParm_direct(registry * const registryP) : registryP(registryP) {} - - registry * registryP; -}; - - -class clientXmlTransport_direct : public clientXmlTransport { -/*---------------------------------------------------------------------------- - Though this fills the shoes of a client XML transport, it's really a - simulation, because it doesn't transport anything anywhere. The call() - method, which is supposed to transport a call to a server and then - transport the response back, actually just executes the method itself. - - Part of a carriage parameter for a transport of this class is the handle - of a method registry, so the transport knows how to execute the method. ------------------------------------------------------------------------------*/ -public: - void - call(xmlrpc_c::carriageParm * const carriageParmP, - string const& callXml, - string * const responseXmlP) { - - carriageParm_direct * const parmP = - dynamic_cast(carriageParmP); - - if (parmP == NULL) - throw(error("Carriage parameter passed to the direct " - "transport is not type carriageParm_direct")); - - parmP->registryP->processCall(callXml, responseXmlP); - } -}; - - - -class clientDirectAsyncTestSuite : public testSuite { -/*---------------------------------------------------------------------------- - See clientDirectTestSuite for a description of how we use a - clientXmlTransport_direct object to test client functions. - - The object of this class tests the async client functions. With - clientXmlTransport_direct, these are pretty simple because the - transport doesn't even implement an asynchronous interface; it - relies on the base class' emulation of start() using call(). - - Some day, we should add true asynchronous capability to - clientXmlTransport_direct and really test things. ------------------------------------------------------------------------------*/ -public: - virtual string suiteName() { - return "clientDirectAsyncTestSuite"; - } - virtual void runtests(unsigned int const) { - - registry myRegistry; - - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - - carriageParm_direct carriageParmDirect(&myRegistry); - clientXmlTransport_direct transportDirect; - client_xml clientDirect(&transportDirect); - paramList paramListSampleAdd1; - paramListSampleAdd1.add(value_int(5)); - paramListSampleAdd1.add(value_int(7)); - paramList paramListSampleAdd2; - paramListSampleAdd2.add(value_int(30)); - paramListSampleAdd2.add(value_int(-10)); - - rpcPtr const rpcSampleAdd1P("sample.add", paramListSampleAdd1); - rpcSampleAdd1P->start(&clientDirect, &carriageParmDirect); - rpcPtr const rpcSampleAdd2P("sample.add", paramListSampleAdd2); - rpcSampleAdd2P->start(&clientDirect, &carriageParmDirect); - - // Note that for clientXmlTransport_direct, start() and call() are - // the same thing. I.e. the RPC is guaranteed finished as soon - // as it is started. - - - clientDirect.finishAsync(timeout()); - clientDirect.finishAsync(timeout(50)); - - TEST(rpcSampleAdd1P->isFinished()); - TEST(rpcSampleAdd1P->isSuccessful()); - value_int const result1(rpcSampleAdd1P->getResult()); - TEST(static_cast(result1) == 12); - - TEST(rpcSampleAdd2P->isFinished()); - TEST(rpcSampleAdd1P->isSuccessful()); - value_int const result2(rpcSampleAdd2P->getResult()); - TEST(static_cast(result2) == 20); - } -}; - - - -class MyRpc : public rpc { - -public: - MyRpc(std::string const methodName, - paramList const& paramList) : - rpc(methodName, paramList) {} - - void - progress(struct xmlrpc_progress_data const& data) const { - - // The way the tests are currently written, this never actually - // runs; we're just testing for ability to compile. - - cout << "Progress of " << this << ": " - << data.call.total << " " - << data.call.now << " " - << data.response.total << " " - << data.response.now - << endl; - } -}; - - - -class clientDerivedRpcTestSuite : public testSuite { -/*---------------------------------------------------------------------------- - The object of this class tests the ability to derive a class - from xmlrpc_c::rpc in order to override certain methods. ------------------------------------------------------------------------------*/ -public: - virtual string suiteName() { - return "clientDerivedRpcTestSuite"; - } - virtual void runtests(unsigned int const ) { - registry myRegistry; - - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - - carriageParm_direct carriageParmDirect(&myRegistry); - clientXmlTransport_direct transportDirect; - client_xml clientDirect(&transportDirect); - paramList paramListSampleAdd; - paramListSampleAdd.add(value_int(5)); - paramListSampleAdd.add(value_int(7)); - { - /* Test a successful RPC */ - rpcPtr rpcSampleAddP(new MyRpc("sample.add", paramListSampleAdd)); - rpcSampleAddP->call(&clientDirect, &carriageParmDirect); - TEST(rpcSampleAddP->isFinished()); - TEST(rpcSampleAddP->isSuccessful()); - value_int const resultDirect(rpcSampleAddP->getResult()); - TEST(static_cast(resultDirect) == 12); - } - } -}; - - - -class clientDirectTestSuite : public testSuite { -/*---------------------------------------------------------------------------- - The object of this class tests the client facilities by using a - special client XML transport defined above and an XML-RPC server we - build ourselves and run inline. We build the server out of a - xmlrpc_c::registry object and our transport just delivers XML - directly to the registry object and gets the response XML from it - and delivers that back. There's no network or socket or pipeline or - anything -- the transport actually executes the XML-RPC method. ------------------------------------------------------------------------------*/ -public: - virtual string suiteName() { - return "clientDirectTestSuite"; - } - virtual void runtests(unsigned int const indentation) { - registry myRegistry; - - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - - carriageParm_direct carriageParmDirect(&myRegistry); - clientXmlTransport_direct transportDirect; - client_xml clientDirect(&transportDirect); - paramList paramListSampleAdd; - paramListSampleAdd.add(value_int(5)); - paramListSampleAdd.add(value_int(7)); - paramList paramListEmpty; - { - /* Test a successful RPC */ - rpcPtr rpcSampleAddP("sample.add", paramListSampleAdd); - rpcSampleAddP->call(&clientDirect, &carriageParmDirect); - TEST(rpcSampleAddP->isFinished()); - TEST(rpcSampleAddP->isSuccessful()); - value_int const resultDirect(rpcSampleAddP->getResult()); - TEST(static_cast(resultDirect) == 12); - } - { - /* Test a failed RPC */ - rpcPtr const rpcSampleAddP("sample.add", paramListEmpty); - rpcSampleAddP->call(&clientDirect, &carriageParmDirect); - TEST(rpcSampleAddP->isFinished()); - TEST(!rpcSampleAddP->isSuccessful()); - fault const fault0(rpcSampleAddP->getFault()); - TEST(fault0.getCode() == fault::CODE_TYPE); - } - - { - /* Test with an auto object transport */ - client_xml clientDirect( - clientXmlTransportPtr(new clientXmlTransport_direct)); - rpcPtr rpcSampleAddP("sample.add", paramListSampleAdd); - rpcSampleAddP->call(&clientDirect, &carriageParmDirect); - TEST(rpcSampleAddP->isFinished()); - TEST(rpcSampleAddP->isSuccessful()); - EXPECT_ERROR(fault fault0(rpcSampleAddP->getFault());); - value_int const resultDirect(rpcSampleAddP->getResult()); - TEST(static_cast(resultDirect) == 12); - } - { - /* Test with implicit RPC -- success */ - rpcOutcome outcome; - clientDirect.call(&carriageParmDirect, "sample.add", - paramListSampleAdd, &outcome); - TEST(outcome.succeeded()); - value_int const result(outcome.getResult()); - TEST(static_cast(result) == 12); - } - { - /* Test with implicit RPC - failure */ - rpcOutcome outcome; - clientDirect.call(&carriageParmDirect, "nosuchmethod", - paramList(), &outcome); - TEST(!outcome.succeeded()); - TEST(outcome.getFault().getCode() == fault::CODE_NO_SUCH_METHOD); - TEST(outcome.getFault().getDescription().size() > 0); - } - - int interruptFlag(0); - EXPECT_ERROR(transportDirect.setInterrupt(&interruptFlag);); - // This transport class isn't interruptible - EXPECT_ERROR(clientDirect.setInterrupt(&interruptFlag);); - // Same as above - - clientDirectAsyncTestSuite().run(indentation+1); - - clientDerivedRpcTestSuite().run(indentation+1); - } -}; - - - -class curlTransportTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "curlTransportTestSuite"; - } - virtual void runtests(unsigned int const) { -#if MUST_BUILD_CURL_CLIENT - clientXmlTransport_curl transport0; - clientXmlTransport_curl transport1("eth0"); - clientXmlTransport_curl transport2("eth0", true); - clientXmlTransport_curl transport3("eth0", true, true); - clientXmlTransport_curl transport4( - clientXmlTransport_curl::constrOpt() - .network_interface("eth0") - .dont_advertise(true) - .user_agent("my user agent") - .referer("my referer") - .no_ssl_verifypeer(true) - .no_ssl_verifyhost(true) - .ssl_cert("/etc/sslcert") - .sslcerttype("PEM") - .sslcertpasswd("mypass") - .sslkey("/etc/sslkey") - .sslkeytype("DER") - .sslkeypasswd("mykeypass") - .sslengine("mysslengine") - .sslengine_default(true) - .sslversion(XMLRPC_SSLVERSION_SSLv2) - .cainfo("/etc/cainfo") - .capath("/etc/cadir") - .randomfile("/dev/random") - .egdsocket("/tmp/egdsocket") - .ssl_cipher_list("RC4-SHA:DEFAULT") - .proxy("example.com") - .proxy_port(8080) - .proxy_userpwd("password") - .proxy_type(XMLRPC_HTTPPROXY_SOCKS5) - .proxy_auth(XMLRPC_HTTPAUTH_BASIC) - .proxy_userpwd("mypassword") - .gssapi_delegation(true) - .timeout(0) - .connect_timeout(0) - ); - - clientXmlTransport_curl transport5( - clientXmlTransport_curl::constrOpt() - .no_ssl_verifypeer(false)); - - clientXmlTransport_curl transport6( - clientXmlTransport_curl::constrOpt()); - - clientXmlTransportPtr transport1P(new clientXmlTransport_curl); - clientXmlTransportPtr transport2P; - transport2P = transport1P; - - time_t nowtime = time(NULL); - transport2P->finishAsync(timeout()); - transport2P->finishAsync(timeout(2000)); - transport2P->finishAsync(2000); - TEST(time(NULL) <= nowtime + 1); - - int interruptFlag; - transport2P->setInterrupt(&interruptFlag); - interruptFlag = 0; - transport2P->finishAsync(2000); - transport2P->finishAsync(timeout()); -#else - EXPECT_ERROR(clientXmlTransport_curl transport0;); - EXPECT_ERROR(clientXmlTransport_curl transport1("eth0");); - EXPECT_ERROR(clientXmlTransport_curl transport0("eth0", true);); - EXPECT_ERROR(clientXmlTransport_curl transport0("eth0", true, true);); -#endif - } -}; - - - -class libwwwTransportTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "libwwwTransportTestSuite"; - } - virtual void runtests(unsigned int const) { -#if MUST_BUILD_LIBWWW_CLIENT - clientXmlTransport_libwww transport0; - clientXmlTransport_libwww transport1("getbent"); - clientXmlTransport_libwww transport2("getbent", "1.0"); - clientXmlTransportPtr transport1P(new clientXmlTransport_libwww); - clientXmlTransportPtr transport2P; - transport2P = transport1P; -#else - EXPECT_ERROR(clientXmlTransport_libwww transport0;); - EXPECT_ERROR(clientXmlTransport_libwww transport1("getbent");); - EXPECT_ERROR(clientXmlTransport_libwww transport2("getbent", "1.0");); -#endif - } -}; - - - -class wininetTransportTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "wininetTransportTestSuite"; - } - virtual void runtests(unsigned int const) { -#if MUST_BUILD_WININET_CLIENT - clientXmlTransport_wininet transport0; - clientXmlTransport_wininet transport1(true); - clientXmlTransportPtr transport1P(new clientXmlTransport_wininet); - clientXmlTransportPtr transport2P; - transport2P = transport1P; -#else - EXPECT_ERROR(clientXmlTransport_wininet transport0;); - EXPECT_ERROR(clientXmlTransport_wininet transport1(true);); -#endif - } -}; - - - -class ambivalentHttpTransportTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "ambivalentHttpTransportTestSuite"; - } - virtual void runtests(unsigned int const) { - vector const typeList( - clientXmlTransport_http::availableTypes()); - - TEST(typeList.size() > 0); - - clientXmlTransportPtr const transportP( - clientXmlTransport_http::create()); - carriageParm_http0 carriageParm0("http://whatsamatta.edux"); - client_xml client0(transportP); - - rpcOutcome outcome; - - // Fails because there's no such server - EXPECT_ERROR( - client0.call(&carriageParm0, "nosuchmethod", paramList(), - &outcome); - ); - } -}; - - - -class pstreamTransportTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "pstreamTransportTestSuite"; - } - virtual void runtests(unsigned int const) { - int const devNullFd(open("/dev/null", 0)); - - if (devNullFd < 0) - throw error("Failed to open /dev/null, needed for test."); - - EXPECT_ERROR(clientXmlTransport_pstream transport1( - clientXmlTransport_pstream::constrOpt() - .fd(37) - );); // ERROR: no such file descriptor - - carriageParm_pstream carriageParm0; - - { - clientXmlTransport_pstream transport2( - clientXmlTransport_pstream::constrOpt() - .fd(devNullFd) - ); - - string callXml("hello"); - string responseXml; - EXPECT_ERROR(transport2.call(NULL, callXml, &responseXml);); - // Error: carriage parm not of type carriageParm_pstream - EXPECT_ERROR(transport2.call(&carriageParm0, callXml, - &responseXml);); - // Error: no response - } - { - clientXmlTransport_pstream transport2( - clientXmlTransport_pstream::constrOpt() - .fd(devNullFd) - .useBrokenConnEx(true) - ); - } - clientXmlTransportPtr transport1P(new clientXmlTransport_pstream( - clientXmlTransport_pstream::constrOpt() - .fd(devNullFd) - )); - clientXmlTransportPtr transport2P; - transport2P = transport1P; - - close(devNullFd); - } -}; - - - -class clientXmlTransportTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "clientXmlTransportTestSuite"; - } - virtual void runtests(unsigned int const indentation) { - curlTransportTestSuite().run(indentation + 1); - libwwwTransportTestSuite().run(indentation + 1); - wininetTransportTestSuite().run(indentation + 1); - ambivalentHttpTransportTestSuite().run(indentation + 1); - pstreamTransportTestSuite().run(indentation + 1); - } -}; - - - -class clientSimpleTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "clientSimpleTestSuite"; - } - virtual void runtests(unsigned int const) { - - clientSimple clientS0; - paramList paramList0; - - value result0; - - // These will fail because there's no such server - EXPECT_ERROR(clientS0.call("http://mf.comm", "biteme", &result0);); - - EXPECT_ERROR( - clientS0.call("http://mf.comm", "biteme", "s", &result0, "hard"); - ); - - EXPECT_ERROR( - clientS0.call("http://mf.comm", "biteme", paramList0, &result0); - ); - } -}; - - - -class clientCurlIntTestSuite : public testSuite { -/*---------------------------------------------------------------------------- - The object of this class tests interruptibility functions of the - combination of a client with Curl transport. - - We don't have an HTTP server, so we test only superficially. ------------------------------------------------------------------------------*/ -public: - virtual string suiteName() { - return "clientCurlIntTestSuite"; - } - virtual void runtests(unsigned int) { -#if MUST_BUILD_CURL_CLIENT - clientXmlTransport_curl transportc0; - client_xml client0(&transportc0); - carriageParm_curl0 carriageParmCurl("http://nosuchserver8677.com"); - - paramList paramList0; - - rpcOutcome outcome0; - - int interruptFlag; - client0.setInterrupt(&interruptFlag); - - interruptFlag = 1; - // This fails because the call gets immediately interrupted - EXPECT_ERROR( - client0.call(&carriageParmCurl, "blowme", paramList0, &outcome0); - ); - interruptFlag = 0; - // This fails because server doesn't exist - EXPECT_ERROR( - client0.call(&carriageParmCurl, "blowme", paramList0, &outcome0); - ); -#endif - } -}; - - - -class clientCurlTestSuite : public testSuite { -/*---------------------------------------------------------------------------- - The object of this class tests the combination of a client with - Curl transport. We assume Curl transports themselves have already - been tested and clients with direct transports have already been tested. - - We don't have an HTTP server, so we test only superficially. - - In the future, we could either start a server or use some server that's - normally avaailble on the Internet. ------------------------------------------------------------------------------*/ -public: - virtual string suiteName() { - return "clientCurlTestSuite"; - } - virtual void runtests(unsigned int const indentation) { -#if MUST_BUILD_CURL_CLIENT - clientXmlTransport_curl transportc0; - client_xml client0(&transportc0); - carriageParm_http0 carriageParmHttp("http://nosuchserver8677.com"); - carriageParm_curl0 carriageParmCurl("http://nosuchserver8677.com"); - connection connection0(&client0, &carriageParmHttp); - - paramList paramList0; - - rpcOutcome outcome0; - - // This fails because server doesn't exist - EXPECT_ERROR( - client0.call(&carriageParmHttp, "blowme", paramList0, &outcome0); - ); - - // This fails because server doesn't exist - EXPECT_ERROR( - client0.call(&carriageParmCurl, "blowme", paramList0, &outcome0); - ); - - rpcPtr rpc0P("blowme", paramList0); - - // This fails because server doesn't exist - EXPECT_ERROR(rpc0P->call(&client0, &carriageParmCurl);); - - rpcPtr rpc1P("blowme", paramList0); - // This fails because server doesn't exist - EXPECT_ERROR(rpc1P->call(connection0);); - - rpcPtr rpc2P("blowme", paramList0); - - // This RPC fails to execute because the server doesn't exist, - // But libcurl "starts" it just fine. - rpc2P->start(&client0, &carriageParmCurl); - - transportc0.finishAsync(5000); - - TEST(rpc2P->isFinished()); - - TEST(!rpc2P->isSuccessful()); - - // Because the RPC did not return an XML-RPC failure (because the - // server doesn't exist), this throws: - EXPECT_ERROR(rpc2P->getFault();); - - rpcPtr rpc3P("blowme", paramList0); - // This RPC fails to execute because the server doesn't exist - rpc3P->start(connection0); - - transportc0.finishAsync(5000); - TEST(rpc2P->isFinished()); - TEST(!rpc2P->isSuccessful()); - - clientCurlIntTestSuite().run(indentation+1); -#else - // This fails because there is no Curl transport in the library. - EXPECT_ERROR(clientXmlTransport_curl transportc0;); -#endif - } -}; - - - -class carriageParmTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "carriageParmTestSuite"; - } - virtual void runtests(unsigned int) { - carriageParm_http0 carriageParm1("http://suckthis.com"); - carriageParm_curl0 carriageParm2("http://suckthis.com"); - carriageParm_libwww0 carriageParm3("http://suckthis.com"); - carriageParm_wininet0 carriageParm4("http://suckthis.com"); - - carriageParm_http0Ptr carriageParm_http1P( - new carriageParm_http0("http://suckthis.com")); - - carriageParm_http1P->setBasicAuth("bryanh", "12345"); - - carriageParm_curl0Ptr carriageParm_curl1P( - new carriageParm_curl0("http://suckthis.com")); - - carriageParm_curl1P->setBasicAuth("bryanh", "12345"); - - carriageParm_curl1P->setUser("bryanh", "12345"); - carriageParm_curl1P->allowAuthBasic(); - carriageParm_curl1P->disallowAuthBasic(); - carriageParm_curl1P->allowAuthDigest(); - carriageParm_curl1P->disallowAuthDigest(); - carriageParm_curl1P->allowAuthNegotiate(); - carriageParm_curl1P->disallowAuthNegotiate(); - carriageParm_curl1P->allowAuthNtlm(); - carriageParm_curl1P->disallowAuthNtlm(); - - carriageParm_libwww0Ptr carriageParm_libwww1P( - new carriageParm_libwww0("http://suckthis.com")); - - carriageParm_libwww1P->setUser("bryanh", "12345"); - carriageParm_libwww1P->allowAuthBasic(); - - carriageParm_wininet0Ptr carriageParm_wininet1P( - new carriageParm_wininet0("http://suckthis.com")); - - carriageParm_wininet1P->setUser("bryanh", "12345"); - carriageParm_wininet1P->allowAuthBasic(); - } -}; - - - -class clientRpcTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "clientRpcTestSuite"; - } - virtual void runtests(unsigned int) { - - registry myRegistry; - - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - - carriageParm_direct carriageParm0(&myRegistry); - clientXmlTransport_direct transportDirect; - client_xml client0(&transportDirect); - paramList paramListSampleAdd; - paramListSampleAdd.add(value_int(5)); - paramListSampleAdd.add(value_int(7)); - paramList paramListEmpty; - - { - /* Test a successful RPC */ - rpcPtr rpcSampleAddP("sample.add", paramListSampleAdd); - TEST(!rpcSampleAddP->isFinished()); - // This fails because RPC has not been executed - EXPECT_ERROR(value result(rpcSampleAddP->getResult());); - - rpcSampleAddP->call(&client0, &carriageParm0); - - TEST(rpcSampleAddP->isFinished()); - TEST(rpcSampleAddP->isSuccessful()); - value_int const resultDirect(rpcSampleAddP->getResult()); - TEST(static_cast(resultDirect) == 12); - // This fails because the RPC succeeded - EXPECT_ERROR(fault fault0(rpcSampleAddP->getFault());); - // This fails because the RPC has already been executed - EXPECT_ERROR( - rpcSampleAddP->call(&client0, &carriageParm0);); - // This fails because the RPC has already been executed - EXPECT_ERROR( - rpcSampleAddP->start(&client0, &carriageParm0);); - } - { - /* Test a failed RPC */ - rpcPtr const rpcSampleAddP("sample.add", paramListEmpty); - rpcSampleAddP->call(&client0, &carriageParm0); - TEST(rpcSampleAddP->isFinished()); - TEST(!rpcSampleAddP->isSuccessful()); - fault const fault0(rpcSampleAddP->getFault()); - TEST(fault0.getCode() == fault::CODE_TYPE); - // This fails because the RPC failed - EXPECT_ERROR(value result(rpcSampleAddP->getResult());); - // This fails because the RPC has already been executed - EXPECT_ERROR( - rpcSampleAddP->call(&client0, &carriageParm0);); - // This fails because the RPC has already been executed - EXPECT_ERROR( - rpcSampleAddP->start(&client0, &carriageParm0);); - } - { - /* Test with a connection */ - - connection connection0(&client0, &carriageParm0); - - rpcPtr const rpcSampleAddP("sample.add", paramListSampleAdd); - - rpcSampleAddP->call(connection0); - - TEST(rpcSampleAddP->isFinished()); - value_int const resultDirect(rpcSampleAddP->getResult()); - TEST(static_cast(resultDirect) == 12); - } - } -}; - - - -class clientPtrTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "clientPtrTestSuite"; - } - virtual void runtests(unsigned int) { - registry myRegistry; - - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - carriageParm_direct carriageParmDirect(&myRegistry); - clientXmlTransport_direct transportDirect; - - clientPtr clientP(new client_xml(&transportDirect)); - - clientPtr client2P(clientP); - - { - clientPtr client3P; - client3P = client2P; - } - rpcOutcome outcome; - - clientP->call(&carriageParmDirect, "nosuchmethod", - paramList(), &outcome); - TEST(!outcome.succeeded()); - TEST(outcome.getFault().getCode() == fault::CODE_NO_SUCH_METHOD); - } -}; - - - -class serverAccessorTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "serverAccessorTestSuite"; - } - virtual void runtests(unsigned int) { - clientXmlTransportPtr const transportP(new clientXmlTransport_direct); - clientPtr const clientP(new client_xml(transportP)); - registry myRegistry; - carriageParmPtr const carriageParmP( - new carriageParm_direct(&myRegistry)); - - serverAccessor server1(clientP, carriageParmP); - - rpcOutcome outcome; - server1.call("nosuchmethod", paramList(), &outcome); - TEST(!outcome.succeeded()); - TEST(outcome.getFault().getCode() == fault::CODE_NO_SUCH_METHOD); - TEST(outcome.getFault().getDescription().size() > 0); - } -}; - - - -class xmlTestSuite : public testSuite { -/*---------------------------------------------------------------------------- - This test suite tests the generation an interpretation of XML-RPC - XML, by doing RPCs via an XML client and server. Each complete RPC - involves generating XML and interpreting it, so this is a handy way - to test. - - A stronger test would be to make an XML transport that actually verifies - the XML. We're too lazy for that. ------------------------------------------------------------------------------*/ -public: - virtual string suiteName() { - return "xmlTestSuite"; - } - virtual void runtests(unsigned int) { - registry myRegistry; - myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); - myRegistry.addMethod("apache", methodPtr(new testApacheDialectMethod)); - carriageParm_direct carriageParmDirect(&myRegistry); - clientXmlTransport_direct transportDirect; - client_xml clientDirect(&transportDirect, xmlrpc_dialect_apache); - - paramList paramListSampleAdd; - paramListSampleAdd.add(value_int(5)); - paramListSampleAdd.add(value_int(7)); - - { - rpcPtr rpcSampleAddP("sample.add", paramListSampleAdd); - rpcSampleAddP->call(&clientDirect, &carriageParmDirect); - TEST(rpcSampleAddP->isFinished()); - TEST(rpcSampleAddP->isSuccessful()); - value_int const result(rpcSampleAddP->getResult()); - TEST(static_cast(result) == 12); - } - paramList paramListApache; - paramListApache.add(value_nil()); - - { - rpcPtr rpcApacheP("apache", paramListApache); - rpcApacheP->call(&clientDirect, &carriageParmDirect); - TEST(rpcApacheP->isFinished()); - TEST(rpcApacheP->isSuccessful()); - value_i8 const result(rpcApacheP->getResult()); - TEST(static_cast(result) == 7ll); - } - } -}; - - - -} // unnamed namespace - - - -string -clientTestSuite::suiteName() { - return "clientTestSuite"; -} - - - -void -clientTestSuite::runtests(unsigned int const indentation) { - - clientDirectTestSuite().run(indentation+1); - - clientXmlTransportTestSuite().run(indentation+1); - - carriageParmTestSuite().run(indentation+1); - - clientCurlTestSuite().run(indentation+1); - - clientRpcTestSuite().run(indentation+1); - - clientPtrTestSuite().run(indentation+1); - - clientSimpleTestSuite().run(indentation+1); - - serverAccessorTestSuite().run(indentation+1); - - xmlTestSuite().run(indentation+1); -} diff --git a/trunk/test/cpp/testclient.hpp b/trunk/test/cpp/testclient.hpp deleted file mode 100644 index 20c1b9f39..000000000 --- a/trunk/test/cpp/testclient.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "tools.hpp" - -class clientTestSuite : public testSuite { - -public: - virtual std::string suiteName(); - virtual void runtests(unsigned int const indentation); -}; - diff --git a/trunk/test/cpp/testclient_dummy.cpp b/trunk/test/cpp/testclient_dummy.cpp deleted file mode 100644 index 5bf3018df..000000000 --- a/trunk/test/cpp/testclient_dummy.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/*============================================================================= - testclient_dummy -=============================================================================== - This is a substitute for testclient.cpp, for use in a test program that is - not linked with the client libraries. - - It simply passes the test. -=============================================================================*/ - -#include -#include - -#include "tools.hpp" -#include "testclient.hpp" - -using namespace std; - -string -clientTestSuite::suiteName() { - return "clientTestSuite"; -} - - -void -clientTestSuite::runtests(unsigned int const indentation) { - - cout << string((indentation+1)*2, ' ') - << "Running dummy test." << endl; -} diff --git a/trunk/test/cpp/tools.cpp b/trunk/test/cpp/tools.cpp deleted file mode 100644 index 5709eff0c..000000000 --- a/trunk/test/cpp/tools.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include -#ifdef _WIN32 -# include -# include -#else -# include -#endif - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; - -#include "tools.hpp" - -using namespace std; - -testSuite::~testSuite() { -} - - - -void -testSuite::run(unsigned int const indentation) { - try { - cout << string(indentation*2, ' ') - << "Running " << suiteName() << endl; - this->runtests(indentation); - } catch (error const& error) { - throwf("%s failed. %s", suiteName().c_str(), error.what()); - } catch (...) { - throw(error(suiteName() + string(" failed. ") + - string("It threw an unexpected type of object"))); - } - cout << string(indentation*2, ' ') - << suiteName() << " tests passed." << endl; -} - - - -// This is a good place to set a breakpoint. -void -logFailedTest(const char * const fileName, - unsigned int const lineNum, - const char * const statement) { - - ostringstream msg; - - msg << endl - << fileName << ":" << lineNum - << ": expected (" << statement << ")" << endl; - - throw(error(msg.str())); -} - - -error -fileLineError(string const filename, - unsigned int const lineNumber, - string const description) { - - ostringstream combined; - - combined << filename << ":" << lineNumber << " " << description; - - return error(combined.str()); -} - - - -struct in_addr -test_ipAddrFromDecimal(unsigned int const byte0, - unsigned int const byte1, - unsigned int const byte2, - unsigned int const byte3) { - - struct in_addr retval; - - retval.s_addr = - htonl((byte0 << 24) + (byte1 << 16) + (byte2 << 8) + (byte3 << 0)); - - return retval; -} - - - diff --git a/trunk/test/cpp/tools.hpp b/trunk/test/cpp/tools.hpp deleted file mode 100644 index fc8c2da7a..000000000 --- a/trunk/test/cpp/tools.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef TEST_HPP_INCLUDED -#define TEST_HPP_INCLUDED - -#ifdef _WIN32 -# include /* For XMLRPC_SOCKET (= SOCKET) */ -# include -#else -#include -#endif - -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; - -class testSuite { -/*---------------------------------------------------------------------------- - This is a base class for a test suite. Give the suite a name - (to be used in messages about it) and some test code via - virtual methods suiteName() and runtests(), respectively. - - runtests() should throw either an 'error' object or an 'XmlRpcFault' - object if the test fails. It should throw something else if the - test can't run. It should throw nothing if the tests pass. - - You don't normally keep an object of this class around. You don't - even give it a name. You simply refer to a literal object, like so: - - myTestSuite().run(0) ------------------------------------------------------------------------------*/ -public: - virtual ~testSuite(); - - void run(unsigned int const indentation); - - virtual void runtests(unsigned int const) { - throw(error("test suite does not have a runtests() method")); - }; - virtual std::string suiteName() { - return "unnamed test suite"; - } -}; - - - -void -logFailedTest(const char * const fileName, - unsigned int const lineNum, - const char * const statement); - -error -fileLineError(std::string const filename, - unsigned int const lineNumber, - std::string const description); - -struct in_addr -test_ipAddrFromDecimal(unsigned int const byte0, - unsigned int const byte1, - unsigned int const byte2, - unsigned int const byte3); - -#define TEST(statement) \ - do { \ - if (!(statement)) \ - logFailedTest(__FILE__, __LINE__, #statement); \ - } while (0) - - -#define TEST_PASSED() \ - do { } while (0) - -#define TEST_FAILED(reason) \ - do { \ - logFailedTest(__FILE__, __LINE__, (reason)); \ - } while (0) - -#define EXPECT_ERROR(statement) \ - do { try { statement } catch (error const&) {break;} \ - throw(fileLineError(__FILE__, __LINE__, "Expected error; didn't get one")); \ - } while (0) - -#define trickToStraightenOutEmacsIndentation \ -; - -#endif diff --git a/trunk/test/cpp/value.cpp b/trunk/test/cpp/value.cpp deleted file mode 100644 index 3e403c9c1..000000000 --- a/trunk/test/cpp/value.cpp +++ /dev/null @@ -1,544 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/oldcppwrapper.hpp" -#include "xmlrpc-c/registry.hpp" -#include "c_util.h" - -#include "tools.hpp" - -#include "value.hpp" - -using namespace xmlrpc_c; -using namespace std; - - - -namespace { - -class intTestSuite : public testSuite { -public: - virtual string suiteName() { - return "intTestSuite"; - } - virtual void runtests(unsigned int const) { - value_int int1(7); - TEST(static_cast(int1) == 7); - value_int int2(-7); - TEST(static_cast(int2) == -7); - value val1(int1); - TEST(val1.type() == value::TYPE_INT); - value_int int3(val1); - TEST(static_cast(int3) == 7); - try { - value_int int4(value_double(3.7)); - TEST_FAILED("invalid cast double-int suceeded"); - } catch (error const&) {} - - value const int1x(toValue(7)); - TEST(int1x.type() == value::TYPE_INT); - TEST(static_cast(value_int(int1x)) == 7); - - int test1x; - fromValue(test1x, int1x); - TEST(test1x == 7); - } -}; - - - -class doubleTestSuite : public testSuite { -public: - virtual string suiteName() { - return "doubleTestSuite"; - } - virtual void runtests(unsigned int const) { - value_double double1(3.14); - TEST(static_cast(double1) == 3.14); - value val1(double1); - TEST(val1.type() == value::TYPE_DOUBLE); - value_double double2(val1); - TEST(static_cast(double2) == 3.14); - try { - value_double double4(value_int(4)); - TEST_FAILED("invalid cast int-double suceeded"); - } catch (error const&) {} - - value const double1x(toValue(3.14)); - TEST(double1x.type() == value::TYPE_DOUBLE); - TEST(static_cast(value_double(double1x)) == 3.14); - - double test1x; - fromValue(test1x, double1x); - TEST(test1x == 3.14); - } -}; - - - -class booleanTestSuite : public testSuite { -public: - virtual string suiteName() { - return "booleanTestSuite"; - } - virtual void runtests(unsigned int const) { - value_boolean boolean1(true); - TEST(static_cast(boolean1) == true); - value_boolean boolean2(false); - TEST(static_cast(boolean2) == false); - value val1(boolean1); - TEST(val1.type() == value::TYPE_BOOLEAN); - value_boolean boolean3(val1); - TEST(static_cast(boolean3) == true); - try { - value_boolean boolean4(value_int(4)); - TEST_FAILED("invalid cast int-boolean suceeded"); - } catch (error const&) {} - - value const boolean1x(toValue(true)); - TEST(boolean1x.type() == value::TYPE_BOOLEAN); - TEST(static_cast(value_boolean(boolean1x)) == true); - - bool test1x; - fromValue(test1x, boolean1x); - TEST(test1x == true); - } -}; - - - -#if XMLRPC_HAVE_TIMEVAL - -static struct timeval -makeTv(time_t const secs, - unsigned int const usecs) { - - struct timeval retval; - - retval.tv_sec = secs; - retval.tv_usec = usecs; - - return retval; -} - -static bool -tvIsEqual(struct timeval const comparand, - struct timeval const comparator) { - return - comparand.tv_sec == comparator.tv_sec && - comparand.tv_usec == comparator.tv_usec; -} -#endif - - - -#if XMLRPC_HAVE_TIMESPEC - -static struct timespec -makeTs(time_t const secs, - unsigned int const usecs) { - - struct timespec retval; - - retval.tv_sec = secs; - retval.tv_nsec = usecs * 1000; - - return retval; -} - -static bool -tsIsEqual(struct timespec const comparand, - struct timespec const comparator) { - return - comparand.tv_sec == comparator.tv_sec && - comparand.tv_nsec == comparator.tv_nsec; -} -#endif - -static xmlrpc_datetime const -makeXd(time_t const secs, - unsigned int const usecs) { - - struct tm const tm = *gmtime(&secs); - - xmlrpc_datetime retval; - - retval.Y = 1900 + tm.tm_year; - retval.M = 1 + tm.tm_mon; - retval.D = tm.tm_mday; - retval.h = tm.tm_hour; - retval.m = tm.tm_min; - retval.s = tm.tm_sec; - retval.u = usecs; - - return retval; -} - -static bool -xdIsEqual(xmlrpc_datetime const comparand, - xmlrpc_datetime const comparator) { - return - comparand.Y == comparator.Y && - comparand.M == comparator.M && - comparand.D == comparator.D && - comparand.h == comparator.h && - comparand.m == comparator.m && - comparand.s == comparator.s && - comparand.u == comparator.u; -} - - - -class datetimeTestSuite : public testSuite { -public: - virtual string suiteName() { - return "datetimeTestSuite"; - } - virtual void runtests(unsigned int const) { - time_t const testTime(900684535); - string const testTime8601("19980717T140855,000000Z"); - value_datetime datetime1("19980717T14:08:55"); - TEST(static_cast(datetime1) == testTime); - value_datetime datetime2(testTime); - TEST(static_cast(datetime2) == testTime); - value val1(datetime1); - TEST(val1.type() == value::TYPE_DATETIME); - value_datetime datetime3(val1); - TEST(static_cast(datetime3) == testTime); -#if XMLRPC_HAVE_TIMEVAL - struct timeval const testTimeTv(makeTv(testTime, 0)); - value_datetime datetime4(testTimeTv); - TEST(static_cast(datetime4) == testTime); - TEST(tvIsEqual(static_cast(datetime4), testTimeTv)); -#endif -#if XMLRPC_HAVE_TIMESPEC - struct timespec const testTimeTs(makeTs(testTime, 0)); - value_datetime datetime5(testTimeTs); - TEST(static_cast(datetime5) == testTime); - TEST(tsIsEqual(static_cast(datetime5), testTimeTs)); -#endif - xmlrpc_datetime const testTimeXd(makeXd(testTime, 5)); - value_datetime datetime6(testTimeXd); - TEST(static_cast(datetime6) == testTime); - TEST(xdIsEqual(static_cast(datetime6), testTimeXd)); - - string const iso8601Value(datetime1.iso8601Value()); - TEST(iso8601Value == testTime8601); - - try { - value_datetime datetime4(value_int(4)); - TEST_FAILED("invalid cast int-datetime suceeded"); - } catch (error const&) {} - } -}; - - - -class stringTestSuite : public testSuite { -public: - virtual string suiteName() { - return "stringTestSuite"; - } - virtual void runtests(unsigned int const) { - value_string string1("hello world"); - TEST(static_cast(string1) == "hello world"); - value_string string2("embedded\0null"); - TEST(static_cast(string2) == "embedded\0null"); - value val1(string1); - TEST(val1.type() == value::TYPE_STRING); - value_string string3(val1); - TEST(static_cast(string3) == "hello world"); - try { - value_string string4(value_int(4)); - TEST_FAILED("invalid cast int-string succeeded"); - } catch (error const&) {} - value_string string5("hello world", value_string::nlCode_all); - TEST(static_cast(string5) == "hello world"); - value_string string6("hello\nthere\rworld\r\n\n", - value_string::nlCode_all); - TEST(static_cast(string6) == "hello\nthere\nworld\n\n"); - TEST(string6.crlfValue() == "hello\r\nthere\r\nworld\r\n\r\n"); - value_string string7("hello\nthere\rworld\r\n\n", - value_string::nlCode_lf); - TEST(static_cast(string7) == "hello\nthere\rworld\r\n\n"); - - value const string1x(toValue("hello world")); - TEST(string1x.type() == value::TYPE_STRING); - TEST(static_cast(value_string(string1x)) == "hello world"); - - string test1x; - fromValue(test1x, string1x); - TEST(test1x == "hello world"); - - value const string2x(toValue(string("hello world"))); - TEST(string2x.type() == value::TYPE_STRING); - TEST(static_cast(value_string(string2x)) == "hello world"); - - string1.validate(); - - value_string badString("hello \x18 there"); - - try { - badString.validate(); - TEST_FAILED("'validate' of string containging a control " - "character succeeded"); - } catch (error const&) {} - } -}; - - - -class bytestringTestSuite : public testSuite { -public: - virtual string suiteName() { - return "bytestringTestSuite"; - } - virtual void runtests(unsigned int const) { - unsigned char bytestringArray[] = {0x10, 0x11, 0x12, 0x13, 0x14}; - cbytestring - bytestringData(&bytestringArray[0], &bytestringArray[4]); - value_bytestring bytestring1(bytestringData); - - cbytestring const dataReadBack1(bytestring1.vectorUcharValue()); - TEST(dataReadBack1 == bytestringData); - value val1(bytestring1); - TEST(val1.type() == value::TYPE_BYTESTRING); - value_bytestring bytestring2(val1); - vector const dataReadBack2( - bytestring2.vectorUcharValue()); - TEST(dataReadBack2 == bytestringData); - try { - value_bytestring bytestring4(value_int(4)); - TEST_FAILED("invalid cast int-bytestring suceeded"); - } catch (error const&) {} - - value const bytestring1x(toValue(bytestringData)); - TEST(bytestring1x.type() == value::TYPE_BYTESTRING); - vector const dataReadBack1x( - value_bytestring(bytestring1x).vectorUcharValue()); - TEST(dataReadBack1x == bytestringData); - - vector test1x; - fromValue(test1x, bytestring1x); - TEST(test1x == bytestringData); - - } -}; - - - -class nilTestSuite : public testSuite { -public: - virtual string suiteName() { - return "nilTestSuite"; - } - virtual void runtests(unsigned int const) { - value_nil nil1; - value val1(nil1); - TEST(val1.type() == value::TYPE_NIL); - value_nil nil2(val1); - try { - value_nil nil4(value_int(4)); - TEST_FAILED("invalid cast int-nil suceeded"); - } catch (error const&) {} - } -}; - - - -class i8TestSuite : public testSuite { -public: - virtual string suiteName() { - return "i8TestSuite"; - } - virtual void runtests(unsigned int const) { - value_i8 int1(7); - TEST(static_cast(int1) == 7); - value_i8 int2(-7); - TEST(static_cast(int2) == -7); - value_i8 int5(1ull << 40); - TEST(static_cast(int5) == (1ull << 40)); - value val1(int1); - TEST(val1.type() == value::TYPE_I8); - value_i8 int3(val1); - TEST(static_cast(int3) == 7); - try { - value_i8 int4(value_double(3.7)); - TEST_FAILED("invalid cast double-i8 suceeded"); - } catch (error const&) {} - - value const int1x(toValue((xmlrpc_int64)7)); - TEST(int1x.type() == value::TYPE_I8); - TEST(static_cast(value_i8(int1x)) == 7); - - xmlrpc_int64 test1x; - fromValue(test1x, int1x); - TEST(test1x == 7); - } -}; - - - -class structTestSuite : public testSuite { -public: - virtual string suiteName() { - return "structTestSuite"; - } - virtual void runtests(unsigned int const) { - cstruct structData; - pair member("the_integer", value_int(9)); - structData.insert(member); - - value_struct struct1(structData); - - map dataReadBack(struct1); - - TEST(static_cast(value_int(dataReadBack["the_integer"])) == 9); - - value val1(struct1); - TEST(val1.type() == value::TYPE_STRUCT); - value_struct struct2(val1); - try { - value_struct struct4(value_int(4)); - TEST_FAILED("invalid cast int-struct suceeded"); - } catch (error const&) {} - - map structDatax; - structDatax["one"] = 1; - structDatax["two"] = 2; - - value const struct5(toValue(structDatax)); - TEST(struct5.type() == value::TYPE_STRUCT); - map dataReadBackx; - dataReadBackx = value_struct(struct5); - - TEST(static_cast(value_int(dataReadBackx["two"])) == 2); - - map test5x; - fromValue(test5x, struct5); - TEST(test5x["two"] == 2); - } -}; - - - -class arrayTestSuite : public testSuite { -public: - virtual string suiteName() { - return "arrayTestSuite"; - } - virtual void runtests(unsigned int const) { - carray arrayData; - arrayData.push_back(value_int(7)); - arrayData.push_back(value_double(2.78)); - arrayData.push_back(value_string("hello world")); - value_array array1(arrayData); - - TEST(array1.size() == 3); - vector dataReadBack1(array1.vectorValueValue()); - TEST(dataReadBack1[0].type() == value::TYPE_INT); - TEST(static_cast(value_int(dataReadBack1[0])) == 7); - TEST(dataReadBack1[1].type() == value::TYPE_DOUBLE); - TEST(static_cast(value_double(dataReadBack1[1])) == 2.78); - TEST(dataReadBack1[2].type() == value::TYPE_STRING); - TEST(static_cast(value_string(dataReadBack1[2])) == - "hello world"); - - value val1(array1); - TEST(val1.type() == value::TYPE_ARRAY); - value_array array2(val1); - TEST(array2.size() == 3); - try { - value_array array4(value_int(4)); - TEST_FAILED("invalid cast int-array suceeded"); - } catch (error const&) {} - - int const arrayDatax[] = {7, 4}; - - value const array5( - arrayValueArray(arrayDatax, ARRAY_SIZE(arrayDatax))); - TEST(array5.type() == value::TYPE_ARRAY); - TEST(value_array(array5).size() == 2); - vector dataReadBackx(value_array(array5).vectorValueValue()); - - TEST(dataReadBackx.size() == 2); - TEST(static_cast(value_int(dataReadBackx[0])) == 7); - vector test5x; - fromValue(test5x, array5); - TEST(test5x[1] == 4); - - vector arrayDataVec; - arrayDataVec.push_back("hello world"); - value const array6(toValue(arrayDataVec)); - TEST(array6.type() == value::TYPE_ARRAY); - TEST(value_array(array6).size() == 1); - } -}; - - -class arrayArrayTestSuite : public testSuite { -public: - virtual string suiteName() { - return "arrayArrayTestSuite"; - } - virtual void runtests(unsigned int const) { - - /* Empty array of arrays */ - vector > arrayArrayDataVec; - - value const arrayArray1(toValue(arrayArrayDataVec)); - TEST(arrayArray1.type() == value::TYPE_ARRAY); - TEST(value_array(arrayArray1).size() == 0); - - /* Array of 1 empty array */ - vector innerArray; - arrayArrayDataVec.push_back(innerArray); - value const arrayArray2(toValue(arrayArrayDataVec)); - - TEST(arrayArray2.type() == value::TYPE_ARRAY); - TEST(value_array(arrayArray2).size() == 1); - vector dataReadBackx( - value_array(arrayArray2).vectorValueValue()); - TEST(dataReadBackx.size() == 1); - TEST(dataReadBackx[0].type() == value::TYPE_ARRAY); - vector dataReadBackx2( - value_array(dataReadBackx[0]).vectorValueValue()); - TEST(dataReadBackx2.size() == 0); - } -}; - - -} // unnamed namespace - - -string -valueTestSuite::suiteName() { - return "valueTestSuite"; -} - - - -void -valueTestSuite::runtests(unsigned int const indentation) { - - intTestSuite().run(indentation+1); - doubleTestSuite().run(indentation+1); - booleanTestSuite().run(indentation+1); - datetimeTestSuite().run(indentation+1); - stringTestSuite().run(indentation+1); - bytestringTestSuite().run(indentation+1); - nilTestSuite().run(indentation+1); - i8TestSuite().run(indentation+1); - structTestSuite().run(indentation+1); - arrayTestSuite().run(indentation+1); - arrayArrayTestSuite().run(indentation+1); -} diff --git a/trunk/test/cpp/value.hpp b/trunk/test/cpp/value.hpp deleted file mode 100644 index 65d0d9088..000000000 --- a/trunk/test/cpp/value.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "tools.hpp" - -class valueTestSuite : public testSuite { - -public: - virtual std::string suiteName(); - virtual void runtests(unsigned int const indentation); -}; - diff --git a/trunk/test/cpp/xml.cpp b/trunk/test/cpp/xml.cpp deleted file mode 100644 index 0a73e24ee..000000000 --- a/trunk/test/cpp/xml.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/*============================================================================= - xml -=============================================================================== - Test the XML generator and parser C++ facilities of XML-RPC for C/C++. - -=============================================================================*/ - -#include - -#include "xmlrpc-c/girerr.hpp" -using girerr::error; -using girerr::throwf; -#include "xmlrpc-c/base.hpp" -#include "xmlrpc-c/xml.hpp" - -#include "tools.hpp" -#include "xml.hpp" - -using namespace xmlrpc_c; -using namespace std; - - -namespace { - -class callTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "callTestSuite"; - } - virtual void runtests(unsigned int const) { - - string callXml; - - string const methodName0("myMethod"); - paramList const paramList0; - - xml::generateCall(methodName0, paramList(), &callXml); - - string methodName; - paramList paramList; - - xml::parseCall(callXml, &methodName, ¶mList); - - TEST(methodName == methodName0); - TEST(paramList.size() == paramList0.size()); - } -}; - - - -class responseTestSuite : public testSuite { - -public: - virtual string suiteName() { - return "responseTestSuite"; - } - virtual void runtests(unsigned int const) { - - string respXml; - - rpcOutcome outcome0(value_int(7)); - - xml::generateResponse(outcome0, &respXml); - - rpcOutcome outcome; - - xml::parseResponse(respXml, &outcome); - - TEST((int)value_int(outcome.getResult()) == - (int)value_int(outcome0.getResult())); - - value result; - - xml::parseSuccessfulResponse(respXml, &result); - - TEST((int)value_int(result) == (int)value_int(outcome0.getResult())); - } -}; - - - -} // unnamed namespace - - - -string -xmlTestSuite::suiteName() { - return "XMLTestSuite"; -} - - - -void -xmlTestSuite::runtests(unsigned int const indentation) { - - callTestSuite().run(indentation+1); - - responseTestSuite().run(indentation+1); -} diff --git a/trunk/test/cpp/xml.hpp b/trunk/test/cpp/xml.hpp deleted file mode 100644 index 3946f46a3..000000000 --- a/trunk/test/cpp/xml.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "tools.hpp" - -class xmlTestSuite : public testSuite { - -public: - virtual std::string suiteName(); - virtual void runtests(unsigned int const indentation); -}; - diff --git a/trunk/test/data/req_no_params.xml b/trunk/test/data/req_no_params.xml deleted file mode 100644 index 6ed51a4fa..000000000 --- a/trunk/test/data/req_no_params.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - foo - diff --git a/trunk/test/data/req_out_of_order.xml b/trunk/test/data/req_out_of_order.xml deleted file mode 100644 index 8b078a4bb..000000000 --- a/trunk/test/data/req_out_of_order.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - 2 - - - 2 - - - add - diff --git a/trunk/test/data/req_value_name.xml b/trunk/test/data/req_value_name.xml deleted file mode 100644 index b55d4f0e1..000000000 --- a/trunk/test/data/req_value_name.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - foo - - - - - 0 - child elements reversed! - - - - - diff --git a/trunk/test/data/sample_add_call.xml b/trunk/test/data/sample_add_call.xml deleted file mode 100644 index b11336a70..000000000 --- a/trunk/test/data/sample_add_call.xml +++ /dev/null @@ -1,8 +0,0 @@ - - -sample.add - -5 -7 - - diff --git a/trunk/test/eftest_wrapper.sh b/trunk/test/eftest_wrapper.sh deleted file mode 100644 index 31606b74c..000000000 --- a/trunk/test/eftest_wrapper.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -echo "*** Testing for heap block overruns..." -efrpctest -if ! test $?; then exit 1; fi - -echo "*** Testing for heap block underruns..." -EF_PROTECT_BELOW=1 efrpctest -if ! test $?; then exit 1; fi - -echo "*** Testing for access to freed heap blocks..." -EF_PROTECT_FREE=1 efrpctest -if ! test $?; then exit 1; fi - -echo "*** Testing for single-byte overruns..." -EF_ALIGNMENT=0 efrpctest -if ! test $?; then exit 1; fi diff --git a/trunk/test/http-req-simple.txt b/trunk/test/http-req-simple.txt deleted file mode 100644 index 00db6a0a0..000000000 --- a/trunk/test/http-req-simple.txt +++ /dev/null @@ -1,11 +0,0 @@ -POST /cgi-bin/sample-cgi.cgi 1.0 -Host: localhost -Content-Type: text/xml -Content-Length: 141 - - - - system.listMethods - - - diff --git a/trunk/test/memblock.c b/trunk/test/memblock.c deleted file mode 100644 index 781afb4f6..000000000 --- a/trunk/test/memblock.c +++ /dev/null @@ -1,237 +0,0 @@ -#include - -#include "xmlrpc_config.h" -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/string_int.h" - -#include "testtool.h" - - -#include "memblock.h" - - - -static char* test_string_1 = "foo"; -static int test_int_array_1[5] = {1, 2, 3, 4, 5}; -static int test_int_array_2[3] = {6, 7, 8}; -static int test_int_array_3[8] = {1, 2, 3, 4, 5, 6, 7, 8}; - - - -static void -testMemBlock(void) { - - xmlrpc_env env; - xmlrpc_mem_block * blockP; - - xmlrpc_mem_block * typedHeapBlockP; - void ** typedContents; - - xmlrpc_env_init(&env); - - /* Allocate a zero-size block. */ - blockP = xmlrpc_mem_block_new(&env, 0); - TEST_NO_FAULT(&env); - TEST(blockP != NULL); - TEST(xmlrpc_mem_block_size(blockP) == 0); - - /* Grow the block a little bit. */ - xmlrpc_mem_block_resize(&env, blockP, strlen(test_string_1) + 1); - TEST_NO_FAULT(&env); - TEST(xmlrpc_mem_block_size(blockP) == strlen(test_string_1) + 1); - - /* Insert a string into the block, and resize it by large amount. - ** We want to cause a reallocation and copy of the block contents. */ - strcpy(xmlrpc_mem_block_contents(blockP), test_string_1); - xmlrpc_mem_block_resize(&env, blockP, 10000); - TEST_NO_FAULT(&env); - TEST(xmlrpc_mem_block_size(blockP) == 10000); - TEST(xmlrpc_streq(xmlrpc_mem_block_contents(blockP), test_string_1)); - - /* Test growing beyond a megabyte */ - xmlrpc_mem_block_resize(&env, blockP, 1024*1024+1); - TEST_NO_FAULT(&env); - TEST(xmlrpc_mem_block_size(blockP) == 1024*1024+1); - TEST(xmlrpc_streq(xmlrpc_mem_block_contents(blockP), test_string_1)); - - /* Test shrinking */ - xmlrpc_mem_block_resize(&env, blockP, 2); - TEST_NO_FAULT(&env); - TEST(xmlrpc_mem_block_size(blockP) == 2); - TEST(xmlrpc_memeq(xmlrpc_mem_block_contents(blockP), test_string_1, 2)); - - /* Test cleanup code (with help from memprof). */ - xmlrpc_mem_block_free(blockP); - - /* Allocate a bigger block. */ - blockP = xmlrpc_mem_block_new(&env, 128); - TEST_NO_FAULT(&env); - TEST(blockP != NULL); - TEST(xmlrpc_mem_block_size(blockP) == 128); - - /* Test cleanup code (with help from memprof). */ - xmlrpc_mem_block_free(blockP); - - /* Allocate a "typed" memory block. */ - typedHeapBlockP = XMLRPC_TYPED_MEM_BLOCK_NEW(void *, &env, 20); - TEST_NO_FAULT(&env); - TEST(typedHeapBlockP != NULL); - TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(void*, typedHeapBlockP) == 20); - typedContents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(void*, typedHeapBlockP); - TEST(typedContents != NULL); - - /* Resize a typed memory block. */ - XMLRPC_TYPED_MEM_BLOCK_RESIZE(void*, &env, typedHeapBlockP, 100); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(void*, typedHeapBlockP) == 100); - - /* Test cleanup code (with help from memprof). */ - XMLRPC_TYPED_MEM_BLOCK_FREE(void*, typedHeapBlockP); - - /* Test xmlrpc_mem_block_append. */ - blockP = XMLRPC_TYPED_MEM_BLOCK_NEW(int, &env, 5); - TEST_NO_FAULT(&env); - memcpy(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(int, blockP), - test_int_array_1, sizeof(test_int_array_1)); - XMLRPC_TYPED_MEM_BLOCK_APPEND(int, &env, blockP, test_int_array_2, 3); - TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(int, blockP) == 8); - TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(int, blockP), - test_int_array_3, sizeof(test_int_array_3)) == 0); - XMLRPC_TYPED_MEM_BLOCK_FREE(int, blockP); - - xmlrpc_env_clean(&env); -} - - - -static void -testMemPool(void) { - - xmlrpc_env env; - - xmlrpc_mem_pool * poolP; - - xmlrpc_env_init(&env); - - poolP = xmlrpc_mem_pool_new(&env, 1); - TEST_NO_FAULT(&env); - TEST(poolP != NULL); - - xmlrpc_mem_pool_free(poolP); - - poolP = xmlrpc_mem_pool_new(&env, 10); - TEST_NO_FAULT(&env); - TEST(poolP != NULL); - - xmlrpc_mem_pool_alloc(&env, poolP, 1); - TEST_NO_FAULT(&env); - - xmlrpc_mem_pool_release(poolP, 1); - TEST_NO_FAULT(&env); - - xmlrpc_mem_pool_alloc(&env, poolP, 5); - TEST_NO_FAULT(&env); - - { - xmlrpc_env env2; - xmlrpc_env_init(&env2); - xmlrpc_mem_pool_alloc(&env2, poolP, 6); - TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); - xmlrpc_env_clean(&env2); - } - - xmlrpc_mem_pool_alloc(&env, poolP, 5); - TEST_NO_FAULT(&env); - - xmlrpc_mem_pool_release(poolP, 5); - TEST_NO_FAULT(&env); - - xmlrpc_mem_pool_release(poolP, 5); - TEST_NO_FAULT(&env); - - xmlrpc_mem_pool_free(poolP); - - xmlrpc_env_clean(&env); -} - - - -static void -testMemBlockPool(void) { - - xmlrpc_env env; - - xmlrpc_mem_pool * poolP; - xmlrpc_mem_block * block1P; - - xmlrpc_env_init(&env); - - /* The memory block facility often allocates more memory that we request, - anticipating the future (e.g. if we create a 1-byte block, it allocates - 16), so we work in large numbers. - */ - - poolP = xmlrpc_mem_pool_new(&env, 1000); - TEST_NO_FAULT(&env); - TEST(poolP != NULL); - - block1P = xmlrpc_mem_block_new_pool(&env, 1000, poolP); - TEST_NO_FAULT(&env); - TEST(block1P != NULL); - - xmlrpc_mem_block_free(block1P); - - block1P = xmlrpc_mem_block_new_pool(&env, 200, poolP); - - { - xmlrpc_env env2; - xmlrpc_env_init(&env2); - xmlrpc_mem_block_new_pool(&env2, 900, poolP); - TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); - xmlrpc_env_clean(&env2); - } - - xmlrpc_mem_block_resize(&env, block1P, 500); - TEST_NO_FAULT(&env); - - { - xmlrpc_env env2; - xmlrpc_env_init(&env2); - xmlrpc_mem_block_resize(&env2, block1P, 1100); - TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); - xmlrpc_env_clean(&env2); - } - - { - xmlrpc_env env2; - xmlrpc_env_init(&env2); - xmlrpc_mem_block_new_pool(&env2, 600, poolP); - TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); - xmlrpc_env_clean(&env2); - } - - xmlrpc_mem_block_free(block1P); - - xmlrpc_mem_pool_free(poolP); - - xmlrpc_env_clean(&env); -} - - - -void -test_memBlock() { - - printf("Running memory manager tests..."); - - testMemBlock(); - - testMemPool(); - - testMemBlockPool(); - - printf("\n"); - printf("Memory manager tests done.\n"); -} - - diff --git a/trunk/test/memblock.h b/trunk/test/memblock.h deleted file mode 100644 index 30ed9fc71..000000000 --- a/trunk/test/memblock.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef TEST_MEMBLOCK_H_INCLUDED -#define TEST_MEMBLOCK_H_INCLUDED - -void -test_memBlock(void); - -#endif diff --git a/trunk/test/method_registry.c b/trunk/test/method_registry.c deleted file mode 100644 index af88bb8aa..000000000 --- a/trunk/test/method_registry.c +++ /dev/null @@ -1,1126 +0,0 @@ -#include -#include - -#include "int.h" -#include "casprintf.h" -#include "girstring.h" - -#include "xmlrpc_config.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" - -#include "testtool.h" -#include "xml_data.h" -#include "method_registry.h" - - -#define FOO_SERVERINFO ((void*) 0xF00) -#define FOO_CALLINFO ((void*) 0xFC0) -#define BAR_SERVERINFO ((void*) 0xBAF) -#define BAR_CALLINFO ((void*) 0xBAC) -#define MULTI_CALLINFO ((void*) 0xFFF) -#define DEFAULT_SERVERINFO ((void*) 0xD00) -#define DEFAULT_CALLINFO ((void*) 0xDC0) - -static const char * const barHelp = "This is the help for Method test.bar."; - - - -static void -testVersion(void) { - - unsigned int major, minor, point; - - xmlrpc_server_version(&major, &minor, &point); - -#ifndef _WIN32 - /* xmlrpc_server_version_major, etc. are not exported from a Windows DLL */ - - TEST(major == xmlrpc_server_version_major); - TEST(minor == xmlrpc_server_version_minor); - TEST(point == xmlrpc_server_version_point); -#endif -} - - - -static xmlrpc_value * -test_foo(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo) { - - xmlrpc_int32 x, y; - - TEST_NO_FAULT(envP); - TEST(paramArrayP != NULL); - TEST(serverInfo == FOO_SERVERINFO); - TEST(callInfo == FOO_CALLINFO || callInfo == MULTI_CALLINFO); - - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - TEST_NO_FAULT(envP); - TEST(x == 25); - TEST(y == 17); - - return xmlrpc_build_value(envP, "i", (xmlrpc_int32) x + y); -} - - - -static xmlrpc_value * -test_foo_type1(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo) { - - xmlrpc_int32 x, y; - - TEST_NO_FAULT(envP); - TEST(paramArrayP != NULL); - TEST(serverInfo == FOO_SERVERINFO); - - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - TEST_NO_FAULT(envP); - TEST(x == 25); - TEST(y == 17); - - return xmlrpc_build_value(envP, "i", (xmlrpc_int32) x + y); -} - - - -static xmlrpc_value * -test_bar(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP, - void * const serverInfo, - void * const callInfo) { - - xmlrpc_int32 x, y; - - TEST_NO_FAULT(envP); - TEST(paramArrayP != NULL); - TEST(serverInfo == BAR_SERVERINFO); - TEST(callInfo == BAR_CALLINFO || callInfo == MULTI_CALLINFO); - - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - TEST_NO_FAULT(envP); - TEST(x == 25); - TEST(y == 17); - - xmlrpc_env_set_fault(envP, 123, "Test fault"); - - return NULL; -} - - - -static xmlrpc_value * -test_default(xmlrpc_env * const envP, - const char * const callInfo, - const char * const methodName, - xmlrpc_value * const paramArrayP, - void * const serverInfo) { - - xmlrpc_int32 x, y; - - TEST_NO_FAULT(envP); - TEST(paramArrayP != NULL); - TEST(serverInfo == DEFAULT_SERVERINFO); - - TEST(streq(methodName, "test.nosuch") || - streq(methodName, "test.nosuch.old")); - - if (streq(methodName, "nosuch.method")) - TEST(callInfo == DEFAULT_CALLINFO); - else if (streq(methodName, "nosuch.method.old")) - TEST(callInfo == NULL); - - xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); - TEST_NO_FAULT(envP); - TEST(x == 25); - TEST(y == 17); - - return xmlrpc_build_value(envP, "i", 2 * (x + y)); -} - - - -static xmlrpc_value * -test_exttype(xmlrpc_env * const envP, - xmlrpc_value * const paramArrayP ATTR_UNUSED, - void * const serverInfo ATTR_UNUSED, - void * const callInfo ATTR_UNUSED) { - - return xmlrpc_build_value(envP, "(In)", (xmlrpc_int64)8); -} - - - -static void -doRpc(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const methodName, - xmlrpc_value * const argArrayP, - void * const callInfo, - xmlrpc_value ** const resultPP) { -/*---------------------------------------------------------------------------- - Do what an XML-RPC server would do -- pass an XML call to the registry - and get XML back. - - Actually to our caller, we look more like an Xmlrpc-c client. We're - both the client and the server all bound together. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * callP; - xmlrpc_mem_block * responseP; - - /* Build a call, and tell the registry to handle it. */ - callP = xmlrpc_mem_block_new(envP, 0); - TEST_NO_FAULT(envP); - xmlrpc_serialize_call(envP, callP, methodName, argArrayP); - TEST_NO_FAULT(envP); - - if (callInfo) - xmlrpc_registry_process_call2( - envP, registryP, - xmlrpc_mem_block_contents(callP), - xmlrpc_mem_block_size(callP), - callInfo, &responseP); - else - responseP = xmlrpc_registry_process_call( - envP, registryP, NULL, - xmlrpc_mem_block_contents(callP), - xmlrpc_mem_block_size(callP)); - - TEST_NO_FAULT(envP); - TEST(responseP != NULL); - - /* Parse the response. */ - *resultPP = xmlrpc_parse_response(envP, - xmlrpc_mem_block_contents(responseP), - xmlrpc_mem_block_size(responseP)); - - xmlrpc_mem_block_free(callP); - xmlrpc_mem_block_free(responseP); -} - - - -static const char * const validSigString[] = { - "i:", - "s:d", - "n:iIbds86SA", - "i:,i:", - "i:dd,s:,A:A", - "i:,", - "b:i,", - "b:i,b:,", - NULL -}; - -static const char * const invalidSigString[] = { - "", - "i", - "q", - "i:q", - "i:ddq", - ",", - ",i:", - "i,", - "b:i,,b:i", - "ii:", - "ii:ii", - NULL -}; - - - -static void -test_system_methodSignature(xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Test system.methodSignature system method. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * argArrayP; - xmlrpc_value * resultP; - const char * type0; - const char * type1; - const char * type2; - const char * type3; - const char * type4; - const char * type5; - const char * type6; - const char * type7; - const char * type8; - const char * type9; - const char * nosigstring; - - xmlrpc_env_init(&env); - - argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosuchmethod"); - doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, - &resultP); - TEST_FAULT(&env, XMLRPC_NO_SUCH_METHOD_ERROR); - xmlrpc_DECREF(argArrayP); - - argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosig0"); - - doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, - &resultP); - TEST_NO_FAULT(&env); - - xmlrpc_read_string(&env, resultP, &nosigstring); - TEST_NO_FAULT(&env); - - TEST(streq(nosigstring, "undef")); - strfree(nosigstring); - xmlrpc_DECREF(resultP); - xmlrpc_DECREF(argArrayP); - - argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig0"); - doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, - &resultP); - TEST_NO_FAULT(&env); - - xmlrpc_decompose_value(&env, resultP, "((s))", &type0); - TEST_NO_FAULT(&env); - TEST(streq(type0, "int")); - strfree(type0); - xmlrpc_DECREF(resultP); - xmlrpc_DECREF(argArrayP); - - argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig2"); - doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, - &resultP); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, resultP, "((ssssssssss))", - &type0, &type1, &type2, &type3, - &type4, &type5, &type6, &type7, - &type8, &type9); - TEST_NO_FAULT(&env); - TEST(streq(type0, "nil")); - TEST(streq(type1, "int")); - TEST(streq(type2, "i8")); - TEST(streq(type3, "boolean")); - TEST(streq(type4, "double")); - TEST(streq(type5, "string")); - TEST(streq(type6, "dateTime.iso8601")); - TEST(streq(type7, "base64")); - TEST(streq(type8, "struct")); - TEST(streq(type9, "array")); - strfree(type0); strfree(type1); strfree(type2); strfree(type3); - strfree(type4); strfree(type5); strfree(type6); strfree(type7); - strfree(type8); strfree(type9); - xmlrpc_DECREF(resultP); - xmlrpc_DECREF(argArrayP); - - argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig3"); - doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, - &resultP); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, resultP, "((s)(s))", &type0, &type1); - - TEST_NO_FAULT(&env); - TEST(streq(type0, "int")); - TEST(streq(type1, "int")); - strfree(type0); - strfree(type1); - xmlrpc_DECREF(resultP); - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); -} - - - -static void -test_signature(void) { - - xmlrpc_env env; - xmlrpc_registry * registryP; - unsigned int i; - - xmlrpc_env_init(&env); - - printf(" Running signature tests."); - - registryP = xmlrpc_registry_new(&env); - TEST_NO_FAULT(&env); - - xmlrpc_registry_add_method2(&env, registryP, "test.nosig0", - test_foo, NULL, NULL, FOO_SERVERINFO); - TEST_NO_FAULT(&env); - - xmlrpc_registry_add_method2(&env, registryP, "test.nosig1", - test_foo, "?", NULL, FOO_SERVERINFO); - TEST_NO_FAULT(&env); - - for (i = 0; validSigString[i]; ++i) { - const char * methodName; - casprintf(&methodName, "test.validsig%u", i); - xmlrpc_registry_add_method2(&env, registryP, methodName, - test_foo, - validSigString[i], NULL, FOO_SERVERINFO); - TEST_NO_FAULT(&env); - strfree(methodName); - } - - for (i = 0; invalidSigString[i]; ++i) { - const char * methodName; - casprintf(&methodName, "test.invalidsig%u", i); - xmlrpc_registry_add_method2(&env, registryP, methodName, - test_foo, - invalidSigString[i], NULL, FOO_SERVERINFO); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - strfree(methodName); - } - - xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, "test.old", - test_foo_type1, FOO_SERVERINFO, - NULL, NULL); - TEST_NO_FAULT(&env); - - xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, "test.old.invalid", - test_foo_type1, FOO_SERVERINFO, - invalidSigString[0], NULL); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - test_system_methodSignature(registryP); - - xmlrpc_registry_free(registryP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -static void -test_disable_introspection(void) { - - xmlrpc_env env; - xmlrpc_registry * registryP; - xmlrpc_value * argArrayP; - xmlrpc_value * resultP; - - xmlrpc_env_init(&env); - - printf(" Running disable introspection tests."); - - registryP = xmlrpc_registry_new(&env); - TEST_NO_FAULT(&env); - - xmlrpc_registry_add_method2(&env, registryP, "test.nosig0", - test_foo, NULL, NULL, FOO_SERVERINFO); - TEST_NO_FAULT(&env); - - xmlrpc_registry_disable_introspection(registryP); - - argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosig0"); - doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, - &resultP); - TEST_FAULT(&env, XMLRPC_INTROSPECTION_DISABLED_ERROR); - xmlrpc_DECREF(argArrayP); - - xmlrpc_registry_free(registryP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -static const char * const expectedMethodName[] = { -/*---------------------------------------------------------------------------- - The list we expect back from system.listMethods. ------------------------------------------------------------------------------*/ - "system.listMethods", - "system.methodExist", - "system.methodHelp", - "system.methodSignature", - "system.multicall", - "system.shutdown", - "system.capabilities", - "system.getCapabilities", - "test.foo", - "test.bar" -}; - - - -static void -test_system_listMethods(xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Test system.listMethods ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_value * argArrayP; - const char * methodName[ARRAY_SIZE(expectedMethodName)]; - unsigned int size; - unsigned int i; - - xmlrpc_env_init(&env); - - printf(" Running system.listMethods tests."); - - argArrayP = xmlrpc_array_new(&env); - TEST_NO_FAULT(&env); - - doRpc(&env, registryP, "system.listMethods", argArrayP, NULL, &resultP); - TEST_NO_FAULT(&env); - - TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_ARRAY); - - size = xmlrpc_array_size(&env, resultP); - - TEST_NO_FAULT(&env); - - TEST(size == ARRAY_SIZE(expectedMethodName)); - - xmlrpc_decompose_value(&env, resultP, "(ssssssssss)", - &methodName[0], &methodName[1], - &methodName[2], &methodName[3], - &methodName[4], &methodName[5], - &methodName[6], &methodName[7], - &methodName[8], &methodName[9]); - - TEST_NO_FAULT(&env); - - for (i = 0; i < ARRAY_SIZE(expectedMethodName); ++i) { - TEST(streq(methodName[i], expectedMethodName[i])); - strfree(methodName[i]); - } - - xmlrpc_DECREF(resultP); - - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -static void -test_system_methodExist(xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Test system.methodExist ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_value * argArrayP; - xmlrpc_bool exists; - - xmlrpc_env_init(&env); - - printf(" Running system.methodExist tests."); - - argArrayP = xmlrpc_build_value(&env, "(s)", "test.foo"); - TEST_NO_FAULT(&env); - - doRpc(&env, registryP, "system.methodExist", argArrayP, NULL, &resultP); - TEST_NO_FAULT(&env); - - TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_BOOL); - - xmlrpc_read_bool(&env, resultP, &exists); - TEST_NO_FAULT(&env); - - TEST(exists); - - xmlrpc_DECREF(resultP); - - xmlrpc_DECREF(argArrayP); - - - argArrayP = xmlrpc_build_value(&env, "(s)", "nosuchmethod"); - TEST_NO_FAULT(&env); - - doRpc(&env, registryP, "system.methodExist", argArrayP, NULL, &resultP); - TEST_NO_FAULT(&env); - - TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_BOOL); - - xmlrpc_read_bool(&env, resultP, &exists); - TEST_NO_FAULT(&env); - - TEST(!exists); - - xmlrpc_DECREF(resultP); - - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -static void -testNoHelp(xmlrpc_registry * const registryP) { - - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_value * argArrayP; - const char * helpString; - - xmlrpc_env_init(&env); - - argArrayP = xmlrpc_build_value(&env, "(s)", "test.foo"); - TEST_NO_FAULT(&env); - - doRpc(&env, registryP, "system.methodHelp", argArrayP, NULL, &resultP); - TEST_NO_FAULT(&env); - - TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_STRING); - - xmlrpc_read_string(&env, resultP, &helpString); - TEST_NO_FAULT(&env); - - TEST(streq(helpString, "No help is available for this method.")); - - strfree(helpString); - - xmlrpc_DECREF(resultP); - - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); -} - - - -static void -testExistentHelp(xmlrpc_registry * const registryP) { - - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_value * argArrayP; - const char * helpString; - - xmlrpc_env_init(&env); - - argArrayP = xmlrpc_build_value(&env, "(s)", "test.bar"); - TEST_NO_FAULT(&env); - - doRpc(&env, registryP, "system.methodHelp", argArrayP, NULL, &resultP); - TEST_NO_FAULT(&env); - - TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_STRING); - - xmlrpc_read_string(&env, resultP, &helpString); - TEST_NO_FAULT(&env); - - TEST(streq(helpString, barHelp)); - - strfree(helpString); - - xmlrpc_DECREF(resultP); - - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); -} - - - -static void -test_system_methodHelp(xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Test system.methodHelp ------------------------------------------------------------------------------*/ - xmlrpc_env env; - - xmlrpc_env_init(&env); - - printf(" Running system.methodHelp tests."); - - testNoHelp(registryP); - - testExistentHelp(registryP); - - printf("\n"); -} - - - -static void -test_system_capabilities(xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Test system.capabilities ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_value * argArrayP; - const char * facility; - xmlrpc_int version_major, version_minor, version_point; - xmlrpc_int protocol_version; - - xmlrpc_env_init(&env); - - printf(" Running system.capabilities tests."); - - argArrayP = xmlrpc_array_new(&env); - TEST_NO_FAULT(&env); - - doRpc(&env, registryP, "system.capabilities", argArrayP, NULL, &resultP); - TEST_NO_FAULT(&env); - - xmlrpc_decompose_value(&env, resultP, "{s:s,s:i,s:i,s:i,s:i,*}", - "facility", &facility, - "version_major", &version_major, - "version_minor", &version_minor, - "version_point", &version_point, - "protocol_version", &protocol_version); - TEST_NO_FAULT(&env); - - TEST(streq(facility, "xmlrpc-c")); - TEST(protocol_version == 2); - - strfree(facility); - - xmlrpc_DECREF(resultP); - - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -static void -test_system_getCapabilities(xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Test system.getCapabilities ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_value * argArrayP; - const char * specUrl; - int specVersion; - - xmlrpc_env_init(&env); - - printf(" Running system.getCapabilities tests."); - - argArrayP = xmlrpc_array_new(&env); - TEST_NO_FAULT(&env); - - doRpc(&env, registryP, "system.getCapabilities", argArrayP, NULL, - &resultP); - TEST_NO_FAULT(&env); - - xmlrpc_decompose_value(&env, resultP, "{s:{s:s,s:i,*},*}", - "introspect", - "specUrl", &specUrl, - "specVersion", &specVersion); - TEST_NO_FAULT(&env); - - TEST(streq(specUrl, - "http://xmlrpc-c.sourceforge.net/xmlrpc-c/introspection.html")); - TEST(specVersion == 1); - - strfree(specUrl); - - xmlrpc_DECREF(resultP); - - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -static void -test_system_multicall(xmlrpc_registry * const registryP) { -/*---------------------------------------------------------------------------- - Test system.multicall ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * multiP; - xmlrpc_int32 foo1_result, foo2_result; - xmlrpc_int32 bar_code, nosuch_code; - char *bar_string, *nosuch_string; - xmlrpc_value * valueP; - xmlrpc_value * argArrayP; - - xmlrpc_env_init(&env); - - printf(" Running multicall tests."); - - /* Build an argument array for our calls. */ - argArrayP = xmlrpc_build_value(&env, "(ii)", - (xmlrpc_int32) 25, (xmlrpc_int32) 17); - TEST_NO_FAULT(&env); - - multiP = xmlrpc_build_value(&env, - "((" - "{s:s,s:A}" /* test.foo */ - "{s:s,s:A}" /* test.bar */ - "{s:s,s:A}" /* test.nosuch */ - "{s:s,s:A}" /* test.foo */ - "))", - "methodName", "test.foo", - "params", argArrayP, - "methodName", "test.bar", - "params", argArrayP, - "methodName", "test.nosuch", - "params", argArrayP, - "methodName", "test.foo", - "params", argArrayP); - TEST_NO_FAULT(&env); - doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, - &valueP); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, valueP, - "(" - "(i)" /* result of test.foo */ - "{s:i,s:s,*}" /* result of test.bar */ - "{s:i,s:s,*}" /* result of test.nosuch */ - "(i)" /* result of test.foo #2 */ - ")", - &foo1_result, - "faultCode", &bar_code, - "faultString", &bar_string, - "faultCode", &nosuch_code, - "faultString", &nosuch_string, - &foo2_result); - xmlrpc_DECREF(valueP); - TEST_NO_FAULT(&env); - TEST(foo1_result == 42); - TEST(bar_code == 123); - TEST(streq(bar_string, "Test fault")); - TEST(nosuch_code == XMLRPC_NO_SUCH_METHOD_ERROR); - TEST(foo2_result == 42); - xmlrpc_DECREF(multiP); - free(bar_string); - free(nosuch_string); - - - /* Now for some invalid multi calls */ - - multiP = xmlrpc_build_value(&env, - "(({s:s,s:V}{s:s,s:()}{s:s,s:V}))", - "methodName", "test.foo", - "params", argArrayP, - "methodName", "system.multicall", - "params", - "methodName", "test.foo", - "params", argArrayP); - TEST_NO_FAULT(&env); - doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, - &valueP); - TEST_FAULT(&env, XMLRPC_REQUEST_REFUSED_ERROR); - - xmlrpc_DECREF(multiP); - - multiP = xmlrpc_build_value(&env, - "(({s:s,s:V}d))", - "methodName", "test.foo", - "params", argArrayP, - 5.0); - - TEST_NO_FAULT(&env); - doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, - &valueP); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - xmlrpc_DECREF(multiP); - - multiP = xmlrpc_build_value(&env, - "({s:s,s:V})", - "methodName", "test.foo", - "params", argArrayP); - - TEST_NO_FAULT(&env); - doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, - &valueP); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - xmlrpc_DECREF(multiP); - - multiP = xmlrpc_build_value(&env, "(({}))"); - TEST_NO_FAULT(&env); - doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, - &valueP); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_DECREF(multiP); - - multiP = xmlrpc_build_value(&env, "(({s:s}))", - "methodName", "test.foo"); - TEST_NO_FAULT(&env); - doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, - &valueP); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_DECREF(multiP); - - - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -static void -testCall(xmlrpc_registry * const registryP) { - - xmlrpc_env env; - xmlrpc_env env2; - xmlrpc_value * argArrayP; - xmlrpc_value * valueP; - xmlrpc_int32 i; - - printf(" Running call tests."); - - xmlrpc_env_init(&env); - - /* Build an argument array for our calls. */ - argArrayP = xmlrpc_build_value(&env, "(ii)", - (xmlrpc_int32) 25, (xmlrpc_int32) 17); - TEST_NO_FAULT(&env); - - /* Call test.foo and check the result. */ - doRpc(&env, registryP, "test.foo", argArrayP, FOO_CALLINFO, &valueP); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - xmlrpc_decompose_value(&env, valueP, "i", &i); - xmlrpc_DECREF(valueP); - TEST_NO_FAULT(&env); - TEST(i == 42); - - /* Call test.bar and check the result. */ - xmlrpc_env_init(&env2); - doRpc(&env2, registryP, "test.bar", argArrayP, BAR_CALLINFO, &valueP); - TEST(env2.fault_occurred); - TEST(env2.fault_code == 123); - TEST(env2.fault_string && streq(env2.fault_string, "Test fault")); - xmlrpc_env_clean(&env2); - - /* Call a non-existant method and check the result. */ - xmlrpc_env_init(&env2); - doRpc(&env2, registryP, "test.nosuch", argArrayP, FOO_CALLINFO, &valueP); - TEST(valueP == NULL); - TEST_FAULT(&env2, XMLRPC_NO_SUCH_METHOD_ERROR); - xmlrpc_env_clean(&env2); - - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -static void -testDefaultMethod(xmlrpc_registry * const registryP) { - - xmlrpc_env env; - xmlrpc_value * argArrayP; - xmlrpc_value * valueP; - xmlrpc_int32 i; - - xmlrpc_env_init(&env); - - printf(" Running default method tests."); - - /* Build an argument array for our calls. */ - argArrayP = xmlrpc_build_value(&env, "(ii)", - (xmlrpc_int32) 25, (xmlrpc_int32) 17); - - xmlrpc_registry_set_default_method(&env, registryP, &test_default, - DEFAULT_SERVERINFO); - TEST_NO_FAULT(&env); - doRpc(&env, registryP, "test.nosuch", argArrayP, DEFAULT_CALLINFO, - &valueP); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - xmlrpc_decompose_value(&env, valueP, "i", &i); - xmlrpc_DECREF(valueP); - TEST_NO_FAULT(&env); - TEST(i == 84); - - /* Now try it with old method interface */ - - doRpc(&env, registryP, "test.nosuch.old", argArrayP, NULL, &valueP); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - xmlrpc_read_int(&env, valueP, &i); - TEST_NO_FAULT(&env); - xmlrpc_DECREF(valueP); - TEST(i == 84); - - /* Change the default method. */ - xmlrpc_registry_set_default_method(&env, registryP, &test_default, - BAR_SERVERINFO); - TEST_NO_FAULT(&env); - - xmlrpc_DECREF(argArrayP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -static void -test_apache_dialect(void) { - - char const expectedResp[] = - XML_PROLOGUE - "\r\n" - "\r\n" - "\r\n" - "8\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n"; - - xmlrpc_env env; - xmlrpc_registry * registryP; - xmlrpc_value * argArrayP; - xmlrpc_mem_block * callP; - xmlrpc_mem_block * responseP; - - xmlrpc_env_init(&env); - - printf(" Running apache dialect tests."); - - registryP = xmlrpc_registry_new(&env); - TEST_NO_FAULT(&env); - - xmlrpc_registry_set_dialect(&env, registryP, xmlrpc_dialect_i8); - TEST_NO_FAULT(&env); - - xmlrpc_registry_set_dialect(&env, registryP, 100); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_registry_set_dialect(&env, registryP, xmlrpc_dialect_apache); - TEST_NO_FAULT(&env); - - xmlrpc_registry_add_method2(&env, registryP, "test_exttype", - test_exttype, NULL, NULL, FOO_SERVERINFO); - TEST_NO_FAULT(&env); - - argArrayP = xmlrpc_array_new(&env); - TEST_NO_FAULT(&env); - - callP = xmlrpc_mem_block_new(&env, 0); - TEST_NO_FAULT(&env); - xmlrpc_serialize_call(&env, callP, "test_exttype", argArrayP); - TEST_NO_FAULT(&env); - - xmlrpc_registry_process_call2( - &env, registryP, - xmlrpc_mem_block_contents(callP), - xmlrpc_mem_block_size(callP), - NULL, &responseP); - - TEST_NO_FAULT(&env); - - TEST(XMLRPC_MEMBLOCK_SIZE(char, responseP) == strlen(expectedResp)); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, responseP), - expectedResp, - XMLRPC_MEMBLOCK_SIZE(char, responseP))); - - xmlrpc_DECREF(argArrayP); - xmlrpc_mem_block_free(callP); - xmlrpc_mem_block_free(responseP); - xmlrpc_registry_free(registryP); - - xmlrpc_env_clean(&env); - - printf("\n"); -} - - - -void -test_method_registry(void) { - - xmlrpc_env env, env2; - xmlrpc_value * valueP; - xmlrpc_registry * registryP; - xmlrpc_mem_block * responseP; - - xmlrpc_env_init(&env); - - testVersion(); - - printf("Running method registry tests."); - - /* Create a new registry. */ - registryP = xmlrpc_registry_new(&env); - TEST_NO_FAULT(&env); - TEST(registryP != NULL); - - /* Add some test methods. */ - xmlrpc_registry_add_method(&env, registryP, NULL, "test.foo", - test_foo_type1, FOO_SERVERINFO); - TEST_NO_FAULT(&env); - xmlrpc_registry_add_method2(&env, registryP, "test.bar", - test_bar, NULL, barHelp, BAR_SERVERINFO); - TEST_NO_FAULT(&env); - - printf("\n"); - testCall(registryP); - - test_system_multicall(registryP); - - xmlrpc_env_init(&env2); - xmlrpc_registry_process_call2(&env, registryP, - expat_error_data, - strlen(expat_error_data), - NULL, - &responseP); - TEST_NO_FAULT(&env); - TEST(responseP != NULL); - valueP = xmlrpc_parse_response(&env2, xmlrpc_mem_block_contents(responseP), - xmlrpc_mem_block_size(responseP)); - TEST(valueP == NULL); - TEST_FAULT(&env2, XMLRPC_PARSE_ERROR); - xmlrpc_mem_block_free(responseP); - xmlrpc_env_clean(&env2); - - printf("\n"); - - testDefaultMethod(registryP); - - test_system_listMethods(registryP); - - test_system_methodExist(registryP); - - test_system_methodHelp(registryP); - - test_system_capabilities(registryP); - - test_system_getCapabilities(registryP); - - test_signature(); - - test_disable_introspection(); - - test_apache_dialect(); - - /* Test cleanup code (w/memprof). */ - xmlrpc_registry_free(registryP); - - printf("\n"); - - xmlrpc_env_clean(&env); -} diff --git a/trunk/test/method_registry.h b/trunk/test/method_registry.h deleted file mode 100644 index bdc325bdb..000000000 --- a/trunk/test/method_registry.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef TEST_METHOD_REGISTRY_H_INCLUDED -#define TEST_METHOD_REGISTRY_H_INCLUDED - -void -test_method_registry(void); - -#endif diff --git a/trunk/test/parse_xml.c b/trunk/test/parse_xml.c deleted file mode 100644 index d6abe5904..000000000 --- a/trunk/test/parse_xml.c +++ /dev/null @@ -1,529 +0,0 @@ -#include -#include - -#include "xmlrpc_config.h" - -#include "girstring.h" -#include "casprintf.h" -#include "xmlrpc-c/base.h" - -#include "testtool.h" -#include "xml_data.h" -#include "parse_xml.h" - - - -static void -testParseNumberValue(void) { - -char const xmldata[] = - XML_PROLOGUE - "\r\n" - "test\r\n" - "\r\n" - "2147483647\r\n" \ - "-2147483648\r\n" \ - "10\r\n" - "10\r\n" - "10\r\n" - "10\r\n" - "10\r\n" - "10\r\n" - "10.1\r\n" - "-10.1\r\n" - "+10.1\r\n" - "0\r\n" - ".01\r\n" - "5.\r\n" - "5.3E6\r\n" - " 1\r\n" - "\r\n" - "\r\n"; - - xmlrpc_env env; - xmlrpc_value * paramArrayP; - const char * methodName; - int arraySize; - xmlrpc_int int_max, int_min; - xmlrpc_int32 i_i1, i_i2, i_i4; - xmlrpc_int64 i_i8, i_ex_i8; - double d1, d2, d3, d4, d5, d6, d7, d8, d9; - - xmlrpc_env_init(&env); - - xmlrpc_parse_call(&env, xmldata, strlen(xmldata), - &methodName, ¶mArrayP); - TEST_NO_FAULT(&env); - - arraySize = xmlrpc_array_size(&env, paramArrayP); - TEST_NO_FAULT(&env); - - TEST(arraySize == 16); - - xmlrpc_decompose_value( - &env, paramArrayP, "(iiiiiIIddddddddd)", - &int_max, &int_min, &i_i1, &i_i2, &i_i4, &i_i8, &i_ex_i8, - &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9); - - TEST_NO_FAULT(&env); - - TEST(int_max == INT_MAX); - TEST(int_min == INT_MIN); - TEST(i_i1 == 10); - TEST(i_i2 == 10); - TEST(i_i4 == 10); - TEST(i_i8 == 10); - TEST(i_ex_i8 == 10); - TESTFLOATEQUAL(d1, 10.0); - TESTFLOATEQUAL(d2, 10.1); - TESTFLOATEQUAL(d3, -10.1); - TESTFLOATEQUAL(d4, +10.1); - TESTFLOATEQUAL(d5, 0.0); - TESTFLOATEQUAL(d6, 0.01); - TESTFLOATEQUAL(d7, 5.0); - TESTFLOATEQUAL(d8, 5.3E6); - TESTFLOATEQUAL(d9, 1.0); - - xmlrpc_DECREF(paramArrayP); - strfree(methodName); - - xmlrpc_env_clean(&env); -} - - - -static void -testParseMiscSimpleValue(void) { - -char const xmldata[] = - XML_PROLOGUE - "\r\n" - "test\r\n" - "\r\n" - "hello\r\n" - "0\r\n" - "1\r\n" - "19980717T14:08:55" - "\r\n" - "" - "19980717T14:08:55.123456" - "\r\n" - "YmFzZTY0IGRhdGE=\r\n" - "\r\n" - "\r\n" - "\r\n" - "\r\n"; - - xmlrpc_env env; - xmlrpc_value * paramArrayP; - const char * methodName; - int arraySize; - const char * str_hello; - xmlrpc_bool b_false, b_true; - const char * datetime_sec; - const char * datetime_usec; - unsigned char * b64_data; - size_t b64_len; - - xmlrpc_env_init(&env); - - xmlrpc_parse_call(&env, xmldata, strlen(xmldata), - &methodName, ¶mArrayP); - TEST_NO_FAULT(&env); - - arraySize = xmlrpc_array_size(&env, paramArrayP); - TEST_NO_FAULT(&env); - - TEST(arraySize == 8); - - xmlrpc_decompose_value( - &env, paramArrayP, "(sbb886nn)", - &str_hello, &b_false, &b_true, &datetime_sec, &datetime_usec, - &b64_data, &b64_len); - - TEST_NO_FAULT(&env); - - TEST(streq(str_hello, "hello")); - TEST(!b_false); - TEST(b_true); - TEST(streq(datetime_sec, "19980717T14:08:55")); - TEST(streq(datetime_usec, "19980717T14:08:55.123456")); - TEST(b64_len == 11); - TEST(memcmp(b64_data, "base64 data", b64_len) == 0); - - free(b64_data); - strfree(str_hello); - strfree(datetime_sec); - strfree(datetime_usec); - xmlrpc_DECREF(paramArrayP); - strfree(methodName); - - xmlrpc_env_clean(&env); -} - - - -static void -validateParseResponseResult(xmlrpc_value * const valueP) { - - xmlrpc_env env; - - xmlrpc_value * s; - xmlrpc_int32 int_max; - xmlrpc_int32 int_min; - xmlrpc_int32 int_one; - xmlrpc_bool bool_false; - xmlrpc_bool bool_true; - char * str_hello; - char * str_untagged; - char * datetime; - unsigned char * b64_data; - size_t b64_len; - double negone; - double zero; - double one; - - xmlrpc_env_init(&env); - - xmlrpc_decompose_value( - &env, valueP, "((iibbs68())idddSs)", - &int_max, &int_min, - &bool_false, &bool_true, &str_hello, - &b64_data, &b64_len, &datetime, - &int_one, &negone, &zero, &one, &s, &str_untagged); - - TEST_NO_FAULT(&env); - TEST(int_max == INT_MAX); - TEST(int_min == INT_MIN); - TEST(!bool_false); - TEST(bool_true); - TEST(strlen(str_hello) == strlen("Hello, world! <&>")); - TEST(streq(str_hello, "Hello, world! <&>")); - TEST(b64_len == 11); - TEST(memcmp(b64_data, "base64 data", b64_len) == 0); - TEST(streq(datetime, "19980717T14:08:55")); - TEST(int_one == 1); - TEST(negone == -1.0); - TEST(zero == 0.0); - TEST(one == 1.0); - TEST(streq(str_untagged, "Untagged string")); - free(str_hello); - free(b64_data); - free(datetime); - free(str_untagged); - - { - /* Analyze the contents of our struct. */ - - xmlrpc_value * sval; - int size, sval_int; - - TEST(s != NULL); - size = xmlrpc_struct_size(&env, s); - TEST_NO_FAULT(&env); - TEST(size == 2); - sval = xmlrpc_struct_get_value(&env, s, "ten <&>"); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, sval, "i", &sval_int); - TEST_NO_FAULT(&env); - TEST(sval_int == 10); - sval = xmlrpc_struct_get_value(&env, s, "twenty"); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, sval, "i", &sval_int); - TEST_NO_FAULT(&env); - TEST(sval_int == 20); - xmlrpc_DECREF(s); - } - - xmlrpc_env_clean(&env); -} - - - -static void -testParseGoodResponse(void) { - - xmlrpc_env env; - xmlrpc_value * valueP; - int faultCode; - const char * faultString; - - xmlrpc_env_init(&env); - - xmlrpc_parse_response2(&env, good_response_xml, strlen(good_response_xml), - &valueP, &faultCode, &faultString); - - TEST_NO_FAULT(&env); - TEST(faultString == NULL); - - validateParseResponseResult(valueP); - - xmlrpc_DECREF(valueP); - - /* Try it again with old interface */ - - valueP = xmlrpc_parse_response(&env, - good_response_xml, - strlen(good_response_xml)); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - - validateParseResponseResult(valueP); - - xmlrpc_DECREF(valueP); - - xmlrpc_env_clean(&env); - -} - - - -static void -testParseBadResponseXml(void) { -/*---------------------------------------------------------------------------- - Test parsing of data that is supposed to be a response, but in not - even valid XML. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * valueP; - int faultCode; - const char * faultString; - - xmlrpc_env_init(&env); - - xmlrpc_parse_response2(&env, - unparseable_value, strlen(unparseable_value), - &valueP, &faultCode, &faultString); - - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); - xmlrpc_env_clean(&env); - - xmlrpc_env_init(&env); - - /* And again with the old interface */ - valueP = xmlrpc_parse_response(&env, unparseable_value, - strlen(unparseable_value)); - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); - xmlrpc_env_clean(&env); - TEST(valueP == NULL); -} - - - -static void -testParseBadResponseXmlRpc(void) { -/*---------------------------------------------------------------------------- - Test parsing of data that is supposed to be a response, and is valid - XML, but is not valid XML-RPC. ------------------------------------------------------------------------------*/ - unsigned int i; - - /* For this test, we test up to but not including the in a - successful RPC response. - */ - - /* Next, check for bogus responses. These are all well-formed XML, but - ** they aren't legal XML-RPC. */ - for (i = 15; bad_responses[i] != NULL; ++i) { - const char * const bad_resp = bad_responses[i]; - xmlrpc_env env; - xmlrpc_value * v; - - xmlrpc_env_init(&env); - - /* Now, make sure the higher-level routine barfs appropriately. */ - v = xmlrpc_parse_response(&env, bad_resp, strlen(bad_resp)); - TEST(env.fault_occurred); - TEST(env.fault_code != 0); /* We use 0 as a code in our bad faults. */ - TEST(v == NULL); - xmlrpc_env_clean(&env); - } -} - - - -static void -testParseBadResult(void) { -/*---------------------------------------------------------------------------- - Test parsing of data that is supposed to be a response, but is not - valid. It looks like a valid success response, but the result value - is not valid XML-RPC. ------------------------------------------------------------------------------*/ - unsigned int i; - - for (i = 0; bad_values[i] != NULL; ++i) { - const char * const bad_resp = bad_values[i]; - xmlrpc_env env; - xmlrpc_value * valueP; - int faultCode; - const char * faultString; - - xmlrpc_env_init(&env); - - xmlrpc_parse_response2(&env, bad_resp, strlen(bad_resp), - &valueP, &faultCode, &faultString); - - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); - xmlrpc_env_clean(&env); - - xmlrpc_env_init(&env); - - /* And again with the old interface */ - - valueP = xmlrpc_parse_response(&env, bad_resp, strlen(bad_resp)); - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); - TEST(valueP == NULL); - xmlrpc_env_clean(&env); - } -} - - - -static void -testParseBadResponse(void) { -/*---------------------------------------------------------------------------- - Test parsing of data that is supposed to be a response, but is not - valid. Either not valid XML or not valid XML-RPC. ------------------------------------------------------------------------------*/ - testParseBadResponseXml(); - - testParseBadResponseXmlRpc(); - - testParseBadResult(); -} - - - -static void -testParseFaultResponse(void) { -/*---------------------------------------------------------------------------- - Test parsing of a valid response that indicates the RPC failed. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - - xmlrpc_env_init(&env); - - { - xmlrpc_value * resultP; - int faultCode; - const char * faultString; - - xmlrpc_parse_response2(&env, - serialized_fault, strlen(serialized_fault), - &resultP, &faultCode, &faultString); - - TEST_NO_FAULT(&env); - TEST(faultString != NULL); - TEST(faultCode == 6); - TEST(streq(faultString, "A fault occurred")); - strfree(faultString); - } - /* Now with the old interface */ - { - xmlrpc_env fault; - - /* Parse a valid fault. */ - xmlrpc_env_init(&fault); - xmlrpc_parse_response(&fault, serialized_fault, - strlen(serialized_fault)); - - TEST(fault.fault_occurred); - TEST(fault.fault_code == 6); - TEST(streq(fault.fault_string, "A fault occurred")); - xmlrpc_env_clean(&fault); - } - - xmlrpc_env_clean(&env); -} - - - -static void -testParseXmlCall(void) { - - xmlrpc_env env; - const char *method_name; - xmlrpc_value *params; - int i1, i2; - const char **bad_call; - - xmlrpc_env_init(&env); - - /* Parse a valid call. */ - xmlrpc_parse_call(&env, serialized_call, strlen(serialized_call), - &method_name, ¶ms); - TEST_NO_FAULT(&env); - TEST(params != NULL); - xmlrpc_decompose_value(&env, params, "(ii)", &i1, &i2); - xmlrpc_DECREF(params); - TEST_NO_FAULT(&env); - TEST(streq(method_name, "gloom&doom")); - TEST(i1 == 10 && i2 == 20); - strfree(method_name); - - /* Test some poorly-formed XML data. */ - xmlrpc_parse_call(&env, unparseable_value, strlen(unparseable_value), - &method_name, ¶ms); - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); - TEST(method_name == NULL && params == NULL); - - /* Next, check for bogus values. These are all well-formed XML, but - they aren't legal XML-RPC. - */ - for (bad_call = bad_calls; *bad_call != NULL; ++bad_call) { - xmlrpc_parse_call(&env, *bad_call, strlen(*bad_call), - &method_name, ¶ms); - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); - TEST(method_name == NULL && params == NULL); - } - xmlrpc_env_clean(&env); -} - - - -static void -testParseXmlValue(void) { - - const char * const xmlInt7 = "7"; - const char * const xmlBadVal1 = "hello"; - const char * const xmlBadVal2 = ""; - - xmlrpc_value * valueP; - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - xmlrpc_parse_value_xml(&env, xmlInt7, strlen(xmlInt7), &valueP); - - TEST_NO_FAULT(&env); - - xmlrpc_DECREF(valueP); - - xmlrpc_parse_value_xml(&env, xmlBadVal1, strlen(xmlBadVal1), &valueP); - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); - xmlrpc_env_clean(&env); - - xmlrpc_env_init(&env); - xmlrpc_parse_value_xml(&env, xmlBadVal2, strlen(xmlBadVal2), &valueP); - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); - - xmlrpc_env_clean(&env); -} - - - -void -test_parse_xml(void) { - - printf("Running XML parsing tests.\n"); - testParseNumberValue(); - testParseMiscSimpleValue(); - testParseGoodResponse(); - testParseFaultResponse(); - testParseBadResponse(); - testParseXmlCall(); - testParseXmlValue(); - printf("\n"); - printf("XML parsing tests done.\n"); -} diff --git a/trunk/test/parse_xml.h b/trunk/test/parse_xml.h deleted file mode 100644 index c3928862b..000000000 --- a/trunk/test/parse_xml.h +++ /dev/null @@ -1,2 +0,0 @@ -void -test_parse_xml(void); diff --git a/trunk/test/req_no_params.xml b/trunk/test/req_no_params.xml deleted file mode 100644 index 6ed51a4fa..000000000 --- a/trunk/test/req_no_params.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - foo - diff --git a/trunk/test/serialize.c b/trunk/test/serialize.c deleted file mode 100644 index 275aa784e..000000000 --- a/trunk/test/serialize.c +++ /dev/null @@ -1,316 +0,0 @@ -#include -#include -#include - -#include "xmlrpc_config.h" - -#include "xmlrpc-c/base.h" - -#include "testtool.h" -#include "xml_data.h" -#include "girstring.h" -#include "serialize_value.h" - -#include "serialize.h" - - -static void -test_serialize_basic(void) { - - xmlrpc_env env; - xmlrpc_value * v; - xmlrpc_mem_block *output; - size_t size; - - xmlrpc_env_init(&env); - - /* Build a nice, messy value to serialize. We should attempt to use - ** use every data type except double (which doesn't serialize in a - ** portable manner. */ - v = xmlrpc_build_value(&env, "(iibbs68())", - (xmlrpc_int32) INT_MAX, (xmlrpc_int32) INT_MIN, - (xmlrpc_bool) 0, (xmlrpc_bool) 1, - "Hello, world! <&>", - "base64 data", (size_t) 11, - "19980717T14:08:55"); - TEST_NO_FAULT(&env); - - /* Serialize the value. */ - output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); - TEST_NO_FAULT(&env); - xmlrpc_serialize_value(&env, output, v); - TEST_NO_FAULT(&env); - - /* Make sure we serialized the correct value. */ - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); - TEST(size == strlen(serialized_data)); - TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), - serialized_data, size) == 0); - - /* (Debugging code to display the value.) */ - /* XMLRPC_TYPED_MEM_BLOCK_APPEND(char, &env, output, "\0", 1); - ** TEST_NO_FAULT(&env); - ** printf("%s\n", XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output)); */ - - /* Clean up our value. */ - XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); - xmlrpc_DECREF(v); - - xmlrpc_env_clean(&env); -} - - - -static void -test_serialize_methodResponse(void) { - - /* Serialize a methodResponse. */ - - char const serialized_response[] = - XML_PROLOGUE - "\r\n" - "\r\n" - "30\r\n" - "\r\n" - "\r\n"; - - xmlrpc_env env; - xmlrpc_value * v; - xmlrpc_mem_block *output; - size_t size; - - xmlrpc_env_init(&env); - - output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); - TEST_NO_FAULT(&env); - v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 30); - TEST_NO_FAULT(&env); - xmlrpc_serialize_response(&env, output, v); - TEST_NO_FAULT(&env); - - /* Make sure we serialized the correct value. */ - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); - TEST(size == strlen(serialized_response)); - TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), - serialized_response, size) == 0); - - /* Clean up our methodResponse. */ - xmlrpc_DECREF(v); - XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); - - xmlrpc_env_clean(&env); -} - - - -static void -test_serialize_methodCall(void) { - - /* Serialize a methodCall. */ - - xmlrpc_env env; - xmlrpc_value * v; - xmlrpc_mem_block *output; - size_t size; - - xmlrpc_env_init(&env); - - output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); - TEST_NO_FAULT(&env); - v = xmlrpc_build_value(&env, "(ii)", (xmlrpc_int32) 10, (xmlrpc_int32) 20); - TEST_NO_FAULT(&env); - xmlrpc_serialize_call(&env, output, "gloom&doom", v); - TEST_NO_FAULT(&env); - - /* Make sure we serialized the correct value. */ - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); - TEST(size == strlen(serialized_call)); - TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), - serialized_call, size) == 0); - - /* Clean up our methodCall. */ - xmlrpc_DECREF(v); - XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); - - xmlrpc_env_clean(&env); -} - - - -static void -test_serialize_fault(void) { - /* Serialize a fault. */ - - xmlrpc_env env; - xmlrpc_env fault; - xmlrpc_mem_block *output; - size_t size; - - xmlrpc_env_init(&env); - - output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); - TEST_NO_FAULT(&env); - xmlrpc_env_init(&fault); - xmlrpc_env_set_fault(&fault, 6, "A fault occurred"); - xmlrpc_serialize_fault(&env, output, &fault); - TEST_NO_FAULT(&env); - - /* Make sure we serialized the correct value. */ - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); - TEST(size == strlen(serialized_fault)); - TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), - serialized_fault, size) == 0); - - /* Clean up our fault. */ - xmlrpc_env_clean(&fault); - XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); - - xmlrpc_env_clean(&env); -} - - - -static void -test_serialize_apache_value(void) { - - char const serializedData[] = - "\r\n" - "7\r\n" - "8\r\n" - "\r\n" - ""; - - xmlrpc_env env; - xmlrpc_value * valueP; - xmlrpc_mem_block * outputP; - size_t size; - - xmlrpc_env_init(&env); - - valueP = xmlrpc_build_value(&env, "(iIn)", 7, (xmlrpc_int64)8); - TEST_NO_FAULT(&env); - - outputP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - TEST_NO_FAULT(&env); - xmlrpc_serialize_value2(&env, outputP, valueP, xmlrpc_dialect_apache); - TEST_NO_FAULT(&env); - - size = XMLRPC_MEMBLOCK_SIZE(char, outputP); - - TEST(size == strlen(serializedData)); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, outputP), serializedData, size)); - - XMLRPC_MEMBLOCK_FREE(char, outputP); - xmlrpc_DECREF(valueP); - - xmlrpc_env_clean(&env); -} - - - -static void -test_serialize_apache_params(void) { - - char const serializedData[] = - "\r\n" - "7\r\n" - "8\r\n" - "\r\n"; - - xmlrpc_env env; - xmlrpc_value * paramArrayP; - xmlrpc_mem_block * outputP; - size_t size; - - xmlrpc_env_init(&env); - - paramArrayP = xmlrpc_build_value(&env, "(iI)", 7, (xmlrpc_int64)8); - TEST_NO_FAULT(&env); - - outputP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - TEST_NO_FAULT(&env); - xmlrpc_serialize_params2(&env, outputP, paramArrayP, - xmlrpc_dialect_apache); - TEST_NO_FAULT(&env); - - size = XMLRPC_MEMBLOCK_SIZE(char, outputP); - - TEST(size == strlen(serializedData)); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, outputP), serializedData, size)); - - XMLRPC_MEMBLOCK_FREE(char, outputP); - xmlrpc_DECREF(paramArrayP); - - xmlrpc_env_clean(&env); -} - - - -static void -test_serialize_apache_response(void) { - - char const serializedData[] = - XML_PROLOGUE - "\r\n" - "\r\n" - "8\r\n" - "\r\n" - "\r\n"; - - xmlrpc_env env; - xmlrpc_value * resultP; - xmlrpc_mem_block * outputP; - size_t size; - - xmlrpc_env_init(&env); - - resultP = xmlrpc_i8_new(&env, 8); - TEST_NO_FAULT(&env); - - outputP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - TEST_NO_FAULT(&env); - xmlrpc_serialize_response2(&env, outputP, resultP, - xmlrpc_dialect_apache); - TEST_NO_FAULT(&env); - - size = XMLRPC_MEMBLOCK_SIZE(char, outputP); - - TEST(size == strlen(serializedData)); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, outputP), serializedData, size)); - - XMLRPC_MEMBLOCK_FREE(char, outputP); - xmlrpc_DECREF(resultP); - - xmlrpc_env_clean(&env); -} - - - -static void -test_serialize_apache(void) { - - /* Serialize various things using the Apache dialect of XML-RPC */ - - test_serialize_apache_value(); - test_serialize_apache_params(); - test_serialize_apache_response(); -} - - - -void -test_serialize(void) { - - printf("Running serialize tests."); - - test_serialize_basic(); - printf("\n"); - test_serialize_value(); - test_serialize_methodResponse(); - test_serialize_methodCall(); - test_serialize_fault(); - test_serialize_apache(); - - printf("\n"); - printf("Serialize tests done.\n"); -} diff --git a/trunk/test/serialize.h b/trunk/test/serialize.h deleted file mode 100644 index f01ef588d..000000000 --- a/trunk/test/serialize.h +++ /dev/null @@ -1,2 +0,0 @@ -void -test_serialize(void); diff --git a/trunk/test/serialize_value.c b/trunk/test/serialize_value.c deleted file mode 100644 index a8d17a3be..000000000 --- a/trunk/test/serialize_value.c +++ /dev/null @@ -1,241 +0,0 @@ -#include -#include -#include - -#include "xmlrpc_config.h" - -#include "xmlrpc-c/base.h" - -#include "testtool.h" -#include "girstring.h" - -#include "serialize_value.h" - - -static void -test_serialize_string(void) { - - /* Test serialize of a string, including all the line ending - complexity. - */ - - xmlrpc_env env; - xmlrpc_value * v; - xmlrpc_mem_block * xmlP; /* Serialized result */ - - xmlrpc_env_init(&env); - - TEST_NO_FAULT(&env); - - v = xmlrpc_string_new(&env, "hello world"); - TEST_NO_FAULT(&env); - - xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - xmlrpc_serialize_value(&env, xmlP, v); - TEST_NO_FAULT(&env); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), - "hello world", - XMLRPC_MEMBLOCK_SIZE(char, xmlP))); - XMLRPC_MEMBLOCK_FREE(char, xmlP); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new(&env, ""); - TEST_NO_FAULT(&env); - xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - xmlrpc_serialize_value(&env, xmlP, v); - TEST_NO_FAULT(&env); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), - "", - XMLRPC_MEMBLOCK_SIZE(char, xmlP))); - XMLRPC_MEMBLOCK_FREE(char, xmlP); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new_lp(&env, 7, "foo\0bar"); - TEST_NO_FAULT(&env); - xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - xmlrpc_serialize_value(&env, xmlP, v); - TEST_NO_FAULT(&env); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), - "foo\0bar", - XMLRPC_MEMBLOCK_SIZE(char, xmlP))); - XMLRPC_MEMBLOCK_FREE(char, xmlP); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new_lp(&env, 7, "foo\nbar"); - TEST_NO_FAULT(&env); - xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - xmlrpc_serialize_value(&env, xmlP, v); - TEST_NO_FAULT(&env); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), - "foo\nbar", - XMLRPC_MEMBLOCK_SIZE(char, xmlP))); - XMLRPC_MEMBLOCK_FREE(char, xmlP); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new_lp(&env, 8, "foo\r\nbar"); - TEST_NO_FAULT(&env); - xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - xmlrpc_serialize_value(&env, xmlP, v); - TEST_NO_FAULT(&env); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), - "foo\nbar", - XMLRPC_MEMBLOCK_SIZE(char, xmlP))); - XMLRPC_MEMBLOCK_FREE(char, xmlP); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new_lp(&env, 7, "foo\rbar"); - TEST_NO_FAULT(&env); - xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - xmlrpc_serialize_value(&env, xmlP, v); - TEST_NO_FAULT(&env); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), - "foo\nbar", - XMLRPC_MEMBLOCK_SIZE(char, xmlP))); - XMLRPC_MEMBLOCK_FREE(char, xmlP); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new_lp_cr(&env, 7, "foo\rbar"); - TEST_NO_FAULT(&env); - xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - xmlrpc_serialize_value(&env, xmlP, v); - TEST_NO_FAULT(&env); - TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), - "foo bar", - XMLRPC_MEMBLOCK_SIZE(char, xmlP))); - XMLRPC_MEMBLOCK_FREE(char, xmlP); - xmlrpc_DECREF(v); - - xmlrpc_env_clean(&env); -} - - - -static void -testOneDouble(double const value) { - - /* Test serialize of a double. */ - - xmlrpc_env env; - xmlrpc_value * valueP; - xmlrpc_mem_block * serializedP; - char * result; - /* serialized result, as asciiz string */ - size_t resultLength; - /* Length in characters of the serialized result */ - double serializedValue; - char nextChar; - int itemsMatched; - - xmlrpc_env_init(&env); - - /* Build a double to serialize */ - valueP = xmlrpc_double_new(&env, value); - TEST_NO_FAULT(&env); - - /* Serialize the value. */ - serializedP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); - TEST_NO_FAULT(&env); - xmlrpc_serialize_value(&env, serializedP, valueP); - TEST_NO_FAULT(&env); - - /* Make sure we serialized the correct value. Note that because - doubles aren't precise, this might serialize as 3.1415899999 - or something like that. So we check it arithmetically. - */ - resultLength = XMLRPC_MEMBLOCK_SIZE(char, serializedP); - result = malloc(resultLength + 1); - - memcpy(result, XMLRPC_MEMBLOCK_CONTENTS(char, serializedP), resultLength); - result[resultLength] = '\0'; - - itemsMatched = sscanf(result, - "%lf\r\n%c", - &serializedValue, &nextChar); - - TEST(itemsMatched == 1); - TESTFLOATEQUAL(serializedValue, value); - - free(result); - - /* Clean up our value. */ - XMLRPC_TYPED_MEM_BLOCK_FREE(char, serializedP); - xmlrpc_DECREF(valueP); - - xmlrpc_env_clean(&env); -} - - - -static void -test_serialize_double(void) { - - testOneDouble(0); - testOneDouble(1); - testOneDouble(0.3); - testOneDouble(4.9); - testOneDouble(9.9999999); - testOneDouble(-8); - testOneDouble(-.7); - testOneDouble(-2.5); - testOneDouble(3.14159); - testOneDouble(1.2E37); - testOneDouble(1.2E-37); - testOneDouble(-5E200); -} - - - -static void -test_serialize_struct(void) { - - /* Serialize a simple struct. */ - - char const serialized_struct[] = - "\r\n" \ - "<&>\r\n" \ - "10\r\n" \ - ""; - - xmlrpc_env env; - xmlrpc_value * v; - xmlrpc_mem_block *output; - size_t size; - - xmlrpc_env_init(&env); - - v = xmlrpc_build_value(&env, "{s:i}", "<&>", (xmlrpc_int32) 10); - TEST_NO_FAULT(&env); - output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); - TEST_NO_FAULT(&env); - xmlrpc_serialize_value(&env, output, v); - TEST_NO_FAULT(&env); - - /* Make sure we serialized the correct value. */ - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); - TEST(size == strlen(serialized_struct)); - TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), - serialized_struct, size) == 0); - - /* Clean up our struct. */ - XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); - xmlrpc_DECREF(v); - - xmlrpc_env_clean(&env); -} - - - -void -test_serialize_value(void) { - - printf(" Running serialize value tests."); - - test_serialize_string(); - - test_serialize_double(); - - test_serialize_struct(); - - printf("\n"); - printf(" Serialize value tests done.\n"); -} diff --git a/trunk/test/serialize_value.h b/trunk/test/serialize_value.h deleted file mode 100644 index d976d076a..000000000 --- a/trunk/test/serialize_value.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef SERIALIZE_VALUE_H_INCLUDED -#define SERIALIZE_VALUE_H_INCLUDED - -void -test_serialize_value(void); - -#endif diff --git a/trunk/test/server_abyss.c b/trunk/test/server_abyss.c deleted file mode 100644 index 591a9880d..000000000 --- a/trunk/test/server_abyss.c +++ /dev/null @@ -1,277 +0,0 @@ -#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ - -#include "unistdx.h" -#include -#include "bool.h" - -#include "xmlrpc_config.h" - -#include "girstring.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "xmlrpc-c/abyss.h" -#include "xmlrpc-c/server_abyss.h" - -#include "testtool.h" - -#include "server_abyss.h" - - -static xmlrpc_call_processor myXmlProcessor; - -static void -myXmlProcessor(xmlrpc_env * const envP ATTR_UNUSED, - void * const processorArg ATTR_UNUSED, - const char * const callXml ATTR_UNUSED, - size_t const callXmlLen ATTR_UNUSED, - TSession * const abyssSessionP ATTR_UNUSED, - xmlrpc_mem_block ** const responseXmlPP ATTR_UNUSED) { - - printf("XML processor running\n"); -} - - - -static void -testSetHandlers(TServer * const abyssServerP) { - - xmlrpc_env env; - xmlrpc_registry * registryP; - xmlrpc_server_abyss_handler_parms parms; - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - TEST_NO_FAULT(&env); - TEST(registryP != NULL); - - parms.xml_processor = &myXmlProcessor; - parms.xml_processor_arg = NULL; - parms.xml_processor_max_stack = 512; - parms.uri_path = "/RPC6"; - parms.chunk_response = true; - parms.allow_origin = "*"; - - xmlrpc_server_abyss_set_handler3( - &env, abyssServerP, &parms, XMLRPC_AHPSIZE(xml_processor_arg)); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* Parms too short */ - xmlrpc_server_abyss_set_handler3( - &env, abyssServerP, &parms, XMLRPC_AHPSIZE(allow_origin)); - TEST_NO_FAULT(&env); - - xmlrpc_server_abyss_set_handler2(abyssServerP, "/RPC5", - &myXmlProcessor, NULL, 512, true); - - xmlrpc_server_abyss_set_handler(&env, abyssServerP, "/RPC3", registryP); - TEST_NO_FAULT(&env); - - xmlrpc_server_abyss_set_handlers2(abyssServerP, "/RPC4", registryP); - - xmlrpc_server_abyss_set_handlers(abyssServerP, registryP); - - xmlrpc_server_abyss_set_default_handler(abyssServerP); - - xmlrpc_registry_free(registryP); - - { - xmlrpc_registry * registryP; - registryP = xmlrpc_registry_new(&env); - xmlrpc_server_abyss_set_handlers(abyssServerP, registryP); - xmlrpc_registry_free(registryP); - } - xmlrpc_env_clean(&env); -} - - - -static void -testServerParms(void) { - xmlrpc_server_abyss_parms parms; - - struct sockaddr sockaddr; - - parms.config_file_name = NULL; - parms.registryP = NULL; - parms.port_number = 1000; - parms.max_conn = 10; - parms.max_conn_backlog = 10; - parms.keepalive_timeout = 5; - parms.keepalive_max_conn = 4; - parms.timeout = 50; - parms.dont_advertise = true; - parms.uri_path = "/RPC9"; - parms.chunk_response = true; - parms.allow_origin = "*"; - parms.access_ctl_expires = true; - parms.access_ctl_max_age = 5; - parms.sockaddr_p = &sockaddr; - parms.sockaddrlen = sizeof(sockaddr); - parms.log_file_name = "/tmp/xmlrpc_logfile"; - - if (parms.config_file_name) {} // Defeat set-but-unused compiler warning -}; - - - -static void -testObjectParm(void) { - - xmlrpc_env env; - - xmlrpc_server_abyss_parms parms; - xmlrpc_registry * registryP; - xmlrpc_server_abyss_t * serverP; - - xmlrpc_env_init(&env); - - xmlrpc_server_abyss_global_init(&env); - TEST_NO_FAULT(&env); - - registryP = xmlrpc_registry_new(&env); - TEST_NO_FAULT(&env); - - MEMSZERO(&parms); - - parms.registryP = registryP; - - xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(sockaddrlen), - &serverP); - - TEST_NO_FAULT(&env); - TEST(serverP != NULL); - - xmlrpc_server_abyss_destroy(serverP); - - xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(sockaddr_p), - &serverP); - - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* sockaddr_p w/o sockaddrlen */ - - parms.port_number = 100000; - - xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(sockaddrlen), - &serverP); - - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* port number too large */ - - xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(port_number), - &serverP); - - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* port number too large */ - { - struct sockaddr_in localhost; - localhost.sin_family = AF_INET; - localhost.sin_port = htons(8080); - localhost.sin_addr = test_ipAddrFromDecimal(127, 0, 0, 1); - - parms.sockaddr_p = (const struct sockaddr *)&localhost; - parms.sockaddrlen = sizeof(localhost); - - xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(sockaddrlen), - &serverP); - - TEST_NO_FAULT(&env); - TEST(serverP != NULL); - - xmlrpc_server_abyss_destroy(serverP); - } - xmlrpc_server_abyss_global_term(); - - xmlrpc_env_clean(&env); -} - - - -static void -testObject(void) { - - xmlrpc_env env; - xmlrpc_server_abyss_parms parms; - xmlrpc_server_abyss_t * serverP; - xmlrpc_registry * registryP; - xmlrpc_server_abyss_sig * oldHandlersP; - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - TEST_NO_FAULT(&env); - - parms.config_file_name = NULL; - parms.registryP = registryP; - - serverP = NULL; - - xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(registryP), - &serverP); - - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* Global init not done */ - - xmlrpc_server_abyss_global_init(&env); - TEST_NO_FAULT(&env); - - xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(registryP), - &serverP); - - TEST_NO_FAULT(&env); - TEST(serverP != NULL); - - xmlrpc_server_abyss_terminate(&env, serverP); - TEST_NO_FAULT(&env); - - xmlrpc_server_abyss_reset_terminate(&env, serverP); - TEST_NO_FAULT(&env); - - xmlrpc_server_abyss_setup_sig(&env, serverP, &oldHandlersP); - TEST_NO_FAULT(&env); - - xmlrpc_server_abyss_use_sigchld(serverP); - - xmlrpc_server_abyss_restore_sig(oldHandlersP); - TEST_NO_FAULT(&env); - - free(oldHandlersP); - - xmlrpc_server_abyss_destroy(serverP); - - xmlrpc_registry_free(registryP); - - xmlrpc_server_abyss_global_term(); - - xmlrpc_server_abyss_setup_sig(&env, serverP, &oldHandlersP); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* Not globally initialized */ - - testObjectParm(); - - xmlrpc_env_clean(&env); -} - - - -void -test_server_abyss(void) { - - TServer abyssServer; - - printf("Running Abyss XML-RPC server tests...\n"); - - ServerCreate(&abyssServer, "testserver", 8080, NULL, NULL); - - testSetHandlers(&abyssServer); - - ServerSetMaxConn(&abyssServer, 10); - ServerSetMaxConnBacklog(&abyssServer, 10); - ServerSetMaxSessionMem(&abyssServer, 64*1024); - ServerSetKeepaliveTimeout(&abyssServer, 60); - ServerSetKeepaliveMaxConn(&abyssServer, 10); - ServerSetTimeout(&abyssServer, 0); - ServerSetAdvertise(&abyssServer, false); - - ServerFree(&abyssServer); - - testServerParms(); - - testObject(); - - printf("\n"); - printf("Abyss XML-RPC server tests done.\n"); -} diff --git a/trunk/test/server_abyss.h b/trunk/test/server_abyss.h deleted file mode 100644 index 2cd527923..000000000 --- a/trunk/test/server_abyss.h +++ /dev/null @@ -1,2 +0,0 @@ -void -test_server_abyss(void); diff --git a/trunk/test/server_abyss_dummy.c b/trunk/test/server_abyss_dummy.c deleted file mode 100644 index 8394728e6..000000000 --- a/trunk/test/server_abyss_dummy.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#include "server_abyss.h" - - - -void -test_server_abyss(void) { - - printf("Running dummy Abyss XML-RPC server test\n"); - - printf("\n"); - printf("Abyss XML-RPC server tests done.\n"); -} diff --git a/trunk/test/test.c b/trunk/test/test.c deleted file mode 100644 index d130a733a..000000000 --- a/trunk/test/test.c +++ /dev/null @@ -1,740 +0,0 @@ -/* Copyright information is at the end of the file. */ - -#ifdef _WIN32 -# include -#else -# include -#endif -#include -#include -#include -#include -#include - -#include "casprintf.h" - -#include "xmlrpc_config.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server.h" -#include "xmlrpc-c/string_int.h" - -#include "bool.h" -#include "testtool.h" -#include "value.h" -#include "serialize.h" -#include "parse_xml.h" -#include "cgi.h" -#include "xml_data.h" -#include "client.h" -#include "abyss.h" -#include "server_abyss.h" -#include "method_registry.h" -#include "memblock.h" - -/*========================================================================= -** Test Harness -**========================================================================= -** This is a super light-weight test harness. It's vaguely inspired by -** Kent Beck's book on eXtreme Programming (XP)--the output is succinct, -** new tests can be coded quickly, and the whole thing runs in a few -** second's time. -** -** To run the tests, type './rpctest'. -** To check for memory leaks, install RedHat's 'memprof' utility, and -** type 'memprof rpctest'. -** -** If you add new tests to this file, please deallocate any data -** structures you use in the appropriate fashion. This allows us to test -** various destructor code for memory leaks. -*/ - -int total_tests = 0; -int total_failures = 0; - -bool const runningUnderWindows = -#ifdef _WIN32 - true; -#else - false; -#endif - - -/*========================================================================= -** Test Data -**========================================================================= -** Some common test data which need to be allocated at a fixed address, -** or which are inconvenient to allocate inline. -*/ - -static char* test_string_1 = "foo"; -static char* test_string_2 = "bar"; - -/*========================================================================= -** Test Suites -**========================================================================= -*/ - -static void -testVersion(void) { - - unsigned int major, minor, point; - - xmlrpc_version(&major, &minor, &point); - -#ifndef _WIN32 - /* xmlrpc_version_major, etc. are not exported from a Windows DLL */ - - TEST(major == xmlrpc_version_major); - TEST(minor == xmlrpc_version_minor); - TEST(point == xmlrpc_version_point); -#endif -} - - - -static void -testEnv(void) { - xmlrpc_env env, env2; - - /* Test xmlrpc_env_init. */ - xmlrpc_env_init(&env); - TEST(!env.fault_occurred); - TEST(env.fault_code == 0); - TEST(env.fault_string == NULL); - - /* Test xmlrpc_set_fault. */ - xmlrpc_env_set_fault(&env, 1, test_string_1); - TEST(env.fault_occurred); - TEST(env.fault_code == 1); - TEST(env.fault_string != test_string_1); - TEST(xmlrpc_streq(env.fault_string, test_string_1)); - - /* Change an existing fault. */ - xmlrpc_env_set_fault(&env, 2, test_string_2); - TEST(env.fault_occurred); - TEST(env.fault_code == 2); - TEST(xmlrpc_streq(env.fault_string, test_string_2)); - - /* Set a fault with a format string. */ - xmlrpc_env_set_fault_formatted(&env, 3, "a%s%d", "bar", 9); - TEST(env.fault_occurred); - TEST(env.fault_code == 3); - TEST(xmlrpc_streq(env.fault_string, "abar9")); - - /* Test cleanup code (with help from memprof). */ - xmlrpc_env_clean(&env); - - /* Test cleanup code on in absence of xmlrpc_env_set_fault. */ - xmlrpc_env_init(&env2); - xmlrpc_env_clean(&env2); -} - - - -static char *(base64_triplets[]) = { - "", "", "\r\n", - "a", "YQ==", "YQ==\r\n", - "aa", "YWE=", "YWE=\r\n", - "aaa", "YWFh", "YWFh\r\n", - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", - "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY" - "2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=", - "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY" - "2Rl\r\n" - "ZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=\r\n", - NULL}; - - - -static void -testBase64Conversion(void) { - - xmlrpc_env env; - char ** triplet; - - xmlrpc_env_init(&env); - - for (triplet = base64_triplets; *triplet != NULL; triplet += 3) { - char * bin_data; - char * nocrlf_ascii_data; - char * ascii_data; - xmlrpc_mem_block * output; - - bin_data = *triplet; - nocrlf_ascii_data = *(triplet + 1); - ascii_data = *(triplet + 2); - - /* Test our encoding routine. */ - output = xmlrpc_base64_encode(&env, - (unsigned char*) bin_data, - strlen(bin_data)); - TEST_NO_FAULT(&env); - TEST(output != NULL); - TEST(xmlrpc_mem_block_size(output) == strlen(ascii_data)); - TEST(memcmp(xmlrpc_mem_block_contents(output), ascii_data, - strlen(ascii_data)) == 0); - xmlrpc_mem_block_free(output); - - /* Test our newline-free encoding routine. */ - output = - xmlrpc_base64_encode_without_newlines(&env, - (unsigned char*) bin_data, - strlen(bin_data)); - TEST_NO_FAULT(&env); - TEST(output != NULL); - TEST(xmlrpc_mem_block_size(output) == strlen(nocrlf_ascii_data)); - TEST(memcmp(xmlrpc_mem_block_contents(output), nocrlf_ascii_data, - strlen(nocrlf_ascii_data)) == 0); - xmlrpc_mem_block_free(output); - - /* Test our decoding routine. */ - output = xmlrpc_base64_decode(&env, ascii_data, strlen(ascii_data)); - TEST_NO_FAULT(&env); - TEST(output != NULL); - TEST(xmlrpc_mem_block_size(output) == strlen(bin_data)); - TEST(memcmp(xmlrpc_mem_block_contents(output), bin_data, - strlen(bin_data)) == 0); - xmlrpc_mem_block_free(output); - } - - /* Now for something broken... */ - { - xmlrpc_env env2; - xmlrpc_mem_block * output; - - xmlrpc_env_init(&env2); - output = xmlrpc_base64_decode(&env2, "====", 4); - TEST(output == NULL); - TEST_FAULT(&env2, XMLRPC_PARSE_ERROR); - xmlrpc_env_clean(&env2); - } - /* Now for something broken in a really sneaky way... */ - { - xmlrpc_env env2; - xmlrpc_mem_block * output; - xmlrpc_env_init(&env2); - output = xmlrpc_base64_decode(&env2, "a==", 4); - TEST(output == NULL); - TEST_FAULT(&env2, XMLRPC_PARSE_ERROR); - xmlrpc_env_clean(&env2); - } - xmlrpc_env_clean(&env); -} - - - -static void -testBoundsChecks(void) { - - xmlrpc_env env; - xmlrpc_value *array; - int i1, i2, i3, i4; - - /* Get an array to work with. */ - xmlrpc_env_init(&env); - array = xmlrpc_build_value(&env, "(iii)", 100, 200, 300); - TEST_NO_FAULT(&env); - xmlrpc_env_clean(&env); - - /* Test xmlrpc_decompose_value with too few values. */ - xmlrpc_env_init(&env); - xmlrpc_decompose_value(&env, array, "(iiii)", &i1, &i2, &i3, &i4); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - xmlrpc_env_clean(&env); - - /* Test xmlrpc_decompose_value with too many values. */ - xmlrpc_env_init(&env); - xmlrpc_decompose_value(&env, array, "(ii)", &i1, &i2, &i3, &i4); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - xmlrpc_env_clean(&env); - - /* Dispose of our array. */ - xmlrpc_DECREF(array); -} - - - -static void -testNestingLimit(void) { - - xmlrpc_env env; - xmlrpc_value *val; - - xmlrpc_env_init(&env); - - /* Test with an adequate limit for a result value which is an - array which contains an element which is a struct, whose values - are simple: 3. - */ - xmlrpc_limit_set(XMLRPC_NESTING_LIMIT_ID, 3); - val = xmlrpc_parse_response(&env, - good_response_xml, strlen(good_response_xml)); - TEST_NO_FAULT(&env); - TEST(val != NULL); - xmlrpc_DECREF(val); - - /* Test with an inadequate limit. */ - xmlrpc_limit_set(XMLRPC_NESTING_LIMIT_ID, 2); - val = xmlrpc_parse_response(&env, - good_response_xml, strlen(good_response_xml)); - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); /* BREAKME - Will change. */ - TEST(val == NULL); - - /* Reset the default limit. */ - xmlrpc_limit_set(XMLRPC_NESTING_LIMIT_ID, XMLRPC_NESTING_LIMIT_DEFAULT); - TEST(xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID) - == XMLRPC_NESTING_LIMIT_DEFAULT); - - xmlrpc_env_clean(&env); -} - - - -static void -testXmlSizeLimit(void) { - - xmlrpc_env env; - const char * methodName; - xmlrpc_value * paramsP; - - /* NOTE - This test suite only verifies the last-ditch size-checking - code. There should also be matching code in all server (and - preferably all client) modules as well. - */ - - /* Set our XML size limit to something ridiculous. */ - xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, 6); - - /* Attempt to parse a call. */ - xmlrpc_env_init(&env); - xmlrpc_parse_call(&env, serialized_call, strlen(serialized_call), - &methodName, ¶msP); - TEST_FAULT(&env, XMLRPC_LIMIT_EXCEEDED_ERROR); - xmlrpc_env_clean(&env); - - { - xmlrpc_value * resultP; - int faultCode; - const char * faultString; - - /* Attempt to parse a response. */ - xmlrpc_env_init(&env); - xmlrpc_parse_response2(&env, - good_response_xml, strlen(good_response_xml), - &resultP, &faultCode, &faultString); - TEST_FAULT(&env, XMLRPC_LIMIT_EXCEEDED_ERROR); - xmlrpc_env_clean(&env); - } - /* Reset the default limit. */ - xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, XMLRPC_XML_SIZE_LIMIT_DEFAULT); -} - - - -/*========================================================================= -** test_sample_files -**========================================================================= -** Read in a bunch of sample test files and make sure we get plausible -** results. -** -** We use these files to test strange-but-legal encodings, illegal-but- -** allowed-by-Xmlrpc-c encodings, etc. -*/ - -/* The test program is designed to be run with the 'test' source directory - (which also contains the test program itself) as the current - directory. Except on Windows, where the Bin directory (which also contains - the test program itself) is supposed to be the current directory. -*/ -#define TESTDATA_DIR "data" - -static const char * goodRequests[] = { - TESTDATA_DIR DIRECTORY_SEPARATOR "req_out_of_order.xml", - TESTDATA_DIR DIRECTORY_SEPARATOR "req_no_params.xml", - TESTDATA_DIR DIRECTORY_SEPARATOR "req_value_name.xml", - NULL -}; - -#define MAX_SAMPLE_FILE_LEN (16 * 1024) - - - -static void -reportFileOpenError(const char * const path, - int const openErrno) { - - if (runningUnderWindows) { - char cwdname[1024]; - char * succeeded; - - succeeded = getcwd(cwdname, sizeof(cwdname)); - if (succeeded) - fprintf(stderr, "Running in current work directory '%s'\n", - cwdname); - } - fprintf(stderr, "Could not open file '%s'. errno=%d (%s)\n", - path, openErrno, strerror(openErrno)); -} - - - -static void -readFile(const char * const path, - const char ** const outDataP, - size_t * const outSizeP) { - - static char fileBuff[MAX_SAMPLE_FILE_LEN]; - - FILE * fileP; - size_t bytesRead; - - fileP = fopen(path, "r"); - - if (fileP == NULL) { - /* Since this error is fairly likely to happen, give an - informative error message... - */ - reportFileOpenError(path, errno); - exit(1); - } - - /* Read in one buffer full of data, and make sure that everything - fit. (We perform a lazy error/no-eof/zero-length-file test using - 'bytesRead'.) - */ - bytesRead = fread(fileBuff, sizeof(char), MAX_SAMPLE_FILE_LEN, fileP); - TEST(0 < bytesRead && bytesRead < MAX_SAMPLE_FILE_LEN); - - fclose(fileP); - - *outDataP = fileBuff; - *outSizeP = bytesRead; -} - - - -static void -testSampleFiles(void) { - - xmlrpc_env env; - const char ** pathP; - - xmlrpc_env_init(&env); - - /* Test our good requests. */ - - for (pathP = goodRequests; *pathP != NULL; ++pathP) { - const char * const path = *pathP; - - const char * data; - size_t dataLen; - const char * methodName; - xmlrpc_value * params; - - readFile(path, &data, &dataLen); - - xmlrpc_parse_call(&env, data, dataLen, &methodName, ¶ms); - - TEST_NO_FAULT(&env); - - strfree(methodName); - xmlrpc_DECREF(params); - } - - xmlrpc_env_clean(&env); -} - - -/*========================================================================= -** test_utf8_coding -**========================================================================= -** We need to test our UTF-8 decoder thoroughly. Most of these test -** cases are taken from the UTF-8-test.txt file by Markus Kuhn -** : -** http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt -*/ - -#if HAVE_UNICODE_WCHAR - -typedef struct { - char *utf8; - wchar_t wcs[16]; -} utf8_and_wcs; - -static utf8_and_wcs good_utf8[] = { - - /* Greek 'kosme'. */ - {"\316\272\341\275\271\317\203\316\274\316\265", - {0x03BA, 0x1F79, 0x03C3, 0x03BC, 0x03B5, 0}}, - - /* First sequences of a given length. */ - /* '\000' is not a legal C string. */ - {"\302\200", {0x0080, 0}}, - {"\340\240\200", {0x0800, 0}}, - - /* Last sequences of a given length. */ - {"\177", {0x007F, 0}}, - {"\337\277", {0x07FF, 0}}, - /* 0xFFFF is not a legal Unicode character. */ - - /* Other boundry conditions. */ - {"\001", {0x0001, 0}}, - {"\355\237\277", {0xD7FF, 0}}, - {"\356\200\200", {0xE000, 0}}, - {"\357\277\275", {0xFFFD, 0}}, - - /* Other random test cases. */ - {"", {0}}, - {"abc", {0x0061, 0x0062, 0x0063, 0}}, - {"[\302\251]", {0x005B, 0x00A9, 0x005D, 0}}, - - {NULL, {0}} -}; - -static char *(bad_utf8[]) = { - - /* Continuation bytes. */ - "\200", "\277", - - /* Lonely start characters. */ - "\300", "\300x", "\300xx", - "\340", "\340x", "\340xx", "\340xxx", - - /* Last byte missing. */ - "\340\200", "\340\200x", "\340\200xx", - "\357\277", "\357\277x", "\357\277xx", - - /* Illegal bytes. */ - "\376", "\377", - - /* Overlong '/'. */ - "\300\257", "\340\200\257", - - /* Overlong ASCII NUL. */ - "\300\200", "\340\200\200", - - /* Maximum overlong sequences. */ - "\301\277", "\340\237\277", - - /* Illegal code positions. */ - "\357\277\276", /* U+FFFE */ - "\357\277\277", /* U+FFFF */ - - /* UTF-16 surrogates (unpaired and paired). */ - "\355\240\200", - "\355\277\277", - "\355\240\200\355\260\200", - "\355\257\277\355\277\277", - - /* Valid UCS-4 characters (we don't handle these yet). - ** On systems with UCS-4 or UTF-16 wchar_t values, we - ** may eventually handle these in some fashion. */ - "\360\220\200\200", - "\370\210\200\200\200", - "\374\204\200\200\200\200", - - NULL -}; -#endif /* HAVE_UNICODE_WCHAR */ - -/* This routine is missing on certain platforms. This implementation -** *appears* to be correct. */ -#if 0 -#ifndef HAVE_WCSNCMP -int wcsncmp(wchar_t *wcs1, wchar_t* wcs2, size_t len) -{ - size_t i; - /* XXX - 'unsigned long' should be 'uwchar_t'. */ - unsigned long c1, c2; - for (i=0; i < len; i++) { - c1 = wcs1[i]; - c2 = wcs2[i]; - /* This clever comparison borrowed from the GNU C Library. */ - if (c1 == 0 || c1 != c2) - return c1 - c2; - } - return 0; -} -#endif /* HAVE_WCSNCMP */ -#endif - -static void -test_utf8_coding(void) { - -#if HAVE_UNICODE_WCHAR - xmlrpc_env env, env2; - utf8_and_wcs *good_data; - char **bad_data; - char *utf8; - wchar_t *wcs; - xmlrpc_mem_block *output; - - xmlrpc_env_init(&env); - - /* Test each of our valid UTF-8 sequences. */ - for (good_data = good_utf8; good_data->utf8 != NULL; good_data++) { - utf8 = good_data->utf8; - wcs = good_data->wcs; - - /* Attempt to validate the UTF-8 string. */ - xmlrpc_validate_utf8(&env, utf8, strlen(utf8)); - TEST_NO_FAULT(&env); - - /* Attempt to decode the UTF-8 string. */ - output = xmlrpc_utf8_to_wcs(&env, utf8, strlen(utf8)); - TEST_NO_FAULT(&env); - TEST(output != NULL); - TEST(wcslen(wcs) == XMLRPC_TYPED_MEM_BLOCK_SIZE(wchar_t, output)); - TEST(0 == - wcsncmp(wcs, XMLRPC_TYPED_MEM_BLOCK_CONTENTS(wchar_t, output), - wcslen(wcs))); - xmlrpc_mem_block_free(output); - - /* Test the UTF-8 encoder, too. */ - output = xmlrpc_wcs_to_utf8(&env, wcs, wcslen(wcs)); - TEST_NO_FAULT(&env); - TEST(output != NULL); - TEST(strlen(utf8) == XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output)); - TEST(xmlrpc_strneq(utf8, XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), - strlen(utf8))); - xmlrpc_mem_block_free(output); - } - - /* Test each of our illegal UTF-8 sequences. */ - for (bad_data = bad_utf8; *bad_data != NULL; bad_data++) { - utf8 = *bad_data; - - /* Attempt to validate the UTF-8 string. */ - xmlrpc_env_init(&env2); - xmlrpc_validate_utf8(&env2, utf8, strlen(utf8)); - TEST_FAULT(&env2, XMLRPC_INVALID_UTF8_ERROR); - /* printf("Fault: %s\n", env2.fault_string); --Hand-checked */ - xmlrpc_env_clean(&env2); - - /* Attempt to decode the UTF-8 string. */ - xmlrpc_env_init(&env2); - output = xmlrpc_utf8_to_wcs(&env2, utf8, strlen(utf8)); - TEST_FAULT(&env2, XMLRPC_INVALID_UTF8_ERROR); - TEST(output == NULL); - xmlrpc_env_clean(&env2); - } - xmlrpc_env_clean(&env); -#endif /* HAVE_UNICODE_WCHAR */ -} - - - -static void -test_server_cgi_maybe(void) { - -#ifndef _WIN32 - - test_server_cgi(); - -#endif -} - - - -static void -test_client_maybe(void) { - -#ifndef _WIN32 /* Must get Windows Curl transport working for this to work */ - - test_client(); - -#endif -} - - - -int -main(int argc, - char ** argv ATTR_UNUSED) { - - int retval; - - if (argc-1 > 0) { - fprintf(stderr, "There are no arguments.\n"); - retval = 1; - } else { - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_init(&env); - testVersion(); - testEnv(); - printf("\n"); - test_memBlock(); - testBase64Conversion(); - printf("\n"); - test_value(); - testBoundsChecks(); - printf("\n"); - test_serialize(); - test_parse_xml(); - test_method_registry(); - testNestingLimit(); - testXmlSizeLimit(); - testSampleFiles(); - printf("\n"); - test_server_cgi_maybe(); - test_abyss(); - test_server_abyss(); - - test_utf8_coding(); - - printf("\n"); - - test_client_maybe(); - - printf("\n"); - - xmlrpc_term(); - - /* Summarize our test run. */ - printf("Ran %d tests, %d failed, %.1f%% passed\n", - total_tests, total_failures, - 100.0 - (100.0 * total_failures) / total_tests); - - /* Print the final result. */ - if (total_failures == 0) { - printf("OK\n"); - retval = 0; - } else { - retval = 1; - printf("FAILED\n"); - } - xmlrpc_env_clean(&env); - } - return retval; -} - - - - -/* 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. */ diff --git a/trunk/test/testtool.c b/trunk/test/testtool.c deleted file mode 100644 index 5aeca8af4..000000000 --- a/trunk/test/testtool.c +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#ifdef _WIN32 -# include -# include -#else -# include -#endif - -#include "xmlrpc_config.h" -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/util_int.h" - -#include "testtool.h" - /* Defines global variable, 'total_tests', 'total_failures' */ - - -/* This is a good place to set a breakpoint. */ -void -test_failure(const char * const file, - unsigned int const line, - const char * const label, - const char * const statement) { - - ++total_failures; - printf("\n%s:%u: test failure: %s (%s)\n", file, line, label, statement); - - /* We abort rather than exit so one can tell from a dump or debug session - who called us. - */ - abort(); -} - - - -void -test_fault(xmlrpc_env * const envP, - int const expectedCode, - const char * const fileName, - unsigned int const lineNumber) { - - ++total_tests; - - if (!envP->fault_occurred) - test_failure(fileName, lineNumber, "no fault occurred", ""); - else if (envP->fault_code != expectedCode) - test_failure(fileName, lineNumber, "wrong fault occurred", - envP->fault_string); - else - printf("."); - - xmlrpc_env_clean(envP); - xmlrpc_env_init(envP); -} - - - -void -test_null_string(const char * const string, - const char * const fileName, - unsigned int const lineNumber) { - - ++total_tests; - - if (string != NULL) - test_failure(fileName, lineNumber, "string not null", string); - else - printf("."); -} - - - -struct in_addr -test_ipAddrFromDecimal(unsigned int const byte0, - unsigned int const byte1, - unsigned int const byte2, - unsigned int const byte3) { - - struct in_addr retval; - - retval.s_addr = - htonl((byte0 << 24) + (byte1 << 16) + (byte2 << 8) + (byte3 << 0)); - - return retval; -} - - - diff --git a/trunk/test/testtool.h b/trunk/test/testtool.h deleted file mode 100644 index abf5a42ec..000000000 --- a/trunk/test/testtool.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef TESTTOOL_H_INCLUDED -#define TESTTOOL_H_INCLUDED - -#include -#include -#include - -#ifdef _WIN32 -# include -# include -#else -#include -#endif - -#include "xmlrpc-c/util.h" -#include "xmlrpc-c/util_int.h" - -extern int total_tests; -extern int total_failures; - - -void -test_failure(const char * const file, - unsigned int const line, - const char * const label, - const char * const statement); - -void -test_fault(xmlrpc_env * const envP, - int const expectedCode, - const char * const fileName, - unsigned int const lineNumber); - -void -test_null_string(const char * const string, - const char * const fileName, - unsigned int const lineNumber); - -#define TEST(statement) \ -do { \ - ++total_tests; \ - if ((statement)) { \ - printf("."); \ - } else { \ - test_failure(__FILE__, __LINE__, "expected", #statement); \ - } \ - } while (0) - -#define TEST_NO_FAULT(env) \ - do { \ - ++total_tests; \ - if (!(env)->fault_occurred) { \ - printf("."); \ - } else { \ - test_failure(__FILE__, __LINE__, "fault occurred", \ - (env)->fault_string); \ - } \ - } while (0) - -#define TEST_EPSILON 1E-5 - -#define FORCENONZERO(x) (MAX(fabs(x), TEST_EPSILON)) - -#define FLOATEQUAL(comparand, comparator) \ - ((fabs((comparand)-(comparator)))/FORCENONZERO(comparand) < TEST_EPSILON) -#define TESTFLOATEQUAL(comparand, comparator) \ - TEST(FLOATEQUAL(comparand, comparator)) - -#define TEST_FAULT(envP, code) \ - do { test_fault(envP, code, __FILE__, __LINE__); } while(0) - -; - -#define TEST_NULL_STRING(string) \ - do { test_null_string(string, __FILE__, __LINE__); } while(0) - -; - -#define TEST_ERROR(reason) \ -do { \ - printf("Unable to test at %s/%u. %s", __FILE__, __LINE__, reason); \ - abort(); \ - } while (0) - -; - -struct in_addr -test_ipAddrFromDecimal(unsigned int const byte0, - unsigned int const byte1, - unsigned int const byte2, - unsigned int const byte3); - -#endif diff --git a/trunk/test/value.c b/trunk/test/value.c deleted file mode 100644 index 8c786058f..000000000 --- a/trunk/test/value.c +++ /dev/null @@ -1,2043 +0,0 @@ -/* Copyright information is at the end of the file. */ - -#include -#include -#include -#include - -#include "casprintf.h" -#include "girstring.h" - -#include "xmlrpc_config.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/string_int.h" - -#include "testtool.h" -#include "value_datetime.h" - -#include "value.h" - - -#if HAVE_UNICODE_WCHAR - -static bool -wcsneq(const wchar_t * const comparand, - const wchar_t * const comparator, - size_t const length) { - - return(wcsncmp(comparand, comparator, length) == 0); -} - -#endif /* HAVE_UNICODE_WCHAR */ - -static void -test_value_alloc_dealloc(void) { - - xmlrpc_value * v; - xmlrpc_env env; - - xmlrpc_env_init(&env); - - /* Test allocation and deallocation (w/memprof). */ - v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 5); - TEST_NO_FAULT(&env); - TEST(v != NULL); - xmlrpc_INCREF(v); - xmlrpc_DECREF(v); - xmlrpc_DECREF(v); - - xmlrpc_env_clean(&env); -} - - -static void -test_value_int(void) { - - xmlrpc_value * v; - xmlrpc_value * v2; - xmlrpc_env env; - xmlrpc_int32 i; - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_INT), "INT")); - - v = xmlrpc_int_new(&env, (xmlrpc_int32) 25); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_INT); - xmlrpc_read_int(&env, v, &i); - TEST_NO_FAULT(&env); - TEST(i == 25); - xmlrpc_DECREF(v); - - v = xmlrpc_int_new(&env, (xmlrpc_int32) -25); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_INT); - xmlrpc_read_int(&env, v, &i); - TEST_NO_FAULT(&env); - TEST(i == -25); - xmlrpc_DECREF(v); - - v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 10); - TEST_NO_FAULT(&env); - TEST(v != NULL); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_INT); - xmlrpc_decompose_value(&env, v, "i", &i); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(i == 10); - - v = xmlrpc_int_new(&env, (xmlrpc_int32) 25); - TEST_NO_FAULT(&env); - v2 = xmlrpc_value_new(&env, v); - TEST_NO_FAULT(&env); - xmlrpc_DECREF(v); - TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_INT); - xmlrpc_read_int(&env, v2, &i); - TEST_NO_FAULT(&env); - TEST(i == 25); - xmlrpc_DECREF(v2); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_bool(void) { - - xmlrpc_value * v; - xmlrpc_value * v2; - xmlrpc_env env; - xmlrpc_bool b; - - /* Test booleans. */ - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_BOOL), "BOOL")); - - v = xmlrpc_bool_new(&env, (xmlrpc_bool) 1); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v)); - xmlrpc_read_bool(&env, v, &b); - TEST_NO_FAULT(&env); - TEST(b); - xmlrpc_DECREF(v); - - v = xmlrpc_build_value(&env, "b", (xmlrpc_bool) 0); - TEST_NO_FAULT(&env); - TEST(v != NULL); - TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v)); - xmlrpc_decompose_value(&env, v, "b", &b); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(!b); - - v = xmlrpc_bool_new(&env, (xmlrpc_bool) 1); - TEST_NO_FAULT(&env); - v2 = xmlrpc_value_new(&env, v); - TEST_NO_FAULT(&env); - xmlrpc_DECREF(v); - TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v2)); - xmlrpc_read_bool(&env, v2, &b); - TEST_NO_FAULT(&env); - TEST(b); - xmlrpc_DECREF(v2); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_double(void) { - - xmlrpc_value * v; - xmlrpc_value * v2; - xmlrpc_env env; - double d; - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_DOUBLE), "DOUBLE")); - - v = xmlrpc_double_new(&env, -3.25); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v)); - xmlrpc_read_double(&env, v, &d); - TEST_NO_FAULT(&env); - TEST(d == -3.25); - xmlrpc_DECREF(v); - - v = xmlrpc_build_value(&env, "d", 1.0); - TEST_NO_FAULT(&env); - TEST(v != NULL); - TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v)); - xmlrpc_decompose_value(&env, v, "d", &d); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(d == 1.0); - - v = xmlrpc_double_new(&env, -3.25); - TEST_NO_FAULT(&env); - v2 = xmlrpc_value_new(&env, v); - xmlrpc_DECREF(v); - TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v2)); - xmlrpc_read_double(&env, v2, &d); - TEST_NO_FAULT(&env); - TEST(d == -3.25); - xmlrpc_DECREF(v2); - - /* Older compilers don't have INFINITY and NAN, so we compute them here. - But newer compilers recognize an error if they see you dividing by - zero, so we have to make it nonobvious that we're doing that. - */ - double const zero = sin(0); - - v = xmlrpc_double_new(&env, 1.0/zero); /* +INFINITY */ - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - v = xmlrpc_double_new(&env, -1.0/zero); /* -INFINITY */ - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - v = xmlrpc_double_new(&env, 0.0/zero); /* NAN */ - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_env_clean(&env); -} - - - -static xmlrpc_value * -test_string_new_va(xmlrpc_env * const envP, - const char * const format, - ...) { - - va_list args; - - xmlrpc_value * v; - - va_start(args, format); - - v = xmlrpc_string_new_va(envP, format, args); - - va_end(args); - - return v; -} - - - -static void -test_value_string_no_null(void) { - - /* Test strings (without '\0' bytes). */ - - xmlrpc_value * v; - xmlrpc_env env; - const char * str; - size_t len; - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_STRING), "STRING")); - - { - const char * const simpleAsciiString = "foo"; - v = xmlrpc_string_new(&env, simpleAsciiString); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_STRING); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, simpleAsciiString)); - xmlrpc_DECREF(v); - strfree(str); - } - { - const char * const utf8String = "KOŚĆ"; - v = xmlrpc_string_new(&env, utf8String); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_STRING); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, utf8String)); - xmlrpc_DECREF(v); - strfree(str); - } - v = xmlrpc_string_new_f(&env, "String %s, number %d", "xyz", 7); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_STRING); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "String xyz, number 7")); - xmlrpc_DECREF(v); - strfree(str); - - v = test_string_new_va(&env, "String %s, number %d", "xyz", 7); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_STRING); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "String xyz, number 7")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_build_value(&env, "s", "foo"); - - TEST_NO_FAULT(&env); - TEST(v != NULL); - TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v)); - - xmlrpc_decompose_value(&env, v, "s", &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo")); - strfree(str); - - xmlrpc_decompose_value(&env, v, "s#", &str, &len); - TEST_NO_FAULT(&env); - TEST(len == strlen("foo")); - TEST(xmlrpc_streq(str, "foo")); - TEST(strlen(str) == strlen("foo")); - strfree(str); - - xmlrpc_DECREF(v); - - { - const char * const simpleAsciiString = "foo"; - xmlrpc_value * v2; - v = xmlrpc_string_new(&env, simpleAsciiString); - TEST_NO_FAULT(&env); - v2 = xmlrpc_value_new(&env, v); - TEST_NO_FAULT(&env); - xmlrpc_DECREF(v); - TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_STRING); - xmlrpc_read_string(&env, v2, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, simpleAsciiString)); - xmlrpc_DECREF(v2); - strfree(str); - } - xmlrpc_env_clean(&env); -} - - - -static void -test_value_string_null(void) { - - xmlrpc_value * v; - xmlrpc_env env; - xmlrpc_env env2; - const char * str; - size_t len; - - /* Test a string with a '\0' byte. */ - - xmlrpc_env_init(&env); - - v = xmlrpc_string_new_lp(&env, 7, "foo\0bar"); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v)); - xmlrpc_read_string_lp(&env, v, &len, &str); - TEST_NO_FAULT(&env); - TEST(len == 7); - TEST(memeq(str, "foo\0bar", 7)); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_build_value(&env, "s#", "foo\0bar", (size_t) 7); - TEST_NO_FAULT(&env); - TEST(v != NULL); - TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v)); - - xmlrpc_decompose_value(&env, v, "s#", &str, &len); - TEST_NO_FAULT(&env); - TEST(memeq(str, "foo\0bar", 7)); - TEST(len == 7); - strfree(str); - - /* Test for type error when decoding a string with a zero byte to a - ** regular C string. */ - xmlrpc_env_init(&env2); - xmlrpc_decompose_value(&env2, v, "s", &str); - TEST_FAULT(&env2, XMLRPC_TYPE_ERROR); - xmlrpc_env_clean(&env2); - xmlrpc_DECREF(v); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_string_multiline(void) { - - xmlrpc_env env; - xmlrpc_value * v; - const char * str; - size_t len; - - xmlrpc_env_init(&env); - - /* LF line ending */ - - v = xmlrpc_string_new(&env, "foo\n"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\n")); - strfree(str); - xmlrpc_read_string_crlf(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\r\n")); - strfree(str); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new(&env, "foo\n\n"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\n\n")); - strfree(str); - xmlrpc_read_string_crlf(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\r\n\r\n")); - strfree(str); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new(&env, "foo\nbar"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\nbar")); - strfree(str); - xmlrpc_read_string_crlf(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\r\nbar")); - strfree(str); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new(&env, "foo\nbar\n"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\nbar\n")); - strfree(str); - xmlrpc_read_string_crlf(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\r\nbar\r\n")); - strfree(str); - xmlrpc_DECREF(v); - - v = xmlrpc_string_new(&env, "foo\nbar\nbaz"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\nbar\nbaz")); - strfree(str); - xmlrpc_read_string_crlf(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\r\nbar\r\nbaz")); - strfree(str); - xmlrpc_DECREF(v); - - /* CR line ending */ - - v = xmlrpc_string_new(&env, "foo\r"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\n")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_string_new(&env, "foo\r\r"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\n\n")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_string_new(&env, "foo\rbar"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\nbar")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_string_new(&env, "foo\rbar\r"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\nbar\n")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_string_new(&env, "foo\rbar\rbaz"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\nbar\nbaz")); - xmlrpc_DECREF(v); - strfree(str); - - /* CRLF line ending */ - - v = xmlrpc_string_new(&env, "foo\r\n"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\n")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_string_new(&env, "foo\r\n\r\n"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\n\n")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_string_new(&env, "foo\r\nbar"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\nbar")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_string_new(&env, "foo\r\nbar\r\n"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\nbar\n")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_string_new(&env, "foo\r\nbar\r\nbaz"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\nbar\nbaz")); - xmlrpc_DECREF(v); - strfree(str); - - /* Embedded null */ - - v = xmlrpc_string_new_lp(&env, 14, "foo\r\n\0bar\r\nbaz"); - TEST_NO_FAULT(&env); - xmlrpc_read_string_lp(&env, v, &len, &str); - TEST_NO_FAULT(&env); - TEST(len == 12); - TEST(memeq(str, "foo\n\0bar\nbaz", len)); - strfree(str); - xmlrpc_read_string_lp_crlf(&env, v, &len, &str); - TEST_NO_FAULT(&env); - TEST(len == 14); - TEST(memeq(str, "foo\r\n\0bar\r\nbaz", len)); - strfree(str); - xmlrpc_DECREF(v); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_string_cr(void) { - - xmlrpc_env env; - xmlrpc_value * v; - const char * str; - size_t len; - - xmlrpc_env_init(&env); - v = xmlrpc_string_new_cr(&env, "foo\r\nbar\r\nbaz"); - TEST_NO_FAULT(&env); - xmlrpc_read_string(&env, v, &str); - TEST_NO_FAULT(&env); - TEST(streq(str, "foo\r\nbar\r\nbaz")); - xmlrpc_DECREF(v); - strfree(str); - - v = xmlrpc_string_new_lp_cr(&env, 7, "\0foo\rbar"); - TEST_NO_FAULT(&env); - xmlrpc_read_string_lp(&env, v, &len, &str); - TEST_NO_FAULT(&env); - TEST(len == 7); - TEST(memeq(str, "\0foo\rbar", len)); - xmlrpc_DECREF(v); - strfree(str); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_string_ctlchar(void) { - - xmlrpc_env env; - xmlrpc_value * vCtl; - xmlrpc_value * vNoCtl; - - xmlrpc_env_init(&env); - vNoCtl = xmlrpc_string_new(&env, "foo bar"); - TEST_NO_FAULT(&env); - - xmlrpc_string_validate(&env, vNoCtl); - TEST_NO_FAULT(&env); - - xmlrpc_env_init(&env); - vCtl = xmlrpc_string_new(&env, "foo\x18 bar"); - TEST_NO_FAULT(&env); - - xmlrpc_string_validate(&env, vCtl); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_DECREF(vNoCtl); - xmlrpc_DECREF(vCtl); - - xmlrpc_env_clean(&env); -} - - - -#if HAVE_UNICODE_WCHAR - -/* Here is a 3-character, NUL-terminated string, once in UTF-8 chars, - and once in UTF-16 wchar_ts. Note that 2 of the UTF-16 characters - translate directly to UTF-8 bytes because only the lower 7 bits of - each is nonzero, but the middle UTF-16 character translates to two - UTF-8 bytes. -*/ -static char utf8_data[] = "[\xC2\xA9]"; -static wchar_t wcs_data[] = {'[', 0x00A9, ']', 0x0000}; - -static void -test_value_string_wide_build(void) { - - xmlrpc_env env; - xmlrpc_value * valueP; - const wchar_t * wcs; - size_t len; - - xmlrpc_env_init(&env); - - /* Build with build_value w# */ - valueP = xmlrpc_build_value(&env, "w#", wcs_data, (size_t)3); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - - /* Verify it */ - xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(wcs != NULL); - TEST(len == 3); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_data, len)); - free((void*)wcs); - - xmlrpc_DECREF(valueP); - - /* Build with build_value w */ - valueP = xmlrpc_build_value(&env, "w", wcs_data); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - - /* Verify it */ - xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(wcs != NULL); - TEST(len == 3); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_data, len)); - free((void*)wcs); - - xmlrpc_DECREF(valueP); -} -#endif /* HAVE_UNICODE_WCHAR */ - - -static void -test_value_string_wide_line(void) { - /* Test with various line delimiters */ - -#if HAVE_UNICODE_WCHAR - xmlrpc_env env; - xmlrpc_value * valueP; - const wchar_t * wcs; - size_t len; - - wchar_t const wcs_lines[] = {'\n', '\r', '\r', '\n', '\0'}; - wchar_t const wcs_lines_lf[] = {'\n', '\n', '\n'}; - wchar_t const wcs_lines_crlf[] = { - '\r', '\n', '\r', '\n', '\r', '\n' }; - - xmlrpc_env_init(&env); - - valueP = xmlrpc_string_w_new(&env, wcs_lines); - TEST_NO_FAULT(&env); - - xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(len == 3); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_lines_lf, len)); - free((void*)wcs); - - xmlrpc_read_string_w_lp_crlf(&env, valueP, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(len == 6); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_lines_crlf, len)); - free((void*)wcs); - - xmlrpc_DECREF(valueP); - - valueP = xmlrpc_string_w_new_cr(&env, wcs_lines); - TEST_NO_FAULT(&env); - - xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(len == 4); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_lines, len)); - free((void*)wcs); - - xmlrpc_DECREF(valueP); - - xmlrpc_env_clean(&env); -#endif /* HAVE_UNICODE_WCHAR */ -} - - - -static void -test_value_string_wide(void) { - -#if HAVE_UNICODE_WCHAR - xmlrpc_env env; - xmlrpc_value * valueP; - xmlrpc_value * value2P; - const wchar_t * wcs; - size_t len; - - xmlrpc_env_init(&env); - - /* Build a string from wchar_t data. */ - valueP = xmlrpc_string_w_new_lp(&env, 3, wcs_data); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - - /* Extract it as a wchar_t string. */ - xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(wcs != NULL); - TEST(len == 3); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_data, len)); - free((void*)wcs); - - xmlrpc_read_string_w(&env, valueP, &wcs); - TEST_NO_FAULT(&env); - TEST(wcs != NULL); - TEST(wcs[3] == '\0'); - TEST(wcsneq(wcs, wcs_data, 3)); - free((void*)wcs); - - xmlrpc_decompose_value(&env, valueP, "w#", &wcs, &len); - TEST_NO_FAULT(&env); - TEST(wcs != NULL); - TEST(len == 3); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_data, len)); - free((void*)wcs); - - { - /* Extract it as a UTF-8 string. */ - const char * str; - size_t len; - - xmlrpc_read_string_lp(&env, valueP, &len, &str); - TEST_NO_FAULT(&env); - TEST(str != NULL); - TEST(len == 4); - TEST(str[len] == '\0'); - TEST(xmlrpc_strneq(str, utf8_data, len)); - free((void*)str); - } - - xmlrpc_DECREF(valueP); - - /* Build from null-terminated wchar_t string */ - valueP = xmlrpc_string_w_new(&env, wcs_data); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - - /* Verify it */ - xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(wcs != NULL); - TEST(len == 3); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_data, len)); - free((void*)wcs); - - xmlrpc_DECREF(valueP); - - test_value_string_wide_build(); - - /* Build a string from UTF-8 data. */ - valueP = xmlrpc_string_new(&env, utf8_data); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - - /* Extract it as a wchar_t string. */ - xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(wcs != NULL); - TEST(len == 3); - TEST(wcs[len] == 0x0000); - TEST(wcsneq(wcs, wcs_data, len)); - free((void*)wcs); - xmlrpc_DECREF(valueP); - - /* Test with embedded NUL. We use a length of 4 so that the terminating - NUL actually becomes part of the string. - */ - valueP = xmlrpc_string_w_new_lp(&env, 4, wcs_data); - TEST_NO_FAULT(&env); - TEST(valueP != NULL); - - /* Extract it as a wchar_t string. */ - xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(wcs != NULL); - TEST(len == 4); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_data, len)); - free((void*)wcs); - - xmlrpc_read_string_w(&env, valueP, &wcs); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - value2P = xmlrpc_value_new(&env, valueP); - TEST_NO_FAULT(&env); - - xmlrpc_read_string_w_lp(&env, value2P, &len, &wcs); - TEST_NO_FAULT(&env); - TEST(wcs != NULL); - TEST(len == 4); - TEST(wcs[len] == '\0'); - TEST(wcsneq(wcs, wcs_data, len)); - free((void*)wcs); - xmlrpc_DECREF(value2P); - - xmlrpc_DECREF(valueP); - - test_value_string_wide_line(); - - xmlrpc_env_clean(&env); -#endif /* HAVE_UNICODE_WCHAR */ -} - - - -static void -test_value_base64(void) { - - /* Test data. */ - - unsigned char const data1[5] = {'a', '\0', 'b', '\n', 'c'}; - unsigned char const data2[3] = {'a', '\0', 'b'}; - - xmlrpc_value * v; - xmlrpc_value * v2; - xmlrpc_env env; - const unsigned char * data; - size_t len; - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_BASE64), "BASE64")); - - v = xmlrpc_base64_new(&env, sizeof(data1), data1); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v)); - xmlrpc_read_base64(&env, v, &len, &data); - TEST_NO_FAULT(&env); - TEST(memeq(data, data1, sizeof(data1))); - TEST(len == sizeof(data1)); - xmlrpc_DECREF(v); - free((void*)data); - - v = xmlrpc_build_value(&env, "6", data2, sizeof(data2)); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v)); - xmlrpc_decompose_value(&env, v, "6", &data, &len); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(len == sizeof(data2)); - TEST(memeq(data, data1, sizeof(data2))); - free((void *)data); - - v = xmlrpc_base64_new(&env, sizeof(data1), data1); - TEST_NO_FAULT(&env); - v2 = xmlrpc_value_new(&env, v); - TEST_NO_FAULT(&env); - xmlrpc_DECREF(v); - TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v2)); - xmlrpc_read_base64(&env, v2, &len, &data); - TEST_NO_FAULT(&env); - TEST(memeq(data, data1, sizeof(data1))); - TEST(len == sizeof(data1)); - xmlrpc_DECREF(v2); - free((void*)data); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_value(void) { - - xmlrpc_value *v, *v2, *v3; - xmlrpc_env env; - - /* Test 'V' with building and parsing. */ - - xmlrpc_env_init(&env); - - v2 = xmlrpc_int_new(&env, (xmlrpc_int32) 5); - TEST_NO_FAULT(&env); - v = xmlrpc_build_value(&env, "V", v2); - TEST_NO_FAULT(&env); - TEST(v == v2); - xmlrpc_decompose_value(&env, v2, "V", &v3); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(v2 == v3); - xmlrpc_DECREF(v3); - xmlrpc_DECREF(v2); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_array(void) { - - xmlrpc_value * v; - xmlrpc_value * v2; - xmlrpc_env env; - size_t len; - xmlrpc_value * itemP; - - /* Basic array-building test. */ - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_ARRAY), "ARRAY")); - - v = xmlrpc_array_new(&env); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); - len = xmlrpc_array_size(&env, v); - TEST_NO_FAULT(&env); - TEST(len == 0); - - itemP = xmlrpc_int_new(&env, 7); - TEST_NO_FAULT(&env); - xmlrpc_array_append_item(&env, v, itemP); - TEST_NO_FAULT(&env); - len = xmlrpc_array_size(&env, v); - TEST_NO_FAULT(&env); - TEST(len == 1); - xmlrpc_DECREF(itemP); - - v2 = xmlrpc_value_new(&env, v); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); - len = xmlrpc_array_size(&env, v); - TEST_NO_FAULT(&env); - TEST(len == 1); - xmlrpc_DECREF(v2); - - xmlrpc_DECREF(v); - - v = xmlrpc_build_value(&env, "()"); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); - len = xmlrpc_array_size(&env, v); - TEST_NO_FAULT(&env); - TEST(len == 0); - xmlrpc_DECREF(v); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_AS(void) { - - xmlrpc_value *v; - xmlrpc_value *v2; - xmlrpc_value *v3; - xmlrpc_env env; - size_t len; - - /* Test parsing of 'A' and 'S'. */ - - xmlrpc_env_init(&env); - - v = xmlrpc_build_value(&env, "((){})"); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, v, "(AS)", &v2, &v3); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v2)); - TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(v3)); - len = xmlrpc_array_size(&env, v2); - TEST_NO_FAULT(&env); - TEST(len == 0); - len = xmlrpc_struct_size(&env, v3); - TEST_NO_FAULT(&env); - TEST(len == 0); - xmlrpc_DECREF(v2); - xmlrpc_DECREF(v3); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_AS_typecheck(void) { - - xmlrpc_env env; - xmlrpc_env env2; - xmlrpc_value *v; - xmlrpc_value *v2; - - /* Test typechecks for 'A' and 'S'. */ - - xmlrpc_env_init(&env); - xmlrpc_env_init(&env2); - - v = xmlrpc_build_value(&env, "s", "foo"); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env2, v, "A", &v2); - TEST_FAULT(&env2, XMLRPC_TYPE_ERROR); - - xmlrpc_decompose_value(&env2, v, "S", &v2); - TEST_FAULT(&env2, XMLRPC_TYPE_ERROR); - xmlrpc_DECREF(v); - xmlrpc_env_clean(&env2); - xmlrpc_env_clean(&env); -} - - - -static void -test_value_array2(void) { - - xmlrpc_value * arrayP; - xmlrpc_env env; - xmlrpc_int32 i, i1, i2, i3, i4, i5; - xmlrpc_value * itemP; - xmlrpc_value * subarrayP; - size_t len; - - /* A more complex array. */ - - xmlrpc_env_init(&env); - - arrayP = xmlrpc_build_value(&env, "(i(ii)i)", - (xmlrpc_int32) 10, (xmlrpc_int32) 20, - (xmlrpc_int32) 30, (xmlrpc_int32) 40); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP)); - - len = xmlrpc_array_size(&env, arrayP); - TEST_NO_FAULT(&env); - TEST(len == 3); - - xmlrpc_array_read_item(&env, arrayP, 1, &subarrayP); - TEST_NO_FAULT(&env); - - len = xmlrpc_array_size(&env, subarrayP); - TEST_NO_FAULT(&env); - TEST(len == 2); - - xmlrpc_array_read_item(&env, subarrayP, 0, &itemP); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, itemP, "i", &i); - xmlrpc_DECREF(itemP); - TEST_NO_FAULT(&env); - TEST(i == 20); - - xmlrpc_DECREF(subarrayP); - - itemP = xmlrpc_array_get_item(&env, arrayP, 0); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, itemP, "i", &i); - TEST_NO_FAULT(&env); - TEST(i == 10); - - xmlrpc_decompose_value(&env, arrayP, "(i(ii)i)", &i1, &i2, &i3, &i4); - TEST_NO_FAULT(&env); - TEST(i1 == 10 && i2 == 20 && i3 == 30 && i4 == 40); - - xmlrpc_decompose_value(&env, arrayP, "(i(i*)i)", &i1, &i2, &i3); - TEST_NO_FAULT(&env); - TEST(i1 == 10 && i2 == 20 && i3 == 40); - - xmlrpc_decompose_value(&env, arrayP, "(i(ii*)i)", &i1, &i2, &i3, &i4); - TEST_NO_FAULT(&env); - - xmlrpc_decompose_value(&env, arrayP, "(i(iii)i)", &i1, &i2, &i3, &i4, &i5); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_decompose_value(&env, arrayP, "(i(i)i)", &i1, &i2, &i3, &i4, &i5); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_decompose_value(&env, arrayP, "(i(ii)i*i)", - &i1, &i2, &i3, &i4, &i5); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, arrayP, "(i(iiQ)i*i)", - &i1, &i2, &i3, &i4, &i5); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, arrayP, "(", - &i1, &i2, &i3, &i4, &i5); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, arrayP, "(i", - &i1, &i2, &i3, &i4, &i5); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, arrayP, "(i*", - &i1, &i2, &i3, &i4, &i5); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - - /* Test bounds check on xmlrpc_array_get_item. */ - xmlrpc_array_read_item(&env, arrayP, 3, &itemP); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_array_get_item(&env, arrayP, 3); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_array_get_item(&env, arrayP, -1); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_DECREF(arrayP); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_array_nil(void) { - - xmlrpc_value * arrayP; - xmlrpc_env env; - xmlrpc_int32 i1, i2; - xmlrpc_value * itemP; - size_t len; - - xmlrpc_env_init(&env); - - arrayP = xmlrpc_build_value(&env, "(nini)", - (xmlrpc_int32) 10, (xmlrpc_int32) 20); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP)); - - len = xmlrpc_array_size(&env, arrayP); - TEST_NO_FAULT(&env); - TEST(len == 4); - - itemP = xmlrpc_array_get_item(&env, arrayP, 0); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, itemP, "n"); - TEST_NO_FAULT(&env); - - itemP = xmlrpc_array_get_item(&env, arrayP, 1); - TEST_NO_FAULT(&env); - { - int i; - xmlrpc_decompose_value(&env, itemP, "i", &i); - TEST_NO_FAULT(&env); - TEST(i == 10); - } - xmlrpc_decompose_value(&env, arrayP, "(nini)", &i1, &i2); - TEST_NO_FAULT(&env); - TEST(i1 == 10 && i2 == 20); - - /* Test bounds check on xmlrpc_array_get_item. */ - xmlrpc_array_read_item(&env, arrayP, 4, &itemP); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_array_get_item(&env, arrayP, 4); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_DECREF(arrayP); - - xmlrpc_env_clean(&env); -} - - - -static void -destroyMyCptr(void * const context, - void * const objectP) { -/*---------------------------------------------------------------------------- - This is a xmlrpc_cptr_dtor_fn. ------------------------------------------------------------------------------*/ - int * const destroyConfirmationP = context; - int * const objectIntP = objectP; - - *destroyConfirmationP = *objectIntP; -} - - - -static void -test_value_cptr(void) { - - int destroyConfirmation; - - xmlrpc_value * v; - xmlrpc_value * v2; - xmlrpc_env env; - void * ptr; - int myObject; - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_C_PTR), "C_PTR")); - - myObject = 7; - - v = xmlrpc_cptr_new(&env, &myObject); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_C_PTR); - xmlrpc_DECREF(v); - - v = xmlrpc_cptr_new_dtor(&env, &myObject, - &destroyMyCptr, &destroyConfirmation); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_C_PTR); - destroyConfirmation = 3; - xmlrpc_DECREF(v); - TEST(destroyConfirmation == 7); // the destructor has set this - - v = xmlrpc_build_value(&env, "p", (void*) 0x00000017); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_C_PTR == xmlrpc_value_type(v)); - xmlrpc_decompose_value(&env, v, "p", &ptr); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(ptr == (void*) 0x00000017); - - v = xmlrpc_cptr_new(&env, &myObject); - TEST_NO_FAULT(&env); - v2 = xmlrpc_value_new(&env, v); - xmlrpc_DECREF(v); - TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_C_PTR); - xmlrpc_DECREF(v2); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_nil(void) { - - xmlrpc_value * v; - xmlrpc_value * v2; - xmlrpc_env env; - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_NIL), "NIL")); - - v = xmlrpc_nil_new(&env); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_NIL); - xmlrpc_DECREF(v); - - v = xmlrpc_build_value(&env, "n"); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_NIL == xmlrpc_value_type(v)); - xmlrpc_decompose_value(&env, v, "n"); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - - v = xmlrpc_nil_new(&env); - TEST_NO_FAULT(&env); - v2 = xmlrpc_value_new(&env, v); - TEST_NO_FAULT(&env); - xmlrpc_DECREF(v); - TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_NIL); - xmlrpc_DECREF(v2); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_i8(void) { - - xmlrpc_value * v; - xmlrpc_value * v2; - xmlrpc_env env; - xmlrpc_int64 i; - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_I8), "I8")); - - v = xmlrpc_i8_new(&env, (xmlrpc_int64) 25); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_I8); - xmlrpc_read_i8(&env, v, &i); - TEST_NO_FAULT(&env); - TEST(i == 25); - xmlrpc_DECREF(v); - - v = xmlrpc_i8_new(&env, (xmlrpc_int64) -25); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_I8); - xmlrpc_read_i8(&env, v, &i); - TEST_NO_FAULT(&env); - TEST(i == -25); - xmlrpc_DECREF(v); - - v = xmlrpc_i8_new(&env, (xmlrpc_int64)1 << 40); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_I8); - xmlrpc_read_i8(&env, v, &i); - TEST_NO_FAULT(&env); - TEST(i == (xmlrpc_int64)1 << 40); - xmlrpc_DECREF(v); - - v = xmlrpc_build_value(&env, "I", (xmlrpc_int64) 10); - TEST_NO_FAULT(&env); - TEST(v != NULL); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_I8); - xmlrpc_decompose_value(&env, v, "I", &i); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(i == 10); - - v = xmlrpc_i8_new(&env, (xmlrpc_int64) 25); - TEST_NO_FAULT(&env); - v2 = xmlrpc_value_new(&env, v); - TEST_NO_FAULT(&env); - xmlrpc_DECREF(v); - TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_I8); - xmlrpc_read_i8(&env, v2, &i); - TEST_NO_FAULT(&env); - TEST(i == 25); - xmlrpc_DECREF(v2); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_type_mismatch(void) { - - xmlrpc_value * v; - xmlrpc_env env; - xmlrpc_env env2; - char * str; - - /* Test for one, simple kind of type mismatch error. We assume that - if one of these typechecks works, the rest work fine. - */ - - xmlrpc_env_init(&env); - xmlrpc_env_init(&env2); - - v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 5); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env2, v, "s", &str); - xmlrpc_DECREF(v); - TEST_FAULT(&env2, XMLRPC_TYPE_ERROR); - - xmlrpc_env_clean(&env2); - xmlrpc_env_clean(&env); -} - - - -static void -test_value_invalid_type(void) { - - xmlrpc_env env; - - /* Test invalid type specifier in format string */ - - xmlrpc_env_init(&env); - - xmlrpc_build_value(&env, "Q"); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_missing_array_delim(void) { - - xmlrpc_env env; - - /* Test missing close parenthesis on array */ - - xmlrpc_env_init(&env); - - xmlrpc_build_value(&env, "("); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_build_value(&env, "(i"); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_missing_struct_delim(void) { - - xmlrpc_env env; - - /* Test missing closing brace on struct */ - - xmlrpc_env_init(&env); - - xmlrpc_build_value(&env, "{"); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_build_value(&env, "{s:i", "key1", 7); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_build_value(&env, "{s:i,s:i", "key1", 9, "key2", -4); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_invalid_struct(void) { - - xmlrpc_env env; - - /* Note that even though the format strings are invalid, we have - to supply the variable arguments that xmlrpc_build_value() will - be looking for as it tries to parse it. Otherwise, we get wild - memory references and consequent Valgrind flags. - */ - - xmlrpc_env_init(&env); - - xmlrpc_build_value(&env, "{s:ii", "key1", 9, 9); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_build_value(&env, "{si:", "key1", 9); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_build_value(&env, "{s", "key1"); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_env_clean(&env); -} - - - -static void -testFailedParseValue(void) { - - xmlrpc_env env; - xmlrpc_value * valueP; - const char * stringval; - int integerval; - - - xmlrpc_env_init(&env); - - valueP = xmlrpc_build_value(&env, "{s:s}", "string", "stringval"); - - TEST_NO_FAULT(&env); - - /* Fail because "integer" member is missing */ - xmlrpc_parse_value(&env, valueP, "{s:s,s:i,*}", - "string", &stringval, "integer", &integerval); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_DECREF(valueP); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_parse_value(void) { - - xmlrpc_env env; - xmlrpc_value * valueP; - const char * base64_data = "base64 data"; - size_t base64_data_length = strlen(base64_data); - const char * datestring = "19980717T14:08:55"; - - xmlrpc_env_init(&env); - - valueP = xmlrpc_build_value(&env, "(idb8ss#6(i){s:i}np(i))", - 7, 3.14, (xmlrpc_bool)1, datestring, - "hello world", "a\0b", (size_t)3, - base64_data, base64_data_length, - 15, "member9", 9, &valueP, -5); - - TEST_NO_FAULT(&env); - - { - xmlrpc_int32 i; - xmlrpc_double d; - xmlrpc_bool b; - const char * dt_str; - const char * s1; - const char * s2; - size_t s2_len; - const unsigned char * b64; - size_t b64_len; - xmlrpc_value * arrayP; - xmlrpc_value * structP; - void * cptr; - xmlrpc_value * subvalP; - - xmlrpc_parse_value(&env, valueP, "(idb8ss#6ASnpV)", - &i, &d, &b, &dt_str, &s1, &s2, &s2_len, - &b64, &b64_len, - &arrayP, &structP, &cptr, &subvalP); - - TEST_NO_FAULT(&env); - - TEST(i == 7); - TEST(d == 3.14); - TEST(b == (xmlrpc_bool)1); - TEST(streq(dt_str, datestring)); - TEST(streq(s1, "hello world")); - TEST(s2_len == 3); - TEST(memeq(s2, "a\0b", 3)); - TEST(b64_len == strlen("base64 data")); - TEST(memeq(b64, "base64 data", b64_len)); - TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP)); - TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(structP)); - TEST(cptr == &valueP); - TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(subvalP)); - - xmlrpc_DECREF(valueP); - } - testFailedParseValue(); - - xmlrpc_env_clean(&env); -} - - - -static void -test_struct_get_element(xmlrpc_value * const structP, - xmlrpc_value * const fooValueP, - xmlrpc_value * const weirdValueP, - const char * const weirdKey, - unsigned int const weirdKeyLen) { - - xmlrpc_env env; - xmlrpc_value * valueP; - xmlrpc_value * fooStringP; - xmlrpc_value * bogusKeyStringP; - - xmlrpc_env_init(&env); - - /* build test tools */ - - fooStringP = xmlrpc_build_value(&env, "s", "foo"); - TEST_NO_FAULT(&env); - - bogusKeyStringP = xmlrpc_build_value(&env, "s", "doesn't_exist"); - TEST_NO_FAULT(&env); - - /* "find" interface */ - - xmlrpc_struct_find_value(&env, structP, "foo", &valueP); - TEST_NO_FAULT(&env); - TEST(valueP == fooValueP); - xmlrpc_DECREF(valueP); - - xmlrpc_struct_find_value(&env, structP, "doesn't_exist", &valueP); - TEST_NO_FAULT(&env); - TEST(valueP == NULL); - - xmlrpc_struct_find_value_v(&env, structP, fooStringP, &valueP); - TEST_NO_FAULT(&env); - TEST(valueP == fooValueP); - xmlrpc_DECREF(valueP); - - xmlrpc_struct_find_value_v(&env, structP, bogusKeyStringP, &valueP); - TEST_NO_FAULT(&env); - TEST(valueP == NULL); - - xmlrpc_struct_find_value(&env, fooValueP, "foo", &valueP); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - /* "read" interface */ - - xmlrpc_struct_read_value(&env, structP, "foo", &valueP); - TEST_NO_FAULT(&env); - TEST(valueP == fooValueP); - xmlrpc_DECREF(valueP); - - xmlrpc_struct_read_value(&env, structP, "doesn't_exist", &valueP); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_struct_read_value_v(&env, structP, fooStringP, &valueP); - TEST_NO_FAULT(&env); - TEST(valueP == fooValueP); - xmlrpc_DECREF(valueP); - - xmlrpc_struct_read_value_v(&env, structP, bogusKeyStringP, &valueP); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - xmlrpc_struct_read_value(&env, fooValueP, "foo", &valueP); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - /* obsolete "get" interface. Note that it does not update the - reference count of the xmlrpc_value it returns. - */ - - valueP = xmlrpc_struct_get_value(&env, structP, "foo"); - TEST_NO_FAULT(&env); - TEST(valueP == fooValueP); - - valueP = xmlrpc_struct_get_value(&env, structP, "doesn't_exist"); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - valueP = xmlrpc_struct_get_value(&env, fooValueP, "foo"); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - valueP = xmlrpc_struct_get_value_n(&env, structP, weirdKey, weirdKeyLen); - TEST_NO_FAULT(&env); - TEST(valueP == weirdValueP); - - /* Clean up */ - - xmlrpc_DECREF(fooStringP); - xmlrpc_DECREF(bogusKeyStringP); - - xmlrpc_env_clean(&env); -} - - - -static void -testStructReadout(xmlrpc_value * const structP, - unsigned int const expectedSize) { - - xmlrpc_env env; - xmlrpc_value * keyP; - xmlrpc_value * valueP; - - unsigned int index; - - xmlrpc_env_init(&env); - - for (index = 0; index < expectedSize; ++index) { - xmlrpc_struct_read_member(&env, structP, index, &keyP, &valueP); - TEST_NO_FAULT(&env); - xmlrpc_DECREF(keyP); - xmlrpc_DECREF(valueP); - } - - xmlrpc_struct_read_member(&env, structP, expectedSize, &keyP, &valueP); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - for (index = 0; index < expectedSize; ++index) { - xmlrpc_struct_get_key_and_value(&env, structP, index, &keyP, &valueP); - TEST_NO_FAULT(&env); - } - xmlrpc_env_clean(&env); -} - - - -static void -test_struct_decompose_invalid_format_string( - xmlrpc_value * const testStructP) { - - xmlrpc_env env; - xmlrpc_int32 ival; - xmlrpc_bool bval; - char * sval; - - xmlrpc_env_init(&env); - - /* Premature end of format string: */ - - xmlrpc_decompose_value(&env, testStructP, "{"); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, testStructP, "{s", "baz"); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, testStructP, "{s:", "baz"); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, testStructP, "{s:", "baz"); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, testStructP, "{s:b", "baz", &bval); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, testStructP, "{s:b,", "baz", &bval); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_decompose_value(&env, testStructP, "{s:b,*", "baz", &bval); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - /* Key not 's' */ - xmlrpc_decompose_value(&env, testStructP, "{i:s,s:i,*}", - "baz", &sval, - "foo", &ival); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - /* Missing colon */ - xmlrpc_decompose_value(&env, testStructP, "{is,s:i,*}", - "baz", &sval, - "foo", &ival); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - /* Missing comma */ - xmlrpc_decompose_value(&env, testStructP, "{i:ss:i,*}", - "baz", &sval, - "foo", &ival); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - /* Undefined format specifier */ - xmlrpc_decompose_value(&env, testStructP, "{s:Q,*}", - "baz", &sval); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - /* No * at end */ - xmlrpc_decompose_value(&env, testStructP, "{s:b,s:s,s:i}", - "baz", &bval, - "foo", &sval, - "bar", &ival); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_env_clean(&env); -} - - - -static void -test_struct_decompose(xmlrpc_value * const testStructP) { - - xmlrpc_env env; - - xmlrpc_int32 ival; - xmlrpc_bool bval; - char * sval; - xmlrpc_value * topStructP; - xmlrpc_value * value1P; - - xmlrpc_env_init(&env); - - /* Make a test struct */ - topStructP = xmlrpc_build_value(&env, "{s:S,s:s}", - "key1", testStructP, - "key2", "my_string_value"); - TEST_NO_FAULT(&env); - - test_struct_decompose_invalid_format_string(testStructP); - - /* Decompose a struct */ - xmlrpc_decompose_value(&env, testStructP, "{s:b,s:s,s:i,*}", - "baz", &bval, - "foo", &sval, - "bar", &ival); - TEST_NO_FAULT(&env); - TEST(ival == 1); - TEST(!bval); - TEST(streq(sval, "Hello!")); - free(sval); - - /* Decompose a deep struct */ - - xmlrpc_decompose_value(&env, topStructP, "{s:S,*}", "key1", &value1P); - TEST_NO_FAULT(&env); - TEST(xmlrpc_value_type(value1P) == XMLRPC_TYPE_STRUCT); - xmlrpc_DECREF(value1P); - - xmlrpc_decompose_value(&env, topStructP, "{s:{s:b,s:s,s:i,*},*}", - "key1", - "baz", &bval, - "foo", &sval, - "bar", &ival); - TEST_NO_FAULT(&env); - TEST(ival == 1); - TEST(!bval); - TEST(streq(sval, "Hello!")); - free(sval); - - /* First value of wrong type */ - xmlrpc_decompose_value(&env, testStructP, "{s:b,s:i,*}", - "baz", &sval, - "foo", &ival); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - /* Subsequent value of wrong type */ - xmlrpc_decompose_value(&env, testStructP, "{s:s,s:i,*}", - "foo", &sval, - "baz", &bval); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - /* Nonexistent key */ - xmlrpc_decompose_value(&env, testStructP, "{s:b,s:i,*}", - "baz", &bval, - "nosuch", &sval); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - - /* Error subsequent to nested value */ - xmlrpc_decompose_value(&env, topStructP, "{s:{s:s,*},s:i,*}", - "key1", - "foo", &sval, - "key2", &ival); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - xmlrpc_DECREF(topStructP); - - xmlrpc_env_clean(&env); -} - - - -static void -test_struct (void) { - - xmlrpc_env env; - xmlrpc_value * value1P; - xmlrpc_value *s, *i, *i1, *i2, *i3, *key, *value; - size_t size; - int present; - xmlrpc_bool bval; - char const weirdKey[] = {'f', 'o', 'o', '\0', 'b', 'a', 'r'}; - - xmlrpc_env_init(&env); - - /* Create a struct. */ - s = xmlrpc_struct_new(&env); - TEST_NO_FAULT(&env); - TEST(s != NULL); - TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s)); - size = xmlrpc_struct_size(&env, s); - TEST_NO_FAULT(&env); - TEST(size == 0); - - /* Create some elements to insert into our struct. */ - i1 = xmlrpc_build_value(&env, "s", "Item #1"); - TEST_NO_FAULT(&env); - i2 = xmlrpc_build_value(&env, "s", "Item #2"); - TEST_NO_FAULT(&env); - i3 = xmlrpc_build_value(&env, "s", "Item #3"); - TEST_NO_FAULT(&env); - - /* Insert a single item. */ - xmlrpc_struct_set_value(&env, s, "foo", i1); - TEST_NO_FAULT(&env); - size = xmlrpc_struct_size(&env, s); - TEST_NO_FAULT(&env); - TEST(size == 1); - - /* Insert an item whose key has the same hash value as "foo". */ - xmlrpc_struct_set_value(&env, s, "qmdebdw", i2); - TEST_NO_FAULT(&env); - size = xmlrpc_struct_size(&env, s); - TEST_NO_FAULT(&env); - TEST(size == 2); - i = xmlrpc_struct_get_value(&env, s, "foo"); - TEST_NO_FAULT(&env); - TEST(i == i1); - i = xmlrpc_struct_get_value(&env, s, "qmdebdw"); - TEST_NO_FAULT(&env); - TEST(i == i2); - - /* Replace an existing element with a different element. */ - xmlrpc_struct_set_value(&env, s, "foo", i3); - TEST_NO_FAULT(&env); - size = xmlrpc_struct_size(&env, s); - TEST_NO_FAULT(&env); - TEST(size == 2); - i = xmlrpc_struct_get_value(&env, s, "foo"); - TEST_NO_FAULT(&env); - TEST(i == i3); - - /* Insert an item with a NUL in the key */ - xmlrpc_struct_set_value_n(&env, s, weirdKey, sizeof(weirdKey), i2); - TEST_NO_FAULT(&env); - size = xmlrpc_struct_size(&env, s); - TEST_NO_FAULT(&env); - TEST(size == 3); - - test_struct_get_element(s, i3, i2, weirdKey, sizeof(weirdKey)); - - /* Replace an existing element with the same element (tricky). */ - xmlrpc_struct_set_value(&env, s, "foo", i3); - TEST_NO_FAULT(&env); - size = xmlrpc_struct_size(&env, s); - TEST_NO_FAULT(&env); - TEST(size == 3); - i = xmlrpc_struct_get_value(&env, s, "foo"); - TEST_NO_FAULT(&env); - TEST(i == i3); - - /* Test for the presence and absence of elements. */ - present = xmlrpc_struct_has_key(&env, s, "foo"); - TEST_NO_FAULT(&env); - TEST(present); - present = xmlrpc_struct_has_key(&env, s, "qmdebdw"); - TEST_NO_FAULT(&env); - TEST(present); - present = xmlrpc_struct_has_key(&env, s, "bogus"); - TEST_NO_FAULT(&env); - TEST(!present); - - /* Make sure our typechecks work correctly. */ - xmlrpc_struct_size(&env, i1); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - xmlrpc_struct_has_key(&env, i1, "foo"); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - xmlrpc_struct_set_value(&env, i1, "foo", i2); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - xmlrpc_struct_set_value_v(&env, s, s, i2); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - - /* Test cleanup code (w/memprof). */ - xmlrpc_DECREF(s); - - s = xmlrpc_build_value(&env, "{s:s,s:i,s:b}", - "foo", "Hello!", - "bar", (xmlrpc_int32) 1, - "baz", (xmlrpc_bool) 0); - TEST_NO_FAULT(&env); - TEST(s != NULL); - TEST(xmlrpc_value_type(s) == XMLRPC_TYPE_STRUCT); - size = xmlrpc_struct_size(&env, s); - TEST_NO_FAULT(&env); - TEST(size == 3); - present = xmlrpc_struct_has_key(&env, s, "foo"); - TEST_NO_FAULT(&env); - TEST(present); - present = xmlrpc_struct_has_key(&env, s, "bar"); - TEST_NO_FAULT(&env); - TEST(present); - present = xmlrpc_struct_has_key(&env, s, "baz"); - TEST_NO_FAULT(&env); - TEST(present); - xmlrpc_struct_read_value(&env, s, "baz", &value1P); - TEST_NO_FAULT(&env); - xmlrpc_read_bool(&env, value1P, &bval); - TEST_NO_FAULT(&env); - TEST(!bval); - xmlrpc_DECREF(value1P); - - testStructReadout(s, 3); - - test_struct_decompose(s); - - /* Test type check. */ - xmlrpc_struct_get_key_and_value(&env, i1, 0, &key, &value); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - TEST(key == NULL && value == NULL); - - /* Test bounds checks. */ - xmlrpc_struct_get_key_and_value(&env, s, -1, &key, &value); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - TEST(key == NULL && value == NULL); - - xmlrpc_struct_get_key_and_value(&env, s, 3, &key, &value); - TEST_FAULT(&env, XMLRPC_INDEX_ERROR); - TEST(key == NULL && value == NULL); - - /* Test cleanup code (w/memprof). */ - xmlrpc_DECREF(s); - - xmlrpc_DECREF(i1); - xmlrpc_DECREF(i2); - xmlrpc_DECREF(i3); - xmlrpc_env_clean(&env); -} - - - -void -test_value(void) { - - printf("Running value tests."); - - test_value_alloc_dealloc(); - test_value_int(); - test_value_bool(); - test_value_double(); - test_value_datetime(); - printf("\n Running string value tests."); - test_value_string_no_null(); - test_value_string_null(); - test_value_string_multiline(); - test_value_string_cr(); - test_value_string_wide(); - test_value_string_ctlchar(); - printf("\n String value tests done.\n"); - test_value_base64(); - test_value_array(); - test_value_array2(); - test_value_array_nil(); - test_value_value(); - test_value_AS(); - test_value_AS_typecheck(); - test_value_cptr(); - test_value_nil(); - test_value_i8(); - test_value_type_mismatch(); - test_value_invalid_type(); - test_value_missing_array_delim(); - test_value_missing_struct_delim(); - test_value_invalid_struct(); - test_value_parse_value(); - test_struct(); - - printf("\n"); - printf("Value tests done.\n"); -} diff --git a/trunk/test/value.h b/trunk/test/value.h deleted file mode 100644 index 2789defb6..000000000 --- a/trunk/test/value.h +++ /dev/null @@ -1,2 +0,0 @@ -void -test_value(void); diff --git a/trunk/test/value_datetime.c b/trunk/test/value_datetime.c deleted file mode 100644 index ff48456ce..000000000 --- a/trunk/test/value_datetime.c +++ /dev/null @@ -1,448 +0,0 @@ -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include -#include - -#include "casprintf.h" -#include "girstring.h" - -#include "xmlrpc_config.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/string_int.h" - -#include "testtool.h" - -#include "value_datetime.h" - - - -static const char * -truncateFracSec(const char * const datestring) { -/*---------------------------------------------------------------------------- - Return 'datestring', but with any fractional seconds chopped off. - E.g. if 'datestring' is "20000301T00:00:00.654321", - we return "20000301T00:00:00". ------------------------------------------------------------------------------*/ - char * buffer; - unsigned int i; - - buffer = strdup(datestring); - - for (i = 0; i < strlen(buffer); ++i) { - if (buffer[i] == '.') - buffer[i] = '\0'; - } - return buffer; -} - - - -#if XMLRPC_HAVE_TIMEVAL - -static struct timeval -makeTv(time_t const secs, - unsigned int const usecs) { - - struct timeval retval; - - retval.tv_sec = secs; - retval.tv_usec = usecs; - - return retval; -} - -static bool -tvIsEqual(struct timeval const comparand, - struct timeval const comparator) { - return - comparand.tv_sec == comparator.tv_sec && - comparand.tv_usec == comparator.tv_usec; -} -#endif - - - -#if XMLRPC_HAVE_TIMESPEC - -static struct timespec -makeTs(time_t const secs, - unsigned int const usecs) { - - struct timespec retval; - - retval.tv_sec = secs; - retval.tv_nsec = usecs * 1000; - - return retval; -} - -static bool -tsIsEqual(struct timespec const comparand, - struct timespec const comparator) { - return - comparand.tv_sec == comparator.tv_sec && - comparand.tv_nsec == comparator.tv_nsec; -} -#endif - - - -static const char * -make8601(time_t const seconds, - unsigned int const usec) { - - struct tm const tm = *gmtime(&seconds); - - const char * retval; - - xmlrpc_asprintf(&retval, "%04u%02u%02uT%02u%02u%02u,%06uZ", - 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, - usec); - - return retval; -} - - - -static void -test_value_datetime_varytime(const char * const datestring, - time_t const datetime, - unsigned int const usec) { - - xmlrpc_value * v; - xmlrpc_env env; - const char * readBackString; - time_t readBackDt; - unsigned int readBackUsec; - const char * datestringSec; -#if XMLRPC_HAVE_TIMEVAL - struct timeval const dtTimeval = makeTv(datetime, usec); - struct timeval readBackTv; -#endif -#if XMLRPC_HAVE_TIMESPEC - struct timespec const dtTimespec = makeTs(datetime, usec); - struct timespec readBackTs; -#endif - const char * const dt8601 = make8601(datetime, usec); - const char * readBack8601; - - datestringSec = truncateFracSec(datestring); - - xmlrpc_env_init(&env); - - /* Test xmlrpc_datetime_new_str and time read functions*/ - v = xmlrpc_datetime_new_str(&env, datestring); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); - - xmlrpc_read_datetime_sec(&env, v, &readBackDt); - TEST_NO_FAULT(&env); - TEST(readBackDt == datetime); - - xmlrpc_read_datetime_usec(&env, v, &readBackDt, &readBackUsec); - TEST_NO_FAULT(&env); - TEST(readBackDt == datetime); - TEST(readBackUsec == usec); - -#if XMLRPC_HAVE_TIMEVAL - xmlrpc_read_datetime_timeval(&env, v, &readBackTv); - TEST_NO_FAULT(&env); - TEST(tvIsEqual(dtTimeval, readBackTv)); -#endif - -#if XMLRPC_HAVE_TIMESPEC - xmlrpc_read_datetime_timespec(&env, v, &readBackTs); - TEST_NO_FAULT(&env); - TEST(tsIsEqual(dtTimespec, readBackTs)); -#endif - - xmlrpc_read_datetime_8601(&env, v, &readBack8601); - TEST_NO_FAULT(&env); - TEST(xmlrpc_streq(dt8601, readBack8601)); - strfree(readBack8601); - - xmlrpc_DECREF(v); - - /* Test xmlrpc_datetime_new_sec */ - v = xmlrpc_datetime_new_sec(&env, datetime); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); - - xmlrpc_read_datetime_str(&env, v, &readBackString); - TEST_NO_FAULT(&env); - TEST(streq(readBackString, datestringSec)); - strfree(readBackString); - - xmlrpc_DECREF(v); - - /* Test xmlrpc_datetime_new_usec */ - v = xmlrpc_datetime_new_usec(&env, datetime, usec); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); - - xmlrpc_read_datetime_str(&env, v, &readBackString); - TEST_NO_FAULT(&env); - TEST(streq(readBackString, datestring)); - strfree(readBackString); - - xmlrpc_DECREF(v); - -#if XMLRPC_HAVE_TIMEVAL - /* Test xmlrpc_datetime_new_timeval */ - v = xmlrpc_datetime_new_timeval(&env, dtTimeval); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); - - xmlrpc_read_datetime_str(&env, v, &readBackString); - TEST_NO_FAULT(&env); - TEST(streq(readBackString, datestring)); - strfree(readBackString); - - xmlrpc_DECREF(v); -#endif - -#if XMLRPC_HAVE_TIMESPEC - /* Test xmlrpc_datetime_new_timespec */ - v = xmlrpc_datetime_new_timespec(&env, dtTimespec); - TEST_NO_FAULT(&env); - TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); - - xmlrpc_read_datetime_str(&env, v, &readBackString); - TEST_NO_FAULT(&env); - TEST(streq(readBackString, datestring)); - strfree(readBackString); - - xmlrpc_DECREF(v); -#endif - - xmlrpc_env_clean(&env); - strfree(datestringSec); -} - - - -static void -test_value_datetime_not_unix(const char * const datestring) { - - xmlrpc_value * v; - xmlrpc_env env; - time_t dt; - - xmlrpc_env_init(&env); - - v = xmlrpc_datetime_new_str(&env, datestring); - TEST_NO_FAULT(&env); - - xmlrpc_read_datetime_sec(&env, v, &dt); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_DECREF(v); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_datetime_str_invalid1(const char * const datestring) { - - /* Ideally, xmlrpc_datetime_new_str() would fail on these, but - the code doesn't implement that today. However, - xmlrpc_read_datetime_sec() does catch many cases, so we - use that. - - Note that xmlrpc_read_datetime_sec() doesn't catch them all. - Sometimes it just returns garbage, e.g. returns July 1 for - June 31. - */ - - xmlrpc_value * v; - xmlrpc_env env; - time_t dt; - - xmlrpc_env_init(&env); - - v = xmlrpc_datetime_new_str(&env, datestring); - TEST_NO_FAULT(&env); - - xmlrpc_read_datetime_sec(&env, v, &dt); - TEST_FAULT(&env, XMLRPC_PARSE_ERROR); - - xmlrpc_DECREF(v); - - xmlrpc_env_clean(&env); -} - - - -static void -test_value_datetime_str_invalid2(const char * const datestring) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - xmlrpc_datetime_new_str(&env, datestring); - TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); - - xmlrpc_env_clean(&env); -} - - - -static void -test_build_decomp_datetime(void) { - - const char * datestring = "19980717T14:08:55"; - time_t const datetime = 900684535; - - xmlrpc_env env; - xmlrpc_value * v; - time_t dt; - const char * ds; - - xmlrpc_env_init(&env); - - v = xmlrpc_build_value(&env, "t", datetime); - TEST_NO_FAULT(&env); - TEST(v != NULL); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_DATETIME); - - dt = 0; - xmlrpc_read_datetime_sec(&env, v, &dt); - TEST(dt == datetime); - - dt = 0; - xmlrpc_decompose_value(&env, v, "t", &dt); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(dt == datetime); - - v = xmlrpc_int_new(&env, 9); - TEST_NO_FAULT(&env); - xmlrpc_decompose_value(&env, v, "t", &dt); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - xmlrpc_env_clean(&env); - xmlrpc_env_init(&env); - xmlrpc_decompose_value(&env, v, "8", &ds); - TEST_FAULT(&env, XMLRPC_TYPE_ERROR); - xmlrpc_env_clean(&env); - xmlrpc_env_init(&env); - xmlrpc_DECREF(v); - - v = xmlrpc_build_value(&env, "8", datestring); - TEST_NO_FAULT(&env); - TEST(v != NULL); - TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_DATETIME); - xmlrpc_decompose_value(&env, v, "8", &ds); - xmlrpc_DECREF(v); - TEST_NO_FAULT(&env); - TEST(streq(ds, datestring)); - strfree(ds); - - xmlrpc_env_clean(&env); -} - - - - -static void -test_value_datetime_basic(void) { - - xmlrpc_value * v; - xmlrpc_env env; - xmlrpc_datetime dt; - xmlrpc_datetime readBackDt; - - xmlrpc_env_init(&env); - - dt.Y = 2001; - dt.M = 12; - dt.D = 25; - dt.h = 1; - dt.m = 2; - dt.s = 3; - dt.u = 4; - - v = xmlrpc_datetime_new(&env, dt); - - xmlrpc_read_datetime(&env, v, &readBackDt); - TEST_NO_FAULT(&env); - TEST(readBackDt.Y = dt.Y); - TEST(readBackDt.M = dt.M); - TEST(readBackDt.D = dt.D); - TEST(readBackDt.h = dt.h); - TEST(readBackDt.m = dt.m); - TEST(readBackDt.s = dt.s); - TEST(readBackDt.u = dt.u); - - xmlrpc_env_clean(&env); -} - - - -void -test_value_datetime(void) { - - const char * datestring = "19980717T14:08:55"; - time_t const datetime = 900684535; - - xmlrpc_env env; - - printf("\n Running datetime value tests"); - - xmlrpc_env_init(&env); - - TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_DATETIME), "DATETIME")); - - test_value_datetime_basic(); - - /* Valid datetime, generated from XML-RPC string, time_t, and - time_t + microseconds - */ - - test_value_datetime_varytime(datestring, datetime, 0); - - /* test microseconds */ - test_value_datetime_varytime("20000301T00:00:00.654321", - 951868800, 654321); - test_value_datetime_varytime("20040229T23:59:59.123000", - 1078099199, 123000); - test_value_datetime_varytime("20000229T23:59:59.000123", - 951868799, 123); - - /* Leap years */ - test_value_datetime_varytime("20000229T23:59:59", 951868799, 0); - test_value_datetime_varytime("20000301T00:00:00", 951868800, 0); - test_value_datetime_varytime("20010228T23:59:59", 983404799, 0); - test_value_datetime_varytime("20010301T00:00:00", 983404800, 0); - test_value_datetime_varytime("20040229T23:59:59", 1078099199, 0); - test_value_datetime_varytime("20040301T00:00:00", 1078099200, 0); - - /* Datetimes that can't be represented as time_t */ - test_value_datetime_not_unix("19691231T23:59:59"); - - /* Invalid datetimes */ - /* Note that the code today does a pretty weak job of validating datetimes, - so we test only the validation that we know is implemented. - */ - test_value_datetime_str_invalid1("19700101T25:00:00"); - test_value_datetime_str_invalid1("19700101T10:61:01"); - test_value_datetime_str_invalid1("19700101T10:59:61"); - test_value_datetime_str_invalid1("19700001T10:00:00"); - test_value_datetime_str_invalid1("19701301T10:00:00"); - test_value_datetime_str_invalid1("19700132T10:00:00"); - test_value_datetime_str_invalid2("19700132T10:00:00."); - test_value_datetime_str_invalid2("19700132T10:00:00,123"); - - test_build_decomp_datetime(); - - xmlrpc_env_clean(&env); - - printf("\n"); - printf(" datetime value tests done.\n"); -} diff --git a/trunk/test/value_datetime.h b/trunk/test/value_datetime.h deleted file mode 100644 index 5a26f60a2..000000000 --- a/trunk/test/value_datetime.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef VALUE_DATETIME_H_INCLUDED -#define VALUE_DATETIME_H_INCLUDED - -void -test_value_datetime(void); - -#endif diff --git a/trunk/test/xml_data.c b/trunk/test/xml_data.c deleted file mode 100644 index a06854e67..000000000 --- a/trunk/test/xml_data.c +++ /dev/null @@ -1,200 +0,0 @@ -#include - -#include "xml_data.h" - -#define RAW_STRING_DATA \ - "\r\n" \ - "2147483647\r\n" \ - "-2147483648\r\n" \ - "0\r\n" \ - "1\r\n" \ - "Hello, world! <&>\r\n" \ - "\r\n" \ - "YmFzZTY0IGRhdGE=\r\n" \ - "\r\n" \ - "" \ - "19980717T14:08:55" \ - "\r\n" \ - "\r\n" \ - "\r\n" \ - "" - -char const serialized_data[] = RAW_STRING_DATA; - -char const serialized_call[] = - XML_PROLOGUE - "\r\n" - "gloom&doom\r\n" - "\r\n" - "10\r\n" - "20\r\n" - "\r\n" - "\r\n"; - -char const serialized_fault[] = - XML_PROLOGUE - "\r\n" - "\r\n" - "\r\n" - "faultCode\r\n" - "6\r\n" - "faultString\r\n" - "A fault occurred\r\n" - "\r\n" - "\r\n" - "\r\n"; - -char const expat_data[] = XML_PROLOGUE RAW_STRING_DATA "\r\n"; -char const expat_error_data[] = - XML_PROLOGUE \ - "abc\r\n"; - /* Invalid because there's no closing */ - - -char const good_response_xml[] = - XML_PROLOGUE - "\r\n" - "\r\n" - RAW_STRING_DATA "\r\n" - "1\r\n" - "-1.0\r\n" - "0.0\r\n" - "1.0\r\n" - "\r\n" - "ten <&>\r\n" - "10\r\n" - "twenty\r\n" - "20\r\n" - "\r\n" - "Untagged string\r\n" - "\r\n" - "\r\n"; - -#define VALUE_HEADER \ - XML_PROLOGUE"\r\n" -#define VALUE_FOOTER \ - "\r\n" - -#define MEMBER_HEADER \ - VALUE_HEADER"" -#define MEMBER_FOOTER \ - ""VALUE_FOOTER -#define ARBITRARY_VALUE \ - "0" - -char const unparseable_value[] = VALUE_HEADER""VALUE_FOOTER; - -const char * bad_values[] = { - VALUE_HEADER"00"VALUE_FOOTER, - VALUE_HEADER""VALUE_FOOTER, - VALUE_HEADER"4"VALUE_FOOTER, - VALUE_HEADER"2147483648"VALUE_FOOTER, - VALUE_HEADER"-2147483649"VALUE_FOOTER, - VALUE_HEADER" 0"VALUE_FOOTER, - VALUE_HEADER"0 "VALUE_FOOTER, - VALUE_HEADER"2"VALUE_FOOTER, - VALUE_HEADER"-1"VALUE_FOOTER, - VALUE_HEADER""VALUE_FOOTER, - VALUE_HEADER"0.0 "VALUE_FOOTER, - VALUE_HEADER"a"VALUE_FOOTER, - VALUE_HEADER"1.1.1"VALUE_FOOTER, - VALUE_HEADER"1a"VALUE_FOOTER, - VALUE_HEADER"1.1a"VALUE_FOOTER, - VALUE_HEADER""VALUE_FOOTER, - VALUE_HEADER""VALUE_FOOTER, - VALUE_HEADER""VALUE_FOOTER, - VALUE_HEADER""VALUE_FOOTER, - VALUE_HEADER""VALUE_FOOTER, - MEMBER_HEADER MEMBER_FOOTER, - MEMBER_HEADER"a"MEMBER_FOOTER, - MEMBER_HEADER"a"ARBITRARY_VALUE""MEMBER_FOOTER, - MEMBER_HEADER""ARBITRARY_VALUE MEMBER_FOOTER, - MEMBER_HEADER"a"MEMBER_FOOTER, - MEMBER_HEADER""ARBITRARY_VALUE MEMBER_FOOTER, - NULL -}; - -#define RESPONSE_HEADER \ - XML_PROLOGUE"\r\n" -#define RESPONSE_FOOTER \ - "\r\n" - -#define PARAMS_RESP_HEADER \ - RESPONSE_HEADER"" -#define PARAMS_RESP_FOOTER \ - ""RESPONSE_FOOTER - -#define FAULT_HEADER \ - RESPONSE_HEADER"" -#define FAULT_FOOTER \ - ""RESPONSE_FOOTER - -#define FAULT_STRUCT_HEADER \ - FAULT_HEADER"" -#define FAULT_STRUCT_FOOTER \ - ""FAULT_FOOTER - -const char * bad_responses[] = { - XML_PROLOGUE"\r\n", - RESPONSE_HEADER RESPONSE_FOOTER, - RESPONSE_HEADER""RESPONSE_FOOTER, - RESPONSE_HEADER""RESPONSE_FOOTER, - - /* Make sure we insist on only one parameter in a response. */ - PARAMS_RESP_HEADER PARAMS_RESP_FOOTER, - PARAMS_RESP_HEADER - "0" - "0" - PARAMS_RESP_FOOTER, - - /* Test other sorts of bad parameters. */ - PARAMS_RESP_HEADER""PARAMS_RESP_FOOTER, - PARAMS_RESP_HEADER""PARAMS_RESP_FOOTER, - PARAMS_RESP_HEADER""PARAMS_RESP_FOOTER, - PARAMS_RESP_HEADER - ""ARBITRARY_VALUE ARBITRARY_VALUE"" - PARAMS_RESP_FOOTER, - - /* Basic fault tests. */ - FAULT_HEADER FAULT_FOOTER, - FAULT_HEADER""FAULT_FOOTER, - FAULT_HEADER""FAULT_FOOTER, - FAULT_HEADER"1"FAULT_FOOTER, - - /* Make sure we insist on the proper members within the fault struct. */ - FAULT_STRUCT_HEADER - "faultString" - "foo" - FAULT_STRUCT_FOOTER, - FAULT_STRUCT_HEADER - "faultCode" - "0" - FAULT_STRUCT_FOOTER, - FAULT_STRUCT_HEADER - "faultCode" - "0" - "faultString" - "0" - FAULT_STRUCT_FOOTER, - FAULT_STRUCT_HEADER - "faultCode" - "0" - "faultString" - "foo" - FAULT_STRUCT_FOOTER, - NULL}; - -#define CALL_HEADER \ - XML_PROLOGUE"\r\n" -#define CALL_FOOTER \ - "\r\n" - -const char * bad_calls[] = { - XML_PROLOGUE"\r\n", - CALL_HEADER CALL_FOOTER, - CALL_HEADER"m"CALL_FOOTER, - CALL_HEADER""CALL_FOOTER, - CALL_HEADER""CALL_FOOTER, - NULL}; - - diff --git a/trunk/test/xml_data.h b/trunk/test/xml_data.h deleted file mode 100644 index 89b5e4938..000000000 --- a/trunk/test/xml_data.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef XML_DATA_H_INCLUDED -#define XML_DATA_H_INCLUDED - -#define XML_PROLOGUE "\r\n" - -#define APACHE_URL "http://ws.apache.org/xmlrpc/namespaces/extensions" -#define XMLNS_APACHE "xmlns:ex=\"" APACHE_URL "\"" - -extern char const serialized_data[]; - -extern char const serialized_call[]; - -extern char const serialized_fault[]; - -extern char const expat_data[]; -extern char const expat_error_data[]; - -extern char const good_response_xml[]; - -extern char const unparseable_value[]; - -extern const char *(bad_values[]); - -extern const char *(bad_responses[]); - -extern const char *(bad_calls[]); - -#endif diff --git a/trunk/tools/Makefile b/trunk/tools/Makefile deleted file mode 100644 index 7cd2e5f5f..000000000 --- a/trunk/tools/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - SRCDIR := $(call updir,$(CURDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools - -include $(BLDDIR)/config.mk - -SUBDIRS = \ - binmode-rpc-kit \ - lib \ - turbocharger \ - xml \ - -ifeq ($(MUST_BUILD_CLIENT),yes) - SUBDIRS += xmlrpc xmlrpc_transport - - ifeq ($(ENABLE_CPLUSPLUS),yes) - SUBDIRS += xml-rpc-api2cpp xml-rpc-api2txt xmlrpc_cpp_proxy - - ifeq ($(BUILD_XMLRPC_PSTREAM),yes) - SUBDIRS += xmlrpc_pstream - endif - endif -endif - -ifeq ($(ENABLE_CPLUSPLUS),yes) - SUBDIRS += xmlrpc_dumpserver -endif - -.PHONY: all clean distclean install uninstall check dep - -all: $(SUBDIRS:%=%/all) - -clean: $(SUBDIRS:%=%/clean) - -distclean: $(SUBDIRS:%=%/distclean) - -install: $(SUBDIRS:%=%/install) - -uninstall: $(SUBDIRS:%=%/uninstall) - -check: - -dep: $(SUBDIRS:%=%/dep) - -include $(SRCDIR)/common.mk diff --git a/trunk/tools/binmode-rpc-kit/COPYING b/trunk/tools/binmode-rpc-kit/COPYING deleted file mode 100644 index 9a97cb38b..000000000 --- a/trunk/tools/binmode-rpc-kit/COPYING +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (C) 2001 by Eric Kidd. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. diff --git a/trunk/tools/binmode-rpc-kit/Makefile b/trunk/tools/binmode-rpc-kit/Makefile deleted file mode 100644 index ea34b1982..000000000 --- a/trunk/tools/binmode-rpc-kit/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: -clean: -distclean: -install: -uninstall: -dep: diff --git a/trunk/tools/binmode-rpc-kit/README b/trunk/tools/binmode-rpc-kit/README deleted file mode 100644 index 029b5b13c..000000000 --- a/trunk/tools/binmode-rpc-kit/README +++ /dev/null @@ -1,31 +0,0 @@ -Binmode RPC Implementor's Kit -============================= - -Version: 0.1 -Author: Eric Kidd -Date: 31 January 2001 - -The Binmode RPC Implementor's Kit was created as part the xmlrpc-c project. - - http://xmlrpc-c.sourceforge.net/ - -The following files are included: - - README This file - COPYING A standard disclaimer, etc. - binmode-rpc-rfc.txt The current draft of the standard - oct2bin A Perl script for turning the notation used by - the standard into actual binary data. - binmode-rpc2xml-rpc A script which translates a Binmode RPC packet - back into XML. You can use this for dumping wire - messages. (It also catches the most obvious ways - to misimplement the standard, so try it on your - output data.) - examples/ Examples and counter-examples from the standard in - machine-readable format. - -If you have any questions, please ask on the xmlrpc-c-devel mailing list: - - http://xmlrpc-c.sourceforge.net/lists.php - -Thank you for investigating Binmode RPC. Share and enjoy! diff --git a/trunk/tools/binmode-rpc-kit/binmode-rpc-rfc.txt b/trunk/tools/binmode-rpc-kit/binmode-rpc-rfc.txt deleted file mode 100644 index 03f026d0c..000000000 --- a/trunk/tools/binmode-rpc-kit/binmode-rpc-rfc.txt +++ /dev/null @@ -1,338 +0,0 @@ -This is a draft, and subject to change. Please do not implement it -yet. Thank you! - -Examples can be found at the bottom of the file. - -Thank you for your feedback! - -Eric Kidd -eric.kidd@pobox.com -30 January 2001 - - -The Binmode RPC Protocol -======================== - -Binmode RPC is an ultra-lightweight RPC protocol designed for 100% -compatibility with XML-RPC . It emphasizes -simplicity, dynamically-typed data, and extreme ease of implementation. - -Two XML-RPC implementations that implement 'binmode-rpc' may negotiate away -the XML part of XML-RPC, and replace it with a simple binary protocol. - -Design goals: - - * The complete specification should fit in a 350-line text file. :-) - * The protocol should be easy to implement. - * The protocol should provide a high degree of compression. - * The protocol should be very fast--faster than zlib compression. - * The protocol must be implementable in portable ANSI C, with no - './configure' checks. - * The protocol must not contain any options, variant encodings - or similar hair. If you want DCE/RPC, you know where to find it. - * All protocol operations must be performed at the byte level - (except for UTF-8 encoding and decoding). - * The protocol must be semi-readable in a hex dump or Emacs buffer. - * The protocol must efficiently encode boxcarred calls that are - implemented using 'system.multicall'. - * The protocol must enable an efficient encoding for - frequently-repeated string values. - - * The protocol must never be sent to clients or servers which - don't understand it. - * There must be a way for clients and servers to active the protocol - if both ends of the connection understand it. - - -The X-XML-RPC-Extensions Header -------------------------------- - -(First, we'll need a mechanism for unobtrusively announcing the presence of -non-standard capabilities.) - -An XML-RPC implementation MAY advertise additional, non-standard -capabilities using the 'X-XML-RPC-Extensions' header. - -Rationale: The 'X-XML-RPC-Extensions' header should be available to CGI -scripts in the environment variable HTTP_X_XML_RPC_EXTENSIONS. - -If present, this header MUST contain a comma-separated list of -keywords. Parameter information MAY be included, if desired, in the -standard fashion used by HTTP 1.1 'Accept-Encoding' headers. - - X-XML-RPC-Extensions: binmode-rpc - X-XML-RPC-Extensions: binmode-rpc, x-telepathic-transport - X-XML-RPC-Extensions: binmode-rpc,x-telepathic-transport - X-XML-RPC-Extensions: binmode-rpc, x-telepathic-transport;speed=low - -If a client sends the X-XML-RPC-Extensions header in a request, the server -MAY use any of the specified extensions in its response. - -Rationale: No client may be sent non-standard data without first having -advertised the ability to accept it. - -If the server includes the X-XML-RPC-Extensions header in a response, the -client MAY use any of the specified extensions in further requests to that -URL. The client MUST NOT assume that the same extensions are available for -any other URL on the same server. - -Rationale: No server may be sent non-standard data without first having -advertised the ability to accept it. Furthermore, this permission is -URL-specific, since different XML-RPC implementations may be located at -different URLs on a single server. - -The client SHOULD NOT cache extension information about a particular server -for an excessive length of time (typically beyond a single program -invocation). If the client does cache this information indefinitely, it -SHOULD be able to cope if an extension is disabled. - -Rationale: The XML-RPC implementation used on the server may be changed by -the administrator. - - -The 'binmode-rpc' Extension ------------------------ - -A client or server which sends the 'binmode-rpc' extension MUST accept -message bodies of type 'application/x-binmode-rpc' in addition to the -regular 'text/xml'. - -All servers which accept the binmode-rpc extension MUST also accept -standard XML-RPC, as described by . - - -The 'application/x-binmode-rpc' Format --------------------------------------- - -All documents of the type 'application/x-binmode-rpc' MUST begin with the -following byte sequence (represented here as a C string): - - 'binmode-rpc:' - -This MUST be followed by a Call or a Response, encoded as described below: - - Call := 'C' String Array - -A Call consists of a single octet with the ASCII value 'C', followed by a -String containing the method name and an Array containing the parameters. - - Response := 'R' (Value|Fault) - -A Response MUST contain either a Value or a Fault. - - Fault := 'F' Struct - -A Fault contains a regular Struct (with members as specified by the the -XML-RPC specification). - -Trailing data at the end of an 'application/x-binmode-rpc' document MUST be -ignored. - - -Byte-Order of Integers ----------------------- - -(The following integer types don't correspond directly to XML-RPC -integers--instead, they'll be used to *build* more complicated types.) - - SignedLSB := a four-octet, signed, twos'-complement integer, - least-significant byte (LSB) first - UnsignedLSB := a four-octet, unsigned integer, LSB first - -Raw integer data is encoded in little-endian format. - -Rationale: A fixed, mandatory byte ordering is easier to implement than -approaches which allow multiple byte orderings, and little-endian CPUs -outnumber big-endian CPUs at the time of writing. - - -Values ------- - - Value := (Integer|Boolean|Double|DateTimeISO8601Binary|Array|Struct| - String|Other) - - Integer := 'I' SignedLSB - Boolean := ('t'|'f') - - Double := 'D' SizeOctet AsciiChar... - DateTimeISO8601 := '8' SizeOctet AsciiChar... - -These two types are encoded with an unsigned size octet followed by the -specified number of ASCII characters. The values are encoded in the fashion -described by the XML-RPC specification. - -Rationale: In both these cases, we're punting. Binary floating point -formats are highly non-portable, and cannot be easily manipulated by most -programming languages. XML-RPC values lack timezone -information, and are therefore difficult to convert to a binary format. - - Binary := 'B' UnsignedLSB Octet... - -This corresponds to the XML-RPC type, but without any encoding. -The UnsignedLSB specifies the number of octets of data. - - Array := 'A' UnsignedLSB Value... - -The UnsignedLSB specifies the number of values in the array. - - Struct := 'S' UnsignedLSB (String,Value)... - -The UnsignedLSB specifies the number of String,Value pairs in the struct. -The strings are keys; the values may be of any type. - - Other := 'O' String Binary - -Future XML-RPC types (if any) may be sent a String containing the type name -and a Binary block (as above) containing type-specific data. -Implementations MUST NOT encode any of the standard types using this -construct. Implementations MAY signal an error if data of type Other is -encountered. - -Rationale: This is allowed to cause an error because most applications -won't understand the contents anyway. But if new types are added, dumb -gateways will be able to manipulate them in encapsulated format (if they so -desire). - - -Strings -------- - - String := (RegularString|RecordedString|RecalledString) - -We have three types of strings. - - RegularString := 'U' StringData - StringData := UnsignedLSB Utf8Octet... - -Strings are encoded in UTF-8 format. The UnsignedLSB specifies the number -of UTF-8 octets. Implementations SHOULD raise an error if they encounter -invalid UTF-8 data (e.g., ISO Latin 1 characters). - -Rationale: Technically speaking, XML-RPC is limited to plain ASCII -characters, and may not contain 8-bit or 16-bit characters in any coding -system. But since XML-RPC is based on XML, adding Unicode is a trivial -enhancement to the basic protocol, and *somebody* will make it sooner or -later. When that day arrives, we want to be able to encode Unicode -characters. - -Implements MUST encode UTF-8 characters using the minimum number of octets. -Implementations SHOULD raise an error if they encounter any UTF-8 -characters encoded using more than the minimum number of octets. - -Rationale: Overlong UTF-8 encodings are sometimes used to bypass string -validation in security code. They serve no legitimate purpose, either. So -to improve the overall security of the Universe, we work hard to discourage -them. - -UTF-8 & Unicode FAQ: http://www.cl.cam.ac.uk/~mgk25/unicode.html - - RecordedString := '>' CodebookPosition StringData - RecalledString := '<' CodebookPosition - CodebookPosition := UnsignedOctet - -The 'binmode' format allows a 256-entry "codebook" of strings. At the -start of a data stream, the codebook is empty. When the decoder -encounters a RecordedString, it MUST store it into the specified codebook -position (and then proceed to decode it as a regular string). - -When the decoder encounters a RecalledString, it MUST look it up in the -specified codebook position. If that codebook position has been set, the -implementation MUST use the string value found in the codebook. If the -position has not been set, the implementation MUST stop decoding and raise -an error. It is legal to change a codebook position once it has been set; -the most recent value applies. - -A RecordedString or a RecalledString may be used anywhere a RegularString -may be used. - -Rationale: XML-RPC data tends to contain large numbers of identical -strings. (These are typically the names of members or the names of -methods in a multicall.) To get any kind of reasonable data compression, -it's necessary to have some way of compressing these values. The codebook -mechanism is relatively simple and uncomplicated. - -Implementations MAY choose not to use this feature when encoding data, but -MUST understand it when decoding data. - -Rationale: On the decoding end of things, this feature is trivial to -implement, and must be present for the sake of interoperability. On the -encoding end of things, however, making effective use of this feature is -slightly trickier, so implementations are allowed (but not encouraged) to -omit it. - - -Compliance ----------- - -Implementations MUST implement all features of this protocol correctly, -particularly on the decoding end. In the case of this protocol, a 95% correct -implementation is 100% broken. Yes, this statement is redundant. ;-) - - -Examples --------- - -Non-ASCII octets are specified as in C strings. Continued lines are -indicated by a trailing '\'; these should be joined together as one -sequence of bytes. - -binmode-rpc:CU\003\0\0\0addA\002\0\0\0I\002\0\0\0I\002\0\0\0 - -binmode-rpc:RI\004\0\0\0 - -binmode-rpc:RFS\002\0\0\0 \ -U\011\0\0\0faultCodeI\001\0\0\0 \ -U\013\0\0\0faultStringU\021\0\0\0An error occurred - -binmode-rpc:RA\006\0\0\0 \ ->\000\003\0\0\0foo \ ->\001\003\0\0\0bar \ -<\000 \ ->\000\003\0\0\0baz \ -<\000 \ -<\001 - -(This deserializes to ['foo', 'bar', 'foo', 'baz', 'baz', 'bar'].) - -binmode-rpc:RU\042\0\0\0Copyright \302\251 1995 J. Random Hacker - -(This is based on an example in the Unicode/UTF-8 FAQ (see above).) - -binmode-rpc:RA\010\0\0\0 \ -I\006\0\0\0 \ -tf \ -D\0042.75 \ -8\02119980717T14:08:55 \ -U\003\0\0\0foo \ -B\003\0\0\0abc \ -S\002\0\0\0U\003\0\0\0runt - -Counter-Examples ----------------- - -The following specimens are illegal, and SHOULD be rejected by a compliant -implementation. Please test your code. - -* A different format name: - - binmode-rpc2:RI\004\0\0\0 - -* A built-in type incorrectly encoded using 'O': - - binmode-rpc:ROU\006\0\0\0stringB\003\0\0\0xyz - -* A recall of an unrecorded string: - - binmode-rpc:R<\002 - -* ISO Latin 1 data in a string. (UTF-8 required!) - - binmode-rpc:RU\041\0\0\0Copyright \251 1995 J. Random Hacker - -* UTF-8 character encoded with too many octets (based on an example in the - Unicode/UTF-8 FAQ): - - binmode-rpc:RU\041\0\0\0Bad linefeed: \300\212 (too many bytes) - -A compliant implementation MUST NOT send any of these sequences. diff --git a/trunk/tools/binmode-rpc-kit/binmode-rpc2xml-rpc b/trunk/tools/binmode-rpc-kit/binmode-rpc2xml-rpc deleted file mode 100755 index 2625629bd..000000000 --- a/trunk/tools/binmode-rpc-kit/binmode-rpc2xml-rpc +++ /dev/null @@ -1,552 +0,0 @@ -#!/usr/bin/perl -w - -use strict; - -# Some constants. -my $crlf = "\015\012"; - -# Try to load our external libraries, but fail gracefully. -eval { - require Frontier::Client; - require MIME::Base64; -}; -if ($@) { - print STDERR <<"EOD"; -This script requires Ken MacLeod\'s Frontier::RPC2 module. You can get this -from CPAN or from his website at http://bitsko.slc.ut.us/~ken/xml-rpc/ . - -For installation instructions, see the XML-RPC HOWTO at: - http://www.linuxdoc.org/HOWTO/XML-RPC-HOWTO/index.html - -This script also requires MIME::Base64. You can get this from CPAN. -EOD - exit 1; -} - -# Parse our command-line arguments. -if (@ARGV != 0) { - print STDERR "Usage: binmode-rpc2xml-rpc < data.binmode > data.xml\n"; - exit 1; -} - -# Perform our I/O in binary mode (hence the name of the protocol). -binmode STDIN; # Because we're reading raw binary data. -binmode STDOUT; # Because we want our XML left unmolested. - -# Just suck all our input into one string and glom it together. -my $binmode_data = join('', ); - -# Check for the mandatory header. -unless ($binmode_data =~ /^binmode-rpc:/) { - die "$0: No 'binmode-rpc:' header present, stopping"; -} - -# Set our decoding-position counter to point just past the header, and -# our end pointer to just beyond the end of the entire message. -my $position = length('binmode-rpc:'); -my $end = length($binmode_data); - -# Set our starting output indentation to zero (for the pretty-printer). -my $indentation = 0; - -# Build an empty codebook of strings. -my @codebook; - -# Begin the hard work. -decode_call_or_response(); - -# Print a warning if there's leftover data. -if ($position != $end) { - printf STDERR "binmode-rpc2xml-rpc: warning: Trailing data ignored\n"; -} - -# We're done! -exit (0); - - -#-------------------------------------------------------------------------- -# Pretty-printing -#-------------------------------------------------------------------------- - -sub escape_string ($) { - my ($string) = @_; - $string =~ s/&/&/g; - $string =~ s/= 0) { - die "Perl can't handle 32-bit unsigned integers portably, stopping"; - } - return $integer; -} - -sub read_signed_lsb () { - die "Unexpected end of input" unless ($position + 4 <= $end); - my $integer = unpack('V', substr($binmode_data, $position, 4)); - $position += 4; - die "Weird error decoding integer" unless (defined $integer); - return $integer; -} - -sub read_data ($) { - my ($length) = @_; - die "Unexpected end of input" unless ($position + $length <= $end); - my $data = unpack("a$length", substr($binmode_data, $position, $length)); - $position += $length; - die "Weird error decoding data" unless (defined $data); - die "Wrong data length" unless (length($data) == $length); - return $data; -} - -sub read_data_w_byte_length () { - my $length = read_byte(); - return read_data($length); -} - -sub read_data_w_unsigned_lsb_length () { - my $length = read_unsigned_lsb(); - return read_data($length) -} - -sub read_string_data () { - my $string = read_data_w_unsigned_lsb_length(); - validate_utf8($string); - return $string; -} - - -#-------------------------------------------------------------------------- -# High-level input routines -#-------------------------------------------------------------------------- -# These use the low-level input routines to read data from the buffer, -# and then convert it into Frontier::RPC2 objects. - -sub read_value () { - my $type = read_character(); - #print STDERR "DEBUG: Reading from '$type'\n"; - if ($type eq 'I') { - return _read_int_value(); - } elsif ($type eq 't') { - return Frontier::RPC2::Boolean->new(1); - } elsif ($type eq 'f') { - return Frontier::RPC2::Boolean->new(0); - } elsif ($type eq 'D') { - return _read_double_value(); - } elsif ($type eq '8') { - return _read_dateTime_value(); - } elsif ($type eq 'B') { - return _read_base64_value(); - } elsif ($type eq 'A') { - return _read_array_value(); - } elsif ($type eq 'S') { - return _read_struct_value(); - } elsif ($type eq 'U') { - return _read_regular_string_value(); - } elsif ($type eq '>') { - return _read_recorded_string_value(); - } elsif ($type eq '<') { - return _read_recalled_string_value(); - } elsif ($type eq 'O') { - die "Type 'O' Binmode RPC data not supported"; - } else { - die "Type '$type' Binmode RPC data does not exist"; - } -} - -sub read_value_and_typecheck ($) { - my ($wanted_type) = @_; - my $value = read_value(); - my $value_type = ref($value); - die "$0: Expected $wanted_type, got $value_type, stopping" - unless ($wanted_type eq $value_type); - return $value; -} - -sub _read_int_value () { - return Frontier::RPC2::Integer->new(read_signed_lsb); -} - -sub _read_double_value () { - return Frontier::RPC2::Double->new(read_data_w_byte_length); -} - -sub _read_dateTime_value () { - return Frontier::RPC2::DateTime::ISO8601->new(read_data_w_byte_length); -} - -sub _read_base64_value () { - my $binary = read_data_w_unsigned_lsb_length; - my $encoded = MIME::Base64::encode_base64($binary, $crlf); - return Frontier::RPC2::Base64->new($encoded); -} - -sub _read_array_value () { - my $size = read_unsigned_lsb; - my @values; - for (my $i = 0; $i < $size; $i++) { - push @values, read_value; - } - return \@values; -} - -sub _read_struct_value () { - my $size = read_unsigned_lsb; - my %struct; - for (my $i = 0; $i < $size; $i++) { - my $key = read_value_and_typecheck('Frontier::RPC2::String'); - $struct{$key->value} = read_value; - } - return \%struct; -} - -sub _read_regular_string_value () { - return Frontier::RPC2::String->new(read_string_data); -} - -sub _read_recorded_string_value () { - my $codebook_entry = read_byte; - my $string = Frontier::RPC2::String->new(read_string_data); - $codebook[$codebook_entry] = $string; - return $string; -} - -sub _read_recalled_string_value () { - my $codebook_entry = read_byte; - my $string = $codebook[$codebook_entry]; - unless (defined $string) { - die "$0: Attempted to use undefined codebook position $codebook_entry"; - } - return $string; -} - - -#-------------------------------------------------------------------------- -# High-level output routines -#-------------------------------------------------------------------------- -# We don't use Frontier::RPC2's output routines, because we're looking -# for maximum readability. This is a debugging tool, after all. - -sub print_xml_header () { - print_xml_line ''; -} - -sub get_escaped_string ($) { - my ($value) = @_; - return escape_string($value->value); -} - -sub print_simple_value ($$) { - my ($tag, $value) = @_; - my $string = get_escaped_string($value); - print_xml_line "<$tag>$string"; -} - -sub print_value ($) { - my ($value) = @_; - my $type = ref($value); - if ($type eq 'Frontier::RPC2::Integer') { - print_simple_value("int", $value); - } elsif ($type eq 'Frontier::RPC2::Double') { - print_simple_value("double", $value); - } elsif ($type eq 'Frontier::RPC2::Boolean') { - print_simple_value("boolean", $value); - } elsif ($type eq 'Frontier::RPC2::String') { - print_simple_value("string", $value); - } elsif ($type eq 'Frontier::RPC2::DateTime::ISO8601') { - print_simple_value("dateTime.iso8601", $value); - } elsif ($type eq 'Frontier::RPC2::Base64') { - print_base64_data($value); - } elsif ($type eq 'ARRAY') { - print_array_value($value); - } elsif ($type eq 'HASH') { - print_struct_value($value); - } else { - die "Unxpected type '$type', stopping"; - } -} - -sub print_params ($) { - my ($params) = @_; - - die "Wanted array" unless (ref($params) eq 'ARRAY'); - - print_xml_line ''; - push_indentation_level; - - foreach my $item (@$params) { - print_xml_line ''; - push_indentation_level; - print_value($item); - pop_indentation_level; - print_xml_line ''; - } - - pop_indentation_level; - print_xml_line ''; -} - -sub print_base64_data ($) { - my ($value) = @_; - print_xml_line ''; - push_indentation_level; - print_xml_line ''; - print $value->value; - print_xml_line ''; - pop_indentation_level; - print_xml_line ''; -} - -sub print_array_value ($) { - my ($array) = @_; - - print_xml_line ''; - push_indentation_level; - print_xml_line ''; - push_indentation_level; - print_xml_line ''; - push_indentation_level; - - foreach my $item (@$array) { - print_value($item); - } - - pop_indentation_level; - print_xml_line ''; - pop_indentation_level; - print_xml_line ''; - pop_indentation_level; - print_xml_line ''; -} - -sub print_struct_value ($) { - my ($struct) = @_; - - print_xml_line ''; - push_indentation_level; - print_xml_line ''; - push_indentation_level; - - for my $key (keys %$struct) { - print_xml_line ''; - push_indentation_level; - - my $name = escape_string($key); - print_xml_line "$name"; - print_value($struct->{$key}); - - pop_indentation_level; - print_xml_line ''; - } - - pop_indentation_level; - print_xml_line ''; - pop_indentation_level; - print_xml_line ''; -} - - -#-------------------------------------------------------------------------- -# High-level decoder routines -#-------------------------------------------------------------------------- -# These routines convert Binmode RPC data into the corresponding XML-RPC -# documents. - -sub decode_call_or_response () { - my $type = read_character(); - if ($type eq 'C') { - decode_call(); - } elsif ($type eq 'R') { - decode_response(); - } else { - die "$0: Unknown binmode-rpc request type '$type', stopping"; - } -} - -sub decode_call () { - my $namevalue = read_value_and_typecheck('Frontier::RPC2::String'); - my $params = read_value_and_typecheck('ARRAY'); - - print_xml_header; - print_xml_line ''; - push_indentation_level; - - my $name = get_escaped_string($namevalue); - print_xml_line "$name"; - - print_params($params); - - pop_indentation_level; - print_xml_line ''; -} - -sub decode_response () { - my $maybe_fault = peek_character; - if ($maybe_fault eq 'F') { - read_character; - my $fault = read_value_and_typecheck('HASH'); - print_xml_header; - - print_xml_line ''; - push_indentation_level; - print_xml_line ''; - push_indentation_level; - - print_value $fault; - - pop_indentation_level; - print_xml_line ''; - pop_indentation_level; - print_xml_line ''; - } else { - my $value = read_value; - print_xml_header; - print_xml_line ''; - push_indentation_level; - print_params [$value]; - pop_indentation_level; - print_xml_line ''; - } -} - - -#-------------------------------------------------------------------------- -# UTF-8 Validation -#-------------------------------------------------------------------------- -# This is based on the UTF-8 section of the Secure Programs HOWTO. -# http://new.linuxnow.com/docs/content/HOWTO/Secure-Programs-HOWTO/ -# This code *hasn't* been stress-tested for correctness yet; please see: -# http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt -# This is not yet good enough to be used as part of a UTF-8 decoder or -# security validator, but it's OK to make sure nobody is sending Latin-1. - -BEGIN { - - use vars qw{@illegal_initial_bytes @sequence_length_info}; - - # Bytes are represented as data/mask pairs. - @illegal_initial_bytes = - (# 10xxxxxx illegal as initial byte of char (80..BF) - [0x80, 0xC0], - # 1100000x illegal, overlong (C0..C1 80..BF) - [0xC0, 0xFE], - # 11100000 100xxxxx illegal, overlong (E0 80..9F) - [0xE0, 0xFF, 0x80, 0xE0], - # 11110000 1000xxxx illegal, overlong (F0 80..8F) - [0xF0, 0xFF, 0x80, 0xF0], - # 11111000 10000xxx illegal, overlong (F8 80..87) - [0xF8, 0xFF, 0x80, 0xF8], - # 11111100 100000xx illegal, overlong (FC 80..83) - [0xFC, 0xFF, 0x80, 0xFC], - # 1111111x illegal; prohibited by spec - [0xFE, 0xFE]); - - # Items are byte, mask, sequence length. - @sequence_length_info = - (# 110xxxxx 10xxxxxx - [0xC0, 0xE0, 2], - # 1110xxxx 10xxxxxx 10xxxxxx - [0xE0, 0xF0, 3], - # 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - [0xF0, 0xF8, 4], - # 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - [0xF8, 0xFC, 5], - # 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - [0xFC, 0xFE, 6]); -} - -sub validate_utf8 ($) { - my ($string) = @_; - my $end = length($string); - - my $i = 0; - while ($i < $end) { - my $byte = ord(substr($string, $i, 1)); - #print STDERR "Checking byte $byte\n"; - - # Check for illegal bytes at the start of this sequence. - NEXT_CANDIDATE: - foreach my $illegal_byte_info (@illegal_initial_bytes) { - my $offset = 0; - for (my $j = 0; $j < @$illegal_byte_info; $j += 2) { - my $pattern = $illegal_byte_info->[$j]; - my $mask = $illegal_byte_info->[$j+1]; - my $data = ord(substr($string, $i+$offset, 1)); - #print STDERR " B: $byte P: $pattern M: $mask D: $data\n"; - next NEXT_CANDIDATE unless ($data & $mask) == $pattern; - $offset++; - } - die "Illegal UTF-8 sequence (" . substr($string, $i, 2) . ")"; - } - - # Find the length of the sequence, and make sure we have enough data. - my $length = 1; - foreach my $length_info (@sequence_length_info) { - my ($pattern, $mask, $length_candidate) = @$length_info; - if (($byte & $mask) == $pattern) { - $length = $length_candidate; - last; - } - } - die "$0: Unexpected end of UTF-8 sequence, stopping" - unless $i + $length <= $end; - - # Verify the sequence is well-formed. - $i++, $length--; - while ($length > 0) { - die "$0: Malformed UTF-8 sequence, stopping" - unless (ord(substr($string, $i, 1)) & 0xC0) == 0x80; - $i++, $length--; - } - } - #printf STDERR "DEBUG: Verified $i bytes\n"; -} diff --git a/trunk/tools/binmode-rpc-kit/examples/good-1.binmode b/trunk/tools/binmode-rpc-kit/examples/good-1.binmode deleted file mode 100644 index 53c57403f0ee1f99275b5f73d4271ab0f75dc541..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80 zcmYew%*)MBN!2YXNVW=ciyB>>_P5YYet diff --git a/trunk/tools/binmode-rpc-kit/examples/good-1.xml b/trunk/tools/binmode-rpc-kit/examples/good-1.xml deleted file mode 100644 index 3f9feaa01..000000000 --- a/trunk/tools/binmode-rpc-kit/examples/good-1.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - 6 - 1 - 0 - 2.75 - 19980717T14:08:55 - foo - - -YWJj - - - - - - run - 1 - - - - - - - - - diff --git a/trunk/tools/binmode-rpc-kit/examples/good-2.binmode b/trunk/tools/binmode-rpc-kit/examples/good-2.binmode deleted file mode 100644 index 8fd69ef786cf153bc0e10e1ef57125ad9125c1eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36 icmYew%*)MBN!2YXNVakgWoBStNK8p_WCGHjZ~_3f3I`|v diff --git a/trunk/tools/binmode-rpc-kit/examples/good-2.xml b/trunk/tools/binmode-rpc-kit/examples/good-2.xml deleted file mode 100644 index ab1db1ad6..000000000 --- a/trunk/tools/binmode-rpc-kit/examples/good-2.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - add - - - 2 - - - 2 - - - diff --git a/trunk/tools/binmode-rpc-kit/examples/good-3.binmode b/trunk/tools/binmode-rpc-kit/examples/good-3.binmode deleted file mode 100644 index a0633e8bebffd4e7599104b7106bf87e03264a24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18 ZcmYew%*)MBN!2YXNVW>{WMN=n002FH1u6gl diff --git a/trunk/tools/binmode-rpc-kit/examples/good-3.xml b/trunk/tools/binmode-rpc-kit/examples/good-3.xml deleted file mode 100644 index 4262551fc..000000000 --- a/trunk/tools/binmode-rpc-kit/examples/good-3.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - 4 - - - diff --git a/trunk/tools/binmode-rpc-kit/examples/good-4.binmode b/trunk/tools/binmode-rpc-kit/examples/good-4.binmode deleted file mode 100644 index 3d95e779985110d395aed59bba23863553b5b088..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76 zcmYew%*)MBN!2YXNVW=c3ua - - - - - - faultString - An error occurred - - - faultCode - 1 - - - - - diff --git a/trunk/tools/binmode-rpc-kit/examples/good-5.binmode b/trunk/tools/binmode-rpc-kit/examples/good-5.binmode deleted file mode 100644 index e869c55d25f5071094ef2ed711c22b51518feba4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51 xcmYew%*)MBN!2YXNVW=cWMg1puw!5bl4<$*c8nlKQeu$}R4gg6%7(#)5db=K3R3_8 diff --git a/trunk/tools/binmode-rpc-kit/examples/good-5.xml b/trunk/tools/binmode-rpc-kit/examples/good-5.xml deleted file mode 100644 index 601ff3d22..000000000 --- a/trunk/tools/binmode-rpc-kit/examples/good-5.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - foo - bar - foo - baz - baz - bar - - - - - - diff --git a/trunk/tools/binmode-rpc-kit/examples/good-6.binmode b/trunk/tools/binmode-rpc-kit/examples/good-6.binmode deleted file mode 100644 index 8a7c6214e77f9493a124c79abdab8c611fb54772..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 zcmYew%*)MBN!2YXNVW - - - - Copyright © 1995 J. Random Hacker - - - diff --git a/trunk/tools/binmode-rpc-kit/examples/invalid-1.binmode b/trunk/tools/binmode-rpc-kit/examples/invalid-1.binmode deleted file mode 100644 index 4076dbb69a1f31f25e7378dfe56bc3a089dc0d9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19 acmYew%*)MBN!2YXNH($x@?>FPU;qF^Uj{4`pLuU??sr%FIi5Vg@oRDysmr$O+B> diff --git a/trunk/tools/binmode-rpc-kit/examples/invalid-3.binmode b/trunk/tools/binmode-rpc-kit/examples/invalid-3.binmode deleted file mode 100644 index ad5e88399..000000000 --- a/trunk/tools/binmode-rpc-kit/examples/invalid-3.binmode +++ /dev/null @@ -1 +0,0 @@ -binmode-rpc:R< \ No newline at end of file diff --git a/trunk/tools/binmode-rpc-kit/examples/invalid-4.binmode b/trunk/tools/binmode-rpc-kit/examples/invalid-4.binmode deleted file mode 100644 index 69aa2f464d31fc15b046650c42c766ffba2a497b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51 zcmYew%*)MBN!2YXNVW out.binmode". - -binmode STDOUT; - -while (<>) { - s/\\(\d\d\d)/chr(oct($1))/ge; - s/\\0/chr(0)/ge; - s/\\\\/\\/g; - print $_; -} diff --git a/trunk/tools/common.mk b/trunk/tools/common.mk deleted file mode 100644 index 1218e18cb..000000000 --- a/trunk/tools/common.mk +++ /dev/null @@ -1,49 +0,0 @@ -CLIENT_LDLIBS = $(shell cat blddir/src/libxmlrpc_client.ldflags) $(LDLIBS_XML) - -CLIENT_LIBS_DEP = \ - $(LIBXMLRPC_CLIENT) \ - $(LIBXMLRPC) \ - $(LIBXMLRPC_XML) \ - $(LIBXMLRPC_UTIL) \ - $(BLDDIR)/src/libxmlrpc_client.ldflags \ - -CLIENTPP_LDLIBS = \ - -Lblddir/src/cpp \ - -lxmlrpc_client++ \ - -lxmlrpc_packetsocket \ - -lxmlrpc++ \ - -Lblddir/lib/libutil++ \ - -lxmlrpc_util++ \ - -SERVER_ABYSS_LDLIBS = \ - $(LIBXMLRPC_SERVER_ABYSS) \ - $(LIBXMLRPC_ABYSS) \ - $(LIBXMLRPC_SERVER) \ - $(LIBXMLRPC) \ - $(LIBXMLRPC_XML) \ - $(LIBXMLRPC_UTIL) \ - $(LDLIBS_XML) \ - -SERVER_ABYSS_LIBS_DEP = \ - $(LIBXMLRPC_SERVER_ABYSS) \ - $(LIBXMLRPC_ABYSS) \ - $(LIBXMLRPC_SERVER) \ - $(LIBXMLRPC) \ - $(LIBXMLRPC_XML) \ - $(LIBXMLRPC_UTIL) \ - -include $(SRCDIR)/common.mk - -ifneq ($(OMIT_LIB_RULE),Y) -blddir/tools/lib/dumpvalue.o: FORCE - $(MAKE) -C $(dir $@) -f $(SRCDIR)/tools/lib/Makefile $(notdir $@) -endif - -.PHONY: install -install: install-common - -.PHONY: check -check: - -.PHONY: FORCE -FORCE: diff --git a/trunk/tools/interop-server/interop-cgi.c b/trunk/tools/interop-server/interop-cgi.c deleted file mode 100644 index d07926716..000000000 --- a/trunk/tools/interop-server/interop-cgi.c +++ /dev/null @@ -1,215 +0,0 @@ -/* A CGI which implements all of the test functions need for an interop -** endpoint. */ - -#include -#include -#include - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/cgi.h" - -#include "version.h" - -#include "config.h" /* information about this build environment */ - - -/*========================================================================= -** Toolkit Identification -**========================================================================= -*/ - -static xmlrpc_value * -whichToolkit(xmlrpc_env * const env, - xmlrpc_value * const param_array, - void * const user_data ATTR_UNUSED) { - - xmlrpc_value * retval; - - /* Parse our argument array. */ - xmlrpc_parse_value(env, param_array, "()"); - if (env->fault_occurred) - retval = NULL; - else { - struct utsname utsname; - - int rc; - rc = uname(&utsname); - if (rc != 0) { - xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, - "uname() failed. errno=%d (%s)", - errno, strerror(errno)); - retval = NULL; - } else { - /* Assemble our result. */ - retval = xmlrpc_build_value(env, "{s:s,s:s,s:s,s:s}", - "toolkitDocsUrl", - "http://xmlrpc-c.sourceforge.net/", - "toolkitName", PACKAGE, - "toolkitVersion", XMLRPC_C_VERSION"+", - "toolkitOperatingSystem", - utsname.sysname); - } - } - return retval; -} - - - -static char whichToolkit_help[] = -"Identify the toolkit used to implement this server. The operating system " -"information is based on where the toolkit was compiled, not where it's " -"currently running."; - - -/*========================================================================= -** noInParams -**========================================================================= -** Test a method with no parameters. -*/ - -static xmlrpc_value * -noInParams(xmlrpc_env * const env, - xmlrpc_value * const param_array, - void * const user_data ATTR_UNUSED) { - - /* Parse our argument array. */ - xmlrpc_parse_value(env, param_array, "()"); - if (env->fault_occurred) - return NULL; - - /* Assemble our result. */ - return xmlrpc_build_value(env, "i", (xmlrpc_int32) 0); -} - -static char noInParams_help[] = -"A method with no parameters. Returns an arbitrary int."; - - -/*========================================================================= -** Echo Tests -**========================================================================= -** We're lazy--we only implement one actual echo method, but we hook it -** up to lots of different names. -*/ - -static xmlrpc_value * -echoValue(xmlrpc_env * const env, - xmlrpc_value * const param_array, - void * const user_data ATTR_UNUSED) { - - xmlrpc_value *val; - - /* Parse our argument array. */ - xmlrpc_parse_value(env, param_array, "(V)", &val); - if (env->fault_occurred) - return NULL; - - /* Create a new reference (because both our parameter list and our - ** return value will be DECREF'd when we return). */ - xmlrpc_INCREF(val); - - /* Return our result. */ - return val; -} - -static char echoValue_help[] = -"Echo an arbitrary XML-RPC value of any type."; - -static char echoString_help[] = -"Echo an arbitrary XML-RPC string."; - -static char echoInteger_help[] = -"Echo an arbitrary XML-RPC integer."; - -static char echoBoolean_help[] = -"Echo an arbitrary XML-RPC boolean value."; - -static char echoFloat_help[] = -"Echo an arbitrary XML-RPC float."; - -static char echoStruct_help[] = -"Echo an arbitrary XML-RPC struct."; - -static char echoDate_help[] = -"Echo an arbitrary XML-RPC date/time value."; - -static char echoBase64_help[] = -"Echo an arbitrary XML-RPC Base64 value."; - -static char echoStringArray_help[] = -"Echo an array of arbitrary XML-RPC strings."; - -static char echoIntegerArray_help[] = -"Echo an array of arbitrary XML-RPC integers."; - -static char echoFloatArray_help[] = -"Echo an array of arbitrary XML-RPC floats."; - -static char echoStructArray_help[] = -"Echo an array of arbitrary XML-RPC structs."; - - -/*========================================================================= -** Server Setup -**========================================================================= -** Set up and run our server. -*/ - -int -main(int const argc ATTR_UNUSED, - char ** const argv ATTR_UNUSED) { - - /* Process our request. */ - xmlrpc_cgi_init(XMLRPC_CGI_NO_FLAGS); - - /* Add a method to identify our toolkit. */ - xmlrpc_cgi_add_method_w_doc("interopEchoTests.whichToolkit", - &whichToolkit, NULL, - "S:", whichToolkit_help); - - /* Add a whole bunch of test methods. */ - xmlrpc_cgi_add_method_w_doc("interopEchoTests.noInParams", - &noInParams, NULL, - "i:", noInParams_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoValue", - &echoValue, NULL, - "?", echoValue_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoString", - &echoValue, NULL, - "s:s", echoString_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoInteger", - &echoValue, NULL, - "i:i", echoInteger_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoBoolean", - &echoValue, NULL, - "b:b", echoBoolean_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoFloat", - &echoValue, NULL, - "d:d", echoFloat_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoStruct", - &echoValue, NULL, - "S:S", echoStruct_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoDate", - &echoValue, NULL, - "8:8", echoDate_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoBase64", - &echoValue, NULL, - "6:6", echoBase64_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoStringArray", - &echoValue, NULL, - "A:A", echoStringArray_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoIntegerArray", - &echoValue, NULL, - "A:A", echoIntegerArray_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoFloatArray", - &echoValue, NULL, - "A:A", echoFloatArray_help); - xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoStructArray", - &echoValue, NULL, - "A:A", echoStructArray_help); - - xmlrpc_cgi_process_call(); - xmlrpc_cgi_cleanup(); - - return 0; -} diff --git a/trunk/tools/lib/Makefile b/trunk/tools/lib/Makefile deleted file mode 100644 index 836d9c97c..000000000 --- a/trunk/tools/lib/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - TOOLSDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(TOOLSDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools/lib - -default: all - -include $(BLDDIR)/config.mk - -OMIT_LIB_RULE = Y - -include $(SRCDIR)/tools/common.mk - -INCLUDES = \ - -Isrcdir/$(SUBDIR)/include \ - -Iblddir \ - -Isrcdir/include \ - -Isrcdir/lib/util/include \ - -LIBOBJS = \ - dumpvalue.o \ - -.PHONY: all -all: $(LIBOBJS) - -%.o:%.c - $(CC) -c $(CFLAGS_ALL) $< - -# This common.mk dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/tools/common.mk: srcdir blddir - -include depend.mk - -.PHONY: dep -dep: dep-common - -.PHONY: clean -clean: clean-common - -.PHONY: distclean -distclean: clean distclean-common diff --git a/trunk/tools/lib/dumpvalue.c b/trunk/tools/lib/dumpvalue.c deleted file mode 100644 index ddb52662d..000000000 --- a/trunk/tools/lib/dumpvalue.c +++ /dev/null @@ -1,497 +0,0 @@ -/* dumpvalue() service, which prints to Standard Output the value of - an xmlrpc_value. - - We've put this in a separate module in hopes that it eventually can be - used for debugging purposes in other places. -*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include - -#include "xmlrpc_config.h" /* information about this build environment */ -#include "int.h" -#include "casprintf.h" -#include "mallocvar.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/string_int.h" - -#include "dumpvalue.h" - - - -static void -dumpInt(const char * const prefix, - xmlrpc_value * const valueP) { - - xmlrpc_env env; - xmlrpc_int value; - - xmlrpc_env_init(&env); - - xmlrpc_read_int(&env, valueP, &value); - - if (env.fault_occurred) - printf("Internal error: unable to extract value of " - "integer xmlrpc_value %lx. %s\n", - (unsigned long)valueP, env.fault_string); - else - printf("%sInteger: %d\n", prefix, value); - - xmlrpc_env_clean(&env); -} - - - -static void -dumpBool(const char * const prefix, - xmlrpc_value * const valueP) { - - xmlrpc_env env; - xmlrpc_bool value; - - xmlrpc_env_init(&env); - - xmlrpc_read_bool(&env, valueP, &value); - - if (env.fault_occurred) - printf("Internal error: Unable to extract value of " - "boolean xmlrpc_value %lx. %s\n", - (unsigned long)valueP, env.fault_string); - else - printf("%sBoolean: %s\n", prefix, value ? "TRUE" : "FALSE"); - - xmlrpc_env_clean(&env); -} - - - -static void -dumpDouble(const char * const prefix, - xmlrpc_value * const valueP) { - - xmlrpc_env env; - xmlrpc_double value; - - xmlrpc_env_init(&env); - - xmlrpc_read_double(&env, valueP, &value); - - if (env.fault_occurred) - printf("Internal error: Unable to extract value from " - "floating point number xmlrpc_value %lx. %s\n", - (unsigned long)valueP, env.fault_string); - else - printf("%sFloating Point: %f\n", prefix, value); - - xmlrpc_env_clean(&env); -} - - - -static void -dumpDatetime(const char * const prefix, - xmlrpc_value * const valueP) { - - xmlrpc_env env; - xmlrpc_datetime value; - - xmlrpc_env_init(&env); - - xmlrpc_read_datetime(&env, valueP, &value); - - if (env.fault_occurred) - printf("Internal error: Unable to extract value from " - "datetime xmlrpc_value %lx. %s\n", - (unsigned long)valueP, env.fault_string); - else - printf("%sDatetime: %u.%02u.%02u %02u:%02u:%02u.%06u\n", - prefix, - value.Y, - value.M, - value.D, - value.h, - value.m, - value.s, - value.u - ); - - xmlrpc_env_clean(&env); -} - - - -static size_t -nextLineSize(const char * const string, - size_t const startPos, - size_t const stringSize) { -/*---------------------------------------------------------------------------- - Return the length of the line that starts at offset 'startPos' in the - string 'string', which is 'stringSize' characters long. - - 'string' in not NUL-terminated. - - A line begins at beginning of string or after a newline character and - runs through the next newline character or end of string. The line - includes the newline character at the end, if any. ------------------------------------------------------------------------------*/ - size_t i; - - for (i = startPos; i < stringSize && string[i] != '\n'; ++i); - - if (i < stringSize) - ++i; /* Include the newline */ - - return i - startPos; -} - - - -static void -dumpMultilineString(const char * const prefix, - const char * const value, - size_t const length) { - - size_t cursor; /* Index into value[] */ - - for (cursor = 0; cursor < length; ) { - /* Print one line of buffer */ - - size_t const lineSize = nextLineSize(value, cursor, length); - const char * const printableLine = - xmlrpc_makePrintable_lp(&value[cursor], lineSize); - - printf("%s%s\n", prefix, printableLine); - - cursor += lineSize; - - strfree(printableLine); - } -} - - - -static void -dumpSimpleString(const char * const value, - size_t const length) { - - const char * const printable = xmlrpc_makePrintable_lp(value, length); - - printf("'%s'\n", printable); - - strfree(printable); -} - - - -static void -dumpString(const char * const prefix, - xmlrpc_value * const valueP) { - - xmlrpc_env env; - size_t length; - const char * value; - - xmlrpc_env_init(&env); - - xmlrpc_read_string_lp(&env, valueP, &length, &value); - - if (env.fault_occurred) - printf("Internal error: Unable to extract value from " - "string xmlrpc_value %lx. %s\n", - (unsigned long)valueP, env.fault_string); - else { - printf("%sString: ", prefix); - if (strlen(value) == length && strchr(value, '\n')) { - const char * prefix2; - casprintf(&prefix2, "%s ", prefix); - printf("\n"); - dumpMultilineString(prefix2, value, length); - strfree(prefix2); - } else - dumpSimpleString(value, length); - - strfree(value); - } - xmlrpc_env_clean(&env); -} - - - -static void -dumpBase64(const char * const prefix, - xmlrpc_value * const valueP) { - - xmlrpc_env env; - const unsigned char * value; - size_t length; - - xmlrpc_env_init(&env); - - xmlrpc_read_base64(&env, valueP, &length, &value); - - if (env.fault_occurred) - printf("Unable to parse base64 bit string xmlrpc_value %lx. %s\n", - (unsigned long)valueP, env.fault_string); - else { - unsigned int i; - - printf("%sBit string: ", prefix); - for (i = 0; i < length; ++i) - printf("%02x", value[i]); - - free((void*)value); - } - xmlrpc_env_clean(&env); -} - - - -static void -dumpArray(const char * const prefix, - xmlrpc_value * const arrayP) { - - xmlrpc_env env; - unsigned int arraySize; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT_ARRAY_OK(arrayP); - - arraySize = xmlrpc_array_size(&env, arrayP); - if (env.fault_occurred) - printf("Unable to get array size. %s\n", env.fault_string); - else { - int const spaceCount = strlen(prefix); - - unsigned int i; - const char * blankPrefix; - - printf("%sArray of %u items:\n", prefix, arraySize); - - casprintf(&blankPrefix, "%*s", spaceCount, ""); - - for (i = 0; i < arraySize; ++i) { - xmlrpc_value * valueP; - - xmlrpc_array_read_item(&env, arrayP, i, &valueP); - - if (env.fault_occurred) - printf("Unable to get array item %u\n", i); - else { - const char * prefix2; - - casprintf(&prefix2, "%s Index %2u ", blankPrefix, i); - dumpValue(prefix2, valueP); - strfree(prefix2); - - xmlrpc_DECREF(valueP); - } - } - strfree(blankPrefix); - } - xmlrpc_env_clean(&env); -} - - - -static void -dumpStructMember(const char * const prefix, - xmlrpc_value * const structP, - unsigned int const index) { - - xmlrpc_env env; - - xmlrpc_value * keyP; - xmlrpc_value * valueP; - - xmlrpc_env_init(&env); - - xmlrpc_struct_read_member(&env, structP, index, &keyP, &valueP); - - if (env.fault_occurred) - printf("Unable to get struct member %u\n", index); - else { - int const blankCount = strlen(prefix); - const char * prefix2; - const char * blankPrefix; - - casprintf(&blankPrefix, "%*s", blankCount, ""); - - casprintf(&prefix2, "%s Key: ", blankPrefix); - dumpValue(prefix2, keyP); - strfree(prefix2); - - casprintf(&prefix2, "%s Value: ", blankPrefix); - dumpValue(prefix2, valueP); - strfree(prefix2); - - strfree(blankPrefix); - - xmlrpc_DECREF(keyP); - xmlrpc_DECREF(valueP); - } - xmlrpc_env_clean(&env); -} - - - -static void -dumpStruct(const char * const prefix, - xmlrpc_value * const structP) { - - xmlrpc_env env; - unsigned int structSize; - - xmlrpc_env_init(&env); - - structSize = xmlrpc_struct_size(&env, structP); - if (env.fault_occurred) - printf("Unable to get struct size. %s\n", env.fault_string); - else { - unsigned int i; - - printf("%sStruct of %u members:\n", prefix, structSize); - - for (i = 0; i < structSize; ++i) { - const char * prefix1; - - if (i == 0) - prefix1 = strdup(prefix); - else { - int const blankCount = strlen(prefix); - casprintf(&prefix1, "%*s", blankCount, ""); - } - dumpStructMember(prefix1, structP, i); - - strfree(prefix1); - } - } - xmlrpc_env_clean(&env); -} - - - -static void -dumpCPtr(const char * const prefix, - xmlrpc_value * const valueP) { - - xmlrpc_env env; - void * value; - - xmlrpc_env_init(&env); - - xmlrpc_read_cptr(&env, valueP, &value); - - if (env.fault_occurred) - printf("Unable to parse C pointer xmlrpc_value %lx. %s\n", - (unsigned long)valueP, env.fault_string); - else - printf("%sC pointer: '%lux'\n", prefix, (unsigned long)value); - - xmlrpc_env_clean(&env); -} - - - -static void -dumpNil(const char * const prefix, - xmlrpc_value * const valueP) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - xmlrpc_read_nil(&env, valueP); - - if (env.fault_occurred) - printf("Internal error: nil value xmlrpc_value %lx " - "is not valid. %s\n", - (unsigned long)valueP, env.fault_string); - else - printf("%sNil\n", prefix); - - xmlrpc_env_clean(&env); -} - - - -static void -dumpI8(const char * const prefix, - xmlrpc_value * const valueP) { - - xmlrpc_env env; - xmlrpc_int64 value; - - xmlrpc_env_init(&env); - - xmlrpc_read_i8(&env, valueP, &value); - - if (env.fault_occurred) - printf("Internal error: unable to extract value of " - "64-bit integer xmlrpc_value %lx. %s\n", - (unsigned long)valueP, env.fault_string); - else - printf("%s64-bit integer: %" XMLRPC_PRId64 "\n", prefix, value); - - xmlrpc_env_clean(&env); -} - - - -static void -dumpUnknown(const char * const prefix, - xmlrpc_value * const valueP) { - - printf("%sDon't recognize value type %u of xmlrpc_value %lx.\n", - prefix, xmlrpc_value_type(valueP), (unsigned long)valueP); - printf("%sCan't print it.\n", prefix); -} - - - -void -dumpValue(const char * const prefix, - xmlrpc_value * const valueP) { - - switch (xmlrpc_value_type(valueP)) { - case XMLRPC_TYPE_INT: - dumpInt(prefix, valueP); - break; - case XMLRPC_TYPE_BOOL: - dumpBool(prefix, valueP); - break; - case XMLRPC_TYPE_DOUBLE: - dumpDouble(prefix, valueP); - break; - case XMLRPC_TYPE_DATETIME: - dumpDatetime(prefix, valueP); - break; - case XMLRPC_TYPE_STRING: - dumpString(prefix, valueP); - break; - case XMLRPC_TYPE_BASE64: - dumpBase64(prefix, valueP); - break; - case XMLRPC_TYPE_ARRAY: - dumpArray(prefix, valueP); - break; - case XMLRPC_TYPE_STRUCT: - dumpStruct(prefix, valueP); - break; - case XMLRPC_TYPE_C_PTR: - dumpCPtr(prefix, valueP); - break; - case XMLRPC_TYPE_NIL: - dumpNil(prefix, valueP); - break; - case XMLRPC_TYPE_I8: - dumpI8(prefix, valueP); - break; - default: - dumpUnknown(prefix, valueP); - } -} diff --git a/trunk/tools/lib/include/dumpvalue.h b/trunk/tools/lib/include/dumpvalue.h deleted file mode 100644 index 84be00972..000000000 --- a/trunk/tools/lib/include/dumpvalue.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef DUMPVALUE_H_INCLUDED -#define DUMPVALUE_H_INCLUDED - -struct _xmlrpc_value; - -void -dumpValue(const char * const prefix, - struct _xmlrpc_value * const valueP); - -#endif diff --git a/trunk/tools/perl_packetsocket/PacketSocket.pm b/trunk/tools/perl_packetsocket/PacketSocket.pm deleted file mode 100644 index 37abd986d..000000000 --- a/trunk/tools/perl_packetsocket/PacketSocket.pm +++ /dev/null @@ -1,186 +0,0 @@ -############################################################################### -# -# This Perl module provides a "packet socket" of the kind that -# XML-RPC For C/C++ uses for its "packet stream" variation on XML-RPC. -# -# This module does not use the XML-RPC For C/C++ libraries. It is -# pure Perl and layers on top of IO::Socket. -# -# By Bryan Henderson, San Jose CA 08.03.12. -# -# Contributed to the public domain by author. -# -############################################################################### - -package IO::PacketSocket; - -use strict; -use warnings; -use Exporter; -use Carp; -use vars qw(@ISA $VERSION @EXPORT); -use Errno qw(:POSIX); -use English; -use IO::Socket::INET - - -$VERSION = 1.00; -@ISA = qw(Exporter IO); - -my ($TRUE, $FALSE) = (1,0); - -my $ESC = chr(0x1B); # ASCII Escape - -my $startDelim = $ESC . 'PKT'; -my $endDelim = $ESC . 'END'; -my $escapedEsc = $ESC . 'ESC'; - - -sub createObject { - my ($class, %args) = @_; - - my $errorRet; - # Description of why we can't create the object. Undefined if - # we haven't given up yet. - - my $packetSocket; - - $packetSocket = {}; - - bless ($packetSocket, $class); - - if (defined($args{STREAMSOCKET})) { - $packetSocket->{STREAMSOCKET} = $args{STREAMSOCKET}; - } else { - $errorRet = "You must specify STREAMSOCKET"; - } - - $packetSocket->{RECEIVE_BUFFER} = ''; - - if ($errorRet && !$args{ERROR}) { - carp("Failed to create PacketSocket object. $errorRet"); - } - if ($args{ERROR}) { - $ {$args{ERROR}} = $errorRet; - } - if ($args{HANDLE}) { - $ {$args{HANDLE}} = $packetSocket; - } -} - - - -sub new { - - my ($class, %args) = @_; - - $args{HANDLE} = \my $retval; - $args{ERROR} = undef; - - $class->createObject(%args); - - return $retval; -} - - - -sub escaped($) { - my ($x) = @_; -#----------------------------------------------------------------------------- -# Return $x, but properly escaped to be inside a packet socket -# packet. -#----------------------------------------------------------------------------- - - $x =~ s{$ESC}{$escapedEsc}g; - - return $x; -} - - - -sub unescaped($) { - my ($x) = @_; -#----------------------------------------------------------------------------- -# Inverse of escaped() -#----------------------------------------------------------------------------- - - $x =~ s{$escapedEsc}{$ESC}g; - - return $x; -} - - - -sub send() { - my($this, $payload) = @_; - - my $retval; - - my $packet = $startDelim . escaped($payload) . $endDelim; - - $retval = $this->{STREAMSOCKET}->send($packet); - - return $retval; -} - - - -sub havePacket() { - - my ($this) = @_; - - return ($this->{RECEIVE_BUFFER} =~ m{$endDelim}); -} - - - -sub validatePacketStart($) { - - my ($packetR) = @_; - - my $delim = substr($$packetR, 0, 4); - - if ($startDelim !~ m{^$delim}) { - die("Received bytes '$delim' are not in any packet. " . - "Sender is probably not using a packet socket"); - } -} - - - -sub recv() { - my ($this, $payloadR) = @_; - - my $gotPacket; - my $eof; - my $escapedPacket; - - $gotPacket = $FALSE; - $eof = $FALSE; - - while (!$gotPacket && !$eof) { - validatePacketStart(\$this->{RECEIVE_BUFFER}); - - $this->{STREAMSOCKET}->recv(my $buffer, 4096, 0); - - if ($buffer eq '') { - $eof = $TRUE; - } else { - $this->{RECEIVE_BUFFER} .= $buffer; - } - - validatePacketStart(\$this->{RECEIVE_BUFFER}); - - if ($this->{RECEIVE_BUFFER} =~ - m{^($startDelim)(.*?)($endDelim)(.*)}s) { - - ($escapedPacket, $this->{RECEIVE_BUFFER}) = ($2, $3); - - $gotPacket = $TRUE; - } - } - - $$payloadR = $eof ? '' : unescaped($escapedPacket); -} - -1; diff --git a/trunk/tools/turbocharger/Makefile b/trunk/tools/turbocharger/Makefile deleted file mode 100644 index ff09f9741..000000000 --- a/trunk/tools/turbocharger/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: -clean: -distclean: -install: -uninstall: -dep: \ No newline at end of file diff --git a/trunk/tools/turbocharger/README b/trunk/tools/turbocharger/README deleted file mode 100644 index 4613bfd20..000000000 --- a/trunk/tools/turbocharger/README +++ /dev/null @@ -1,37 +0,0 @@ -XML-RPC Turbocharger (Experimental) -=================================== - -This a hacked copy of mod_gzip. In addition to the usual "gzip" encoding, -it also handles "deflate" encoding. - -When used in conjuction with the xmlrpc-c client, this should reduce your -outbound XML-RPC network traffic by an amazing amount--compression ratios -of 10:1 and 30:1 are not unheard of. If you're clever, you should be able -to use this with just about any Apache-based XML-RPC server. - -You can find the standard distribution of mod_gzip here: - - http://www.remotecommunications.com/apache/mod_gzip/ - -The hacked distribution is installed and used in exactly the same fashion -as the regular distribution. There's one extra logging directive available: - - %{mod_gzip_compression_format}n Compression format chosen by client. - -Go read the mod_gzip documentation; it should all make sense. - -If you want to discuss the XML-RPC Turbocharger, please sign up for the -xmlrpc-c-devel mailing list at: - - http://xmlrpc-c.sourceforge.net/ - -This code is highly experimental, and may do some strange things. You'll -probably need to screw around with mod_gzip for a while until you get -everything to work. Don't run this on your production web server, OK? - -Eric Kidd -eric.kidd@pobox.com - -P.S. The Turbocharger appears to dump core in mod_gzip decides to serialize -a large response to disk. Do you see what I mean by "experimental" and -"don't run this on your production web server"? :-) diff --git a/trunk/tools/turbocharger/mod_gzip.c b/trunk/tools/turbocharger/mod_gzip.c deleted file mode 100644 index 3d74553a3..000000000 --- a/trunk/tools/turbocharger/mod_gzip.c +++ /dev/null @@ -1,9843 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1995-2000 The Apache Group. 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. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED 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 APACHE GROUP OR - * ITS 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. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see . - * - */ - -/* - * mod_gzip.c - * - * Apache gzip compression module. - * - * This module adds 'on the fly' compression of HTTP content to - * any Apache Web Server. It uses the IETF Content-encoding standard(s). - * - * It will compress both static files and the output of any CGI - * program inclding shell scripts, perl scripts, executables, - * PHP used as CGI, etc. - * - * There is NO client-side software required for using this module - * other than any fully HTTP 1.1 compliant user agent. - * - * Any fully HTTP 1.1 compliant user agent will be able to receive and - * automatically decode the compressed content. - * - * All fully HTTP 1.1 compliant user agents that are capable of receiving - * gzip encoded data will indicate their ability to do so by adding the - * standard "Accept-Encoding: gzip" field to the inbound request header. - * - * This module may be compiled as a stand-alone external 'plug-in' - * or be compiled into the Apache core server as a 'built-in' module. - * - * Sponsor: Remote Communications, Inc. http://www.RemoteCommunications.com/ - * Authors: Konstantin Balashov, Alex Kosobrukhov and Kevin Kiley. - * Contact: info@RemoteCommunications.com - * - * Initial public release date: 13-Oct-2000 - * - * Miscellaneous release notes: - * - * THIS IS A COMPLETELY SELF-CONTAINED MODULE. MOD_GZIP.C IS THE - * ONY SOURCE CODE FILE THERE IS AND THERE ARE NO MODULE SPECIFIC - * HEADER FILES OR THE NEED FOR ANY 3RD PARTY COMPRESSION LIBRARIES. - * ALL OF THE COMPRESSION CODE NEEDED BY THIS MODULE IS CONTAINED - * WITHIN THIS SINGLE SOURCE FILE. - * - * Many standard compression libraries are not designed or optimized - * for use as real-time compression codecs nor are they guaranteed - * to be 'thread-safe'. The internal compression code used by mod_gzip - * is all of those things. It is a highly-optimized and thread-safe - * implementation of the standard LZ77 + Huffman compression - * technique that has come to be known as GZIP. - * - * MOD_GZIP LOG FORMATS... - * - * mod_gzip makes a number of statistical items for each transaction - * available through the use of Apache's 'LogFormat' directives which - * can be specified in the httpd.conf Apache config file - * - * mod_gzip uses the standard Apache NOTES interface to allow compression - * information to be added to the Apache Web Server log files. - * - * Standard NOTES may be added to Apache logs using the following syntax - * in any LogFormat directive... - * * %...{Foobar}n: The contents of note "Foobar" from another module. - * - * Additional notes about logging compression information... - * - * The Apache LogFormat directive is unable to actually display - * the 'percent' symbol since it is used exclusively as a 'pickup' - * character in the formatting string and cannot be 'escaped' so - * all logging of compression ratios cannot use the PERCENT symbol. - * Use ASCII 'pct.' designation instead for all PERCENTAGE values. - * - * Example: This will display the compression ratio percentage along - * with the standard CLF ( Common Log Format ) information... - * - * Available 'mod_gzip' compression information 'notes'... - * - * %{mod_gzip_result}n - A short 'result' message. Could be OK or DECLINED, etc. - * %{mod_gzip_input_size}n - The size ( in bytes ) of the requested object. - * %{mod_gzip_output_size}n - The size ( in bytes ) of the compressed version. - * %{mod_gzip_compression_ration}n - The compression rate achieved. - * - * LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info1 - * LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_result}n In:%{mod_gzip_input_size}n Out:%{mod_gzip_output_size}n:%{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info2 - * - * If you create your own custom 'LogFormat' lines don't forget that - * the entire LogFormat line must be encased in quote marks or you - * won't get the right results. The visible effect of there not being - * and end-quote on a LogFormat line is that the NAME you are choosing - * for the LogFormat line is the only thing that will appear in the - * log file that tries to use the unbalanced line. - * - * Also... when using the %{mod_gzip_xxxxx}n note references in your - * LogFormat line don't forget to add the lowercase letter 'n' after - * the closing bracket to indicate that this is a module 'note' value. - * - * Once a LogFormat directive has been added to your httpd.conf file - * which displays whatever level of compression information desired - * simply use the 'name' associated with that LogFormat line in - * the 'CustomLog' directive for 'access.log'. - * - * Example: The line below simply changes the default access.log format - * for Apache to the special mog_gzip information record defined above... - * CustomLog logs/access.log common - * - * CustomLog logs/access.log common_with_mod_gzip_info2 - * - * Using the 'common_with_mod_gzip_info1' LogFormat line for Apache's - * normal access.log file produces the following results in the access.log - * file when a gigantic 679,188 byte online CD music collection HTML - * document called 'music.htm' is requested and the Server delivers the - * file via mod_gzip compressed 93 percent down to only 48,951 bytes... - * - * 216.20.10.1 [12/Oct...] "GET /music.htm HTTP/1.1" 200 48951 mod_gzip: 93pct. - * - * The line below shows what will appear in the Apache access.log file - * if the more detailed 'common_with_mod_gzip_info2' LogFormat line is used. - * The line has been intentionally 'wrapped' for better display below - * but would normally appear as a single line entry in access.log. - * - * 216.20.10.1 [12/Oct...] "GET /music.htm HTTP/1.1" 200 48951 - * mod_gzip: OK In:679188 Out:48951:93pct. - * - * The 'OK' result string shows that the compression was successful. - * The 'In:' value is the size (in bytes) of the requested file and - * the 'Out:' value is the size (in bytes) after compression followed - * by a colon and a number showing that the document was compressed - * 93 percent before being returned to the user. - * - * Please NOTE that if you add any ASCII strings to your LogFormat - * string then they will appear in your log file regardless of - * whether this module was actually 'called' to process the - * transaction or not. If the module was not called to handle the - * transaction then the places where the statistical information - * associated with the 'NOTES' references would normally appear - * will be filled in with 'dashes' to denote 'no value available'. - * - * MOD_GZIP RUNTIME DEBUG... - * - * If you set your default Apache logging level to 'LogLevel debug' - * in your httpd.conf file then this module will add certain - * diagnostic debug messages to your error log for each and every - * transaction that is actually passed to the module. - * - * If Apache does not 'call' this module to handle a particular - * transaction then no special log information will appear in - * your error log(s) for that transaction. - * - * MOD_GZIP CONFIGURATION DIRECTIVES... - * - * The section that follows is a sample mod_gzip configuration - * section that will provide basic compression of all static - * TEXT and HTML files as well as dynamic compression of most - * standard CGI including Shell scripts, Perl, PHP, etc. - * - * The configuration directives themselves are documented in more - * detail in the README and INSTALL files that accompany this module. - * - * You should be able to simply 'cut and paste' the follwing section - * directly into the BOTTOM of your current httpd.conf Apache - * configuration file and be able to start using mod_gzip immediately. - * - -# -# MOD_GZIP Configuration Directives -# -# All you should have to do to get up and running using -# mod_gzip with some basic STATIC and DYNAMIC compression -# capabilites is copy the mod_gzip dynamic library to your -# ../modules directory and then add this entire example -# configuration section to the BOTTOM of your httpd.conf file. -# -# Add this entire section including all lines down to where -# it says '# End of MOD_GZIP Configuration Directives'. -# -# The LoadModule command is included here for clarity -# but you may want to move it the the BOTTOM of your -# current LoadModule list in httpd.conf. -# -# Change the 'mod_gzip_temp_dir' to the name of a directory -# on your machine where temporary workfiles can be created -# and destroyed. This directory MUST be readable/writable -# by the Server itself while it is running. If the directory -# does not exist you must create it yourself with the right -# permissions before running the Server. -# -# If no 'mod_gzip_temp_dir' is specified then the default location -# for temporary workfiles will be 'ServerRoot' directory. -# -# The special mod_gzip log formats are, of course, optional. -# -# You must, of course, load the right module name for your OS -# so make sure the correct 'LoadModule' command is uncommented -# directly below... - -# Load Win32 module... -LoadModule gzip_module modules/ApacheModuleGzip.dll - -# Load UNIX module... -# LoadModule gzip_module modules/mod_gzip.so - -LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info1 -LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_result}n In:%{mod_gzip_input_size}n Out:%{mod_gzip_output_size}n:%{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info2 - -# NOTE: This 'CustomLog' directive shows how to set your access.log file -# to use the mod_gzip format but please remember that for every 'CustomLog' -# directive that Apache finds in httpd.conf there will be corresponding -# line of output in the access.log file. If you only want ONE line of -# results in access.log for each transaction then be sure to comment out -# any other 'CustomLog' directives so that this is the only one. - -CustomLog logs/access.log common_with_mod_gzip_info2 - -# Runtime control directives... - -mod_gzip_on Yes -mod_gzip_do_cgi Yes -mod_gzip_do_static_files Yes -mod_gzip_minimum_file_size 300 -mod_gzip_maximum_inmem_size 60000 -mod_gzip_keep_workfiles No -mod_gzip_temp_dir "C:/Program Files/Apache Group/Apache/temp" - -# Item lists... -# -# Item names can be any one of the following... -# -# cgi-script - A valid 'handler' name -# text/* - A valid MIME type name ( '*' wildcard allowed ) -# .phtml - A valid file type extension - -# Dynamic items... -# -# NOTE: FOR NOW ALL DYNAMIC ITEMS SHOULD BE -# DECLARED BEFORE ANY STATIC ITEMS TO PREVENT -# PICKUP CONFLICTS. IF YOU USE !cgi-script -# BE SURE IT IS DECLARED BEFORE ANY text/* -# MIME TYPE ENTRIES. -# -# The items listed here are the types of dynamic -# output that will be compressed... -# -# Dynamic items MUST have the "!" BANG character -# on the front of the item name. -# -mod_gzip_item_include !cgi-script -mod_gzip_item_include !.php -mod_gzip_item_include !.php3 -mod_gzip_item_include !.phtml - -# Static items... -# -# The items listed here are the types of static -# files that will be compressed... -# -# NOTE: FOR NOW ALL STATIC INCLUDES MUST -# COME AFTER DYNAMIC INCLUDES TO PREVENT -# PICKUP CONFLICTS -# -mod_gzip_item_include text/* - -# Uncomment this line to compress graphics -# when graphics compression is allowed... -#mod_gzip_item_include image/* - - -# Exclusions... MIME types and FILE types... -# -# The items listed here will be EXCLUDED from -# any attempt to apply compression... -# -mod_gzip_item_exclude .js -mod_gzip_item_exclude .css - -# Exclusions... HTTP support levels... -# -# By specifying a certain minimum level of HTTP support -# certain older user agents ( browsers ) can be -# automatically excluded from receiving compressed data. -# -# The item value should be in the same HTTP numeric format -# that Apache uses to designate HTTP version levels. -# -# 1001 = HTTP/1.1 -# -# So 'mod_gzip_min_http 1001' means that a requesting -# user agent ( browser ) must report a minimum HTTP support -# level of 1.1 or it will not receive any compressed data. -# -mod_gzip_min_http 1001 - -# Debugging... -# -# If your Apache 'LogLevel' is set to 'debug' then -# mod_gzip will add some diagnostic and compression -# information to your error.log file for each request -# that is processed by mod_gzip. -# -# LogLevel debug - -# End of MOD_GZIP Configuration Directives - - * End of inline comments - */ - -#include -/* - * Apache headers... - */ - -#define CORE_PRIVATE - -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_log.h" -#include "http_main.h" -#include "http_protocol.h" -#include "util_script.h" - -/* - * Add this header for ap_server_root[ MAX_STRING_LEN ] global... - * - * #include "http_conf_globals.h" - * - * ...or just include what we need from http_conf_globals.h - * since that is, in fact, only 1 item at this time. - */ -extern API_VAR_EXPORT char ap_server_root[ MAX_STRING_LEN ]; - -/* - * Add this header to get 'ap_update_mtime()' prototype... - * - * #include "http_request.h" - * - * ...or just include what we need from http_request.h since - * that is, in fact, only 1 item at this time. - */ -extern API_EXPORT(time_t) -ap_update_mtime(request_rec *r, time_t dependency_mtime); - -/* - * Version information... - * - * Since this product is 'married' to the ASF Apache Web Server - * the version numbers should always 'match' the changing - * version numbers of Apache itself so users can be sure - * they have the 'right' module. This allows us to move the - * version numbers either backwards or forwards in case issues - * arise which require specific versions of mod_gzip for - * specific versions of Apache. - * - * The original code was first tested against the Apache 1.3.14 - * release but should be compatible with the entire 1.3.x series. - * If earlier 1.3.x versions of Apache required special versions - * then the mod_gzip version number will still match the Apache - * version number ( As in... mod_gzip v1.3.12.1, if needed ). - * - * If a special version is required for Apache 2.0 then the - * version number(s) will change to match release numbers in - * that series. ( As in... mod_gzip v 2.0.1.1, etc. ). - * - * The first 3 numbers of the version are always the equivalent - * Apache release numbers. The fourth number is always the actual - * mod_gzip 'build' number for that version of Apache. - */ - -char mod_gzip_version[] = "1.3.14.5"; /* Global version string */ - -/* - * Declare the NAME by which this module will be known. - * This is the NAME that will be used in LoadModule command(s). - */ -extern module MODULE_VAR_EXPORT gzip_module; - -/* - * Allow this module to 'read' config information from - * ( and interact with ) the 'real' mod_cgi module... - */ -extern module cgi_module; - -/* - * Some compile-time code inclusion switches... - */ - -/* - * Turn MOD_GZIP_ALLOWS_INTERNAL_COMMANDS switch ON to allow - * information requests to be sent via any standard browser. - */ - -#define MOD_GZIP_ALLOWS_INTERNAL_COMMANDS - -/* - * Turn MOD_GZIP_USES_APACHE_LOGS switch ON to include the - * code that can update Apache logs with compression information. - */ - -#define MOD_GZIP_USES_APACHE_LOGS - - /* - * Turn MOD_GZIP_USES_AP_SEND_MMAP switch ON to use the - * ap_send_mmap() method for transmitting data. If this - * switch is OFF then the default is to use ap_rwrite(). - * This might need to be platform specific at some point. - */ - -#define MOD_GZIP_USES_AP_SEND_MMAP - -/* - * Turn MOD_GZIP_DEBUG1 switch ON for verbose diags. - * This is normally OFF by default and should only be - * used for diagnosing problems. The log output is - * VERY detailed and the log files will be HUGE. - */ - -/* -#define MOD_GZIP_DEBUG1 -*/ - -/* - * Some useful instance globals... - */ - -#ifndef MOD_GZIP_MAX_PATH_LEN -#define MOD_GZIP_MAX_PATH_LEN 512 -#endif - -char mod_gzip_temp_dir[ MOD_GZIP_MAX_PATH_LEN + 2 ]; - -long mod_gzip_iusn = 0; /* Instance Unique Sequence Number */ - -long mod_gzip_maximum_inmem_size = 60000L; -long mod_gzip_minimum_file_size = 300L; - -#ifdef _WIN32 -char mod_gzip_dirsep[]="\\"; /* Dir separator is a backslash for Windows */ -#else /* !_WIN32 */ -char mod_gzip_dirsep[]="/"; /* Dir separator is a forward slash for UNIX */ -#endif /* _WIN32 */ - -/* - * The Compressed Object Cache control structure... - */ - -#define MOD_GZIP_SEC_ONE_DAY 86400 /* Total seconds in one day */ -#define MOD_GZIP_SEC_ONE_HR 3600 /* Total seconds in one hour */ - -#define MOD_GZIP_DEFAULT_CACHE_SPACE 5 -#define MOD_GZIP_DEFAULT_CACHE_MAXEXPIRE MOD_GZIP_SEC_ONE_DAY -#define MOD_GZIP_DEFAULT_CACHE_EXPIRE MOD_GZIP_SEC_ONE_HR -#define MOD_GZIP_DEFAULT_CACHE_LMFACTOR (0.1) -#define MOD_GZIP_DEFAULT_CACHE_COMPLETION (0.9) - -struct mod_gzip_cache_conf { - - const char *root; /* The location of the cache directory */ - off_t space; /* Maximum cache size (in 1024 bytes) */ - char space_set; - time_t maxexpire; /* Maximum time to keep cached files (secs) */ - char maxexpire_set; - time_t defaultexpire; /* Default time to keep cached file (secs) */ - char defaultexpire_set; - double lmfactor; /* Factor for estimating expires date */ - char lmfactor_set; - time_t gcinterval; /* Garbage collection interval (secs) */ - char gcinterval_set; - int dirlevels; /* Number of levels of subdirectories */ - char dirlevels_set; - int dirlength; /* Length of subdirectory names */ - char dirlength_set; -}; - -/* - * The Inclusion/Exclusion map item structure... - */ - -#define MOD_GZIP_IMAP_MAXNAMES 256 -#define MOD_GZIP_IMAP_MAXNAMELEN 90 - -#define MOD_GZIP_IMAP_ISMIME 1 -#define MOD_GZIP_IMAP_ISEXT 2 -#define MOD_GZIP_IMAP_ISHANDLER 3 - -#define MOD_GZIP_IMAP_STATIC1 9001 -#define MOD_GZIP_IMAP_DYNAMIC1 9002 -#define MOD_GZIP_IMAP_DECLINED1 9003 - -typedef struct { - - int include; /* 1=Include 0=Exclude */ - int type; /* _ISMIME, _ISEXT, _ISHANDLER, etc. */ - int action; /* _STATIC1, _DYNAMIC1, etc. */ - - char name[ MOD_GZIP_IMAP_MAXNAMELEN + 2 ]; - -} mod_gzip_imap; - -/* - * The primary module configuration record... - */ - -typedef struct { - - struct mod_gzip_cache_conf cache; /* Compressed Object Cache control */ - - int req; /* 1=mod_gzip handles requests 0=No */ - char req_set; /* Mirrors the 'req' flag */ - int do_static_files; /* 1=Yes 0=No */ - int do_cgi; /* 1=Yes 0=No */ - int keep_workfiles; /* 1=Keep workfiles 0=No */ - int min_http; /* Minimum HTTP level ( 1001=HTTP/1.1 ) */ - long minimum_file_size; /* Minimum size in bytes for compression attempt */ - long maximum_inmem_size; /* Maximum size in bytes for im-memory compress */ - - /* Inclusion/Exclusion list(s)... */ - - int imap_total_entries; - - mod_gzip_imap imap[ MOD_GZIP_IMAP_MAXNAMES + 1 ]; - -} mod_gzip_conf; - -/* - * The GZP request control structure... - */ - -#define GZIP_FORMAT (0) -#define DEFLATE_FORMAT (1) - -typedef struct _GZP_CONTROL { - - int decompress; /* 0=Compress 1=Decompress */ - - int compression_format; /* GZIP_FORMAT or DEFLATE_FORMAT */ - - /* Input control... */ - - int input_ismem; /* Input source is memory buffer, not file */ - char *input_ismem_ibuf; /* Pointer to input memory buffer */ - long input_ismem_ibuflen; /* Total length of input data */ - - char input_filename[ MOD_GZIP_MAX_PATH_LEN + 2 ]; /* Input file name */ - - /* Output control... */ - - int output_ismem; /* Output source is memory buffer, not file */ - char *output_ismem_obuf; /* Pointer to output memory buffer */ - long output_ismem_obuflen; /* Maximum length of output data buffer */ - - char output_filename[ MOD_GZIP_MAX_PATH_LEN + 2 ]; /* Output file name */ - - /* Results... */ - - int result_code; /* Result code */ - long bytes_out; /* Total number of compressed output bytes */ - -} GZP_CONTROL; - -/* - * Forward prototypes for internal routines... - */ - -int gzp_main( GZP_CONTROL *gzp ); /* Primary GZP API entry point */ - -int mod_gzip_request_handler( request_rec *r ); -int mod_gzip_cgi_handler( request_rec *r ); -int mod_gzip_static_file_handler( request_rec *r ); -int mod_gzip_prepare_for_dynamic_call( request_rec *r ); -int mod_gzip_imap_show_items( mod_gzip_conf *mgc ); -int mod_gzip_get_action_flag( request_rec *r, mod_gzip_conf *conf ); -int mod_gzip_ismatch( char *s1, char *s2, int len1, int haswilds ); - -FILE *mod_gzip_open_output_file( -request_rec *r, -char *output_filename, -int *rc -); - -int mod_gzip_create_unique_filename( -mod_gzip_conf *mgc, -char *target, -int targetmaxlen -); - -int mod_gzip_encode_and_transmit( -request_rec *r, -char *source, -int source_is_a_file, -long input_size, -int nodecline -); - - -#ifdef MOD_GZIP_ALLOWS_INTERNAL_COMMANDS - -int mod_gzip_send_html_command_response( -request_rec *r, /* Request record */ -char *tmp, /* Response to send */ -char *ctype /* Content type string */ -); - -#endif /* MOD_GZIP_ALLOWS_INTERNAL_COMMANDS */ - -/* - * Module routines... - */ - -#ifdef MOD_GZIP_DEBUG1 - -void mod_gzip_printf( const char *fmt, ... ) -{ - int l; - FILE *log; - - va_list ap; - - char logname[256]; - char log_line[4096]; - - /* Start... */ - - /* If UNIX then mod_gzip_dirsep = '/' Backward slash */ - /* If _WIN32 then mod_gzip_dirsep = '\' Forward slash */ - - #ifdef FUTURE_USE - /* - For now we need both startup and runtime diags in the same - log so it all goes to ServerRoot. 'mod_gzip_temp_dir' name - isn't even valid until late in the startup process so we - have to write to ServerRoot anyway until temp dir is known. - */ - if ( strlen(mod_gzip_temp_dir) ) /* Use temp directory ( if specified )... */ - { - sprintf( logname, "%s%smod_gzip.log", mod_gzip_temp_dir, mod_gzip_dirsep ); - } - else /* Just use 'ap_server_root' Apache ServerRoot directory... */ - { - sprintf( logname, "%s%smod_gzip.log", ap_server_root, mod_gzip_dirsep ); - } - #endif /* FUTURE_USE */ - - /* Just use ServerRoot for now... */ - sprintf( logname, "%s%smod_gzip.log", ap_server_root, mod_gzip_dirsep ); - - log = fopen( logname,"a" ); - - if ( !log ) /* Log file did not open... */ - { - /* Just turn and burn... */ - - return; /* Void return */ - } - - /* Get the variable parameter list... */ - - va_start( ap, fmt ); - - l = vsprintf(log_line, fmt, ap); - - /* See if we need to add LF... */ - - if ( l > 0 ) - { - if ( log_line[l-1] != '\n' ) - { - log_line[l]='\n'; - l++; - } - - log_line[l+1] = 0; - } - - fprintf( log, "%s", log_line ); - - fclose( log ); - - va_end(ap); /* End session */ - - return; /* Void return */ - -}/* End of log_d() */ - -void mod_gzip_hexdump( char *buffer, int buflen ) -{ - int i,o1,o2,o3; - - int len1; - int len2; - - char ch1; - char ch2; - char s[40]; - char l1[129]; - char l2[129]; - char l3[300]; - - long offset1=0L; - - /* Start... */ - - o1=0; - o2=0; - o3=0; - - l1[0] = 0; - l2[0] = 0; - l3[0] = 0; - - offset1 = 0; - - for ( i=0; i 126) ch2 = DUMPIT_LAPOSTROPHE; - else if ( ch1 == 37 ) ch2 = DUMPIT_ASTERISK; /* Mask PERCENT for UNIX */ - else if ( ch1 == 92 ) ch2 = DUMPIT_ASTERISK; /* Mask BACKSLASH for UNIX */ - else ch2 = ch1; - - /* ENDIF on MASK_ALL_NON_PRINTABLE_CHARS */ - #endif - - l2[o2++] = ch2; - - sprintf( s, "%02X", ch1 ); - - if ( strlen(s) > 2 ) s[2]=0; /* Prevent overflow */ - - len1 = strlen(s); - len2 = strlen(l1); - - if ( strlen(l1) < (sizeof(l1) - (len1+1)) ) - { - strcat( l1, s ); - strcat( l1, " " ); - } - - if ( o2 >= 16 ) - { - l2[o2]=0; - - mod_gzip_printf( "%6lu| %-49.49s| %-16.16s |\n", offset1, l1, l2 ); - - offset1 += o2; - - o1=0; - o2=0; - o3=0; - - l1[0] = 0; - l2[0] = 0; - l3[0] = 0; - } - - }/* End 'for( i=0; i 0 ) - { - l2[o2]=0; - - mod_gzip_printf( "%6lu| %-49.49s| %-16.16s |\n", offset1, l1, l2 ); - - offset1 += o2; - - o1 = o2 = o3 = 0; - - l1[0] = 0; - l2[0] = 0; - l3[0] = 0; - } - -}/* End of mod_gzip_hexdump() */ - -#endif /* MOD_GZIP_DEBUG1 */ - -static void mod_gzip_init( server_rec *server, pool *p ) -{ - /* - * The module initialization procedure... - */ - - FILE *fh1; - char filename[ 512 ]; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_init()"; - #endif - - mod_gzip_conf *mgc; - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry...\n", cn ); - #endif - - /* - * Set some instance specific globals... - * - * The default 'temp' dir, lacking an httpd.conf config file - * override, is the Apache 'ServerRoot'. Don't assume that /logs - * dir exists because some Apache installations just use syslog - * or stderr as their log output target. - * - * On most Apache installations 'ServerRoot' is automatically - * readable/writable by the Server while it is running. - * - * On systems where it is not there MUST be an override - * in the httpd.conf file. - * - * See the comments regarding the 'mod_gzip_temp_dir' directive - * in the httpd.conf configuration file. - */ - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(server->module_config, &gzip_module); - - /* Make sure we can read/write the temp directory... */ - - sprintf( filename, "%s%smod_gzip.id", mgc->cache.root, mod_gzip_dirsep ); - - fh1 = fopen( filename, "wb" ); - - if ( !fh1 ) /* Write an ERROR to console and to log(s)... */ - { - fprintf( stderr, "mod_gzip: Cannot read/write dir/file [%s]\n",filename); - fprintf( stderr, "mod_gzip: Make sure the directory exists and that the Server\n"); - fprintf( stderr, "mod_gzip: has read/write permission(s) for the directory.\n"); - fprintf( stderr, "mod_gzip: See the 'mod_gzip_temp_dir' configuration notes.\n"); - - /* This is a startup ERROR and has to be fixed... */ - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_ERR, server, - "mod_gzip: Cannot read/write dir/file [%s]", filename); - ap_log_error( "",0,APLOG_NOERRNO|APLOG_ERR, server, - "mod_gzip: Make sure the directory exists and that the Server"); - ap_log_error( "",0,APLOG_NOERRNO|APLOG_ERR, server, - "mod_gzip: has read/write permission(s) for the directory."); - ap_log_error( "",0,APLOG_NOERRNO|APLOG_ERR, server, - "mod_gzip: See the 'mod_gzip_temp_dir' configuration notes."); - } - else /* File opened OK... just add some data and close it... */ - { - /* - * Since this is just a MARK file we could simply wipe - * it out but might as well print the actual version - * number into it and leave it there in case there is - * any question about which version is actually running. - */ - - fprintf( fh1, "mod_gzip version %s\n", mod_gzip_version ); - fclose( fh1 ); - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_imap_show_items( (mod_gzip_conf *) mgc ); /* Show item list */ - mod_gzip_printf( "%s: Exit > return( void ) >\n", cn ); - mod_gzip_printf( "\n" ); /* Separator for log file */ - #endif - -}/* End of mod_gzip_init() */ - -int mod_gzip_strnicmp( char *s1, char *s2, int len1 ) -{ - /* Behaves just like strnicmp() but IGNORES differences */ - /* between FORWARD or BACKWARD slashes in a STRING... */ - /* Also uses straight pointers and avoids stdlib calls. */ - - int i; - char ch1; - char ch2; - - /* WARNING! We MUST have a check for 'NULL' on the pointer(s) */ - /* themselves or we might GP ( like NETSCAPE does ) */ - /* if a 'NULL' pointer is passed to this routine... */ - - if ( ( s1 == 0 ) || ( s2 == 0 ) ) - { - /* SAFETY! If pointer itself if NULL */ - /* don't enter LOOP or NETSCAPE will GP... */ - - return( 1 ); /* Return '1' for NOMATCH... */ - } - - for ( i=0; i 96 ) ch1 -= 32; - if ( ch2 > 96 ) ch2 -= 32; - - if ( ch1 == '/' ) ch1 = '\\'; - if ( ch2 == '/' ) ch2 = '\\'; - - if ( ch1 != ch2 ) return( 1 ); /* No match! */ - - s1++; - s2++; - - }/* End 'i' loop */ - - /* If we make it to here then everything MATCHED! */ - - return( 0 ); /* MATCH! */ - -}/* End mod_gzip_strnicmp() */ - -extern API_VAR_EXPORT module *top_module; - -struct _table { - array_header a; -#ifdef MAKE_TABLE_PROFILE - void *creator; -#endif -}; -typedef struct _table _table; - -const char *mod_gzip_isscript( request_rec *r, _table *t, const char *key) -{ - /* - * Get a 'handler' name for a MIME type right out of - * the Apache 'Action' table(s)... - * - * Example: - * - * If "key" is "applications/x-httpd-php3" - * then this search will return "/php3/php.exe" - * or whatever the equivalent PHP executable - * pathname is as specified by an 'Action' statement - * in the httpd.conf configuration file. - * - * This pathname might still have 'aliases' in it - * so we will have to consult with mod_alias - * following this call and get any aliases converted. - */ - - table_entry *elts = - (table_entry *) t->a.elts; - int i; - - char cn[]="mod_gzip_isscript()"; - - /* - * Start... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry...\n",cn); - mod_gzip_printf( "%s: key=[%s]\n",cn,key ); - #endif - - if ( key == NULL ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 'key' has no length\n",cn); - mod_gzip_printf( "%s: Exit > return( NULL ) >\n",cn); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: Search key is NULL.",cn); - } - - return NULL; - } - - for (i = 0; i < t->a.nelts; ++i) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( - "%s: i=%4.4d Comparing [%s] with elts.key[%s].val[%s]\n", - cn, i, key, elts[i].key, elts[i].val ); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: i=%4.4d Comparing [%s] with elts.key[%s].val[%s]", - cn, i, key, elts[i].key, elts[i].val ); - } - - if (!strcasecmp(elts[i].key, key)) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: MATCH FOUND!",cn); - mod_gzip_printf( "%s: Exit > return(%s) >\n",cn,elts[i].val); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: MATCH FOUND...",cn); - } - - return elts[i].val; - } - - }/* End 'i' loop */ - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: NO MATCH FOUND...",cn); - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: NO MATCH FOUND!\n",cn); - mod_gzip_printf( "%s: Exit > return( NULL ) >\n",cn); - #endif - - return NULL; - -}/* End of 'mod_gzip_isscript()' */ - -typedef struct { - table *action_types; /* Added with Action... */ - char *scripted[METHODS]; /* Added with Script... */ - array_header *xmethods; /* Added with Script -- extension methods */ -} mod_actions_local_config; - -int mod_gzip_run_mod_action( request_rec *r ) -{ - module *modp; - int count=0; - int pass=0; - - mod_actions_local_config *mod_actions_conf; - - const char *t=0; - const char *action=0; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_run_mod_action()"; - #endif - - #ifdef MOD_GZIP_FUTURE_USE - const handler_rec *handp; - #endif - - /* Currently 9 possible 'event' handlers. */ - /* Actual content handler in a module is 'extra'. */ - #define MOD_GZIP_NMETHODS 9 - - /* - * Start... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry...\n",cn); - mod_gzip_printf( "%s: *IN: r->uri =[%s]\n", cn, r->uri ); - mod_gzip_printf( "%s: *IN: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); - mod_gzip_printf( "%s: *IN: r->filename =[%s]\n", cn, r->filename ); - mod_gzip_printf( "%s: r->content_type =[%s]\n", cn,r->content_type); - mod_gzip_printf( "%s: r->handler =[%s]\n", cn,r->handler); - #endif - - for ( modp = top_module; modp; modp = modp->next ) - { - /* modp->name list will look like this... */ - /*--------------------*/ - /* 00 [mod_gzip.c] */ - /* 01 [mod_isapi.c] */ - /* 02 [mod_setenv.c] */ - /* 02 [mod_actions.c] */ - /* ............... */ - /* ............... */ - /* 18 [mod_so.c] */ - /* 19 [http_core.c] <- Always bottom of list (last one called) */ - /*--------------------*/ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: count=%4.4d modp = %10.10ld modp->name=[%s]\n", - cn,count,(long)modp, modp->name ); - #endif - - if ( mod_gzip_strnicmp( (char *) modp->name, "mod_actions.c", 13 ) == 0 ) - { - - /* Module information... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ++++++++++ MODULE FOUND!...\n",cn); - mod_gzip_printf( "%s: ++++++++++ modp->module_index = %d\n",cn,(int)modp->module_index); - #endif - - /* Get a pointer to the module configuration data... */ - - mod_actions_conf = (mod_actions_local_config *) - ap_get_module_config(r->per_dir_config, modp ); - - /* Get script name... */ - - /* Make 2 passes if necessary. If we don't find a */ - /* program name associated with MIME type first */ - /* then punt and look for a program name associated */ - /* with the r->handler name such as [php-script] */ - - for ( pass = 0; pass < 2; pass++ ) - { - if ( pass == 0 ) /* Check r->content_type first */ - { - /* This is the first pass... */ - - /* Set 'action' search key to 'r->content_type' */ - /* so we search for [application/x-httpd-php3] */ - - action = r->content_type; - } - else if ( pass == 1 ) /* Try r->handler */ - { - /* This is the second pass... */ - - /* Set 'action' search key to 'r->handler' */ - /* so we search for [php-script] */ - - action = r->handler; - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ++++++++++ pass =%d\n", cn,pass); - mod_gzip_printf( "%s: ++++++++++ t =[%s]\n",cn,t); - mod_gzip_printf( "%s: ++++++++++ r->content_type =[%s]\n",cn,r->content_type); - mod_gzip_printf( "%s: ++++++++++ r->handler =[%s]\n",cn,r->handler); - mod_gzip_printf( "%s: ++++++++++ action =[%s]\n",cn,action); - mod_gzip_printf( "%s: ++++++++++ r->filename =[%s]\n",cn,r->filename); - mod_gzip_printf( "%s: ++++++++++ r->uri =[%s]\n",cn,r->uri); - mod_gzip_printf( "%s: ++++++++++ Call mod_gzip_isscript()...\n",cn); - #endif - - t = - mod_gzip_isscript( - r, - (_table *) mod_actions_conf->action_types, - action ? action : ap_default_type(r) - ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ++++++++++ Back mod_gzip_isscript()...\n",cn); - mod_gzip_printf( "%s: ++++++++++ t =[%s]\n",cn,t); - mod_gzip_printf( "%s: ++++++++++ action =[%s]\n",cn,action); - #endif - - if ( t ) - { - /* - * If a program name was found then make it r->filename - * and r->uri will become the input name for the program - */ - - r->filename = ap_pstrdup(r->pool,t); - - break; - } - - }/* End 'for( pass )' loop */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ++++++++++ r->filename=[%s]\n",cn,r->filename); - mod_gzip_printf( "%s: ++++++++++ r->uri =[%s]\n",cn,r->uri); - #endif - - /* If a handler was found we are DONE... */ - - if ( t ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Handler was found...\n",cn); - mod_gzip_printf( "%s: Exit > return( OK ) >\n",cn); - #endif - - return OK; - } - - #ifdef MOD_GZIP_FUTURE_USE - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ++++++++++ METHODS\n",cn); - mod_gzip_printf( "%s: ++++++++++ modp->translate_handler = %ld\n",cn,(long)modp->translate_handler); - mod_gzip_printf( "%s: ++++++++++ modp->ap_check_user_id = %ld\n",cn,(long)modp->ap_check_user_id); - mod_gzip_printf( "%s: ++++++++++ modp->auth_checker = %ld\n",cn,(long)modp->auth_checker); - mod_gzip_printf( "%s: ++++++++++ modp->access_checker = %ld\n",cn,(long)modp->access_checker); - mod_gzip_printf( "%s: ++++++++++ modp->type_checker = %ld\n",cn,(long)modp->type_checker); - mod_gzip_printf( "%s: ++++++++++ modp->fixer_upper = %ld\n",cn,(long)modp->fixer_upper); - mod_gzip_printf( "%s: ++++++++++ modp->logger = %ld\n",cn,(long)modp->logger); - mod_gzip_printf( "%s: ++++++++++ modp->header_parser = %ld\n",cn,(long)modp->header_parser); - mod_gzip_printf( "%s: .......... CONTENT HANDLERS\n",cn); - #endif /* MOD_GZIP_DEBUG1 */ - - if ( !modp->handlers ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: .......... NO CONTENT HANDLERS!\n",cn); - #endif - } - else /* There are some handlers... */ - { - for ( handp = modp->handlers; handp->content_type; ++handp ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: .......... handp->content_type = [%s]\n", - cn,handp->content_type); - mod_gzip_printf( "%s: .......... handp->handler = %ld\n",cn,(long)handp->handler); - #endif - - }/* End 'handp' loop */ - - }/* End 'else' */ - - #endif /* MOD_GZIP_FUTURE_USE */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: No handler was found...\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - return DECLINED; - - }/* 'if ( mod_gzip_strnicmp( (char *) modp->name, "mod_actions.c", 13 ) == 0 )' */ - - count++; - - }/* End 'modp' loop... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: No handler found...\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) > ERROR >\n",cn); - #endif - - return DECLINED; - -}/* End of mod_gzip_run_mod_action() */ - - -int mod_gzip_run_mod_alias( request_rec *r ) -{ - /* - * This calls 'translate_alias_redir()' routine in mod_alias.c - * which will search/replace keywords in the URI with the correct - * 'ScriptAlias' value(s) from the httpd.conf configuration file. - * - * 'translate_alias_redir()' is the name of routine registered - * by mod_alias.c module as the 'translate' hook. - */ - - module *modp; - int count=0; - int rc; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_run_mod_alias()"; - #endif - - const handler_rec *handp; - - /* Currently 9 possible 'event' handlers. */ - /* Actual content handler in a module is 'extra'. */ - #define MOD_GZIP_NMETHODS 9 - - char *save_filename = 0; - char *save_uri = 0; - - char nothing[256]; - - /* - * Start... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry...\n",cn); - mod_gzip_printf( "%s: *IN: r->uri =[%s]\n", cn, r->uri ); - mod_gzip_printf( "%s: *IN: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); - mod_gzip_printf( "%s: *IN: r->filename =[%s]\n", cn, r->filename ); - #endif - - for ( modp = top_module; modp; modp = modp->next ) - { - /* modp->name list will look like this... */ - /*--------------------*/ - /* 00 [mod_gzip.c] */ - /* 01 [mod_isapi.c] */ - /* 02 [mod_setenv.c] */ - /* 02 [mod_actions.c] */ - /* ............... */ - /* ............... */ - /* 18 [mod_so.c] */ - /* 19 [http_core.c] <- Always bottom of list (last one called) */ - /*--------------------*/ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: count=%4.4d modp = %10.10ld modp->name=[%s]\n", - cn,count,(long)modp, modp->name ); - #endif - - /* - There are only 3 modules that normally have - 'translate' handlers registered... - - mod_alias - mod_userdir - http_core - */ - - if ( ( mod_gzip_strnicmp( (char *) modp->name, "mod_alias.c", 11 ) == 0 ) || - ( mod_gzip_strnicmp( (char *) modp->name, "mod_userdir.c", 13 ) == 0 ) || - ( mod_gzip_strnicmp( (char *) modp->name, "http_core.c", 11 ) == 0 ) ) - { - - /* Module information... */ - - #ifdef MOD_GZIP_DEBUG1 - - mod_gzip_printf( "%s: ++++++++++ MODULE FOUND!...\n",cn); - mod_gzip_printf( "%s: ++++++++++ modp->module_index = %d\n",cn,(int)modp->module_index); - - mod_gzip_printf( "%s: ++++++++++ METHODS\n",cn); - mod_gzip_printf( "%s: ++++++++++ modp->translate_handler = %ld\n",cn,(long)modp->translate_handler); - mod_gzip_printf( "%s: ++++++++++ modp->ap_check_user_id = %ld\n",cn,(long)modp->ap_check_user_id); - mod_gzip_printf( "%s: ++++++++++ modp->auth_checker = %ld\n",cn,(long)modp->auth_checker); - mod_gzip_printf( "%s: ++++++++++ modp->access_checker = %ld\n",cn,(long)modp->access_checker); - mod_gzip_printf( "%s: ++++++++++ modp->type_checker = %ld\n",cn,(long)modp->type_checker); - mod_gzip_printf( "%s: ++++++++++ modp->fixer_upper = %ld\n",cn,(long)modp->fixer_upper); - mod_gzip_printf( "%s: ++++++++++ modp->logger = %ld\n",cn,(long)modp->logger); - mod_gzip_printf( "%s: ++++++++++ modp->header_parser = %ld\n",cn,(long)modp->header_parser); - mod_gzip_printf( "%s: .......... CONTENT HANDLERS\n",cn); - - #endif /* MOD_GZIP_DEBUG1 */ - - if ( !modp->handlers ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: .......... NO CONTENT HANDLERS!\n",cn); - #endif - } - else /* There are some handlers... */ - { - for ( handp = modp->handlers; handp->content_type; ++handp ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: .......... handp->content_type = [%s]\n", - cn,handp->content_type); - mod_gzip_printf( "%s: .......... handp->handler = %ld\n",cn,(long)handp->handler); - #endif - - }/* End 'handp' loop */ - - }/* End 'else' */ - - if ( modp->translate_handler ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: modp->translate_handler is VALID...\n",cn); - #endif - - /* - There are only 3 modules that normally have - 'translate' handlers registered... - - mod_alias <- Will translate /php3/xxx to c:/php3017/xx - mod_userdir - http_core - */ - - /* - * This calls 'translate_alias_redir()' routine in mod_alias.c - * which will search/replace keywords in the URI with the correct - * 'ScriptAlias' value(s) from the httpd.conf configuration file. - * - * 'translate_alias_redir()' is the name of routine registered - * by mod_alias.c module as the 'translate' hook. - * - * The 'translate_alias_redir()' function in mod_alias.c - * is really simple. All it does is check to make sure - * that r->uri has some value and, if it does, it calls - * another routine in mod_alias.c named 'try_alias_list()' - * which replaces any 'ScriptAlias' phrases with their - * real values and copies the result to r->filename. - * - * We must make sure the phrase we want translated is - * in r->uri and check for results in r->filename. - */ - - /* - * Calling mod_alias.c translate handler will correctly - * translate 'ScriptAlias' phrases such as... - * - * URI value... - * /php3/php3.exe - * becomes... - * c:/php3017/php3.exe - */ - - save_filename = r->filename; - save_uri = r->uri; - nothing[0] = 0; - - r->filename = nothing; - r->uri = save_filename; /* Phrase to translate */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: r->filename = [%s]\n",cn,r->filename); - mod_gzip_printf( "%s: r->uri = [%s]\n",cn,r->uri); - mod_gzip_printf( "%s: Call (modp->translate_handler)(r)...\n",cn); - #endif - - /* Call the actual translate routine in mod_action module... */ - - rc = (modp->translate_handler)( (request_rec *) r ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back (modp->translate_handler)(r)...\n",cn); - mod_gzip_printf( "%s: r->filename = [%s]\n",cn,r->filename); - mod_gzip_printf( "%s: r->uri = [%s]\n",cn,r->uri); - #endif - - /* - * If there was a successful translation then the return - * code will be OK and the translated URI will be sitting - * in r->filename. If there were no phrase replacements - * then the return code will be DECLINED. - */ - - #ifdef MOD_GZIP_DEBUG1 - - if ( rc == OK ) - { - mod_gzip_printf( "%s: rc = %d = OK\n",cn, rc ); - } - else if ( rc == DECLINED ) - { - mod_gzip_printf( "%s: rc = %d = DECLINED\n",cn, rc ); - } - else if ( rc == DONE ) /* -2 means 'totally done' */ - { - mod_gzip_printf( "%s: rc = %d = DONE\n",cn, rc ); - } - else /* Probably an HTTP ERROR value... */ - { - mod_gzip_printf( "%s: rc = %d = HTTP_ERROR?\n",cn, rc ); - } - - #endif /* MOD_GZIP_DEBUG */ - - /* - * Evaluate the results... - */ - - if ( rc == OK ) /* There was a phrase translation... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: There was a phrase translation...\n",cn ); - mod_gzip_printf( "%s: Keeping new 'r->filename'\n",cn ); - #endif - - /* Do NOT restore 'r->filename' to original value... */ - /* Just fall-through and continue... */ - } - else /* No phrases were replaced... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: There were NO phrases translated...\n",cn ); - mod_gzip_printf( "%s: Restoring 'r->filename' to original value...\n",cn ); - #endif - - /* Restore 'r->filename' to original value... */ - - r->filename = save_filename; - } - - /* Always 'restore' URI to original value... */ - - r->uri = save_uri; - - /* Turn and burn... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( rc=%d ) >\n",cn,rc); - #endif - - return rc; - } - else /* modp->translate_handler is NULL... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: modp->translate_handler is NOT VALID.\n",cn); - #endif - } - - }/* 'if ( mod_gzip_strnicmp( (char *) modp->name, "mod_actions.c", 13 ) == 0 )' */ - - count++; - - }/* End 'modp' loop... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: No handler found...\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) > ERROR >\n",cn); - #endif - - return DECLINED; - -}/* End of mod_gzip_run_mod_alias() */ - - -static int mod_gzip_handler( request_rec *r ) -{ - /* - * The primary module request handler... - */ - - int rc=0; - char cn[]="mod_gzip_handler()"; - int access_status=0; - int access_status2=0; - - /* - * Start... - */ - - if ( r->server->loglevel == APLOG_DEBUG ) - { - /* - * If the user has 'LogLevel debug' set in httpd.conf then - * it's ok to go ahead and strike some diagnostic information - * to the Apache log(s). - * - * APLOG_MARK is what supplies __FILE__ and __LINE__ info and - * it is actually defined in HTTP_LOG.H as... - * - * define APLOG_MARK __FILE__,__LINE__ - * - * Sometimes the original __FILE__ name is very long and is - * fairly useless information cluttering up the logs when - * there is only 1 possible source file name so - * to NOT use it just supply 2 dummy parameters instead. - * - * The first parameter can be a custom message instead of - * the __FILE__ string that would normally be substituted. - */ - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: Entry point...",cn); - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: r->the_request = [%s]",cn,r->the_request); - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: r->protocol = [%s]",cn,r->protocol); - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: r->proto_num = %d",cn,(int)r->proto_num); - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: r->filename = [%s]",cn,r->filename); - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: r->uri = [%s]",cn,r->uri); - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: r->content_type = [%s]",cn,r->content_type); - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: r->handler = [%s]",cn,r->handler); - - }/* End 'if( r->server->loglevel == APLOG_DEBUG )' */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "\n" ); - mod_gzip_printf( "%s: ```` Entry...\n",cn); - mod_gzip_printf( "%s: -------------------------------------------------------------\n",cn); - mod_gzip_printf( "%s: *IN: r->uri =[%s]\n", cn, r->uri ); - mod_gzip_printf( "%s: *IN: r->unparsed_uri =[%s]\n", cn, r->unparsed_uri ); - mod_gzip_printf( "%s: *IN: r->filename =[%s]\n", cn, r->filename ); - mod_gzip_printf( "%s: *IN: r->path_info =[%s]\n", cn, r->path_info ); - mod_gzip_printf( "%s: *IN: r->args =[%s]\n", cn, r->args ); - mod_gzip_printf( "%s: *IN: r->header_only =[%s]\n", cn, r->header_only ); - mod_gzip_printf( "%s: *IN: r->protocol =[%s]\n", cn, r->protocol ); - mod_gzip_printf( "%s: *IN: r->proto_num =%d\n", cn, r->proto_num ); - mod_gzip_printf( "%s: *IN: r->hostname =[%s]\n", cn, r->hostname ); - mod_gzip_printf( "%s: *IN: r->the_request =[%s]\n", cn, r->the_request ); - mod_gzip_printf( "%s: *IN: r->assbackwards =%d\n", cn, r->assbackwards ); - mod_gzip_printf( "%s: *IN: r->status_line =[%s]\n", cn, r->status_line ); - mod_gzip_printf( "%s: *IN: r->status =%d\n", cn, r->status ); - mod_gzip_printf( "%s: *IN: r->method =[%s]\n", cn, r->method ); - mod_gzip_printf( "%s: *IN: r->method_number =%d\n", cn, r->method_number ); - mod_gzip_printf( "%s: *IN: r->content_type =[%s]\n", cn, r->content_type ); - mod_gzip_printf( "%s: *IN: r->handler =[%s]\n", cn, r->handler ); - mod_gzip_printf( "%s: *IN: r->content_encoding =[%s]\n", cn, r->content_encoding ); - mod_gzip_printf( "%s: *IN: r->content_language =[%s]\n", cn, r->content_language ); - mod_gzip_printf( "%s: -------------------------------------------------------------\n",cn); - mod_gzip_printf( "%s: *IN: r->parsed_uri.scheme =[%s]\n", cn, r->parsed_uri.scheme ); - mod_gzip_printf( "%s: *IN: r->parsed_uri.hostinfo =[%s]\n", cn, r->parsed_uri.hostinfo ); - mod_gzip_printf( "%s: *IN: r->parsed_uri.user =[%s]\n", cn, r->parsed_uri.user ); - mod_gzip_printf( "%s: *IN: r->parsed_uri.password =[%s]\n", cn, r->parsed_uri.password ); - mod_gzip_printf( "%s: *IN: r->parsed_uri.hostname =[%s]\n", cn, r->parsed_uri.hostname ); - mod_gzip_printf( "%s: *IN: r->parsed_uri.port_str =[%s]\n", cn, r->parsed_uri.port_str ); - mod_gzip_printf( "%s: *IN: r->parsed_uri.port =%u\n", cn, r->parsed_uri.port ); - mod_gzip_printf( "%s: *IN: r->parsed_uri.path =[%s]\n", cn, r->parsed_uri.path ); - mod_gzip_printf( "%s: *IN: r->parsed_uri.query =[%s]\n", cn, r->parsed_uri.query ); - mod_gzip_printf( "%s: *IN: r->parsed_uri.fragment =[%s]\n", cn, r->parsed_uri.fragment ); - mod_gzip_printf( "%s: -------------------------------------------------------------\n",cn); - - #endif /* MOD_GZIP_DEBUG1 */ - - /* - * Call the real transaction handler.... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call mod_gzip_request_handler()...\n", cn ); - #endif - - rc = mod_gzip_request_handler( (request_rec *) r ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back mod_gzip_request_handler()... rc=%d\n",cn,rc); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - /* - * If LogLevel is 'debug' then show the final return code - * value in the log(s)... - */ - - if ( rc == OK ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: Exit: return( rc = %d = OK )", cn, rc ); - } - else if ( rc == DECLINED ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: Exit: return( rc = %d = DECLINED )", cn, rc ); - } - else /* It's probably an HTTP error code... */ - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "%s: Exit: return( rc = %d = HTTP ERROR CODE? )", cn, rc ); - } - - }/* End 'if( r->server->loglevel == APLOG_DEBUG )' */ - - #ifdef MOD_GZIP_DEBUG1 - - if ( rc == OK ) - { - mod_gzip_printf( "%s: rc = %d OK\n", cn, (int) rc); - } - else if ( rc == DECLINED ) - { - mod_gzip_printf( "%s: rc = %d DECLINED\n", cn, (int) rc ); - } - else /* It's probably an HTTP error code... */ - { - mod_gzip_printf( "%s: rc = %d ( HTTP ERROR CODE? )\n", cn, (int) rc ); - } - - mod_gzip_printf( "%s: Exit > return( rc = %d ) >\n",cn,rc ); - - #endif /* MOD_GZIP_DEBUG1 */ - - return rc; - -}/* End of mod_gzip_handler() */ - -typedef struct { - table *action_types; /* Added with Action... */ - char *scripted[METHODS]; /* Added with Script... */ - array_header *xmethods; /* Added with Script -- extension methods */ -} action_dir_config2; - -extern module action_module; - -int mod_gzip_request_handler( request_rec *r ) -{ - /* - * Process a new request... - */ - - int rc = 0; - int loglevel = 0; - int do_command = 0; - int process = 0; - int action_flag = 0; - long compression_ratio = 0; - - const char* has_encoding = 0; - const char* accept_encoding = 0; - - #ifdef MOD_GZIP_ALLOWS_INTERNAL_COMMANDS - char tmp[4096]; /* Scratch buffer for HTML output */ - #endif - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_request_handler()"; - const char* the_type = 0; - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - char log_info[40]; /* Scratch buffer */ - #endif - - void *modconf = r->server->module_config; - - mod_gzip_conf *conf = 0; /* Pointer to our own config data */ - - /* - * Start... - * - * Establish a local pointer to module configuration data... - */ - - conf = (mod_gzip_conf *) - ap_get_module_config(modconf, &gzip_module); - - /* - * Get the current Apache log level... - */ - - loglevel = r->server->loglevel; - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* - * If the MOD_GZIP_USES_APACHE_LOGS compile-time switch is ON - * then the Apache log module interface code is being included. - * - * Reset the module 'notes' that are used by mod_gzip to - * add entries to Apache standard log files... - * - * See the note farther below about how to add mod_gzip - * compression information to any standard Apache log file. - */ - - /* Default for 'mod_result' message is 'DECLINED:NOP'... */ - - ap_table_setn( r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:NOP")); - - /* Default for in/out size is 'n/a'... 'Not available'...*/ - - sprintf( log_info, "n/a" ); - - ap_table_setn( r->notes,"mod_gzip_input_size",ap_pstrdup(r->pool,log_info)); - ap_table_setn( r->notes,"mod_gzip_output_size",ap_pstrdup(r->pool,log_info)); - - /* Default for compression ratio is '0' percent... */ - - ap_table_setn( r->notes,"mod_gzip_compression_ratio",ap_pstrdup(r->pool,"0")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - #ifdef MOD_GZIP_DEBUG1 - - /* Request info... */ - - mod_gzip_printf( "%s: Entry...\n",cn); - mod_gzip_printf( "%s: mod_gzip_version =[%s]\n", cn, mod_gzip_version); - mod_gzip_printf( "%s: conf->req = %d\n", cn, (int) conf->req); - mod_gzip_printf( "%s: conf->cache.root =[%s]\n", cn, conf->cache.root); - mod_gzip_printf( "%s: *IN: r->uri =[%s]\n", cn, r->uri); - mod_gzip_printf( "%s: *IN: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri); - mod_gzip_printf( "%s: *IN: r->filename =[%s]\n", cn, r->filename); - mod_gzip_printf( "%s: *IN: r->handler =[%s]\n", cn, r->handler); - mod_gzip_printf( "%s: r->finfo.st_size = %ld\n", cn, (long) r->finfo.st_size); - - /* NOTE: The r->headers_out content type value has not normally */ - /* been set at this point but grab a pointer to it and show */ - /* it just to make sure. The r->content_type value, however, */ - /* normally WILL have some value at this point. */ - - the_type = ap_table_get( r->headers_out,"Content-type" ); - - mod_gzip_printf( "%s: r->headers_out, Content-type = [%s]\n",cn,the_type); - mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type ); - - /* The r->handler ASCII name string is the all-important */ - /* jump table name for the module that will handle the */ - /* transaction. If this is a CGI jump then it will normally */ - /* have a value of 'cgi-script' at this point. */ - - mod_gzip_printf( "%s: r->handler = [%s]\n",cn,r->handler ); - - /* Server info... */ - - mod_gzip_printf( "%s: r->server->path = [%s]\n",cn,r->server->path ); - mod_gzip_printf( "%s: r->server->pathlen = %d\n", cn,r->server->pathlen); - mod_gzip_printf( "%s: r->server->server_admin = [%s]\n",cn,r->server->server_admin); - mod_gzip_printf( "%s: r->server->server_hostname = [%s]\n",cn,r->server->server_hostname); - mod_gzip_printf( "%s: r->server->error_fname = [%s]\n",cn,r->server->error_fname); - - /* Environment info... */ - - mod_gzip_printf( "%s: DOCUMENT_ROOT = [%s]\n",cn,ap_document_root(r)); - - #endif /* MOD_GZIP_DEBUG1 */ - - /* - * Check the 'master' request control switch and see if mod_gzip - * is ON (ENABLED) or OFF (DISABLED)... - */ - - if ( conf->req != 1 ) - { - /* mod_gzip is currently DISABLED so DECLINE the processing... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: conf->req = %d = OFF\n",cn,conf->req); - mod_gzip_printf( "%s: The module is currently DISABLED\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:DISABLED")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - - }/* End 'if( conf->req != 1 )' */ - - /* - * Check for a default HTTP support level ( if used ). - * If no value for conf->min_http was supplied in the - * httpd.conf file then the default value will be 0 - * so that ALL levels of HTTP will be OK... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: *HTTP CHECK:conf->min_http = %d\n", cn, conf->min_http ); - mod_gzip_printf( "%s: *HTTP CHECK:r->proto_num = %d\n", cn, r->proto_num ); - mod_gzip_printf( "%s: *HTTP CHECK:r->protocol = [%s]\n", cn, r->protocol ); - #endif - - if ( r->proto_num < conf->min_http ) - { - /* The HTTPx/x version number does not meet the minimum requirement */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Request HTTP level does not meet minimum requirement\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - sprintf( log_info, "DECLINED:%s:%d", r->protocol, r->proto_num ); - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,log_info)); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - - }/* End 'if ( r->proto_num < conf->min_http )' */ - - else /* Protocol level is OK... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Request HTTP level is OK...\n",cn); - #endif - } - - #ifdef MOD_GZIP_ALLOWS_INTERNAL_COMMANDS - - /* - * Internal command pickups... - * - * If this module was compiled with the - * MOD_GZIP_ALLOWS_INTERNAL_COMMANDS switch ON - * then the first thing we do is check for valid - * URL-based internal commands. - * - * Rather than check for all possible commands each time - * just do 1 quick check for the command prefix and set - * a flag to indicate if there is any need to enter the - * actual command handler... - */ - - if ( strstr( r->filename, "mod_gzip_command_" ) ) - { - do_command = 1; /* Process the command */ - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: do_command = %d\n",cn,do_command); - #endif - - if ( do_command ) - { - /* Determine the exact command and respond... */ - - if ( strstr( r->filename, "mod_gzip_command_version" ) ) - { - /*------------------------------------------------------*/ - /* Command: 'mod_gzip_command_version' */ - /* Purpose: Return the current mod_gzip version number. */ - /* Comment: Allows anyone to query any Apache Server at */ - /* any URL with a browser and discover if */ - /* mod_gzip is in use at that site. */ - /*------------------------------------------------------*/ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 'mod_gzip_command_version' seen...\n",cn); - #endif - - /* NOTE: mod_gzip command results are not sent compressed */ - - /* Build the response buffer... */ - - sprintf( tmp, - "
"
-          "mod_gzip is available on this Server\r\n"
-          "mod_gzip version = %s\r\n"
-          "
", - mod_gzip_version - ); - - /* For all mod_gzip commands that are intercepted we */ - /* simply return OK. */ - - return( mod_gzip_send_html_command_response( r, tmp, "text/html" )); - } - else if ( strstr( r->filename, "mod_gzip_command_showstats" ) ) - { - /*------------------------------------------------------*/ - /* Command: 'mod_gzip_command_showstats' */ - /* Purpose: Display compression statistics. */ - /* Comment: Allows anyone to query any Apache Server at */ - /* any URL with a browser and get a report */ - /* about compression results. */ - /*------------------------------------------------------*/ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 'mod_gzip_command_showstats' seen...\n",cn); - #endif - - /* NOTE: mod_gzip command results are not sent compressed */ - - /* Build the response buffer... */ - - /* NOTE: This command has been temporarily removed */ - - sprintf( tmp, - "
"
-          "mod_gzip is available on this Server\r\n"
-          "mod_gzip version = %s\r\n\r\n"
-          "The 'mod_gzip_command_showstats' command has been temporarily removed.\r\n"
-          "
", - mod_gzip_version - ); - - /* For all mod_gzip commands that are intercepted we */ - /* simply return OK. */ - - return( mod_gzip_send_html_command_response( r, tmp, "text/html" )); - } - else if ( strstr( r->filename, "mod_gzip_command_resetstats" ) ) - { - /*------------------------------------------------------*/ - /* Command: 'mod_gzip_command_resetstats' */ - /* Purpose: Resets the compression statistics. */ - /* Comment: Allows the compression statistics to be */ - /* reset using only a browser. */ - /*------------------------------------------------------*/ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 'mod_gzip_command_resetstats' seen...\n",cn); - #endif - - /* NOTE: mod_gzip command results are not sent compressed */ - - /* Build the response buffer... */ - - /* NOTE: This command has been temporarily removed */ - - sprintf( tmp, - "
"
-          "mod_gzip is available on this Server\r\n"
-          "mod_gzip version = %s\r\n\r\n"
-          "The 'mod_gzip_command_resetstats' command has been temporarily removed.\r\n"
-          "
", - mod_gzip_version - ); - - /* For all mod_gzip commands that are intercepted we */ - /* simply return OK. */ - - return( mod_gzip_send_html_command_response( r, tmp, "text/html" )); - } - else /* Unrecognized command... */ - { - /* The command prefix was 'seen' and the 'do_command' flag */ - /* was TRUE but either the command was mis-typed or there */ - /* is no such command available. This is not an ERROR and */ - /* we should simply fall-through and assume that the URL */ - /* is valid for the local Server. A 404 will be returned */ - /* if there is no object that actually matches the name. */ - } - - }/* End 'if( do_command )' */ - - #endif /* MOD_GZIP_ALLOWS_INTERNAL_COMMANDS */ - - /* - * Sanity checks... - */ - - /* - * If the requested file already contains the .gz designation - * then we must assume it is pre-compressed and let the - * default logic take care of sending the file. This module - * doesn't really care if a .gz file was actually requested - * or if it is the source target because of a successful - * Server side 'negotiation'. Doesn't matter. - */ - - if ( ( r->filename ) && ( strstr( r->filename, ".gz" ) ) ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: r->filename already contains '.gz'.\n",cn); - mod_gzip_printf( "%s: Pre-compression is assumed.\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:HAS.GZ")); - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: Files with .gz file extension are skipped."); - } - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - } - else /* r->filename doesn not contain '.gz' designator... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: r->filename does NOT contain '.gz'.\n",cn); - mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); - #endif - } - - /* - * For now just block all attempts to compress 'image/*' MIME - * type even if user is trying to do so. Too many issues with - * broken browsers when it comes to decoding compressed images. - * - * WARNING: Don't submit r->content_type to strstr() it if is - * NULL or the API call will GP fault. Go figure. - */ - - if ( ( r->content_type ) && ( strstr( r->content_type, "image/" ) ) ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: r->content_type contains 'image/'.\n",cn); - mod_gzip_printf( "%s: Image compression is temporaily BLOCKED\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:IMAGE")); - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: Graphics image compression option is temporarily disabled."); - } - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - } - - /* - * Safeguard against situations where some other module or - * filter has gotten to this request BEFORE us and has already - * added the 'Content-encoding: gzip' field to the output header. - * It must be assumed that whoever added the header prior to this - * point also took care of the compression itself. - * - * If the output header already contains "Content-encoding: gzip" - * then simply DECLINE the processing and let the default chain - * take care of it... - */ - - has_encoding = ap_table_get( r->headers_out, "Content-encoding" ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: has_encoding = [%s]\n",cn,has_encoding); - #endif - - if ( has_encoding ) /* 'Content-encoding' field is present... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Output header already contains 'Content-encoding:' field\n",cn); - mod_gzip_printf( "%s: Checking for 'gzip' designator...\n",cn); - #endif - - if ( strstr( has_encoding, "gzip" ) || - strstr( has_encoding, "deflate" ) ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' or 'deflate' designator...\n",cn); - mod_gzip_printf( "%s: Pre-compression is assumed.\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:HAS_CE:GZIP")); - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: Header already has 'Content-encoding: gzip'"); - } - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - } - else /* 'gzip' designator not found... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' or 'deflate' designator...\n",cn); - mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); - #endif - } - - }/* End 'if( has_encoding )' */ - - else /* Output header does NOT contain 'Content-encoding:' field... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Output header does NOT contain 'Content-encoding:' field.\n",cn); - mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); - #endif - } - - /* - * Basic sanity checks completed and we are still here. - * - * Now we must determine if the User-Agent is capable of receiving - * compressed data... - * - * There are, currently, many reasons why it is actually never - * enough to simply trust the 'Accept-encoding: foo, bar' - * request header field when it comes to actually determining - * if a User-agent is capable of receiving content or transfer - * encodings. - * - * Some of them are... - * - * 1. There have been several major releases of popular browsers - * that actually send the 'Accept-encoding:' request field but - * are, in reality, unable to perform the specified decoding(s). - * In some cases the result will be that the browser screen - * simply fills with garbage ( the binary compressed data - * itself ) but in some cases the browser will actually crash. - * - * 2. There have been other major releases of browsers that are - * specifying multiple 'Accept-encoding' techniques with no - * 'Q' values whatsoever and they are actually only able to - * handle one of the multiple types specified. There is no - * way to know which type is 'real' other than by using other - * empiricial data extracted from the 'User-agent' field - * or other inbound request headers. - * - * 3. Same as 1 and 2 but relates to SIZE. Some major browser - * releases can handle the encoded content but only up to - * a certain 'SIZE' limit and then they will fail. There - * is no way for a User-agent to specify this limitation - * via HTTP so empirical header analysis is the only option. - * - * 4. The HTTP specification has no way for a Server to distinguish - * from the 'Accept encoding: foo, bar' input request field - * whether the user agent can only support the specified encodings - * as either a Content-encoding OR a Transfer-encoding, but - * not both. There is also no way of knowing if the user - * agent is able to handle any of the specified types being - * used as both a Content-encoding AND a Transfer-encoding - * for the same message body. All the Server can do is assume - * that the encodings are valid in any/all combinations - * and that the user agent can 'Accept' them as either - * 'Content' encodings and/or 'Transfer' encodings under - * any and all circumstances. This blanket assumption will - * cause problems with some release versions of some browsers - * because the assumed 'do all' capability is simply not a - * reality. - * - * 5. Many browsers ( such as Netscape 4.75 for UNIX ) are unable - * to handle Content-encoding only for specific kinds of HTML - * transactions such as Style Sheets even though the browser - * says it is HTTP 1.1 compliant and is suppying the standard - * 'Accept-encoding: gzip' field. According to the IETF - * specifications any user-agent that says it can accept - * encodings should be able to do so for all types of HTML - * transactions but this is simply not the current reality. - * Some will, some won't... even if they say they can. - * - * This version of this module takes the 'What, me worry' approach - * and simply uses the accepted method of relying solely on the - * 'Accept-encoding: foo, bar' field and also assumes this means - * that the User-agent can accept the specified encodings as - * either Content-encodings (CE) and/or Transfer-encodings (TE) - * under all circumstances and in any combinations that the - * Server decides to send. - * - * It also assumes that the caller has no preference and should - * be able to decode any of the specified encodings equally well. - * Most user-agents sending the 'Accept-encoding:' field do NOT - * supply any 'Q' values to help with determining preferences. - */ - - accept_encoding = ap_table_get( r->headers_in, "Accept-Encoding" ); - - #ifdef MOD_GZIP_DEBUG1 - - if ( accept_encoding ) - { - mod_gzip_printf( "%s: 'Accept Encoding:' field seen.\n",cn); - } - else - { - mod_gzip_printf( "%s: 'Accept Encoding' field NOT seen.\n",cn); - } - - #endif /* MOD_GZIP_DEBUG1 */ - - /* If Accept-Encoding is applicable to this request...*/ - - if ( accept_encoding ) - { - /* ...and if it has the right 'gzip' indicator... */ - /* We record the compression format in a request note, so we - * can get it again later, and so it can potentially be logged. - */ - if ( strstr( accept_encoding, "gzip" ) ) - { - process = 1; /* ...set the 'process' flag TRUE */ - ap_table_setn( r->notes,"mod_gzip_compression_format", - ap_pstrdup(r->pool,"gzip")); - - } - else if ( strstr( accept_encoding, "deflate" ) ) - { - process = 1; /* ...set the 'process' flag TRUE */ - ap_table_setn( r->notes,"mod_gzip_compression_format", - ap_pstrdup(r->pool,"deflate")); - } - - }/* End 'if( accept_encoding )' */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 'process' flag = %d\n",cn,process); - #endif - - if ( !process ) /* Request does not meet criteria for processing... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: No 'gzip' capability specified by user-agent.\n",cn); - mod_gzip_printf( "%s: 'process' flag is FALSE.\n",cn); - mod_gzip_printf( "%s: This request will not be processed.\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:NO_GZIP")); - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: The inbound request header does not have 'Accept-encoding: gzip'"); - } - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - } - else /* 'gzip' designator was seen in 'Accept-Encoding:' field */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 'gzip' or 'deflate' capability specified by user-agent.\n",cn); - mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); - #endif - } - - /* - * Handle the transaction... - * - * At this point the inbound header analysis has been completed - * and we are assuming that the user agent is capable of accepting - * the content encodings we can provide. - * - * We must now 'do the right thing' based on what type of - * request it actually is... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: r->handler = [%s]\n",cn,r->handler); - mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); - mod_gzip_printf( "%s: Call mod_gzip_get_action_flag()...\n",cn); - #endif - - action_flag = - mod_gzip_get_action_flag( - (request_rec *) r, - (mod_gzip_conf *) conf - ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back mod_gzip_get_action_flag()...\n",cn); - mod_gzip_printf( "%s: action_flag = %d\n",cn,action_flag); - mod_gzip_printf( "%s: conf->do_static_files = %d\n",cn,(int)conf->do_static_files); - mod_gzip_printf( "%s: conf->do_cgi = %d\n",cn,(int)conf->do_cgi); - #endif - - /* - * Perform the right 'action' for this transaction... - */ - - if ( action_flag == MOD_GZIP_IMAP_DECLINED1 ) - { - /* - * If the transaction is to be DECLINED then just set the final - * return code to DECLINED, fall through, and return. - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_DECLINED1\n",cn); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: action_flag = MOD_GZIP_IMAP_DECLINED1 "); - } - - rc = DECLINED; - } - else if ( action_flag == MOD_GZIP_IMAP_DYNAMIC1 ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_DYNAMIC1\n",cn); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: action_flag = MOD_GZIP_IMAP_DYNAMIC1 "); - } - - /* - * Check the flag that can control whether or not the - * CGI dynamic output handler is ever called... - */ - - if ( conf->do_cgi != 1 ) /* CGI handler is OFF for now... */ - { - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: Calls to CGI handler currently DISABLED "); - } - - #ifdef MOD_GZIP_USES_APACHE_LOGS - /* Update the result string for Apache log(s)... */ - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:CGI_OFF")); - #endif - - rc = DECLINED; /* Just set final return code and fall through */ - - }/* End 'if( conf->do_cgi == 0 )' */ - - else /* It's OK to call the handler... */ - { - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: Calling cgi_handler for r->uri=[%s]",r->uri); - } - - /* Take care of some business BEFORE calling the */ - /* dynamic handler... */ - - mod_gzip_prepare_for_dynamic_call( r ); - - /* PHP NOTE */ - /* r->path_info must be set before ap_add_cgi_vars() */ - /* is called from within the upcoming hander or we */ - /* won't get PATH_INFO or PATH_TRANSLATED environment */ - /* variables set and PHP.EXE will return 'No input file' */ - /* error message since it depends on both of these being */ - /* set. r->path_info must be set to r->uri */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 1 r->uri = [%s]\n", cn, r->uri ); - mod_gzip_printf( "%s: 1 r->path_info = [%s]\n", cn, r->path_info ); - mod_gzip_printf( "%s: Setting r->path_info to r->uri for CGI...\n", cn ); - #endif - - r->path_info = r->uri; - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 2 r->uri = [%s]\n", cn, r->uri ); - mod_gzip_printf( "%s: 2 r->path_info = [%s]\n", cn, r->path_info ); - #endif - - /* Call the actual handler... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call mod_gzip_cgi_handler()...\n",cn); - #endif - - rc = mod_gzip_cgi_handler( (request_rec *) r ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back mod_gzip_cgi_handler()... rc=%d\n",cn,rc); - #endif - - }/* End 'else' - OK to call handler */ - } - else if ( action_flag == MOD_GZIP_IMAP_STATIC1 ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_STATIC1\n",cn); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: action_flag = MOD_GZIP_IMAP_STATIC1 "); - } - - /* - * Check the flag that can control whether or not the - * static handler is ever called... - */ - - if ( conf->do_static_files != 1 ) /* Static handler is OFF for now... */ - { - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: Calls to static handler currently DISABLED "); - } - - #ifdef MOD_GZIP_USES_APACHE_LOGS - /* Update the result string for Apache log(s)... */ - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:STATIC_OFF")); - #endif - - rc = DECLINED; /* Just set final return code and fall through */ - - }/* End 'if( conf->do_static == 0 )' */ - - else /* It's OK to call the handler... */ - { - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: Calling static_handler for r->uri=[%s]",r->uri); - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call mod_gzip_static_file_handler()...\n",cn); - #endif - - rc = mod_gzip_static_file_handler( (request_rec *) r ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back mod_gzip_static_file_handler()... rc=%d\n",cn,rc); - #endif - - }/* End 'else' - OK to call the handler */ - } - else /* Safety catch... No pickup for the 'action' flag... */ - { - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: action_flag = MOD_GZIP_IMAP_????? Unknown value"); - } - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: No pickup for specified 'action' flag."); - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: action_flag = MOD_GZIP_??? Unknown value\n",cn); - #endif - - rc = DECLINED; - } - - /* - * Record results to logs, if applicable, and return... - * - * The 'r->notes' values that can be used to disply result - * information in the standard Apache log files should have - * already been updated by the handler that was actually - * used to process the transaction. - */ - - #ifdef MOD_GZIP_DEBUG1 - - if ( rc == OK ) - { - mod_gzip_printf( "%s: Exit > return( rc=%d OK ) >\n",cn,rc); - } - else if ( rc == DECLINED ) - { - mod_gzip_printf( "%s: Exit > return( rc=%d DECLINED ) >\n",cn,rc); - } - else /* HTTP ERROR VALUE... */ - { - mod_gzip_printf( "%s: Exit > return( rc=%d HTTP_ERROR ) >\n",cn,rc); - } - - #endif /* MOD_GZIP_DEBUG1 */ - - return rc; /* Could be OK or DECLINED or HTTP_ERROR */ - -}/* End of mod_gzip_request_handler() */ - -int mod_gzip_prepare_for_dynamic_call( request_rec *r ) -{ - int rc; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_prepare_for_dynamic_call()"; - #endif - - /* - * Start... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry...\n",cn); - #endif - - /* - * mod_gzip can run other modules directly... - */ - - /* - * First run mod_action and see it there's a SCRIPT - * for this mime type... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: 1 ***: r->uri =[%s]\n", cn, r->uri ); - mod_gzip_printf( "%s: 1 ***: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); - mod_gzip_printf( "%s: 1 ***: r->filename =[%s]\n", cn, r->filename ); - mod_gzip_printf( "%s: 1 ***: r->content_type=[%s]\n", cn, r->content_type ); - mod_gzip_printf( "%s: 1 ***: r->handler =[%s]\n", cn, r->handler ); - mod_gzip_printf( "%s: Call mod_gzip_run_mod_action(r)...\n",cn); - #endif - - rc = mod_gzip_run_mod_action( (request_rec *) r ); - - #ifdef MOD_GZIP_DEBUG1 - - mod_gzip_printf( "%s: Back mod_gzip_run_mod_action(r)...\n",cn); - - if ( rc == OK ) - { - mod_gzip_printf( "%s: rc = %d = OK\n",cn, rc ); - } - else if ( rc == DECLINED ) - { - mod_gzip_printf( "%s: rc = %d = DECLINED\n",cn, rc ); - } - else if ( rc == DONE ) /* -2 means 'totally done' */ - { - mod_gzip_printf( "%s: rc = %d = DONE\n",cn, rc ); - } - else /* Probably an HTTP ERROR value... */ - { - mod_gzip_printf( "%s: rc = %d = HTTP_ERROR?\n",cn, rc ); - } - - mod_gzip_printf( "%s: 2 ***: r->uri =[%s]\n", cn, r->uri ); - mod_gzip_printf( "%s: 2 ***: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); - mod_gzip_printf( "%s: 2 ***: r->filename =[%s]\n", cn, r->filename ); - mod_gzip_printf( "%s: 2 ***: r->content_type=[%s]\n", cn, r->content_type ); - mod_gzip_printf( "%s: 2 ***: r->handler =[%s]\n", cn, r->handler ); - - #endif /* MOD_GZIP_DEBUG1 */ - - /* - * Now run mod_alias and get any aliases converted - * to real pathnames... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call mod_gzip_run_mod_alias(r)...\n",cn); - #endif - - rc = mod_gzip_run_mod_alias( (request_rec *) r ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back mod_gzip_run_mod_alias(r)...\n",cn); - - if ( rc == OK ) - { - mod_gzip_printf( "%s: rc = %d = OK\n",cn, rc ); - } - else if ( rc == DECLINED ) - { - mod_gzip_printf( "%s: rc = %d = DECLINED\n",cn, rc ); - } - else if ( rc == DONE ) /* -2 means 'totally done' */ - { - mod_gzip_printf( "%s: rc = %d = DONE\n",cn, rc ); - } - else /* Probably an HTTP ERROR value... */ - { - mod_gzip_printf( "%s: rc = %d = HTTP_ERROR?\n",cn, rc ); - } - - mod_gzip_printf( "%s: 3 ***: r->uri =[%s]\n", cn, r->uri ); - mod_gzip_printf( "%s: 3 ***: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); - mod_gzip_printf( "%s: 3 ***: r->filename =[%s]\n", cn, r->filename ); - mod_gzip_printf( "%s: 3 ***: r->content_type=[%s]\n", cn, r->content_type ); - mod_gzip_printf( "%s: 3 ***: r->handler =[%s]\n", cn, r->handler ); - - #endif /* MOD_GZIP_DEBUG1 */ - - return OK; - -}/* End of mod_gzip_prepare_for_dynamic_call() */ - - -int mod_gzip_static_file_handler( request_rec *r ) -{ - int rc = 0; - long input_size = 0; - FILE* ifh1 = 0; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_static_file_handler()"; - #endif - - /* - * Start... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Processing file [%s]\n",cn,r->filename); - mod_gzip_printf( "%s: r->finfo.st_size = %ld\n", - cn, (long) r->finfo.st_size); - #endif - - /* - * If there is a valid file size already associated with - * the request then we can assume the core stat() call succeeded - * and that r->filename actually exists. We shouldn't need - * to waste a call to 'fopen()' just to find out for ourselves - * if the file exists. - * - * If the inbound file size was '0' then we need to do some - * verifications of our own before we give up since the - * absence of size might just be a simple bug in the parent code. - */ - - if ( r->finfo.st_size > 0 ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Source file length already known...\n",cn); - #endif - - input_size = (long) r->finfo.st_size; - } - else /* Do our own checking... */ - { - /* - * See if the requested source file exists... - * Be SURE to open the file in BINARY mode... - */ - - ifh1 = fopen( r->filename, "rb" ); - - if ( !ifh1 ) /* The file cannot be found or opened... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: The requested source file was NOT FOUND.\n",cn); - mod_gzip_printf( "%s: Exit > return( HTTP_NOT_FOUND ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* HTTP ERROR conditions provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:HTTP_NOT_FOUND")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return HTTP_NOT_FOUND; - } - else /* The file was found and opened OK... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: The requested source file is now OPEN...\n",cn); - #endif - } - - /* - * Move the current file pointer to the end of the file... - */ - - if ( fseek( ifh1, 0, SEEK_END ) ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ERROR: fseek() call failed...\n",cn); - #endif - - fclose( ifh1 ); /* FILE is still open so CLOSE it... */ - - /* fseek() failure could be a platform issue so log the event... */ - - ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_ERR, r->server, - "mod_gzip: fseek() failed for r->filename=[%s]",r->filename ); - - /* Return DECLINED and let default logic finish the request... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:FSEEK_FAIL")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - } - - /* - * Get the current SIZE of the requested file... - */ - - input_size = (long) ftell( ifh1 ); - - if ( input_size == -1l ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ERROR: ftell() call failed...\n",cn); - #endif - - fclose( ifh1 ); /* FILE is still open so CLOSE it... */ - - /* ftell() failure could be a platform issue so log the event... */ - - ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_ERR, r->server, - "mod_gzip: ftell() failed for r->filename=[%s]", r->filename ); - - /* Return DECLINED and let default logic finish the request... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:FTELL_FAIL")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - } - - /* - * Once we have the length just close the file... - */ - - if ( fclose( ifh1 ) == EOF ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ERROR: fclose() following ftell() call failed...\n",cn); - #endif - - /* fclose() failure could be a platform issue so log the event... */ - - ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_ERR, r->server, - "mod_gzip: fclose() failed for r->filename=[%s]",r->filename ); - - /* Return DECLINED and let default logic finish the request... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:FCLOSE_FAIL")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - } - - }/* End 'else' */ - - /* - * We have the static filename and the length. - * That's pretty much all we need at this point so - * go ahead and encode/transmit the object... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call mod_gzip_encode_and_transmit()...\n",cn); - #endif - - rc = - mod_gzip_encode_and_transmit( - (request_rec *) r, /* request_rec */ - (char *) r->filename, /* source ( Filename or Memory buffer ) */ - (int ) 1, /* 1=Source is a file 0=Memory buffer */ - (long ) input_size, /* input_size */ - (int ) 0 /* nodecline flag 0=Ok to DECLINE 1=No */ - ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back mod_gzip_encode_and_transmit()...\n",cn); - #endif - - /* - * The encode/transmit path should have already updated - * any relevant 'r->note' values ( if used ) for the transaction - * to reflect the results of the operation. - * - * Just return the result code and finish the transaction. - */ - - #ifdef MOD_GZIP_DEBUG1 - if ( rc == OK ) - { - mod_gzip_printf( "%s: Exit > return( rc = %d OK ) >\n",cn,rc); - } - else if ( rc == DECLINED ) - { - mod_gzip_printf( "%s: Exit > return( rc = %d DECLINED ) >\n",cn,rc); - } - else /* HTTP ERROR */ - { - mod_gzip_printf( "%s: Exit > return( rc = %d HTTP_ERROR ) >\n",cn,rc); - } - #endif /* MOD_GZIP_DEBUG1 */ - - return( rc ); - -}/* End of mod_gzip_static_file_handler() */ - -int mod_gzip_create_unique_filename( -mod_gzip_conf *mgc, -char *target, -int targetmaxlen -) -{ - /* - * Creates a unique work file name. - */ - - long process_id = 0; /* Current Process ID */ - long thread_id = 0; /* Current thread ID */ - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_create_unique_filename()"; - #endif - - /* Start... */ - - #ifdef _WIN32 - process_id = (long) GetCurrentProcessId(); - thread_id = (long) GetCurrentThreadId(); - #else /* !_WIN32 */ - process_id = (long) getpid(); - thread_id = (long) process_id; /* TODO: Add pthreads call */ - #endif /* _WIN32 */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry...\n",cn ); - mod_gzip_printf( "%s: target = %ld\n",cn,(long)target); - mod_gzip_printf( "%s: targetmaxlen = %ld\n",cn,(long)targetmaxlen); - mod_gzip_printf( "%s: process_id = %ld\n",cn,(long)process_id ); - mod_gzip_printf( "%s: thread_id = %ld\n",cn,(long)thread_id ); - mod_gzip_printf( "%s: mod_gzip_iusn = %ld\n",cn,(long)mod_gzip_iusn ); - #endif - - /* - * Sanity checks... - */ - - if ( ( !target ) || ( targetmaxlen == 0 ) ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Invalid target or targetmaxlen value.\n",cn); - mod_gzip_printf( "%s: Exit > return( 1 ) > ERROR >\n",cn ); - #endif - - return 1; - } - - /* - * Use the PROCESS + THREAD ID's and the current IUSN - * ( Instance Unique Sequence Number ) transaction ID to - * create a one-time only unique output workfile name... - */ - - sprintf( - target, - "%s%s_%ld_%ld_%ld.wrk", - mgc->cache.root, /* Either ServerRoot or Config specified dir. */ - mod_gzip_dirsep, /* Forward slash for UNIX, backslash for WIN32 */ - (long) process_id, /* Current process ID */ - (long) thread_id, /* Current thread ID */ - (long) mod_gzip_iusn /* Instance Unique Sequence Number */ - ); - - mod_gzip_iusn++; /* Increment Instance Unique Sequence Number */ - - if ( mod_gzip_iusn > 999999999L ) mod_gzip_iusn = 1; /* Wrap */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: target = [%s]\n",cn,target); - mod_gzip_printf( "%s: Exit > return( 0 ) >\n",cn ); - #endif - - return 0; - -}/* End of mod_gzip_create_unique_filename() */ - - -#ifdef MOD_GZIP_ALLOWS_INTERNAL_COMMANDS - -int mod_gzip_send_html_command_response( -request_rec *r, /* Request record */ -char *tmp, /* Response to send */ -char *ctype /* Content type string */ -) -{ - /* Generic command response transmitter... */ - - int tmplen=0; - char content_length[20]; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_send_html_command_response()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry...\n",cn); - mod_gzip_printf( "%s: ctype=[%s]\n",cn,ctype); - #endif - - /* Add the length of the response to the output header... */ - /* The third parameter to ap_table_set() MUST be a string. */ - - tmplen = strlen( tmp ); - - sprintf( content_length, "%d", tmplen ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: content_length = [%s]\n",cn,content_length); - #endif - - ap_table_set( r->headers_out, "Content-Length", content_length ); - - /* Make sure the content type matches this response... */ - - r->content_type = ctype; /* Actual type passed by caller */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); - #endif - - /* Start a timer... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call ap_soft_timeout()...\n",cn); - #endif - - ap_soft_timeout( "mod_gzip_send_html_command", r ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_soft_timeout()...\n",cn); - #endif - - #ifdef MOD_GZIP_COMMANDS_USE_LAST_MODIFIED - - /* Be sure to update the modifcation 'time' to current */ - /* time before calling 'ap_set_last_modified()'. All that */ - /* call does is set the r->xxxx value into the output */ - /* header. It doesn't actually update the time itself. */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call ap_update_mtime(r,r-finfo.st_mtime)...\n",cn); - #endif - - ap_update_mtime( r, r->finfo.st_mtime ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_update_mtime(r,r-finfo.st_mtime)...\n",cn); - #endif - - /* Update the 'Last modified' stamp in output header... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call ap_set_last_modified()...\n",cn); - #endif - - ap_set_last_modified(r); - - /* TODO: Add 'no-cache' option(s) to mod_gzip command responses */ - /* so user doesn't have hit reload to get fresh data. */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_set_last_modified()...\n",cn); - #endif - - #endif /* MOD_GZIP_COMMANDS_USE_LAST_MODIFIED */ - - /* Send the HTTP response header... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call ap_send_http_header()...\n",cn); - #endif - - ap_send_http_header(r); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_send_http_header()...\n",cn); - #endif - - /* Send the response BODY... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Sending response...\n%s\n",cn,tmp); - #endif - - #ifdef MOD_GZIP_USES_AP_SEND_MMAP - - /* Use ap_send_mmap() call to send the data... */ - - ap_send_mmap( tmp, r, 0, tmplen ); - - #else /* !MOD_GZIP_USES_AP_SEND_MMAP */ - - /* Use ap_rwrite() call to send the data... */ - - ap_rwrite( tmp, tmplen, r ); - - #endif /* MOD_GZIP_USES_AP_SEND_MMAP */ - - /* Clean up and exit... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call ap_kill_timeout()...\n",cn); - #endif - - ap_kill_timeout(r); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_kill_timeout()...\n",cn); - mod_gzip_printf( "%s: Exit > return( OK ) >\n",cn); - #endif - - return OK; - -}/* End of mod_gzip_send_html_command_response() */ - -#endif /* MOD_GZIP_ALLOWS_INTERNAL_COMMANDS */ - -static void * -mod_gzip_create_config( pool *p, server_rec *s ) -{ - int i; - - mod_gzip_conf *ps = 0; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_create_config()"; - #endif - - /* - * Set all the configuration default values... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - #endif - - /* - * Allocate a new config structure... - */ - - ps = ( mod_gzip_conf * ) ap_pcalloc( p, sizeof( mod_gzip_conf ) ); - - /* - * Set all default values... - */ - - ps->req = 1; /* Default is ON */ - ps->req_set = 1; /* Default is ON */ - ps->do_static_files = 1; /* Default is ON */ - ps->do_cgi = 1; /* Default is ON */ - ps->keep_workfiles = 0; /* 1=Keep workfiles 0=No */ - ps->min_http = 0; /* 1001=HTTP/1.1 Default=All HTTP levels */ - - ps->minimum_file_size = (long) mod_gzip_minimum_file_size; - /* Minimum file size in bytes */ - ps->maximum_inmem_size = (long) mod_gzip_maximum_inmem_size; - /* Maximum size for in-memory compression */ - - /* Compressed object cache control variables... */ - - /* Using these default values the compressed object cache - /* can have 2^18 directories (256,000) */ - - ps->cache.root = ap_server_root; /* Default DIR is ServerRoot */ - - ps->cache.space = MOD_GZIP_DEFAULT_CACHE_SPACE; - ps->cache.space_set = 0; - ps->cache.maxexpire = MOD_GZIP_DEFAULT_CACHE_MAXEXPIRE; - ps->cache.maxexpire_set = 0; - ps->cache.defaultexpire = MOD_GZIP_DEFAULT_CACHE_EXPIRE; - ps->cache.defaultexpire_set = 0; - ps->cache.lmfactor = MOD_GZIP_DEFAULT_CACHE_LMFACTOR; - ps->cache.lmfactor_set = 0; - ps->cache.gcinterval = -1; - ps->cache.gcinterval_set = 0; - ps->cache.dirlevels = 3; - ps->cache.dirlevels_set = 0; - ps->cache.dirlength = 1; - ps->cache.dirlength_set = 0; - - /* Initialize the include/exclude item map list... */ - - /* For now all init values are ZERO but don't use */ - /* memset() since this may not always be the case. */ - - ps->imap_total_entries = 0; - - for ( i=0; iimap[i].include = 0; - ps->imap[i].type = 0; - ps->imap[i].action = 0; - ps->imap[i].name[0] = 0; - - }/* End 'i' loop */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ps->imap_total_entries = %d\n", cn, ps->imap_total_entries ); - mod_gzip_printf( "%s: Exit > return( ps ) >\n", cn ); - #endif - - return ps; - -}/* End of mod_gzip_create_config() */ - -static void * -mod_gzip_merge_config( pool *p, void *basev, void *overridesv ) -{ - mod_gzip_conf *ps = ap_pcalloc(p, sizeof(mod_gzip_conf)); - mod_gzip_conf *base = (mod_gzip_conf *) basev; - mod_gzip_conf *overrides = (mod_gzip_conf *) overridesv; - - ps->req = (overrides->req_set == 0) ? base->req : overrides->req; - ps->cache.root = (overrides->cache.root == NULL) ? base->cache.root : overrides->cache.root; - ps->cache.space = (overrides->cache.space_set == 0) ? base->cache.space : overrides->cache.space; - ps->cache.maxexpire = (overrides->cache.maxexpire_set == 0) ? base->cache.maxexpire : overrides->cache.maxexpire; - ps->cache.defaultexpire = (overrides->cache.defaultexpire_set == 0) ? base->cache.defaultexpire : overrides->cache.defaultexpire; - ps->cache.lmfactor = (overrides->cache.lmfactor_set == 0) ? base->cache.lmfactor : overrides->cache.lmfactor; - ps->cache.gcinterval = (overrides->cache.gcinterval_set == 0) ? base->cache.gcinterval : overrides->cache.gcinterval; - ps->cache.dirlevels = (overrides->cache.dirlevels_set == 0) ? base->cache.dirlevels : overrides->cache.dirlevels; - ps->cache.dirlength = (overrides->cache.dirlength_set == 0) ? base->cache.dirlength : overrides->cache.dirlength; - - return ps; - -}/* End of mod_gzip_merge_config() */ - -/* - * Module configuration directive handlers... - */ - -static const char * -mod_gzip_set_on(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_set_on()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) ) - { - /* Set the master 'request control' switches ON... */ - - mgc->req = 1; /* Yes */ - mgc->req_set = 1; /* Yes */ - } - else /* Set the master 'request control' switches OFF... */ - { - mgc->req = 0; /* No */ - mgc->req_set = 0; /* No */ - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: mgc->req = %ld\n", cn, (long) mgc->req ); - mod_gzip_printf( "%s: mgc->req_set = %ld\n", cn, (long) mgc->req_set ); - #endif - - return NULL; -} - -static const char * -mod_gzip_set_keep_workfiles(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_set_keep_workfiles()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) ) - { - mgc->keep_workfiles = 1; /* Yes */ - } - else - { - mgc->keep_workfiles = 0; /* No */ - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: mgc->keep_workfiles = %ld\n", cn, - (long) mgc->keep_workfiles ); - #endif - - return NULL; -} - -static const char * -mod_gzip_set_min_http(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_set_min_http()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - mgc->min_http = (int) atoi( arg ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: mgc->min_http = %ld\n", cn, - (long) mgc->min_http ); - #endif - - return NULL; -} - - -static const char * -mod_gzip_imap_add_item( mod_gzip_conf *mgc, char *arg, int flag1 ) -{ - int x; - char *p1; - int ch1; - int this_type=0; - int this_action=0; - int this_include=flag1; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_imap_add_item()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: 1 arg=[%s]\n", cn, arg ); - - if ( flag1 == 1 ) - { - mod_gzip_printf( "%s: flag1 = %d = INCLUDE\n", cn, flag1 ); - } - else if ( flag1 == 0 ) - { - mod_gzip_printf( "%s: flag1 = %d = EXCLUDE\n", cn, flag1 ); - } - else - { - mod_gzip_printf( "%s: flag1 = %d = ??? Unknown value\n", cn, flag1 ); - } - - mod_gzip_printf( "%s: MOD-GZIP_IMAP_MAXNAMES = %d\n", - cn, MOD_GZIP_IMAP_MAXNAMES ); - - mod_gzip_printf( "%s: mgc->imap_total_entries = %d\n", - cn, mgc->imap_total_entries ); - - #endif /* MOD_GZIP_DEBUG1 */ - - /* - * Parse the config line... - */ - - p1 = arg; - while((*p1!=0)&&(*p1<33)) p1++; - ch1 = *p1; - - this_type = MOD_GZIP_IMAP_ISHANDLER; - this_action = MOD_GZIP_IMAP_DYNAMIC1; - - if ( ch1 == '!' ) - { - arg++; - p1 = arg; - while((*p1!=0)&&(*p1<33)) p1++; - ch1 = *p1; - } - else - { - this_action = MOD_GZIP_IMAP_STATIC1; - } - - if ( ch1 == '.' ) - { - this_type = MOD_GZIP_IMAP_ISEXT; - } - else - { - p1 = arg; - while (*p1!=0) - { - if ( *p1 == '/' ) - { - this_type = MOD_GZIP_IMAP_ISMIME; - } - p1++; - } - } - - /* - * Safety checks... - */ - - if ( ( this_type != MOD_GZIP_IMAP_ISMIME ) && - ( this_type != MOD_GZIP_IMAP_ISEXT ) && - ( this_type != MOD_GZIP_IMAP_ISHANDLER ) ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: this_type = %d = MOD_GZIP_IMAP_IS??? Unknown type\n",cn,this_type); - mod_gzip_printf( "%s: return( mod_gzip: ERROR: Unrecognized item 'type'\n",cn); - #endif - - return( "mod_gzip: ERROR: Unrecognized item 'type'" ); - } - - if ( ( this_action != MOD_GZIP_IMAP_DYNAMIC1 ) && - ( this_action != MOD_GZIP_IMAP_STATIC1 ) ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: this_action = %d = MOD_GZIP_IMAP_??? Unknown action\n",cn,this_action); - mod_gzip_printf( "%s: return( mod_gzip: ERROR: Unrecognized item 'action'\n",cn); - #endif - - return( "mod_gzip: ERROR: Unrecognized item 'action'" ); - } - - /* - * Wildcards... - */ - - if ( this_type != MOD_GZIP_IMAP_ISMIME ) - { - /* - * Wildcards are only allowed in MIME strings such as 'image/*' - */ - - p1 = arg; - while (*p1!=0) - { - if ( *p1 == '*' ) - { - return( "mod_gzip: ERROR: Wildcards are only allowed in MIME strings." ); - } - p1++; - } - } - - /* - * If there is room for a new record then add it... - */ - - if ( mgc->imap_total_entries < MOD_GZIP_IMAP_MAXNAMES ) - { - if ( strlen( arg ) < MOD_GZIP_IMAP_MAXNAMELEN ) - { - x = mgc->imap_total_entries; - - p1 = arg; - while((*p1!=0)&&(*p1<33)) p1++; - - strcpy( mgc->imap[x].name, p1 ); - - mgc->imap[x].include = this_include; - mgc->imap[x].type = this_type; - mgc->imap[x].action = this_action; - - mgc->imap_total_entries++; /* Increase onboard items */ - } - else /* ERROR: Name is too long */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: return( mod_gzip: ERROR: Item name is too long\n",cn); - #endif - - return( "mod_gzip: ERROR: Item name is too long" ); - } - } - else /* ERROR: INDEX is FULL */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: return( mod_gzip: ERROR: Item index is full\n",cn); - #endif - - return( "mod_gzip: ERROR: Item index is full" ); - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( NULL ) >\n",cn); - #endif - - return NULL; - -}/* End of mod_gzip_imap_add_item() */ - -#ifdef MOD_GZIP_DEBUG1 - -int mod_gzip_imap_show_items( mod_gzip_conf *mgc ) -{ - /* - * DEBUG only. Show the complete include/exclude list. - * This is normally called from mod_gzip_init() - * after all the configuration routines have executed. - */ - - int i; - int x; - char cn[]="mod_gzip_imap_show_items()"; - - /* Start... */ - - mod_gzip_printf( "\n"); - mod_gzip_printf( "%s: Entry\n", cn ); - - mod_gzip_printf( "%s: mgc->imap_total_entries= %d\n", cn, - (long) mgc->imap_total_entries ); - - for ( i=0; iimap_total_entries; i++ ) - { - x = i; /* Work variable */ - - mod_gzip_printf( "\n"); - mod_gzip_printf( "%s: mgc->imap[%3.3d].include = %d\n", cn,x,mgc->imap[x].include); - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d\n", cn,x,mgc->imap[x].type); - - if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISMIME ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISMIME\n",cn,x); - } - else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISEXT ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISEXT\n",cn,x); - } - else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISHANDLER ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISHANDLER\n",cn,x); - } - else /* Unrecognized item type... */ - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_IS??? Unknown type\n",cn,x); - } - - mod_gzip_printf( "%s: mgc->imap[%3.3d].action = %d\n", cn,x,mgc->imap[x].action); - - if ( mgc->imap[x].action == MOD_GZIP_IMAP_DYNAMIC1 ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_DYNAMIC1\n",cn,x); - } - else if ( mgc->imap[x].action == MOD_GZIP_IMAP_STATIC1 ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_STATIC1\n",cn,x); - } - else /* Unrecognized action type... */ - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_??? Unknown action\n",cn,x); - } - - mod_gzip_printf( "%s: mgc->imap[%3.3d].name = [%s]\n",cn,x,mgc->imap[x].name); - - }/* End 'i' loop */ - - mod_gzip_printf( "\n"); - - return 0; - -}/* End of mod_gzip_imap_show_items() */ - -#endif /* MOD_GZIP_DEBUG1 */ - -static const char * -mod_gzip_set_item_include(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_set_item_include()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - /* Pass pre-determined pointer to config structure... */ - /* Pass '1' for parm 3 to INCLUDE this item... */ - - return( mod_gzip_imap_add_item( mgc, arg, 1 ) ); -} - -static const char * -mod_gzip_set_item_exclude(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_set_item_exclude()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - /* Pass pre-determined pointer to config structure... */ - /* Pass '0' for parm 3 to EXCLUDE this item... */ - - return( mod_gzip_imap_add_item( mgc, arg, 0 ) ); -} - -static const char * -mod_gzip_set_temp_dir(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - - char cn[]="mod_gzip_set_temp_dir()"; - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - mgc->cache.root = arg; /* For now temp dir is used as cache root */ - - strcpy( mod_gzip_temp_dir, arg ); - mgc->cache.root = mod_gzip_temp_dir; - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: mgc->cache.root=[%s]\n", cn, mgc->cache.root ); - #endif - - return NULL; -} - -static const char * -mod_gzip_set_minimum_file_size(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - long lval; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_set_minimum_file_size()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - lval = (long) atol(arg); - - /* 300 bytes is the minimum at all times */ - if ( lval < 300L ) lval = 300L; - - mgc->minimum_file_size = (long) lval; /* Set config */ - mod_gzip_minimum_file_size = (long) lval; /* Set global */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ....mgc->minimum_file_size = %ld\n", cn, - (long) mgc->minimum_file_size ); - mod_gzip_printf( "%s: mod_gzip_minimum_file_size = %ld\n", cn, - (long) mod_gzip_minimum_file_size ); - #endif - - return NULL; -} - -static const char * -mod_gzip_set_maximum_inmem_size(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - long lval=0; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_set_maximum_inmem_size()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - lval = (long) atol(arg); - - /* 60000 bytes is the current maximum since a malloc() call is used */ - if ( lval > 60000L ) lval = 60000L; - - mgc->maximum_inmem_size = (long) lval; /* Set config */ - mod_gzip_maximum_inmem_size = (long) lval; /* Set global */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ....mgc->maximum_inmem_size = %ld\n", cn, - (long) mgc->maximum_inmem_size ); - mod_gzip_printf( "%s: mod_gzip_maximum_inmem_size = %ld\n", cn, - (long) mod_gzip_maximum_inmem_size ); - #endif - - return NULL; -} - -static const char * -mod_gzip_set_do_static_files(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_set_do_static_files()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) ) - { - mgc->do_static_files = 1; /* Yes */ - } - else - { - mgc->do_static_files = 0; /* No */ - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: mgc->do_static_files = %ld\n", cn, - (long) mgc->do_static_files ); - #endif - - return NULL; -} - -static const char * -mod_gzip_set_do_cgi(cmd_parms *parms, void *dummy, char *arg) -{ - mod_gzip_conf *mgc; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_set_do_cgi()"; - #endif - - /* Start... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry\n", cn ); - mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); - #endif - - mgc = ( mod_gzip_conf * ) - ap_get_module_config(parms->server->module_config, &gzip_module); - - if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) ) - { - mgc->do_cgi = 1; /* Yes */ - } - else - { - mgc->do_cgi = 0; /* No */ - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: mgc->do_cgi = %ld\n", cn, - (long) mgc->do_cgi ); - #endif - - return NULL; -} - -static const handler_rec mod_gzip_handlers[] = -{ - /* - * This is where we associate an ASCII NAME for our 'handler' - * which is what gets set into the r->handler field for a - * request and allows the function name associated with the - * ASCII name to be called and handle the request... - */ - - /* Add a 'name' and some types to our handler... */ - - {"mod_gzip_handler", mod_gzip_handler}, - {CGI_MAGIC_TYPE, mod_gzip_handler}, - {"cgi-script", mod_gzip_handler}, - {"*", mod_gzip_handler}, - {NULL} -}; - - -static const command_rec mod_gzip_cmds[] = -{ - /* - * Define our httpd.conf configuration diectives and - * the local routines that are responsible for processing - * those directives when the time comes... - */ - - {"mod_gzip_on", mod_gzip_set_on, NULL, RSRC_CONF, TAKE1, - "Yes=mod_gzip will handle requests No=mod_gzip runs in 'passthrough' mode"}, - - {"mod_gzip_do_static_files", mod_gzip_set_do_static_files, NULL, RSRC_CONF, TAKE1, - "'Yes' means mod_gzip will compress static files."}, - - {"mod_gzip_do_cgi", mod_gzip_set_do_cgi, NULL, RSRC_CONF, TAKE1, - "'Yes' means mod_gzip will compress dynamic CGI script output."}, - - {"mod_gzip_keep_workfiles", mod_gzip_set_keep_workfiles, NULL, RSRC_CONF, TAKE1, - "On=Keep work files Off=No"}, - - {"mod_gzip_min_http", mod_gzip_set_min_http, NULL, RSRC_CONF, TAKE1, - "Minimum HTTP support level to receive compression. 1001=HTTP/1.1"}, - - {"mod_gzip_minimum_file_size", mod_gzip_set_minimum_file_size, NULL, RSRC_CONF, TAKE1, - "The minimum size ( in bytes ) before compression will be attempted"}, - - {"mod_gzip_maximum_inmem_size", mod_gzip_set_maximum_inmem_size, NULL, RSRC_CONF, TAKE1, - "The maximum size ( in bytes ) to use for in-memory compression."}, - - {"mod_gzip_temp_dir", mod_gzip_set_temp_dir, NULL, RSRC_CONF, TAKE1, - "The directory to use for work files and compression cache"}, - - {"mod_gzip_item_include", mod_gzip_set_item_include, NULL, RSRC_CONF, TAKE1, - "Add the item the inclusion list"}, - - {"mod_gzip_item_exclude", mod_gzip_set_item_exclude, NULL, RSRC_CONF, TAKE1, - "Add the item the exclusion list"}, - - {NULL} -}; - -/* - * The actual module 'jump' table... - * - * If one of the fixed 'call' points has a valid function - * address then Apache will 'call' into it at the appropriate time. - * - * When the compressed object cache is engaged we will need to - * simply add some handlers for the URI detection and translation - * call point(s). - */ - -module MODULE_VAR_EXPORT gzip_module = -{ - STANDARD_MODULE_STUFF, - mod_gzip_init, /* initializer */ - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - mod_gzip_create_config, /* create per-server config structure */ - mod_gzip_merge_config, /* merge per-server config structures */ - mod_gzip_cmds, /* command table */ - mod_gzip_handlers, /* handlers */ - NULL, /* translate_handler */ - NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* pre-run fixups */ - NULL, /* logger */ - NULL, /* header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* post read-request */ -}; - -#ifdef NETWARE -int main(int argc, char *argv[]) -{ - ExitThread(TSR_THREAD, 0); -} -#endif - -FILE *mod_gzip_open_output_file( -request_rec *r, -char *output_filename, -int *rc -) -{ - FILE *ifh; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_open_output_file():::"; - #endif - - /* - * Start... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Entry...\n",cn); - mod_gzip_printf( "%s: output_filename=[%s]\n",cn,output_filename); - #endif - - ifh = fopen( output_filename, "rb" ); /* Open in BINARY mode */ - - if ( !ifh ) /* The file failed to open... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ERROR: Cannot open file [%s]\n", - cn,output_filename); - #endif - - /* - * The workfile was created OK but now will not re-open. - * This is worth a strike in the ERROR log. - */ - - ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_ERR, r->server, - "mod_gzip: Cannot re-open output_filename=[%s]", - output_filename ); - - /* Return DECLINED and let default logic finish the request... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( NULL ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:WORK_OPENFAIL")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - *rc = DECLINED; /* Update caller's result code... */ - - return NULL; - - }/* End 'if ( !ifh )' */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: File is now open...\n",cn); - mod_gzip_printf( "%s: Exit > return( FILE *ifh ) >\n",cn); - #endif - - *rc = OK; /* Update caller's result code */ - - return ifh; /* Return the file handle */ - -}/* End of mod_gzip_open_output_file() */ - -int mod_gzip_encode_and_transmit( -request_rec *r, -char *source, -int source_is_a_file, -long input_size, -int nodecline -) -{ - GZP_CONTROL gzc; - GZP_CONTROL* gzp = &gzc; - - int rc = 0; - FILE *ifh = 0; - int bytesread = 0; - long output_size = 0; - long compression_ratio = 0; - char* gz1_ismem_obuf = 0; - int finalize_stats = 1; - - int gz1_ismem_obuf_was_allocated = 0; - - char content_length[20]; /* For Content-length updates */ - - #define MOD_GZIP_LARGE_BUFFER_SIZE 8192 - - char tmp[ MOD_GZIP_LARGE_BUFFER_SIZE + 2 ]; /* Scratch buffer */ - - char *actual_content_encoding_name = "gzip"; /* Adjustable */ - const char *compression_format; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_encode_and_transmit()"; - #endif - - void *modconf = r->server->module_config; - - #ifdef MOD_GZIP_USES_APACHE_LOGS - char log_info[40]; /* Scratch buffer */ - #endif - - /* - * Start... - * - * Establish a local pointer to module configuration data... - */ - - mod_gzip_conf *conf = - (mod_gzip_conf *) ap_get_module_config( modconf, &gzip_module ); - - #ifdef MOD_GZIP_DEBUG1 - - mod_gzip_printf( "%s: Entry...\n", cn); - mod_gzip_printf( "%s: source_is_a_file = %d\n", cn, source_is_a_file); - mod_gzip_printf( "%s: nodecline = %d\n", cn, nodecline); - - if ( source_is_a_file ) /* Show the filename... */ - { - mod_gzip_printf( "%s: source = [%s]\n", cn, source); - } - else /* Don't try to print the memory buffer... */ - { - mod_gzip_printf( "%s: source = MEMORY BUFFER\n", cn ); - } - - mod_gzip_printf( "%s: input_size = %ld\n", cn,(long)input_size); - - #endif /* MOD_GZIP_DEBUG1 */ - - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* This routine 'assumes' that the final result is 'OK' */ - /* and lets the remainder of the processing set the result */ - /* string to some other value, if necessary. */ - - /* Since we are now using the 'nodecline' flag and might */ - /* have to 'stand and deliver' then this allows the right */ - /* result code to appear in the log files even if we */ - /* cannot DECLINE the processing. */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"OK")); - - /* We can also update the 'input' size right away since it is known */ - - sprintf( log_info,"%d", (int) input_size ); - ap_table_setn( r->notes,"mod_gzip_input_size",ap_pstrdup(r->pool,log_info)); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - /* - * If the source has no length then DECLINE the processing... - */ - - if ( input_size < 1 ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ERROR: Input source has no valid length.\n",cn); - mod_gzip_printf( "%s: This request will not be processed...\n",cn); - #endif - - /* An existing request object with no length is worth a warning... */ - - ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_WARNING, r->server, - "mod_gzip: r->filename=[%s] has no length",r->filename ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:NO_I_LEN")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return DECLINED; - } - - /* - * If we're only supposed to send header information (HEAD request) - * then all we need to do is call ap_send_http_header() at this point - * and then return 'OK'... - */ - - if ( r->header_only ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: HEAD request only... ignore body data...\n",cn); - #endif - - /* - * Set outbound response header fields... - * - * NOTE: If this is just a HEAD request then - * there is no need to make the API call... - * - * ap_update_mtime( r, r->finfo.st_mtime ); - * - * ...and update the actual time. Use the time - * that's currently associated with the object. - */ - - ap_set_last_modified(r); - ap_set_etag(r); - ap_table_setn(r->headers_out, "Accept-Ranges", "bytes"); - - /* Start a timer for this transaction... */ - - ap_soft_timeout( "mod_gzip: HEAD request handler", r ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: r->content_type=[%s]\n",cn,r->content_type); - mod_gzip_printf( "%s: Call ap_send_http_header()...\n",cn); - #endif - - ap_send_http_header(r); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_send_http_header()...\n",cn); - mod_gzip_printf( "%s: Call ap_kill_timeout()...\n",cn); - #endif - - ap_kill_timeout(r); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_kill_timeout()...\n",cn); - mod_gzip_printf( "%s: Exit > return( OK ) >\n",cn); - #endif - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Return OK but distinguish it from a 'GET' request in logs... */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"OK:HEAD_ONLY")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - return OK; - - }/* End 'if( r->header_only )' */ - - /* - * See if the source meets the MINUMUM SIZE requirement... - * - * Default to 300 bytes as a minimum size requirement for it - * to even be worth a compression attempt. This works well as a - * minimum for both GZIP and ZLIB which are both LZ77 based and, - * as such, always have the potential to actually increase the - * size of the file. - * - * The value is a module global that can be adjusted 'on the fly' - * as load conditions change or as required for other reasons. - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: conf->minimum_file_size = %ld\n", - cn, (long) conf->minimum_file_size ); - #endif - - if ( input_size < (long) conf->minimum_file_size ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Source does not meet the minimum size requirement...\n",cn); - mod_gzip_printf( "%s: nodecline = %d\n",cn,nodecline); - #endif - - /* Set the 'mod_gzip_result' note value to something */ - /* that indicates this was too small... */ - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:TOO_SMALL")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - /* Is it OK to DECLINE?... */ - - if ( nodecline ) /* We have been told NOT to DECLINE */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: DECLINE is NOT allowed...\n",cn); - #endif - - /* Skip the compression phase and just set the output */ - /* control skid up to send the real input data... */ - - output_size = input_size; - - if ( source_is_a_file ) /* Source is a workfile... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Force send - source = FILE[%s]\n", - cn,source); - #endif - - strcpy( gzp->output_filename, source ); - gzp->output_ismem = 0; /* Output is a disk file */ - gz1_ismem_obuf = 0; /* Make sure this is NULL */ - gzp->output_ismem_obuf = 0; /* Not used for this method */ - gzp->output_ismem_obuflen = 0; /* Not used for this method */ - - ifh = mod_gzip_open_output_file( r, gzp->output_filename, &rc ); - - if ( !ifh ) /* The file failed to open... */ - { - /* We really MUST decline... */ - /* Logs have already been updated... */ - - return( rc ); - } - } - else /* Source is just a memory buffer... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Force send - source = MEMORY BUFFER\n",cn); - #endif - - gzp->output_ismem = 1; - gz1_ismem_obuf = source; - - gz1_ismem_obuf_was_allocated = 0; /* No 'free' is required */ - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: No compression attempt was made.\n",cn); - mod_gzip_printf( "%s: Advancing directly to transmit phase...\n",cn); - #endif - - goto mod_gzip_encode_and_transmit_send_start; /* Jump */ - } - else /* It's OK to DECLINE the processing... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: DECLINE is allowed...\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - return DECLINED; - } - } - else /* The source is larger than the minimum size requirement... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Source meets the minimum size requirement.\n",cn); - mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); - #endif - } - - /* - * We must now encode the requested object... - * - * Statistically speaking, most 'text/*' pages are - * less than 60k. XML documents are an exception. - * - * If the size of the requested object is less than 60k - * then go ahead and compress the source directly to a - * small memory buffer. If the requested object is greater - * than 60k then go ahead and swap the results to an output - * disk file and then send the contents of the result file. - * - * We can't ever allocate all the memory we want inside of - * a Server task thread so there must always be this kind - * of 'decision' making about when we can compress to - * a memory buffer ( Less than 60k ) and when we must - * compress to DISK. ( Greater than 60k ). - * - * There is a trade-off here between running the risk of - * too many tasks stealing away all the heap space and - * still maintaining performance. Given all the variables - * involved such as the true efficiency of the compression - * algorithm(s) and the speed of the CPU and the amount of - * memory/disk space available there is no 'real' answer to - * this dilemma other than relying on statistical data - * and empirical observations. The 60k limit on in-memory - * compression seems to strike a good balance and performs - * incredibly well under the heaviest of loads. - * - * At all times, the greatest benefit being gained is the - * appreciable reduction of data that must actually be - * sent by the TCP/IP sub-system and the reduced usage - * of those resources to perform the transmission task(s), - * - * The key, then, is to always strive for a balance where - * the time and resource usage it takes to compress a - * deliverable object will always be less than the processor - * burden that would otherwise be realized by handing the - * full, uncompressed object to the TCP/IP sub-system which - * always extend the time that the thread and all its - * locked resources must be maintained as well as the - * overhead for keeping a connection active any longer - * than is absolutely necessary. - * - * As long as the resource usage it takes to accomplish - * a significant reduction in the amount of data that - * must actually be processed by the remainder of the - * HTTP task thread and the TCP/IP sub-system itself - * is always less than the processor burden seen by - * NOT doing so then we are always 'ahead of the game'. - */ - - /* - * See if the object size exceeds the current MAXIMUM size - * to use for in-memory compression... - * - * See notes above about a range of 60k or so being the best - * value for heavy load conditions. - * - * This number is currently a global so it can be changed - * 'on the fly' and can 'breathe' as the load changes. - * It should probably become a thread specific variable - * so each task can have its 'own' max value depending - * on current load conditions. - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: conf->maximum_inmem_size = %ld\n", - cn, (long) conf->maximum_inmem_size ); - #endif - - /* - * Set up the INPUT target... - */ - - /* The size and type of the input source is always known */ - /* and was passed by the caller... */ - - if ( source_is_a_file ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Input source is file[%s]\n",cn,source); - #endif - - strcpy( gzp->input_filename, source ); - - gzp->input_ismem = 0; /* Input is a disk file */ - gzp->input_ismem_ibuf = 0; /* Source buffer */ - gzp->input_ismem_ibuflen = 0; /* Length of data */ - } - else - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Input source is a MEMORY BUFFER\n",cn); - #endif - - *gzp->input_filename = 0; /* Not used */ - - gzp->input_ismem = 1; /* Input is a memory buffer */ - gzp->input_ismem_ibuf = source; /* Source buffer */ - gzp->input_ismem_ibuflen = input_size; /* Length of data */ - } - - /* - * Set up the OUTPUT target... - */ - - gzp->decompress = 0; /* Perform encoding */ - - /* Recover the compression format we're supposed to use. */ - compression_format = ap_table_get(r->notes, "mod_gzip_compression_format"); - if (compression_format && strcmp(compression_format, "deflate") == 0) - { - actual_content_encoding_name = "deflate"; - gzp->compression_format = DEFLATE_FORMAT; - } - else - { - gzp->compression_format = GZIP_FORMAT; - } - - if ( input_size <= (long) conf->maximum_inmem_size ) - { - /* The input source is small enough to compress directly */ - /* to an in-memory output buffer... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Input source is small enough for in-memory compression.\n",cn); - #endif - - *gzp->output_filename = 0; /* Not used */ - gzp->output_ismem = 1; /* Output is a memory buffer */ - - /* - * Allocate a memory buffer to hold compressed output. - * - * For now this is borrowed from the heap for only - * the lifetime of this function call. If the stack - * can handle the current in-memory MAXSIZE then - * that will work just as well. - * - * Add at least 1000 bytes in case the compression - * algorithm(s) actually expands the source ( which is - * not likely but is always a possibility when using - * any LZ77 based compression such as GZIP or ZLIB ) - */ - - gz1_ismem_obuf = (char *) malloc( input_size + 1000 ); - - if ( !gz1_ismem_obuf ) - { - /* - * There wasn't enough memory left for another - * in-memory compression buffer so default to using - * an output disk file instead... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ERROR: Cannot allocate GZP memory...\n",cn); - mod_gzip_printf( "%s: Defaulting to output file method... \n",cn); - #endif - - gzp->output_ismem = 0; /* Switch to using a disk file */ - } - - else /* We got the memory we need for in-memory compression... */ - { - /* Set the local flag which tells the exit logic */ - /* that 'gz1_ismem_obuf' was actually allocated */ - /* and not simply set to 'source' so that the */ - /* allocation can be 'freed' on exit... */ - - gz1_ismem_obuf_was_allocated = 1; /* 'free' is required */ - - /* Compression codecs require a 'clean' buffer so */ - /* we need to spend the cycles for a memset() call. */ - - memset( gz1_ismem_obuf, 0, ( input_size + 1000 ) ); - - /* Set OUTPUT buffer control variables... */ - - gzp->output_ismem_obuf = gz1_ismem_obuf; - gzp->output_ismem_obuflen = input_size + 1000; - } - - }/* End 'if ( input_size <= conf->maximum_inmem_size )' */ - - /* - * If we are unable ( or it is unadvisable ) to use - * an in-memory output buffer at this time then the - * 'gzp->output_ismem' flag will still be ZERO at this point. - */ - - if ( gzp->output_ismem != 1 ) - { - /* - * The input source is NOT small enough to compress to an - * in-memory output buffer or it is unadvisable to do - * so at this time so just use an output file... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Input source too big for in-memory compression.\n",cn); - #endif - - /* - * Create the GZP output target name... - */ - - mod_gzip_create_unique_filename( - (mod_gzip_conf *) conf, - (char *) gzp->output_filename, - MOD_GZIP_MAX_PATH_LEN - ); - - /* - * COMPRESSION OBJECT CACHE - * - * TODO: Obviously one place to add the compression cache - * logic is right here. If there is already a pre-compressed - * version of the requested entity sitting in the special - * compression cache and it is 'fresh' then go ahead and - * send it as the actual response. Add a CRC/MD5 checksum - * to the stored compression object(s) so we can quickly - * determine if the compressed object is 'fresh'. Relying - * on Content-length and/or modification time/date won't handle - * all possible expiration scenarios for compressed objects. - */ - - gzp->output_ismem = 0; /* Output is a disk file */ - - gz1_ismem_obuf = 0; /* Make sure this is NULL */ - - /* Set OUTPUT buffer control variables... */ - - gzp->output_ismem_obuf = 0; /* Not used for this method */ - gzp->output_ismem_obuflen = 0; /* Not used for this method */ - - }/* End 'else' */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: gzp->decompress = %d\n" ,cn,gzp->decompress); - mod_gzip_printf( "%s: gzp->compression_format = %d\n",cn,gzp->compression_format); - mod_gzip_printf( "%s: gzp->input_ismem = %d\n", cn,gzp->input_ismem); - mod_gzip_printf( "%s: gzp->output_ismem = %d\n", cn,gzp->output_ismem); - mod_gzip_printf( "%s: gzp->input_filename = [%s]\n",cn,gzp->input_filename); - mod_gzip_printf( "%s: gzp->output_filename = [%s]\n",cn,gzp->output_filename); - mod_gzip_printf( "%s: Call gzp_main()...\n",cn); - #endif - - rc = gzp_main( gzp ); /* Perform the compression... */ - - output_size = (long) gzp->bytes_out; - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back gzp_main()...\n",cn); - mod_gzip_printf( "%s: input_size = %ld\n",cn,(long)input_size); - mod_gzip_printf( "%s: output_size = %ld\n",cn,(long)output_size); - mod_gzip_printf( "%s: gzp->bytes_out = %ld\n",cn,(long)gzp->bytes_out); - mod_gzip_printf( "%s: Bytes saved = %ld\n",cn, - (long)input_size-gzp->bytes_out ); - #endif - - /* Compute the compresion ratio for access.log and */ - /* internal statistics update... */ - - compression_ratio = 0; /* Reset */ - - /* Prevent 'Divide by zero' error... */ - - if ( ( input_size > 0 ) && - ( output_size > 0 ) ) - { - compression_ratio = 100 - (int) - ( output_size * 100L / input_size ); - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Compression ratio = %ld percent\n",cn, - (long) compression_ratio ); - #endif - - /* - * Update the logs with output size information - * as soon as it is known in case there was an - * error or we must DECLINE. At least the logs - * will then show the sizes and the results. - */ - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - sprintf( log_info,"%d", (int) output_size ); - ap_table_setn( r->notes,"mod_gzip_output_size",ap_pstrdup(r->pool,log_info)); - - sprintf( log_info,"%d", (int) compression_ratio ); - ap_table_setn( r->notes,"mod_gzip_compression_ratio",ap_pstrdup(r->pool,log_info)); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - /* - * Evaluate the compression result(s)... - * - * If the compression pass failed then the output length - * will be ZERO bytes... - */ - - if ( output_size < 1 ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Compressed version has no length.\n",cn); - mod_gzip_printf( "%s: Sending the original version uncompressed...\n",cn); - #endif - - finalize_stats = 0; /* Don't update stats again */ - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: gzp_main(ERR): r->uri=[%s] input_size=%ld output_size=%ld gzp->output_filename=[%s]", - r->uri,(long)input_size,(long)output_size,gzp->output_filename); - } - - /* - * NOTE: It's perfectly possible that we have made it all - * the way to here and the straight execution of the - * compressor is the first time there has been a check for - * the actual existence of the requested object. This will - * be especially true for STATIC requests. - * - * The compressor itself will fail if/when it can't find - * the input target so 'DECLINED:NO_O_LEN' could simply - * means the file was not found. In these cases the Apache - * logs should also contain the correct '404 Not Found' code. - */ - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:NO_O_LEN")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - /* Is it OK to DECLINE?... */ - - if ( nodecline ) /* We have been told NOT to DECLINE... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: DECLINE is NOT allowed...\n",cn); - #endif - - /* Just set the output control skid */ - /* to send the real input data... */ - - output_size = input_size; - - if ( source_is_a_file ) /* Source is a workfile... */ - { - strcpy( gzp->output_filename, source ); - - gzp->output_ismem = 0; /* Output is a disk file */ - gz1_ismem_obuf = 0; /* Make sure this is NULL */ - gzp->output_ismem_obuf = 0; /* Not used for this method */ - gzp->output_ismem_obuflen = 0; /* Not used for this method */ - - ifh = mod_gzip_open_output_file( r, gzp->output_filename, &rc ); - - if ( !ifh ) /* We really must DECLINE... */ - { - return( rc ); - } - } - else /* Source is just a memory buffer... */ - { - gzp->output_ismem = 1; - gz1_ismem_obuf = source; - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Advancing directly to transmit phase...\n",cn); - #endif - - goto mod_gzip_encode_and_transmit_send_start; /* Jump */ - } - else /* It's OK to DECLINE the processing... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: DECLINE is allowed...\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - /* Free the local memory buffer allocation ( if necessary )... */ - - if ( gz1_ismem_obuf ) - { - /* The pointer may have been 'borrowed' and was */ - /* not actually 'allocated' so check the flag... */ - - if ( gz1_ismem_obuf_was_allocated ) - { - free( gz1_ismem_obuf ); - - gz1_ismem_obuf = 0; - gz1_ismem_obuf_was_allocated = 0; - - }/* End 'if( gz1_ismem_obuf_was_allocated )' */ - - }/* End 'if( gz1_ismem_obuf )' */ - - /* Return... */ - - return DECLINED; - } - - }/* End 'if( output_size < 1 )' */ - - /* - * If we reach this point then the compressed version has - * a valid length. Time to see if it it's worth sending. - * - * If the original source is SMALLER than the COMPRESSED - * version ( not likely but possible with LZ77 ) then - * just punt and send the original source... - */ - - if ( output_size > input_size ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Compressed version is larger than original.\n",cn); - mod_gzip_printf( "%s: Sending the original version uncompressed...\n",cn); - #endif - - finalize_stats = 0; /* Don't update stats again */ - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ - - ap_table_setn( - r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:ORIGINAL_SMALLER")); - - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - /* Is it OK to DECLINE?... */ - - if ( nodecline ) /* We have been told NOT to DECLINE... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: DECLINE is NOT allowed...\n",cn); - #endif - - /* Just set the output control skid */ - /* to send the real input data... */ - - output_size = input_size; - - if ( source_is_a_file ) /* Source is a workfile... */ - { - strcpy( gzp->output_filename, source ); - - gzp->output_ismem = 0; /* Output is a disk file */ - gz1_ismem_obuf = 0; /* Make sure this is NULL */ - gzp->output_ismem_obuf = 0; /* Not used for this method */ - gzp->output_ismem_obuflen = 0; /* Not used for this method */ - - ifh = mod_gzip_open_output_file( r, gzp->output_filename, &rc ); - - if ( !ifh ) /* We really must DECLINE... */ - { - return( rc ); - } - } - else /* Source is just a memory buffer... */ - { - gzp->output_ismem = 1; - gz1_ismem_obuf = source; - - gz1_ismem_obuf_was_allocated = 0; /* No 'free' is required */ - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Advancing directly to transmit phase...\n",cn); - #endif - - goto mod_gzip_encode_and_transmit_send_start; /* Jump */ - } - else /* It's OK to DECLINE the processing... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: DECLINE is allowed...\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - /* Free the local memory buffer allocation ( if necessary )... */ - - if ( gz1_ismem_obuf ) - { - /* The pointer may have been 'borrowed' and was */ - /* not actually 'allocated' so check the flag... */ - - if ( gz1_ismem_obuf_was_allocated ) - { - free( gz1_ismem_obuf ); - - gz1_ismem_obuf = 0; - gz1_ismem_obuf_was_allocated = 0; - - }/* End 'if( gz1_ismem_obuf_was_allocated )' */ - - }/* End 'if( gz1_ismem_obuf )' */ - - /* Return... */ - - return DECLINED; - } - } - else /* Compressed version is smaller than original... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Compressed version is smaller than original.\n",cn); - mod_gzip_printf( "%s: Sending the compressed version...\n",cn); - #endif - } - - /* - * If an output workfile was used then make SURE it is going - * to reopen before beginning the transmit phase. - * - * If we begin the transmit phase before discovering a problem - * re-opening the workfile then we have lost the chance to - * DECLINE the processing and allow the default logic to - * deliver the requested object. - * - * This only matters for 'static' files or times when the - * 'nodecline' flag is FALSE and it is actually OK to DECLINE. - */ - - if ( !gzp->output_ismem ) /* Workfile was used... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Opening compressed output file [%s]...\n", - cn, gzp->output_filename ); - #endif - - ifh = mod_gzip_open_output_file( r, gzp->output_filename, &rc ); - - if ( !ifh ) /* The file failed to open... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: ERROR: Cannot re-open file [%s]\n", - cn,gzp->output_filename); - #endif - - /* We really must DECLINE... */ - /* Logs have already been updated... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif - - return DECLINED; - - }/* End 'if ( !ifh )' */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Workile re-opened OK...\n",cn); - #endif - - }/* End 'if ( !gzp->output_ismem )' */ - - /* - * IMPORTANT - * - * If we have made it to here then all is well and only - * now can we set the encoding for this response... - * - * We must do this 'above' any jump points that might - * be sending the 'untouched' data or the browser will - * get confused regarding the actual content. - */ - - r->content_encoding = actual_content_encoding_name; - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: r->content_encoding is now [%s]\n", - cn, r->content_encoding ); - #endif - - /* - * Begin the transmission phase... - * - * Even if the 'nodecline' flag is TRUE if we encounter - * any fatal errors at this point we must 'DECLINE'. - */ - - mod_gzip_encode_and_transmit_send_start: ; /* <<-- Jump point */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Starting transmit phase...\n",cn); - #endif - - /* - * We are ready to send content so update the "Content-length:" - * response field and send the HTTP header. We don't need to - * worry about setting the "Content-type:" field since we are - * simply accepting the value that was passed to us as indicated - * by the inbound r->content_type string. The "Content-type:" - * field never changes even when multiple encodings have been - * applied to the content itself. - * - * This version does not make any attempt to use 'Chunked' - * transfer encoding since there are so many user agents that - * do not support it and when Content-length is known prior - * to header transmission ( as is always the case with this - * code ) then there is simply no reason to even think about - * using the slower and more problematic 'Chunked' encoding - * transfer method. - */ - - /* - * Set relevant outbound response header fields... - * - * Be sure to call ap_update_mtime() before calling - * ap_set_last_modified() to be sure the 'current' - * time is actually updated in outbound response header. - */ - - ap_update_mtime( r, r->finfo.st_mtime ); - ap_set_last_modified(r); - ap_set_etag(r); - ap_table_setn(r->headers_out, "Accept-Ranges", "bytes"); - - /* - * Start a timer for this transaction... - */ - - ap_soft_timeout( "mod_gzip: Encoded data transmit", r ); - - /* - * Return the length of the compressed output in - * the response header. - * - * See notes above about there never being a requirement - * to use 'Chunked' transfer encoding since the content - * length is always 'known' prior to transmission. - */ - - sprintf( content_length, "%ld", output_size ); - ap_table_set (r->headers_out, "Content-Length", content_length ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: output_size = %ld\n",cn,(long)output_size); - mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); - mod_gzip_printf( "%s: Call ap_send_http_header()...\n",cn); - #endif - - ap_send_http_header(r); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_send_http_header()...\n",cn); - #endif - - /* - * Send the response... - * - * If the requested object was small enough to fit into - * our special in-memory output space then send the result - * directly from memory. If the requested object exceeded - * the minimum size for in-memory compression then an output - * file was used so re-open and send the results file... - */ - - if ( gzp->output_ismem ) - { - /* Send the in-memory output buffer... */ - - #ifdef MOD_GZIP_DEBUG1 - - mod_gzip_printf( "%s: Sending the in-memory output buffer...\n",cn); - mod_gzip_printf( "%s: output_size = %ld\n",cn,(long)output_size); - - /* Turn this 'on' for VERY verbose diagnostics... - #define MOD_GZIP_DUMP_JUST_BEFORE_SENDING - */ - #ifdef MOD_GZIP_DUMP_JUST_BEFORE_SENDING - mod_gzip_hexdump( gz1_ismem_obuf, output_size ); - #endif - - #endif /* MOD_GZIP_DEBUG1 */ - - /* This module can use either ap_send_mmap() or ap_rwrite()... */ - - #ifdef MOD_GZIP_USES_AP_SEND_MMAP - - /* Use ap_send_mmap() call to send the data... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call ap_send_mmap( gz1_ismem_obuf, bytes=%ld )...\n", - cn, (long)output_size ); - #endif - - ap_send_mmap( gz1_ismem_obuf, r, 0, output_size ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_send_mmap( gz1_ismem_obuf, bytes=%ld )...\n", - cn, (long)output_size ); - #endif - - #else /* !MOD_GZIP_USES_AP_SEND_MMAP */ - - /* Use ap_rwrite() call to send the data... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call ap_rwrite( gz1_ismem_obuf, bytes=%ld )...\n", - cn, (long)output_size ); - #endif - - ap_rwrite( gz1_ismem_obuf, output_size, r ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_rwrite( gz1_ismem_obuf, bytes=%ld )...\n", - cn, (long)output_size ); - #endif - - #endif /* MOD_GZIP_USES_AP_SEND_MMAP */ - - /* Stop the timer... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call ap_kill_timeout()...\n",cn); - #endif - - ap_kill_timeout(r); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_kill_timeout()...\n",cn); - #endif - - /* Free the local memory buffer allocation ( if necessary )... */ - - if ( gz1_ismem_obuf ) - { - /* The pointer may have been 'borrowed' and was */ - /* not actually 'allocated' so check the flag... */ - - if ( gz1_ismem_obuf_was_allocated ) - { - free( gz1_ismem_obuf ); - - gz1_ismem_obuf = 0; - gz1_ismem_obuf_was_allocated = 0; - - }/* End 'if( gz1_ismem_obuf_was_allocated )' */ - - }/* End 'if( gz1_ismem_obuf )' */ - } - else /* Output workfile was used so send the contents... */ - { - /* - * NOTE: The workfile was already 're-opened' up above - * before the transmit phase began so that we still had - * the chance to return DECLINED if, for some reason, the - * workfile could not be re-opened. - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: sizeof( tmp ) = %d\n",cn,sizeof(tmp)); - mod_gzip_printf( "%s: Transmit buffer size = %d\n",cn,sizeof(tmp)); - mod_gzip_printf( "%s: Sending compressed output file...\n",cn); - #endif - - for (;;) - { - bytesread = fread( tmp, 1, sizeof( tmp ), ifh ); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back fread(): bytesread=%d\n",cn,bytesread); - #endif - - if ( bytesread < 1 ) break; /* File is exhausted... We are done...*/ - - /* This module can use either ap_send_mmap() or ap_rwrite()... */ - - #ifdef MOD_GZIP_USES_AP_SEND_MMAP - - /* Use ap_send_mmap() call to send the data... */ - - ap_send_mmap( tmp, r, 0, bytesread ); - - #else /* !MOD_GZIP_USES_AP_SEND_MMAP */ - - /* Use ap_rwrite() call to send the data... */ - - ap_rwrite( tmp, bytesread, r ); - - #endif /* MOD_GZIP_USES_AP_SEND_MMAP */ - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Done Sending compressed output file...\n",cn); - mod_gzip_printf( "%s: Closing workfile [%s]...\n", - cn, gzp->output_filename ); - #endif - - fclose( ifh ); /* Close the input file */ - - /* Stop the timer before attempting to delete the workfile... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Call ap_kill_timeout()...\n",cn); - #endif - - ap_kill_timeout(r); - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Back ap_kill_timeout()...\n",cn); - #endif - - /* Delete the workfile if 'keep' flag is OFF... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: conf->keep_workfiles = %d\n", - cn, conf->keep_workfiles ); - #endif - - if ( !conf->keep_workfiles ) /* Default is OFF */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Deleting workfile [%s]...\n", - cn, gzp->output_filename ); - #endif - - #ifdef _WIN32 - DeleteFile( gzp->output_filename ); - #else /* !_WIN32 */ - unlink( gzp->output_filename ); - #endif /* _WIN32 */ - } - else /* Keep all work files... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Keeping workfile [%s]...\n", - cn, gzp->output_filename ); - #endif - } - - }/* End 'else' that sends compressed workfile */ - - /* - * The compressed object has been sent... - */ - - #ifdef MOD_GZIP_USES_APACHE_LOGS - - if ( finalize_stats ) - { - sprintf( log_info,"%d", (int) output_size ); - ap_table_setn( r->notes,"mod_gzip_output_size",ap_pstrdup(r->pool,log_info)); - - sprintf( log_info,"%d", (int) compression_ratio ); - ap_table_setn( r->notes,"mod_gzip_compression_ratio",ap_pstrdup(r->pool,log_info)); - - } - #endif /* MOD_GZIP_USES_APACHE_LOGS */ - - if ( r->server->loglevel == APLOG_DEBUG ) - { - /* - * If LogLevel is 'debug' then show the compression results - * in the log(s)... - */ - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: r->uri=[%s] OK: Bytes In:%ld Out:%ld Compression: %ld pct.", - r->uri, - (long) input_size, - (long) output_size, - (long) compression_ratio - ); - - }/* End 'if( r->server->loglevel == APLOG_DEBUG )' */ - - /* - * Return OK to the Server to indicate SUCCESS... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( OK ) >\n",cn); - #endif - - return OK; - -}/* End of mod_gzip_encode_and_transmit() */ - -int mod_gzip_ismatch( char *s1, char *s2, int len1, int haswilds ) -{ - /* Behaves just like strncmp() but IGNORES differences */ - /* between FORWARD or BACKWARD slashes in a STRING, allows */ - /* wildcard matches, and can ignore length value. */ - /* It uses pointers and is faster than using lib calls. */ - - /* Unlike strncmp() this routine returns TRUE (1) if the */ - /* strings match and FALSE (0) if they do not... */ - - int i; - int l1; - int l2; - int distance; - char ch1; - char ch2; - - /* WARNING! We MUST have a check for 'NULL' on the pointer(s) */ - /* themselves or we might GP */ - - if ( ( s1 == 0 ) || ( s2 == 0 ) ) - { - /* SAFETY! If pointer itself if NULL */ - /* don't enter LOOP... */ - - return( 0 ); /* Return FALSE for NOMATCH... */ - } - - distance = len1; /* Default to value passed... */ - - /* If no length was given then the 2 strings must already */ - /* have the same length or this is a 'no match'... */ - /* Exception to this is if wildcards are present. */ - - if ( len1 == 0 ) - { - l1 = strlen( s1 ); - l2 = strlen( s2 ); - - /* If either string had a valid pointer but is EMPTY */ - /* then this is an automatic 'no match'... */ - - if ((l1==0)||(l2==0)) - { - return( 0 ); /* Return FALSE for NOMATCH... */ - } - - if ( l1 != l2 ) - { - if ( haswilds == 0 ) - { - return( 0 ); /* Return FALSE for NOMATCH... */ - } - } - - /* If the lengths ARE equal then this is a possible */ - /* match. Use the smaller of the 2 values for scan...*/ - - if ( l1 < l2 ) distance = l1; - else distance = l2; - } - - /* Final check... if distance is still 0 then this */ - /* is an automatic 'no match'... */ - - if ( distance == 0 ) - { - return( 0 ); /* Return FALSE for NOMATCH... */ - } - - /* Do the deed... */ - - for ( i=0; icontent_type ) clen = strlen( r->content_type ); - if ( r->handler ) hlen = strlen( r->handler ); - - if ( r->filename ) - { - flen = strlen( r->filename ); - p1 = r->filename; - while(*p1!=0){if (*p1=='.') file_extension=p1; p1++;} - if ( file_extension ) file_extension_len = strlen( file_extension ); - } - - #ifdef MOD_GZIP_DEBUG1 - - mod_gzip_printf( "%s: Entry...\n",cn); - mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); - mod_gzip_printf( "%s: clen = %d\n", cn,clen); - mod_gzip_printf( "%s: r->handler = [%s]\n",cn,r->handler); - mod_gzip_printf( "%s: hlen = %d\n", cn,hlen); - mod_gzip_printf( "%s: r->filename = [%s]\n",cn,r->filename); - mod_gzip_printf( "%s: flen = %d\n", cn,flen); - mod_gzip_printf( "%s: file_extension = [%s]\n",cn,file_extension); - mod_gzip_printf( "%s: file_extension_len = %d\n", cn,file_extension_len); - - #endif /* MOD_GZIP_DEBUG1 */ - - /* - * Sanity checks... - */ - - if ( ( hlen == 0 ) && ( clen == 0 ) ) - { - /* - * If the header analysis and/or negotiation phase has - * determined this to be a CGI script then the r->content_type - * field will be (null) but r->handler will contain "cgi-script". - * or "php-script" or the like. - * - * If the analysis has determined this is a static file - * then r->handler will be (null) but the r->content_type - * field will be "text/html" or "text/plain" or whatever. - * - * Both the r->content_type field and the r->handler - * field are empty. Ignore this one... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Both hlen and clen are ZERO...\n",cn); - mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_DECLINED1 ) >\n",cn); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: There is no valid r->handler or r->content_length "); - } - - return( MOD_GZIP_IMAP_DECLINED1 ); - } - - /* - * Perform 2 passes at the Include/Exclude list... - * - * The first pass is the higher-priority EXCLUSION check. - * The second pass is the lower-priority INCLUSION check. - */ - - for ( pass=0; pass<2; pass++ ) - { - - pass_result = 0; /* Reset result */ - - if ( pass == 0 ) /* EXCLUSION CHECK */ - { - filter_value = 0; - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: EXCLUSION CHECK...\n",cn); - #endif - } - else if ( pass == 1 ) /* INCLUSION CHECK */ - { - filter_value = 1; - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: INCLUSION CHECK...\n",cn); - #endif - } - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: pass = %d\n", cn, pass ); - mod_gzip_printf( "%s: filter_value = %d\n", cn, filter_value ); - mod_gzip_printf( "%s: mgc->imap_total_entries = %d\n", cn, - (int) mgc->imap_total_entries ); - #endif - - for ( x=0; ximap_total_entries; x++ ) - { - if ( r->server->loglevel == APLOG_DEBUG ) - { - /* Show the lookups in the Apache ERROR log if DEBUG is on */ - - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: mgc->imap[%3.3d] = i%2.2d t%4.4d a%4.4d n[%s]", - x, - mgc->imap[x].include, - mgc->imap[x].type, - mgc->imap[x].action, - mgc->imap[x].name - ); - } - - #ifdef MOD_GZIP_DEBUG1 - - mod_gzip_printf( "%s: --------------------------------------------\n",cn); - mod_gzip_printf( "%s: r->handler = [%s]\n",cn,r->handler); - mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); - mod_gzip_printf( "%s: r->filename = [%s]\n",cn,r->filename); - mod_gzip_printf( "%s: file_extension = [%s]\n",cn,file_extension); - mod_gzip_printf( "%s: mgc->imap[%3.3d].include = %d\n",cn,x,mgc->imap[x].include); - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d\n",cn,x,mgc->imap[x].type); - - if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISMIME ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISMIME\n",cn,x); - } - else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISEXT ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISEXT\n",cn,x); - } - else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISHANDLER ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISHANDLER\n",cn,x); - } - else /* Unrecognized item type... */ - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_IS??? Unknown type\n",cn,x); - } - - mod_gzip_printf( "%s: mgc->imap[%3.3d].action = %d\n", cn,x,mgc->imap[x].action); - - if ( mgc->imap[x].action == MOD_GZIP_IMAP_DYNAMIC1 ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_DYNAMIC1\n",cn,x); - } - else if ( mgc->imap[x].action == MOD_GZIP_IMAP_STATIC1 ) - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_STATIC1\n",cn,x); - } - else /* Unrecognized action type... */ - { - mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_??? Unknown action\n",cn,x); - } - - mod_gzip_printf( "%s: mgc->imap[%3.3d].name = [%s]\n",cn,x,mgc->imap[x].name); - - #endif /* MOD_GZIP_DEBUG1 */ - - /* 'filter_value' mirrors 'pass' value for now but this might */ - /* not always be true. First pass is EXCLUDE and second is INCLUDE */ - - if ( mgc->imap[x].include == filter_value ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: This record matches filter_value %d\n", - cn, filter_value ); - mod_gzip_printf( "%s: The record will be checked...\n",cn); - #endif - - /* - * Set work values for this record... - */ - - this_type = mgc->imap[x].type; - this_action = mgc->imap[x].action; - this_name = mgc->imap[x].name; - - /* - * If the header analysis and/or negotiation phase has - * determined this to be a CGI script then the r->content_type - * field will be (null) but r->handler will contain "cgi-script". - * - * If the analysis has determined this is a static file - * then r->handler will be (null) but the r->content_type - * field will be "text/html" or "text/plain" or whatever. - */ - - if ( hlen > 0 ) /* r->handler field has a value... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: hlen has value...\n",cn); - #endif - - if ( this_type == MOD_GZIP_IMAP_ISHANDLER ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: this_type = ISHANDLER\n",cn); - mod_gzip_printf( "%s: Call mod_gzip_ismatch(%s,%s,0,0)...\n", - cn, this_name, r->handler ); - #endif - - /* mod_gzip_ismatch()... */ - - /* The 2 strings must match exactly so */ - /* pass '0' for parm 3... */ - - /* Wildcard matches are not allowed for */ - /* handler strings like 'cgi-script' so */ - /* Fourth parm should be 0.. */ - - if ( mod_gzip_ismatch( - this_name, (char *)r->handler,0,0) ) - { - pass_result = 1; /* We found a match */ - action_flag = this_action; /* What to do */ - break; /* Stop now */ - } - - }/* End 'if ( this_type == MOD_GZIP_IMAP_ISHANDLER )' */ - - }/* End 'if( hlen > 0 )' */ - - if ( clen > 0 ) /* r->content_type field has a value... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: clen has value...\n",cn); - #endif - - if ( this_type == MOD_GZIP_IMAP_ISMIME ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: this_type = ISMIME\n",cn); - mod_gzip_printf( "%s: Wildcards matches are OK for MIME types.\n",cn); - mod_gzip_printf( "%s: Call mod_gzip_ismatch(%s,%s,0,1)...\n", - cn, this_name, r->content_type ); - #endif - - /* mod_gzip_ismatch()... */ - - /* Wildcard matches are ALLOWED for */ - /* MIME type strings like 'cgi-script' */ - /* so fourth parm should be 1... */ - - if ( mod_gzip_ismatch( - this_name, (char *)r->content_type, 0, 1 ) ) - { - pass_result = 1; /* We found a match */ - action_flag = this_action; /* What to do */ - break; /* Stop now */ - } - - }/* End 'if ( this_type == MOD_GZIP_IMAP_ISMIME )' */ - - }/* End 'if( clen > 0 )' */ - - if ( flen > 0 ) /* r->filename field has a value... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: flen has value...\n",cn); - #endif - - if ( this_type == MOD_GZIP_IMAP_ISEXT ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: this_type = ISEXT\n",cn); - #endif - - if ( file_extension_len > 0 ) /* There is a file extension */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: file_extension_len has value...\n",cn); - mod_gzip_printf( "%s: Call mod_gzip_ismatch(%s,%s,0,0)...\n", - cn, this_name, file_extension ); - #endif - - /* mod_gzip_ismatch()... */ - - /* The 2 strings must match exactly so */ - /* pass '0' for parm 3... */ - - /* Wildcard matches are not allowed for */ - /* file extensions like '.html' so */ - /* Fourth parm should be 0.. */ - - if ( mod_gzip_ismatch( - this_name, file_extension, 0, 0 ) ) - { - pass_result = 1; /* We found a match */ - action_flag = this_action; /* What to do */ - break; /* Stop now */ - } - - }/* End 'if( file_extension_len > 0 )' */ - - }/* End 'if( this_type == MOD_GZIP)IMAP_ISEXT )' */ - - }/* End 'if( flen > 0 )' */ - - }/* End 'if ( mgc->imap[x].include == filter )' */ - - else /* The record did not match the current 'filter' value... */ - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: This record does NOT match filter_value %d\n", - cn, filter_value ); - mod_gzip_printf( "%s: The record has been SKIPPED...\n",cn); - #endif - } - - }/* End 'x' loop that looks at 'filtered' records... */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: --------------------------------------------\n",cn); - mod_gzip_printf( "%s: pass_result = %d\n",cn,pass_result); - #endif - - if ( pass_result ) /* We are done... */ - { - if ( pass == 0 ) item_is_excluded = 1; - else item_is_included = 1; - - break; /* Break out of 'pass' loop now... */ - } - - }/* End 'pass' loop */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: item_is_excluded = %d\n",cn,item_is_excluded); - mod_gzip_printf( "%s: item_is_included = %d\n",cn,item_is_included); - mod_gzip_printf( "%s: action_flag = %d\n",cn,action_flag); - #endif - - if ( item_is_excluded ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: The item is excluded...\n",cn); - mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_DECLINED1 ) >\n",cn); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: This item is EXCLUDED as per httpd.conf"); - } - - return( MOD_GZIP_IMAP_DECLINED1 ); - } - - else if ( item_is_included ) - { - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: The item is included...\n",cn); - mod_gzip_printf( "%s: Exit > return( action_flag = %d ) >\n",cn,action_flag); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: This item is INCLUDED as per httpd.conf"); - } - - return( action_flag ); /* STATIC1 or DYNAMIC1 */ - } - - /* - * Default action is to DECLINE processing... - */ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_DECLINED1 ) >\n",cn); - #endif - - if ( r->server->loglevel == APLOG_DEBUG ) - { - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: This item was NOT FOUND in any mod_gzip httpd item record."); - ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, - "mod_gzip: This item will NOT be processed."); - } - - return( MOD_GZIP_IMAP_DECLINED1 ); - -}/* End of mod_gzip_get_action_flag() */ - -/*--------------------------------------------------------------------------*/ -/* ALL SOURCE CODE BELOW THIS POINT IS COMPRESSION SPECIFIC... */ -/*--------------------------------------------------------------------------*/ - -#define USE_GATHER -extern MODULE_VAR_EXPORT int ap_suexec_enabled; -extern API_EXPORT(void) -ap_internal_redirect_handler(const char *new_uri, request_rec *); -long mod_gzip_ap_send_fb( -BUFF *fb, -request_rec *r, -int *final_return_code -); -long mod_gzip_ap_send_fb_length( -BUFF *fb, -request_rec *r, -long length, -int *final_return_code -); -#define DEFAULT_LOGBYTES 10385760 -#define DEFAULT_BUFBYTES 1024 -static int mod_gzip_cgi_child(void *child_stuff, child_info *pinfo); -typedef struct { - char *logname; - long logbytes; - int bufbytes; -} cgi_server_conf; -struct mod_gzip_cgi_child_stuff { -#ifdef TPF - TPF_FORK_CHILD t; -#endif - request_rec *r; - int nph; - int debug; - char *argv0; -}; -static int is_scriptaliased( request_rec *r ) -{ - const char *t = ap_table_get(r->notes, "alias-forced-type"); - return t && (!strcasecmp(t, "cgi-script")); -} -static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret, - int show_errno, char *error) -{ - FILE *f; - struct stat finfo; - ap_log_rerror(APLOG_MARK, show_errno|APLOG_ERR, r, - "%s: %s", error, r->filename); - if (!conf->logname || - ((stat(ap_server_root_relative(r->pool, conf->logname), &finfo) == 0) - && (finfo.st_size > conf->logbytes)) || - ((f = ap_pfopen(r->pool, ap_server_root_relative(r->pool, conf->logname), - "a")) == NULL)) { - return ret; - } - fprintf(f, "%%%% [%s] %s %s%s%s %s\n", ap_get_time(), r->method, r->uri, - r->args ? "?" : "", r->args ? r->args : "", r->protocol); - fprintf(f, "%%%% %d %s\n", ret, r->filename); - fprintf(f, "%%error\n%s\n", error); - ap_pfclose(r->pool, f); - return ret; -} -static int log_script(request_rec *r, cgi_server_conf * conf, int ret, - char *dbuf, const char *sbuf, BUFF *script_in, BUFF *script_err) -{ - array_header *hdrs_arr = ap_table_elts(r->headers_in); - table_entry *hdrs = (table_entry *) hdrs_arr->elts; - char argsbuffer[HUGE_STRING_LEN]; - FILE *f; - int i; - struct stat finfo; - if (!conf->logname || - ((stat(ap_server_root_relative(r->pool, conf->logname), &finfo) == 0) - && (finfo.st_size > conf->logbytes)) || - ((f = ap_pfopen(r->pool, ap_server_root_relative(r->pool, conf->logname), - "a")) == NULL)) { - while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_in) > 0) - continue; -#if defined(_WIN32) || defined(NETWARE) - while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) { - ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, r, - "%s", argsbuffer); - } -#else - while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) - continue; -#endif - return ret; - } - fprintf(f, "%%%% [%s] %s %s%s%s %s\n", ap_get_time(), r->method, r->uri, - r->args ? "?" : "", r->args ? r->args : "", r->protocol); - fprintf(f, "%%%% %d %s\n", ret, r->filename); - fputs("%request\n", f); - for (i = 0; i < hdrs_arr->nelts; ++i) { - if (!hdrs[i].key) - continue; - fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); - } - if ((r->method_number == M_POST || r->method_number == M_PUT) - && *dbuf) { - fprintf(f, "\n%s\n", dbuf); - } - fputs("%response\n", f); - hdrs_arr = ap_table_elts(r->err_headers_out); - hdrs = (table_entry *) hdrs_arr->elts; - for (i = 0; i < hdrs_arr->nelts; ++i) { - if (!hdrs[i].key) - continue; - fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); - } - if (sbuf && *sbuf) - fprintf(f, "%s\n", sbuf); - if (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_in) > 0) { - fputs("%stdout\n", f); - fputs(argsbuffer, f); - while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_in) > 0) - fputs(argsbuffer, f); - fputs("\n", f); - } - if (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) { - fputs("%stderr\n", f); - fputs(argsbuffer, f); - while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) - fputs(argsbuffer, f); - fputs("\n", f); - } - ap_bclose( script_in ); - ap_bclose( script_err ); - ap_pfclose(r->pool, f); - return ret; -} -int mod_gzip_cgi_handler( request_rec *r ) -{ - int bytesread; - int retval, nph, dbpos = 0; - char *argv0, *dbuf = NULL; - BUFF *script_out, *script_in, *script_err; - char argsbuffer[HUGE_STRING_LEN]; - int is_included = !strcmp(r->protocol, "INCLUDED"); - void *sconf = r->server->module_config; - int final_result = DECLINED; - #define MOD_GZIP_ENGAGED - #ifdef MOD_GZIP_ENGAGED - cgi_server_conf conf_local; - cgi_server_conf *conf = &conf_local; - char cgi_logname[]=""; - #else - cgi_server_conf *conf = - (cgi_server_conf *) ap_get_module_config(sconf, &cgi_module); - #endif - const char *location; - struct mod_gzip_cgi_child_stuff cld; - #ifdef MOD_GZIP_ENGAGED - conf->logname = cgi_logname; - conf->logbytes = (long) 60000L; - conf->bufbytes = (int) 20000; - #endif - if ( r->method_number == M_OPTIONS ) - { - r->allowed |= (1 << M_GET); - r->allowed |= (1 << M_POST); - return DECLINED; - } - if ((argv0 = strrchr(r->filename, '/')) != NULL) - { - argv0++; - } - else - { - argv0 = r->filename; - } - nph = !(strncmp(argv0, "nph-", 4)); - if ( !(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r) ) - { - return log_scripterror(r, conf, FORBIDDEN, APLOG_NOERRNO, - "Options ExecCGI is off in this directory"); - } - if ( nph && is_included ) - { - return log_scripterror(r, conf, FORBIDDEN, APLOG_NOERRNO, - "attempt to include NPH CGI script"); - } - #if defined(OS2) || defined(_WIN32) - if ( r->finfo.st_mode == 0 ) - { - struct stat statbuf; - char *newfile; - newfile = ap_pstrcat(r->pool, r->filename, ".EXE", NULL); - if ((stat(newfile, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode))) - { - return log_scripterror(r, conf, NOT_FOUND, 0, - "script not found or unable to stat"); - } - else - { - r->filename = newfile; - } - } - #else - if ( r->finfo.st_mode == 0 ) - { - return log_scripterror(r, conf, NOT_FOUND, APLOG_NOERRNO, - "script not found or unable to stat"); - } - #endif - if ( S_ISDIR( r->finfo.st_mode ) ) - { - return log_scripterror(r, conf, FORBIDDEN, APLOG_NOERRNO, - "attempt to invoke directory as script"); - } - if ( !ap_suexec_enabled ) - { - if ( !ap_can_exec( &r->finfo ) ) - { - return log_scripterror(r, conf, FORBIDDEN, APLOG_NOERRNO, - "file permissions deny server execution"); - } - } - if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) - { - return retval; - } - ap_add_common_vars(r); - cld.argv0 = argv0; - cld.r = r; - cld.nph = nph; - cld.debug = conf->logname ? 1 : 0; - #ifdef TPF - cld.t.filename = r->filename; - cld.t.subprocess_env = r->subprocess_env; - cld.t.prog_type = FORK_FILE; - #endif - #ifdef CHARSET_EBCDIC - ap_bsetflag( r->connection->client, B_EBCDIC2ASCII, 1 ); - #endif - if ( !ap_bspawn_child( - r->main ? r->main->pool : r->pool, - mod_gzip_cgi_child, - (void *) &cld, - kill_after_timeout, - &script_out, - &script_in, - &script_err - ) - ) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "couldn't spawn child process: %s", r->filename); - return HTTP_INTERNAL_SERVER_ERROR; - } - else - { - } - if ( ap_should_client_block(r) ) - { - int dbsize, len_read; - if ( conf->logname ) - { - dbuf = ap_pcalloc( r->pool, conf->bufbytes + 1 ); - dbpos = 0; - } - ap_hard_timeout("copy script args", r); - for (;;) - { - len_read = - ap_get_client_block( r, argsbuffer, HUGE_STRING_LEN ); - if ( len_read < 1 ) - { - break; - } - if (conf->logname) - { - if ((dbpos + len_read) > conf->bufbytes) - { - dbsize = conf->bufbytes - dbpos; - } - else - { - dbsize = len_read; - } - memcpy(dbuf + dbpos, argsbuffer, dbsize); - dbpos += dbsize; - } - ap_reset_timeout(r); - if ( ap_bwrite(script_out, argsbuffer, len_read) < len_read ) - { - while ( len_read= - ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0) - { - } - break; - } - else - { - } - } - ap_bflush( script_out ); - ap_kill_timeout(r); - } - else - { - } - ap_bclose( script_out ); - if ( script_in && !nph ) - { - char sbuf[MAX_STRING_LEN]; - int ret; - if ((ret = ap_scan_script_header_err_buff(r, script_in, sbuf))) - { - return log_script(r, conf, ret, dbuf, sbuf, script_in, script_err); - } - #ifdef CHARSET_EBCDIC - ap_checkconv(r); - #endif - location = ap_table_get( r->headers_out, "Location" ); - if ( location && location[0] == '/' && r->status == 200 ) - { - ap_hard_timeout("read from script", r); - while ( ap_bgets(argsbuffer, HUGE_STRING_LEN, script_in) > 0 ) - { - continue; - } - while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) - { - continue; - } - ap_kill_timeout(r); - r->method = ap_pstrdup(r->pool, "GET"); - r->method_number = M_GET; - ap_table_unset( r->headers_in, "Content-Length" ); - ap_internal_redirect_handler( location, r ); - return OK; - } - else if ( location && r->status == 200 ) - { - return REDIRECT; - } - #ifdef USE_GATHER - if ( r->header_only ) - { - ap_send_http_header(r); - } - else - { - } - #else /* !USE_GATHER */ - ap_send_http_header(r); - #endif /* USE_GATHER */ - if (!r->header_only) - { - mod_gzip_ap_send_fb( script_in, r, &final_result ); - } - ap_bclose( script_in ); - ap_soft_timeout("soaking script stderr", r); - for (;;) - { - bytesread = ap_bgets( argsbuffer, HUGE_STRING_LEN, script_err ); - if ( bytesread < 1 ) - { - break; - } - } - ap_kill_timeout(r); - ap_bclose( script_err ); - } - else - { - } - if ( script_in && nph ) - { - #ifdef RUSSIAN_APACHE - if (ra_charset_active(r)) - { - r->ra_codep=NULL; - } - #endif - mod_gzip_ap_send_fb( script_in, r, &final_result ); - } - else - { - } - #ifdef ORIGINAL - return OK; - #endif - return final_result; -} -static int mod_gzip_cgi_child(void *child_stuff, child_info *pinfo) -{ - struct mod_gzip_cgi_child_stuff *cld = (struct mod_gzip_cgi_child_stuff *) child_stuff; - request_rec *r = cld->r; - char *argv0 = cld->argv0; - int child_pid; - -/* WARNING! If the following DEBUG_CGI switch is ON you may need to */ -/* run Apache with the -X switch or the dynamic compression */ -/* of some CGI output ( most notable Zope ) will start to fail. */ -/* This DEBUG_CGI switch should NEVER be on for production runs. */ -/* -#define DEBUG_CGI -*/ - -#ifdef DEBUG_CGI -#ifdef OS2 - FILE *dbg = fopen("con", "w"); -#else - #ifdef _WIN32 - FILE *dbg = fopen("c:\\script.dbg", "a" ); - #else - FILE *dbg = fopen("/dev/tty", "w"); - #endif -#endif - int i; -#endif - char **env; - RAISE_SIGSTOP(CGI_CHILD); -#ifdef DEBUG_CGI - fprintf(dbg, "Attempting to exec %s as %sCGI child (argv0 = %s)\n", - r->filename, cld->nph ? "NPH " : "", argv0); -#endif - ap_add_cgi_vars(r); - env = ap_create_environment(r->pool, r->subprocess_env); -#ifdef DEBUG_CGI - fprintf(dbg, "Environment: \n"); - for (i = 0; env[i]; ++i) - fprintf(dbg, "'%s'\n", env[i]); -#endif -#ifndef _WIN32 - #ifdef DEBUG_CGI - fprintf(dbg, "Call ap_chdir_file(r->filename=[%s]\n",r->filename); - #endif - ap_chdir_file(r->filename); - #ifdef DEBUG_CGI - fprintf(dbg, "Back ap_chdir_file(r->filename=[%s]\n",r->filename); - #endif -#endif - if (!cld->debug) - ap_error_log2stderr(r->server); -#ifdef TPF - #ifdef DEBUG_CGI - #ifdef _WIN32 - fprintf(dbg, "TPF defined... return( 0 ) now...\n"); - if ( dbg ) { fclose(dbg); dbg=0; } - #endif - #endif - return (0); -#else - #ifdef DEBUG_CGI - fprintf(dbg, "Call ap_cleanup_for_exec()...\n"); - #endif - ap_cleanup_for_exec(); - #ifdef DEBUG_CGI - fprintf(dbg, "Back ap_cleanup_for_exec()...\n"); - fprintf(dbg, "Call ap_call_exec()...\n"); - #endif - child_pid = ap_call_exec(r, pinfo, argv0, env, 0); - #ifdef DEBUG_CGI - fprintf(dbg, "Back ap_call_exec()...\n"); - #endif -#if defined(_WIN32) || defined(OS2) - #ifdef DEBUG_CGI - #ifdef _WIN32 - fprintf(dbg, "_WIN32 or OS2 defined... return( child_pid ) now...\n"); - if ( dbg ) { fclose(dbg); dbg=0; } - #endif - #endif - return (child_pid); -#else - ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "exec of %s failed", r->filename); - exit(0); - #ifdef DEBUG_CGI - #ifdef _WIN32 - if ( dbg ) { fclose(dbg); dbg=0; } - #endif - #endif - return (0); -#endif -#endif -} -#define MOD_GZIP_SET_BYTES_SENT(r) \ - do { if (r->sent_bodyct) \ - ap_bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \ - } while (0) -long mod_gzip_ap_send_fb( BUFF *fb, request_rec *r, int *final_return_code ) -{ - long lrc; - int return_code=DECLINED; - lrc = (long ) mod_gzip_ap_send_fb_length( fb, r, -1, &return_code ); - *final_return_code = return_code; - return lrc; -} -#ifdef USE_TPF_SELECT -#define mod_gzip_ap_select(_a, _b, _c, _d, _e) \ - tpf_select(_a, _b, _c, _d, _e) -#elif defined(SELECT_NEEDS_CAST) -#define mod_gzip_ap_select(_a, _b, _c, _d, _e) \ - select((_a), (int *)(_b), (int *)(_c), (int *)(_d), (_e)) -#else -#define mod_gzip_ap_select(_a, _b, _c, _d, _e) \ - select(_a, _b, _c, _d, _e) -#endif -long mod_gzip_ap_send_fb_length( -BUFF *fb, -request_rec *r, -long length, -int *final_return_code -) -{ - char cn[]="mod_gzip_ab_send_fb_length()"; - char buf[IOBUFSIZE]; - long total_bytes_sent = 0; - register int n; - register int len; - register int fd; - fd_set fds; - int rc; - #ifndef USE_GATHER - register int w; - register int o; - #endif - #ifdef USE_GATHER - int gather_on = 0; - int gather_todisk = 0; - int gather_origin = 0; - char *gather_bufstart = 0; - char *gather_source = 0; - char *gather_buf = 0; - int gather_bufmaxlen = 60000; - int gather_byteswritten = 0; - int gather_length = 0; - int gather_maxlen = 0; - long gather_totlen = 0; - FILE *gather_fh1 = 0; - char gather_filename[ MOD_GZIP_MAX_PATH_LEN + 2 ]; - #endif - void *modconf = r->server->module_config; - mod_gzip_conf *conf; - *final_return_code = DECLINED; - conf = (mod_gzip_conf *) ap_get_module_config( modconf, &gzip_module ); - if ( length == 0 ) - { - return 0; - } - ap_bsetflag( fb, B_RD, 0 ); - #ifndef TPF - ap_bnonblock( fb, B_RD ); - #endif - fd = ap_bfileno( fb, B_RD ); - #ifdef CHECK_FD_SETSIZE - if ( fd >= FD_SETSIZE ) - { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, - "send body: filedescriptor (%u) larger than FD_SETSIZE (%u) " - "found, you probably need to rebuild Apache with a " - "larger FD_SETSIZE", fd, FD_SETSIZE); - return 0; - } - else - { - } - #else - #endif - ap_soft_timeout("send body", r); - FD_ZERO( &fds ); - #ifdef USE_GATHER - gather_on = 0; - if ( (long) conf->maximum_inmem_size < (long) gather_bufmaxlen ) - { - gather_maxlen = (int) conf->maximum_inmem_size; - } - else - { - gather_maxlen = (int) gather_bufmaxlen; - } - gather_bufstart = malloc( (int)(gather_maxlen + 2) ); - if ( gather_bufstart ) - { - gather_on = 1; - gather_buf = gather_bufstart; - gather_source = gather_bufstart; - gather_origin = 0; - } - else - { - } - #endif - while( !r->connection->aborted ) - { - #ifdef NDELAY_PIPE_RETURNS_ZERO - int afterselect = 0; - #endif - if ( (length > 0) && (total_bytes_sent + IOBUFSIZE) > length ) - { - len = length - total_bytes_sent; - } - else - { - len = IOBUFSIZE; - } - do { - n = ap_bread( fb, buf, len ); - #ifdef NDELAY_PIPE_RETURNS_ZERO - if ((n > 0) || (n == 0 && afterselect)) - { - break; - } - #else - if (n >= 0) - { - break; - } - #endif - if ( r->connection->aborted ) - { - break; - } - if ( n < 0 && errno != EAGAIN ) - { - break; - } - if ( ap_bflush( r->connection->client ) < 0 ) - { - ap_log_rerror(APLOG_MARK, APLOG_INFO, r, - "client stopped connection before send body completed"); - ap_bsetflag( r->connection->client, B_EOUT, 1 ); - r->connection->aborted = 1; - break; - } - #ifdef _WIN32 - FD_SET( (unsigned) fd, &fds ); - #else - FD_SET( fd, &fds ); - #endif - #ifdef FUTURE_USE - mod_gzip_ap_select(fd + 1, &fds, NULL, NULL, NULL); - #endif - #ifdef NDELAY_PIPE_RETURNS_ZERO - afterselect = 1; - #endif - } while ( !r->connection->aborted ); - if ( n < 1 || r->connection->aborted ) - { - break; - } - #ifdef USE_GATHER - if ( gather_on ) - { - if ( ( gather_length + n ) >= gather_maxlen ) - { - if ( !gather_fh1 ) - { - mod_gzip_create_unique_filename( - (mod_gzip_conf *) conf, - (char *) gather_filename, - sizeof( gather_filename ) - ); - gather_fh1 = fopen( gather_filename, "wb" ); - if ( gather_fh1 ) - { - gather_source = gather_filename; - gather_origin = 1; - } - else - { - gather_on = 0; - } - } - if ( ( gather_fh1 ) && ( gather_length > 0 ) ) - { - gather_byteswritten = - fwrite( gather_bufstart, 1, gather_length, gather_fh1 ); - if ( gather_byteswritten != gather_length ) - { - gather_on = 0; - } - } - if ( ( gather_fh1 ) && ( n > 0 ) ) - { - gather_byteswritten = - fwrite( buf, 1, n, gather_fh1 ); - if ( gather_byteswritten != n ) - { - gather_on = 0; - } - } - gather_buf = gather_bufstart; - gather_length = 0; - } - else - { - if ( gather_on ) - { - memcpy( gather_buf, buf, n ); - gather_buf += n; - gather_length += n; - } - } - gather_totlen += n; - } - #endif - #ifdef FUTURE_USE - o = 0; - while ( n && !r->connection->aborted ) - { - #ifdef RUSSIAN_APACHE - unsigned char *newbuf,*p; - int newlen=0; - if ( ra_charset_active(r) ) - { - if ( ra_flag( r, RA_WIDE_CHARS_SC ) ) - { - ra_data_server2client(r,&buf[o],n,&newbuf,&newlen); - p=newbuf; - while( newlen > 0 ) - { - w = ap_bwrite( r->connection->client, p, newlen ); - if(w<=0) goto RECODE_DONE; - newlen-=w; - p+=w; - } - w=n; - } - else - { - unsigned char *t = r->ra_codep->cp_otabl_p; - unsigned char *b = (unsigned char *)&buf[o]; - unsigned char *end = b+n; - while( b < end ) - { - *b = t[*b]; - b++; - } - w = ap_bwrite( r->connection->client, &buf[o], n ); - } - } - else - { - w = ap_bwrite( r->connection->client, &buf[o], n ); - } - RECODE_DONE:; - #else - w = ap_bwrite( r->connection->client, &buf[o], n ); - #endif - if ( w > 0 ) - { - ap_reset_timeout(r); - total_bytes_sent += w; - n -= w; - o += w; - } - else if ( w < 0 ) - { - if ( !r->connection->aborted ) - { - ap_log_rerror(APLOG_MARK, APLOG_INFO, r, - "client stopped connection before send body completed"); - ap_bsetflag(r->connection->client, B_EOUT, 1); - r->connection->aborted = 1; - } - break; - } - } - #endif - } - ap_kill_timeout(r); - MOD_GZIP_SET_BYTES_SENT(r); - #ifdef USE_GATHER - if ( gather_fh1 ) - { - if ( gather_length > 0 ) - { - gather_byteswritten = - fwrite( gather_bufstart, 1, gather_length, gather_fh1 ); - if ( gather_byteswritten != gather_length ) - { - gather_on = 0; - } - } - fclose( gather_fh1 ); - gather_fh1 = 0; - } - if ( gather_totlen > 0 ) - { - rc = - mod_gzip_encode_and_transmit( - (request_rec *) r, - (char *) gather_source, - (int ) gather_origin, - (long ) gather_totlen, - (int ) 1 - ); - *final_return_code = rc; - } - if ( gather_bufstart ) - { - free( gather_bufstart ); - gather_bufstart = 0; - } - gather_on = 0; - #endif - return total_bytes_sent; -} - -/*--------------------------------------------------------------------------*/ -/* COMPRESSION SUPPORT ROUTINES */ -/*--------------------------------------------------------------------------*/ - -#define BIG_MEM - -typedef unsigned uns; -typedef unsigned int uni; -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; -typedef int gz1_file_t; - -#ifdef __STDC__ - typedef void *voidp; -#else - typedef char *voidp; -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif - -#if defined(__OS2__) && !defined(OS2) -# define OS2 -#endif - -#if defined(OS2) && defined(MSDOS) -# undef MSDOS -#endif - -#ifdef MSDOS -# ifdef __GNUC__ -# define near -# else -# define MAXSEG_64K -# ifdef __TURBOC__ -# define NO_OFF_T -# ifdef __BORLANDC__ -# define DIRENT -# else -# define NO_UTIME -# endif -# else -# define HAVE_SYS_UTIME_H -# define NO_UTIME_H -# endif -# endif -# define PATH_SEP2 '\\' -# define PATH_SEP3 ':' -# define MAX_PATH_LEN 128 -# define NO_MULTIPLE_DOTS -# define MAX_EXT_CHARS 3 -# define Z_SUFFIX "z" -# define NO_CHOWN -# define PROTO -# define STDC_HEADERS -# define NO_SIZE_CHECK -# define casemap(c) tolow(c) -# include -# undef OS_CODE -# define OS_CODE 0x00 -# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY) -# if !defined(NO_ASM) && !defined(ASMV) -# define ASMV -# endif -#else -# define near -#endif - -#ifdef OS2 -# define PATH_SEP2 '\\' -# define PATH_SEP3 ':' -# define MAX_PATH_LEN 260 -# ifdef OS2FAT -# define NO_MULTIPLE_DOTS -# define MAX_EXT_CHARS 3 -# define Z_SUFFIX "z" -# define casemap(c) tolow(c) -# endif -# define NO_CHOWN -# define PROTO -# define STDC_HEADERS -# include -# undef OS_CODE -# define OS_CODE 0x06 -# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY) -# ifdef _MSC_VER -# define HAVE_SYS_UTIME_H -# define NO_UTIME_H -# define MAXSEG_64K -# undef near -# define near _near -# endif -# ifdef __EMX__ -# define HAVE_SYS_UTIME_H -# define NO_UTIME_H -# define DIRENT -# define EXPAND(argc,argv) \ - {_response(&argc, &argv); _wildcard(&argc, &argv);} -# endif -# ifdef __BORLANDC__ -# define DIRENT -# endif -# ifdef __ZTC__ -# define NO_DIR -# define NO_UTIME_H -# include -# define EXPAND(argc,argv) \ - {response_expand(&argc, &argv);} -# endif -#endif - -#ifdef _WIN32 -# define HAVE_SYS_UTIME_H -# define NO_UTIME_H -# define PATH_SEP2 '\\' -# define PATH_SEP3 ':' -# undef MAX_PATH_LEN -# define MAX_PATH_LEN 260 -# define NO_CHOWN -# define PROTO -# define STDC_HEADERS -# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY) -# include -# ifdef NTFAT -# define NO_MULTIPLE_DOTS -# define MAX_EXT_CHARS 3 -# define Z_SUFFIX "z" -# define casemap(c) tolow(c) -# endif -# undef OS_CODE - -# define OS_CODE 0x00 - -#endif - -#ifdef MSDOS -# ifdef __TURBOC__ -# include -# define DYN_ALLOC - void * fcalloc (unsigned items, unsigned size); - void fcfree (void *ptr); -# else -# define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize)) -# define fcfree(ptr) hfree(ptr) -# endif -#else -# ifdef MAXSEG_64K -# define fcalloc(items,size) calloc((items),(size)) -# else -# define fcalloc(items,size) malloc((size_t)(items)*(size_t)(size)) -# endif -# define fcfree(ptr) free(ptr) -#endif - -#if defined(VAXC) || defined(VMS) -# define PATH_SEP ']' -# define PATH_SEP2 ':' -# define SUFFIX_SEP ';' -# define NO_MULTIPLE_DOTS -# define Z_SUFFIX "-gz" -# define RECORD_IO 1 -# define casemap(c) tolow(c) -# undef OS_CODE -# define OS_CODE 0x02 -# define OPTIONS_VAR "GZIP_OPT" -# define STDC_HEADERS -# define NO_UTIME -# define EXPAND(argc,argv) vms_expand_args(&argc,&argv); -# include -# define unlink delete -# ifdef VAXC -# define NO_FCNTL_H -# include -# endif -#endif - -#ifdef AMIGA -# define PATH_SEP2 ':' -# define STDC_HEADERS -# undef OS_CODE -# define OS_CODE 0x01 -# define ASMV -# ifdef __GNUC__ -# define DIRENT -# define HAVE_UNISTD_H -# else -# define NO_STDIN_FSTAT -# define SYSDIR -# define NO_SYMLINK -# define NO_CHOWN -# define NO_FCNTL_H -# include -# define direct dirent - extern void _expand_args(int *argc, char ***argv); -# define EXPAND(argc,argv) _expand_args(&argc,&argv); -# undef O_BINARY -# endif -#endif - -#if defined(ATARI) || defined(atarist) -# ifndef STDC_HEADERS -# define STDC_HEADERS -# define HAVE_UNISTD_H -# define DIRENT -# endif -# define ASMV -# undef OS_CODE -# define OS_CODE 0x05 -# ifdef TOSFS -# define PATH_SEP2 '\\' -# define PATH_SEP3 ':' -# define MAX_PATH_LEN 128 -# define NO_MULTIPLE_DOTS -# define MAX_EXT_CHARS 3 -# define Z_SUFFIX "z" -# define NO_CHOWN -# define casemap(c) tolow(c) -# define NO_SYMLINK -# endif -#endif - -#ifdef MACOS -# define PATH_SEP ':' -# define DYN_ALLOC -# define PROTO -# define NO_STDIN_FSTAT -# define NO_CHOWN -# define NO_UTIME -# define chmod(file, mode) (0) -# define OPEN(name, flags, mode) open(name, flags) -# undef OS_CODE -# define OS_CODE 0x07 -# ifdef MPW -# define isatty(fd) ((fd) <= 2) -# endif -#endif - -#ifdef __50SERIES -# define PATH_SEP '>' -# define STDC_HEADERS -# define NO_MEMORY_H -# define NO_UTIME_H -# define NO_UTIME -# define NO_CHOWN -# define NO_STDIN_FSTAT -# define NO_SIZE_CHECK -# define NO_SYMLINK -# define RECORD_IO 1 -# define casemap(c) tolow(c) -# define put_char(c) put_byte((c) & 0x7F) -# define get_char(c) ascii2pascii(get_byte()) -# undef OS_CODE -# define OS_CODE 0x0F -# ifdef SIGTERM -# undef SIGTERM -# endif -#endif - -#if defined(pyr) && !defined(NOMEMCPY) -# define NOMEMCPY -#endif - -#ifdef TOPS20 -# undef OS_CODE -# define OS_CODE 0x0a -#endif - -#ifndef unix -# define NO_ST_INO -#endif - -#ifndef OS_CODE -# undef OS_CODE -# define OS_CODE 0x03 -#endif - -#ifndef PATH_SEP -# define PATH_SEP '/' -#endif - -#ifndef casemap -# define casemap(c) (c) -#endif - -#ifndef OPTIONS_VAR -# define OPTIONS_VAR "GZIP" -#endif - -#ifndef Z_SUFFIX -# define Z_SUFFIX ".gz" -#endif - -#ifdef MAX_EXT_CHARS -# define MAX_SUFFIX MAX_EXT_CHARS -#else -# define MAX_SUFFIX 30 -#endif - -#ifndef MIN_PART -# define MIN_PART 3 -#endif - -#ifndef EXPAND -# define EXPAND(argc,argv) -#endif - -#ifndef RECORD_IO -# define RECORD_IO 0 -#endif - -#ifndef SET_BINARY_MODE -# define SET_BINARY_MODE(fd) -#endif - -#ifndef OPEN -# define OPEN(name, flags, mode) open(name, flags, mode) -#endif - -#ifndef get_char -# define get_char() get_byte() -#endif - -#ifndef put_char -# define put_char(c) put_byte(c) -#endif - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -#define OK 0 -#define LZ1_ERROR 1 -#define WARNING 2 -#define STORED 0 -#define COMPRESSED 1 -#define PACKED 2 -#define LZHED 3 -#define DEFLATED 8 -#define MAX_METHODS 9 - -#ifndef O_CREAT -#include -#ifndef O_CREAT -#define O_CREAT FCREAT -#endif -#ifndef O_EXCL -#define O_EXCL FEXCL -#endif -#endif - -#ifndef S_IRUSR -#define S_IRUSR 0400 -#endif -#ifndef S_IWUSR -#define S_IWUSR 0200 -#endif -#define RW_USER (S_IRUSR | S_IWUSR) - -#ifndef MAX_PATH_LEN -#define MAX_PATH_LEN 256 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#define PACK_MAGIC "\037\036" -#define GZIP_MAGIC "\037\213" -#define OLD_GZIP_MAGIC "\037\236" -#define LZH_MAGIC "\037\240" -#define PKZIP_MAGIC "\120\113\003\004" -#define ASCII_FLAG 0x01 -#define CONTINUATION 0x02 -#define EXTRA_FIELD 0x04 -#define ORIG_NAME 0x08 -#define COMMENT 0x10 -#define ENCRYPTED 0x20 -#define RESERVED 0xC0 -#define UNKNOWN 0xffff -#define BINARY 0 -#define ASCII 1 - -#ifndef WSIZE -#define WSIZE 0x8000 -#endif - -#ifndef INBUFSIZ -#ifdef SMALL_MEM -#define INBUFSIZ 0x2000 -#else -#define INBUFSIZ 0x8000 -#endif -#endif -#define INBUF_EXTRA 64 - -#ifndef OUTBUFSIZ -#ifdef SMALL_MEM -#define OUTBUFSIZ 8192 -#else -#define OUTBUFSIZ 0x4000 -#endif -#endif -#define OUTBUF_EXTRA 2048 - -#ifndef DIST_BUFSIZE -#ifdef SMALL_MEM -#define DIST_BUFSIZE 0x2000 -#else -#define DIST_BUFSIZE 0x8000 -#endif -#endif - -#ifndef BITS -#define BITS 16 -#endif - -#define LZW_MAGIC "\037\235" - -#define MIN_MATCH 3 -#define MAX_MATCH 258 - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -#define MAX_DIST (WSIZE-MIN_LOOKAHEAD) - -#ifdef SMALL_MEM -#define HASH_BITS 13 -#endif -#ifdef MEDIUM_MEM -#define HASH_BITS 14 -#endif -#ifndef HASH_BITS -#define HASH_BITS 15 -#endif - -#define HASH_SIZE (unsigned)(1<block_start >= 0L ? (char*)&gz1->window[(unsigned)gz1->block_start] : \ - (char*)NULL, (long)gz1->strstart - gz1->block_start, (eof)) - -#ifdef DYN_ALLOC -# define ALLOC(type, array, size) { \ - array = (type*)fcalloc((size_t)(((size)+1L)/2), 2*sizeof(type)); \ - if (array == NULL) error("insufficient memory"); \ - } -# define FREE(array) {if (array != NULL) fcfree(array), array=NULL;} -#else -# define ALLOC(type, array, size) -# define FREE(array) -#endif - -#define GZ1_MAX(a,b) (a >= b ? a : b) - -#define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) - -#define smaller(tree, n, m) \ - (tree[n].fc.freq < tree[m].fc.freq || \ - (tree[n].fc.freq == tree[m].fc.freq && gz1->depth[n] <= gz1->depth[m])) - -#define send_code(c, tree) send_bits(gz1,tree[c].fc.code, tree[c].dl.len) - -#define put_byte(c) {gz1->outbuf[gz1->outcnt++]=(uch)(c); if (gz1->outcnt==OUTBUFSIZ)\ - flush_outbuf(gz1);} - -#define put_short(w) \ -{ if (gz1->outcnt < OUTBUFSIZ-2) { \ - gz1->outbuf[gz1->outcnt++] = (uch) ((w) & 0xff); \ - gz1->outbuf[gz1->outcnt++] = (uch) ((ush)(w) >> 8); \ - } else { \ - put_byte((uch)((w) & 0xff)); \ - put_byte((uch)((ush)(w) >> 8)); \ - } \ -} - -#define put_long(n) { \ - put_short((n) & 0xffff); \ - put_short(((ulg)(n)) >> 16); \ -} - -#ifdef CRYPT - -# define NEXTBYTE() \ - (decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte()) -#else -# define NEXTBYTE() (uch)get_byte() -#endif - -#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<>=(n);k-=(n);} - -#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) -#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)) - -#define put_ubyte(c) {gz1->window[gz1->outcnt++]=(uch)(c); if (gz1->outcnt==WSIZE)\ - flush_window(gz1);} - -#define WARN(msg) { if (gz1->exit_code == OK) gz1->exit_code = WARNING; } - -#define get_byte() (gz1->inptr < gz1->insize ? gz1->inbuf[gz1->inptr++] : fill_inbuf(gz1,0)) -#define try_byte() (gz1->inptr < gz1->insize ? gz1->inbuf[gz1->inptr++] : fill_inbuf(gz1,1)) - -#define d_code(dist) \ - ((dist) < 256 ? gz1->dist_code[dist] : gz1->dist_code[256+((dist)>>7)]) - -typedef struct config { - ush good_length; - ush max_lazy; - ush nice_length; - ush max_chain; -} config; - -config configuration_table[10] = { - - {0, 0, 0, 0}, - {4, 4, 8, 4}, - {4, 5, 16, 8}, - {4, 6, 32, 32}, - {4, 4, 16, 16}, - {8, 16, 32, 32}, - {8, 16, 128, 128}, - {8, 32, 128, 256}, - {32, 128, 258, 1024}, - {32, 258, 258, 4096}}; - -typedef struct ct_data { - - union { - ush freq; - ush code; - } fc; - union { - ush dad; - ush len; - } dl; - -} ct_data; - -typedef struct tree_desc { - ct_data *dyn_tree; - ct_data *static_tree; - int *extra_bits; - int extra_base; - int elems; - int max_length; - int max_code; -} tree_desc; - -struct huft { - uch e; - uch b; - union { - ush n; - struct huft *t; - } v; -}; - -uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; - -int extra_lbits[LENGTH_CODES] - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -int extra_dbits[D_CODES] - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -int extra_blbits[BL_CODES] - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -ulg crc_32_tab[] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -typedef struct _GZ1 { - long compression_format; - - long versionid1; - int state; - int done; - int deflate1_initialized; - unsigned deflate1_hash_head; - unsigned deflate1_prev_match; - int deflate1_flush; - int deflate1_match_available; - unsigned deflate1_match_length; - - char ifname[MAX_PATH_LEN]; - char ofname[MAX_PATH_LEN]; - - struct stat istat; - gz1_file_t zfile; - - int input_ismem; - char *input_ptr; - long input_bytesleft; - - int output_ismem; - char *output_ptr; - uns output_maxlen; - - int compr_level; - long time_stamp; - long ifile_size; - int ifd; - int ofd; - int part_nb; - int last_member; - int save_orig_name; - long header_bytes; - long bytes_in; - long bytes_out; - uns insize; - uns inptr; - uns outcnt; - uns ins_h; - long block_start; - uns good_match; - uni max_lazy_match; - uni prev_length; - uns max_chain_length; - uns strstart; - uns match_start; - int eofile; - uns lookahead; - ush *file_type; - int *file_method; - ulg opt_len; - ulg static_len; - ulg compressed_len; - ulg input_len; - uns last_flags; - uch flags; - uns last_lit; - uns last_dist; - uch flag_bit; - int heap_len; - int heap_max; - ulg bb; - uns bk; - ush bi_buf; - int bi_valid; - uns hufts; - int decrypt; - int ascii; - int msg_done; - int abortflag; - int decompress; - int do_lzw; - int to_stdout; - int force; - int verbose; - int quiet; - int list; - int test; - int ext_header; - int pkzip; - int method; - int level; - int no_time; - int no_name; - int exit_code; - int lbits; - int dbits; - ulg window_size; - ulg crc; - ulg adler; - - uch dist_code[512]; - uch length_code[MAX_MATCH-MIN_MATCH+1]; - int heap[2*L_CODES+1]; - uch depth[2*L_CODES+1]; - int base_length[LENGTH_CODES]; - int base_dist[D_CODES]; - ush bl_count[MAX_BITS+1]; - uch flag_buf[(LIT_BUFSIZE/8)]; - - #ifdef DYN_ALLOC - uch *inbuf; - uch *outbuf; - ush *d_buf; - uch *window; - #else - uch inbuf [INBUFSIZ +INBUF_EXTRA]; - uch outbuf[OUTBUFSIZ+OUTBUF_EXTRA]; - ush d_buf [DIST_BUFSIZE]; - uch window[2L*WSIZE]; - #endif - - #ifdef FULL_SEARCH - #define nice_match MAX_MATCH - #else - int nice_match; - #endif - - #ifdef CRYPT - uch cc; - #endif - - ct_data static_ltree[L_CODES+2]; - ct_data static_dtree[D_CODES]; - ct_data dyn_dtree[(2*D_CODES+1)]; - ct_data dyn_ltree[HEAP_SIZE]; - ct_data bl_tree[2*BL_CODES+1]; - - tree_desc l_desc; - tree_desc d_desc; - tree_desc bl_desc; - - #ifndef MAXSEG_64K - - ush prev2[1L<prev2 - #define head (gz1->prev2+WSIZE) - - #else - - ush * prev2; - ush * tab_prefix1; - - #define prev gz1->prev2 - #define head gz1->tab_prefix1 - - #endif - -} GZ1; -typedef GZ1 *PGZ1; -int gz1_size = sizeof( GZ1 ); - -/* Declare some local function protypes... */ - -/* Any routine name that can/might conflict with */ -/* other modules or object code should simply have */ -/* the standard prefix 'gz1_' added to the front. */ -/* This will only usually be any kind of problem at all */ -/* if the code is being compiled directly into the parent */ -/* instead of being built as a standalone DLL or DSO library. */ - -PGZ1 gz1_init ( void ); -int gz1_cleanup ( PGZ1 gz1 ); -ulg gz1_deflate ( PGZ1 gz1 ); -ulg gz1_deflate_fast( PGZ1 gz1 ); - -/* The rest of the routines should not need the 'gz1_' prefix. */ -/* No conflicts reported at this time. */ - -int inflate ( PGZ1 gz1 ); -int inflate_dynamic( PGZ1 gz1 ); -int inflate_stored ( PGZ1 gz1 ); -int inflate_fixed ( PGZ1 gz1 ); -void fill_window ( PGZ1 gz1 ); -void flush_outbuf ( PGZ1 gz1 ); -void flush_window ( PGZ1 gz1 ); -void bi_windup ( PGZ1 gz1 ); -void set_file_type ( PGZ1 gz1 ); -void init_block ( PGZ1 gz1 ); -int build_bl_tree ( PGZ1 gz1 ); -void read_error ( PGZ1 gz1 ); -void write_error ( PGZ1 gz1 ); -int get_header ( PGZ1 gz1, int in ); -int inflate_block ( PGZ1 gz1, int *e ); -int fill_inbuf ( PGZ1 gz1, int eof_ok ); -char *gz1_basename ( PGZ1 gz1, char *fname ); -int longest_match ( PGZ1 gz1, unsigned cur_match ); -void bi_init ( PGZ1 gz1, gz1_file_t zipfile ); -int file_read ( PGZ1 gz1, char *buf, unsigned size ); -void write_buf ( PGZ1 gz1, int fd, voidp buf, unsigned cnt ); - -void error( char *msg ); - -/* XXX - Precomputed zlib header. If you change the window size or - * compression level from the defaults, this will break badly. The - * algorithm to build this is fairly complex; you can find it in - * the file deflate.c from the zlib distribution. - */ -#define ZLIB_HEADER "\170œ" - -ulg adler32(ulg adler, uch *buf, unsigned len); - -int zip( -PGZ1 gz1, -int in, -int out -); - -ulg flush_block( -PGZ1 gz1, -char *buf, -ulg stored_len, -int eof -); - -void copy_block( -PGZ1 gz1, -char *buf, -unsigned len, -int header -); - -int ct_tally( -PGZ1 gz1, -int dist, -int lc -); - -void send_bits( -PGZ1 gz1, -int value, -int length -); - -void send_tree( -PGZ1 gz1, -ct_data *tree, -int max_code -); - -void send_all_trees( -PGZ1 gz1, -int lcodes, -int dcodes, -int blcodes -); - -void ct_init( -PGZ1 gz1, -ush *attr, -int *methodp -); - -void lm_init( -PGZ1 gz1, -int pack_level, -ush *flags -); - -void build_tree( -PGZ1 gz1, -tree_desc *desc -); - -void compress_block( -PGZ1 gz1, -ct_data *ltree, -ct_data *dtree -); - -void gen_bitlen( -PGZ1 gz1, -tree_desc *desc -); - -void pqdownheap( -PGZ1 gz1, -ct_data *tree, -int k -); - -int huft_build( -PGZ1 gz1, -unsigned *b, -unsigned n, -unsigned s, -ush *d, -ush *e, -struct huft **t, -int *m -); - -ulg updcrc( -PGZ1 gz1, -uch *s, -unsigned n -); - -int inflate_codes( -PGZ1 gz1, -struct huft *tl, -struct huft *td, -int bl, -int bd -); - -void gen_codes( -PGZ1 gz1, -ct_data *tree, -int max_code -); - -void scan_tree( -PGZ1 gz1, -ct_data *tree, -int max_code -); - -unsigned bi_reverse( -PGZ1 gz1, -unsigned code, -int len -); - -int huft_free( -PGZ1 gz1, -struct huft *t -); - -PGZ1 gz1_init() -{ - PGZ1 gz1=0; - - gz1 = (PGZ1) malloc( gz1_size ); - - if ( !gz1 ) - { - return 0; - } - - memset( gz1, 0, gz1_size ); - - ALLOC(uch, gz1->inbuf, INBUFSIZ +INBUF_EXTRA); - - if ( !gz1->inbuf ) - { - free( gz1 ); - return 0; - } - - ALLOC(uch, gz1->outbuf, OUTBUFSIZ+OUTBUF_EXTRA); - - if ( !gz1->outbuf ) - { - FREE( gz1->inbuf ); - free( gz1 ); - return 0; - } - - ALLOC(ush, gz1->d_buf, DIST_BUFSIZE); - - if ( !gz1->d_buf ) - { - FREE( gz1->outbuf ); - FREE( gz1->inbuf ); - free( gz1 ); - return 0; - } - - ALLOC(uch, gz1->window, 2L*WSIZE); - - if ( !gz1->window ) - { - FREE( gz1->d_buf ); - FREE( gz1->outbuf ); - FREE( gz1->inbuf ); - free( gz1 ); - return 0; - } - - #ifndef MAXSEG_64K - - #else - - ALLOC(ush, gz1->prev2, 1L<<(BITS-1) ); - - if ( !gz1->prev2 ) - { - FREE( gz1->window ); - FREE( gz1->d_buf ); - FREE( gz1->outbuf ); - FREE( gz1->inbuf ); - free( gz1 ); - return 0; - } - - ALLOC(ush, gz1->tab_prefix1, 1L<<(BITS-1) ); - - if ( !gz1->tab_prefix1 ) - { - FREE( gz1->prev2 ); - FREE( gz1->window ); - FREE( gz1->d_buf ); - FREE( gz1->outbuf ); - FREE( gz1->inbuf ); - free( gz1 ); - return 0; - } - - #endif - - gz1->method = DEFLATED; - gz1->level = 6; - gz1->no_time = -1; - gz1->no_name = -1; - gz1->exit_code = OK; - gz1->lbits = 9; - gz1->dbits = 6; - - gz1->window_size = (ulg)2*WSIZE; - gz1->crc = (ulg)0xffffffffL; - - gz1->d_desc.dyn_tree = (ct_data *) gz1->dyn_dtree; - gz1->d_desc.static_tree = (ct_data *) gz1->static_dtree; - gz1->d_desc.extra_bits = (int *) extra_dbits; - gz1->d_desc.extra_base = (int ) 0; - gz1->d_desc.elems = (int ) D_CODES; - gz1->d_desc.max_length = (int ) MAX_BITS; - gz1->d_desc.max_code = (int ) 0; - - gz1->l_desc.dyn_tree = (ct_data *) gz1->dyn_ltree; - gz1->l_desc.static_tree = (ct_data *) gz1->static_ltree; - gz1->l_desc.extra_bits = (int *) extra_lbits; - gz1->l_desc.extra_base = (int ) LITERALS+1; - gz1->l_desc.elems = (int ) L_CODES; - gz1->l_desc.max_length = (int ) MAX_BITS; - gz1->l_desc.max_code = (int ) 0; - - gz1->bl_desc.dyn_tree = (ct_data *) gz1->bl_tree; - gz1->bl_desc.static_tree = (ct_data *) 0; - gz1->bl_desc.extra_bits = (int *) extra_blbits; - gz1->bl_desc.extra_base = (int ) 0; - gz1->bl_desc.elems = (int ) BL_CODES; - gz1->bl_desc.max_length = (int ) MAX_BL_BITS; - gz1->bl_desc.max_code = (int ) 0; - - return (PGZ1) gz1; - -} - -int gz1_cleanup( PGZ1 gz1 ) -{ - - #ifndef MAXSEG_64K - - #else - - FREE( gz1->tab_prefix1 ); - FREE( gz1->prev2 ); - #endif - - FREE( gz1->window ); - FREE( gz1->d_buf ); - FREE( gz1->outbuf ); - FREE( gz1->inbuf ); - - free( gz1 ); - gz1 = 0; - - return 0; -} - -int (*read_buf)(PGZ1 gz1, char *buf, unsigned size); - -void error( char *msg ) -{ - msg = msg; -} - -int (*work)( PGZ1 gz1, int infile, int outfile ) = 0; - -#ifdef __BORLANDC__ -#pragma argsused -#endif - -int get_header( PGZ1 gz1, int in ) -{ - uch flags; - char magic[2]; - ulg stamp; - unsigned len; - unsigned part; - - if ( gz1->force && gz1->to_stdout ) - { - magic[0] = (char)try_byte(); - magic[1] = (char)try_byte(); - } - else - { - magic[0] = (char)get_byte(); - magic[1] = (char)get_byte(); - } - - gz1->method = -1; - gz1->header_bytes = 0; - gz1->last_member = RECORD_IO; - gz1->part_nb++; - - if ( memcmp(magic, GZIP_MAGIC, 2 ) == 0 || - memcmp(magic, OLD_GZIP_MAGIC, 2 ) == 0 ) - { - gz1->method = (int)get_byte(); - - if ( gz1->method != DEFLATED ) - { - gz1->exit_code = LZ1_ERROR; - - return -1; - } - - return -1; - - if ((flags & ENCRYPTED) != 0) - { - gz1->exit_code = LZ1_ERROR; - return -1; - } - - if ((flags & CONTINUATION) != 0) - { - gz1->exit_code = LZ1_ERROR; - if ( gz1->force <= 1) return -1; - } - - if ((flags & RESERVED) != 0) - { - gz1->exit_code = LZ1_ERROR; - if ( gz1->force <= 1) - return -1; - } - - stamp = (ulg)get_byte(); - stamp |= ((ulg)get_byte()) << 8; - stamp |= ((ulg)get_byte()) << 16; - stamp |= ((ulg)get_byte()) << 24; - - if ( stamp != 0 && !gz1->no_time ) - { - gz1->time_stamp = stamp; - } - - (void)get_byte(); - (void)get_byte(); - - if ((flags & CONTINUATION) != 0) - { - part = (unsigned) get_byte(); - part |= ((unsigned) get_byte())<<8; - } - - if ((flags & EXTRA_FIELD) != 0) - { - len = (unsigned) get_byte(); - len |= ((unsigned) get_byte())<<8; - - while (len--) (void)get_byte(); - } - - if ((flags & COMMENT) != 0) - { - while (get_char() != 0) ; - } - - if ( gz1->part_nb == 1 ) - { - gz1->header_bytes = gz1->inptr + 2*sizeof(long); - } - } - - return gz1->method; -} - -int fill_inbuf( PGZ1 gz1, int eof_ok ) -{ - int len; - int bytes_to_copy; - - gz1->insize = 0; - errno = 0; - - do { - if ( gz1->input_ismem ) - { - if ( gz1->input_bytesleft > 0 ) - { - bytes_to_copy = INBUFSIZ - gz1->insize; - - if ( bytes_to_copy > gz1->input_bytesleft ) - { - bytes_to_copy = gz1->input_bytesleft; - } - - memcpy( - (char*)gz1->inbuf+gz1->insize, - gz1->input_ptr, - bytes_to_copy - ); - - gz1->input_ptr += bytes_to_copy; - gz1->input_bytesleft -= bytes_to_copy; - - len = bytes_to_copy; - } - else - { - len = 0; - } - } - else - { - len = - read( - gz1->ifd, - (char*)gz1->inbuf+gz1->insize, - INBUFSIZ-gz1->insize - ); - } - - if (len == 0 || len == EOF) break; - - gz1->insize += len; - - } while( gz1->insize < INBUFSIZ ); - - if ( gz1->insize == 0 ) - { - if( eof_ok ) return EOF; - read_error( gz1 ); - } - - gz1->bytes_in += (ulg) gz1->insize; - gz1->inptr = 1; - - return gz1->inbuf[0]; -} - -ulg updcrc( -PGZ1 gz1, -uch *s, -unsigned n -) -{ - register ulg c; - - if ( s == NULL ) - { - c = 0xffffffffL; - } - else - { - c = gz1->crc; - - if ( n ) - { - do{ - c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); - - } while( --n ); - } - } - - gz1->crc = c; - - return( c ^ 0xffffffffL ); -} - -void read_error( PGZ1 gz1 ) -{ - gz1->abortflag = 1; -} - -void mod_gzip_strlwr( char *s ) -{ - char *p1=s; - - if ( s == 0 ) return; - - while ( *p1 != 0 ) - { - if ( *p1 > 96 ) *p1 = *p1 - 32; - p1++; - } -} - -#ifdef __BORLANDC__ -#pragma argsused -#endif - -char *gz1_basename( PGZ1 gz1, char *fname ) -{ - char *p; - - if ((p = strrchr(fname, PATH_SEP)) != NULL) fname = p+1; - - #ifdef PATH_SEP2 - if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1; - #endif - - #ifdef PATH_SEP3 - if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1; - #endif - - #ifdef SUFFIX_SEP - if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0'; - #endif - - if (casemap('A') == 'a') mod_gzip_strlwr(fname); - - return fname; -} - -void write_buf( PGZ1 gz1, int fd, voidp buf, unsigned cnt ) -{ - unsigned n; - - if ( gz1->output_ismem ) - { - if ( ( gz1->bytes_out + cnt ) < gz1->output_maxlen ) - { - memcpy( gz1->output_ptr, buf, cnt ); - gz1->output_ptr += cnt; - } - else - { - write_error( gz1 ); - } - } - else - { - while ((n = write(fd, buf, cnt)) != cnt) - { - if (n == (unsigned)(-1)) - { - write_error( gz1 ); - } - cnt -= n; - buf = (voidp)((char*)buf+n); - } - } -} - -void write_error( PGZ1 gz1 ) -{ - gz1->abortflag = 1; -} - -#ifdef __TURBOC__ -#ifndef BC55 - -static ush ptr_offset = 0; - -void * fcalloc( -unsigned items, -unsigned size -) -{ - void * buf = farmalloc((ulg)items*size + 16L); - - if (buf == NULL) return NULL; - - if (ptr_offset == 0) - { - ptr_offset = (ush)((uch*)buf-0); - } - else if (ptr_offset != (ush)((uch*)buf-0)) - { - error("inconsistent ptr_offset"); - } - - *((ush*)&buf+1) += (ptr_offset + 15) >> 4; - *(ush*)&buf = 0; - - return buf; -} - -void fcfree( void *ptr ) -{ - *((ush*)&ptr+1) -= (ptr_offset + 15) >> 4; - *(ush*)&ptr = ptr_offset; - - farfree(ptr); -} - -#endif -#endif - -int zip( -PGZ1 gz1, -int in, -int out -) -{ - uch flags = 0; - ush attr = 0; - ush deflate_flags = 0; - - gz1->ifd = in; - gz1->ofd = out; - gz1->outcnt = 0; - - gz1->method = DEFLATED; - - put_byte(GZIP_MAGIC[0]); - put_byte(GZIP_MAGIC[1]); - put_byte(DEFLATED); - - if ( gz1->save_orig_name ) - { - flags |= ORIG_NAME; - } - - put_byte(flags); - put_long(gz1->time_stamp); - - gz1->crc = -1; - - updcrc( gz1, NULL, 0 ); - - bi_init( gz1, out ); - ct_init( gz1, &attr, &gz1->method ); - lm_init( gz1, gz1->level, &deflate_flags ); - - put_byte((uch)deflate_flags); - - put_byte(OS_CODE); - - if ( gz1->save_orig_name ) - { - char *p = gz1_basename( gz1, gz1->ifname ); - - do { - put_char(*p); - - } while (*p++); - } - - gz1->header_bytes = (long)gz1->outcnt; - - (void) gz1_deflate( gz1 ); - - put_long( gz1->crc ); - put_long( gz1->bytes_in ); - - gz1->header_bytes += 2*sizeof(long); - - flush_outbuf( gz1 ); - - return OK; -} - -ulg gz1_deflate( PGZ1 gz1 ) -{ - unsigned hash_head; - unsigned prev_match; - int flush; - int match_available = 0; - register unsigned match_length = MIN_MATCH-1; -#ifdef DEBUG - long isize; -#endif - - if (gz1->compr_level <= 3) - { - return gz1_deflate_fast(gz1); - } - - while (gz1->lookahead != 0) - { - gz1->ins_h = - (((gz1->ins_h)<window[gz1->strstart+MIN_MATCH-1])) & HASH_MASK; - - prev[ gz1->strstart & WMASK ] = hash_head = head[ gz1->ins_h ]; - - head[ gz1->ins_h ] = gz1->strstart; - - gz1->prev_length = match_length, prev_match = gz1->match_start; - match_length = MIN_MATCH-1; - - if (hash_head != NIL && gz1->prev_length < gz1->max_lazy_match && - gz1->strstart - hash_head <= MAX_DIST) { - - match_length = longest_match( gz1, hash_head ); - - if (match_length > gz1->lookahead) match_length = gz1->lookahead; - - if (match_length == MIN_MATCH && gz1->strstart-gz1->match_start > TOO_FAR){ - - match_length--; - } - } - - if (gz1->prev_length >= MIN_MATCH && match_length <= gz1->prev_length) { - - flush = ct_tally(gz1,gz1->strstart-1-prev_match, gz1->prev_length - MIN_MATCH); - - gz1->lookahead -= ( gz1->prev_length - 1 ); - gz1->prev_length -= 2; - - do { - gz1->strstart++; - - gz1->ins_h = - (((gz1->ins_h)<window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK; - - prev[ gz1->strstart & WMASK ] = hash_head = head[gz1->ins_h]; - - head[ gz1->ins_h ] = gz1->strstart; - - } while (--gz1->prev_length != 0); - match_available = 0; - match_length = MIN_MATCH-1; - gz1->strstart++; - if (flush) FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; - - } else if (match_available) { - - if (ct_tally( gz1, 0, gz1->window[gz1->strstart-1] )) { - FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; - } - gz1->strstart++; - gz1->lookahead--; - } else { - - match_available = 1; - gz1->strstart++; - gz1->lookahead--; - } - - while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile) fill_window(gz1); - } - if (match_available) ct_tally( gz1, 0, gz1->window[gz1->strstart-1] ); - - return FLUSH_BLOCK(1); - - return 0; -} - -void flush_outbuf( PGZ1 gz1 ) -{ - if ( gz1->outcnt == 0 ) - { - return; - } - - write_buf( gz1, gz1->ofd, (char *)gz1->outbuf, gz1->outcnt ); - - gz1->bytes_out += (ulg)gz1->outcnt; - gz1->outcnt = 0; -} - -void lm_init( -PGZ1 gz1, -int pack_level, -ush *flags -) -{ - register unsigned j; - - if ( pack_level < 1 || pack_level > 9 ) - { - error("bad pack level"); - } - - gz1->compr_level = pack_level; - - #if defined(MAXSEG_64K) && HASH_BITS == 15 - for (j = 0; j < HASH_SIZE; j++) head[j] = NIL; - #else - memset( (char*)head, 0, (HASH_SIZE*sizeof(*head)) ); - #endif - - gz1->max_lazy_match = configuration_table[pack_level].max_lazy; - gz1->good_match = configuration_table[pack_level].good_length; - #ifndef FULL_SEARCH - gz1->nice_match = configuration_table[pack_level].nice_length; - #endif - gz1->max_chain_length = configuration_table[pack_level].max_chain; - - if ( pack_level == 1 ) - { - *flags |= FAST; - } - else if ( pack_level == 9 ) - { - *flags |= SLOW; - } - - gz1->strstart = 0; - gz1->block_start = 0L; - #ifdef ASMV - match_init(); - #endif - - gz1->lookahead = read_buf(gz1,(char*)gz1->window, - sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE); - - if (gz1->lookahead == 0 || gz1->lookahead == (unsigned)EOF) - { - gz1->eofile = 1, gz1->lookahead = 0; - return; - } - - gz1->eofile = 0; - - while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile) - { - fill_window(gz1); - } - - gz1->ins_h = 0; - - for ( j=0; jins_h = - (((gz1->ins_h)<window[j])) & HASH_MASK; - } -} - -void fill_window( PGZ1 gz1 ) -{ - register unsigned n, m; - - unsigned more = - (unsigned)( gz1->window_size - (ulg)gz1->lookahead - (ulg)gz1->strstart ); - - if ( more == (unsigned)EOF) - { - more--; - } - else if ( gz1->strstart >= WSIZE+MAX_DIST ) - { - memcpy((char*)gz1->window, (char*)gz1->window+WSIZE, (unsigned)WSIZE); - - gz1->match_start -= WSIZE; - gz1->strstart -= WSIZE; - - gz1->block_start -= (long) WSIZE; - - for ( n = 0; n < HASH_SIZE; n++ ) - { - m = head[n]; - head[n] = (ush)(m >= WSIZE ? m-WSIZE : NIL); - } - - for ( n = 0; n < WSIZE; n++ ) - { - m = prev[n]; - - prev[n] = (ush)(m >= WSIZE ? m-WSIZE : NIL); - } - - more += WSIZE; - } - - if ( !gz1->eofile ) - { - n = read_buf(gz1,(char*)gz1->window+gz1->strstart+gz1->lookahead, more); - - if ( n == 0 || n == (unsigned)EOF ) - { - gz1->eofile = 1; - } - else - { - gz1->lookahead += n; - } - } -} - -ulg gz1_deflate_fast( PGZ1 gz1 ) -{ - unsigned hash_head; - int flush; - unsigned match_length = 0; - - gz1->prev_length = MIN_MATCH-1; - - while (gz1->lookahead != 0) - { - gz1->ins_h = - (((gz1->ins_h)<window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK; - - prev[ gz1->strstart & WMASK ] = hash_head = head[ gz1->ins_h ]; - - head[ gz1->ins_h ] = gz1->strstart; - - if (hash_head != NIL && gz1->strstart - hash_head <= MAX_DIST) { - - match_length = longest_match( gz1, hash_head ); - - if (match_length > gz1->lookahead) match_length = gz1->lookahead; - } - if (match_length >= MIN_MATCH) { - - flush = ct_tally(gz1,gz1->strstart-gz1->match_start, match_length - MIN_MATCH); - - gz1->lookahead -= match_length; - - if (match_length <= gz1->max_lazy_match ) - { - match_length--; - - do { - gz1->strstart++; - - gz1->ins_h = - (((gz1->ins_h)<window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK; - - prev[ gz1->strstart & WMASK ] = hash_head = head[ gz1->ins_h ]; - - head[ gz1->ins_h ] = gz1->strstart; - - } while (--match_length != 0); - gz1->strstart++; - } else { - gz1->strstart += match_length; - match_length = 0; - gz1->ins_h = gz1->window[gz1->strstart]; - - gz1->ins_h = - (((gz1->ins_h)<window[gz1->strstart+1])) & HASH_MASK; - -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - } else { - - flush = ct_tally(gz1, 0, gz1->window[gz1->strstart]); - gz1->lookahead--; - gz1->strstart++; - } - if (flush) FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; - - while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile) fill_window(gz1); - } - - return FLUSH_BLOCK(1); -} - -void ct_init( -PGZ1 gz1, -ush *attr, -int *methodp -) -{ - #ifdef DD1 - int i,ii; - #endif - - int n; - int bits; - int length; - int code; - int dist; - - gz1->file_type = attr; - gz1->file_method = methodp; - gz1->compressed_len = gz1->input_len = 0L; - - if ( gz1->static_dtree[0].dl.len != 0 ) - { - return; - } - - length = 0; - - for ( code = 0; code < LENGTH_CODES-1; code++ ) - { - gz1->base_length[code] = length; - - for ( n = 0; n < (1<length_code[length++] = (uch)code; - } - } - - gz1->length_code[length-1] = (uch)code; - - dist = 0; - - for ( code = 0 ; code < 16; code++ ) - { - gz1->base_dist[code] = dist; - - for ( n = 0; n < (1<dist_code[dist++] = (uch)code; - } - } - - dist >>= 7; - - for ( ; code < D_CODES; code++ ) - { - gz1->base_dist[code] = dist << 7; - - for ( n = 0; n < (1<<(extra_dbits[code]-7)); n++ ) - { - gz1->dist_code[256 + dist++] = (uch)code; - } - } - - for ( bits = 0; bits <= MAX_BITS; bits++ ) - { - gz1->bl_count[bits] = 0; - } - - n = 0; - - while (n <= 143) gz1->static_ltree[n++].dl.len = 8, gz1->bl_count[8]++; - while (n <= 255) gz1->static_ltree[n++].dl.len = 9, gz1->bl_count[9]++; - while (n <= 279) gz1->static_ltree[n++].dl.len = 7, gz1->bl_count[7]++; - while (n <= 287) gz1->static_ltree[n++].dl.len = 8, gz1->bl_count[8]++; - - gen_codes(gz1,(ct_data *)gz1->static_ltree, L_CODES+1); - - for ( n = 0; n < D_CODES; n++ ) - { - gz1->static_dtree[n].dl.len = 5; - gz1->static_dtree[n].fc.code = bi_reverse( gz1, n, 5 ); - } - - init_block( gz1 ); -} - -ulg flush_block( -PGZ1 gz1, -char *buf, -ulg stored_len, -int eof -) -{ - ulg opt_lenb; - ulg static_lenb; - int max_blindex; - - gz1->flag_buf[gz1->last_flags] = gz1->flags; - - if (*gz1->file_type == (ush)UNKNOWN) set_file_type(gz1); - - build_tree( gz1, (tree_desc *)(&gz1->l_desc) ); - build_tree( gz1, (tree_desc *)(&gz1->d_desc) ); - - max_blindex = build_bl_tree( gz1 ); - - opt_lenb = (gz1->opt_len+3+7)>>3; - static_lenb = (gz1->static_len+3+7)>>3; - gz1->input_len += stored_len; - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - -#ifdef FORCE_METHOD - - if ( level == 1 && eof && gz1->compressed_len == 0L ) -#else - if (stored_len <= opt_lenb && eof && gz1->compressed_len == 0L && 0 ) -#endif - { - if (buf == (char*)0) error ("block vanished"); - - copy_block( gz1, buf, (unsigned)stored_len, 0 ); - - gz1->compressed_len = stored_len << 3; - *gz1->file_method = STORED; - -#ifdef FORCE_METHOD - } else if (level == 2 && buf != (char*)0) { -#else - } else if (stored_len+4 <= opt_lenb && buf != (char*)0) { - -#endif - - send_bits(gz1,(STORED_BLOCK<<1)+eof, 3); - gz1->compressed_len = (gz1->compressed_len + 3 + 7) & ~7L; - gz1->compressed_len += (stored_len + 4) << 3; - - copy_block(gz1, buf, (unsigned)stored_len, 1); - -#ifdef FORCE_METHOD - } else if (level == 3) { -#else - } else if (static_lenb == opt_lenb) { -#endif - send_bits(gz1,(STATIC_TREES<<1)+eof, 3); - - compress_block( - gz1, - (ct_data *)gz1->static_ltree, - (ct_data *)gz1->static_dtree - ); - - gz1->compressed_len += 3 + gz1->static_len; - } - else - { - send_bits(gz1,(DYN_TREES<<1)+eof, 3); - - send_all_trees( - gz1, - gz1->l_desc.max_code+1, - gz1->d_desc.max_code+1, - max_blindex+1 - ); - - compress_block( - gz1, - (ct_data *)gz1->dyn_ltree, - (ct_data *)gz1->dyn_dtree - ); - - gz1->compressed_len += 3 + gz1->opt_len; - } - - init_block( gz1 ); - - if ( eof ) - { - bi_windup( gz1 ); - - gz1->compressed_len += 7; - } - - return gz1->compressed_len >> 3; -} - -#ifdef __BORLANDC__ -#pragma argsused -#endif - -unsigned bi_reverse( -PGZ1 gz1, -unsigned code, -int len -) -{ - register unsigned res = 0; - - do { - res |= code & 1; - code >>= 1, res <<= 1; - - } while (--len > 0); - - return res >> 1; -} - -void set_file_type( PGZ1 gz1 ) -{ - int n = 0; - unsigned ascii_freq = 0; - unsigned bin_freq = 0; - - while (n < 7) bin_freq += gz1->dyn_ltree[n++].fc.freq; - while (n < 128) ascii_freq += gz1->dyn_ltree[n++].fc.freq; - while (n < LITERALS) bin_freq += gz1->dyn_ltree[n++].fc.freq; - - *gz1->file_type = bin_freq > (ascii_freq >> 2) ? BINARY : ASCII; -} - -void init_block( PGZ1 gz1 ) -{ - int n; - - for (n = 0; n < L_CODES; n++) gz1->dyn_ltree[n].fc.freq = 0; - for (n = 0; n < D_CODES; n++) gz1->dyn_dtree[n].fc.freq = 0; - for (n = 0; n < BL_CODES; n++) gz1->bl_tree[n].fc.freq = 0; - - gz1->dyn_ltree[END_BLOCK].fc.freq = 1; - - gz1->opt_len = 0L; - gz1->static_len = 0L; - gz1->last_lit = 0; - gz1->last_dist = 0; - gz1->last_flags = 0; - gz1->flags = 0; - gz1->flag_bit = 1; -} - -void bi_init( PGZ1 gz1, gz1_file_t zipfile ) -{ - gz1->zfile = zipfile; - gz1->bi_buf = 0; - gz1->bi_valid = 0; - - if ( gz1->zfile != NO_FILE ) - { - read_buf = file_read; - } -} - -int ct_tally( -PGZ1 gz1, -int dist, -int lc -) -{ - int dcode; - - gz1->inbuf[gz1->last_lit++] = (uch)lc; - - if ( dist == 0 ) - { - gz1->dyn_ltree[lc].fc.freq++; - } - else - { - dist--; - - gz1->dyn_ltree[gz1->length_code[lc]+LITERALS+1].fc.freq++; - gz1->dyn_dtree[d_code(dist)].fc.freq++; - gz1->d_buf[gz1->last_dist++] = (ush)dist; - gz1->flags |= gz1->flag_bit; - } - - gz1->flag_bit <<= 1; - - if ( (gz1->last_lit & 7) == 0 ) - { - gz1->flag_buf[gz1->last_flags++] = gz1->flags; - gz1->flags = 0, gz1->flag_bit = 1; - } - - if ( gz1->level > 2 && (gz1->last_lit & 0xfff) == 0) - { - ulg out_length = (ulg) ( gz1->last_lit * 8L ); - ulg in_length = (ulg) ( gz1->strstart - gz1->block_start ); - - for ( dcode = 0; dcode < D_CODES; dcode++ ) - { - out_length += (ulg) ((gz1->dyn_dtree[dcode].fc.freq)*(5L+extra_dbits[dcode])); - } - - out_length >>= 3; - - if ( gz1->last_dist < gz1->last_lit/2 && out_length < in_length/2 ) - { - return 1; - } - } - - return( gz1->last_lit == LIT_BUFSIZE-1 || gz1->last_dist == DIST_BUFSIZE ); -} - -void compress_block( -PGZ1 gz1, -ct_data *ltree, -ct_data *dtree -) -{ - unsigned dist; - int lc; - unsigned lx = 0; - unsigned dx = 0; - unsigned fx = 0; - uch flag = 0; - unsigned code; - int extra; - - if (gz1->last_lit != 0) do { - if ((lx & 7) == 0) flag = gz1->flag_buf[fx++]; - lc = gz1->inbuf[lx++]; - if ((flag & 1) == 0) { - send_code(lc, ltree); - } else { - - code = gz1->length_code[lc]; - send_code(code+LITERALS+1, ltree); - extra = extra_lbits[code]; - if (extra != 0) { - lc -= gz1->base_length[code]; - send_bits(gz1,lc, extra); - } - dist = gz1->d_buf[dx++]; - - code = d_code(dist); - - send_code(code, dtree); - extra = extra_dbits[code]; - if (extra != 0) { - dist -= gz1->base_dist[code]; - send_bits(gz1,dist, extra); - } - } - flag >>= 1; - } while (lx < gz1->last_lit); - - send_code(END_BLOCK, ltree); -} - -#ifndef ASMV - -int longest_match( PGZ1 gz1, unsigned cur_match ) -{ - unsigned chain_length = gz1->max_chain_length; - register uch *scan = gz1->window + gz1->strstart; - register uch *match; - register int len; - int best_len = gz1->prev_length; - unsigned limit = gz1->strstart > (unsigned)MAX_DIST ? gz1->strstart - (unsigned)MAX_DIST : NIL; - -#if HASH_BITS < 8 || MAX_MATCH != 258 - error: Code too clever -#endif - -#ifdef UNALIGNED_OK - - register uch *strend = gz1->window + gz1->strstart + MAX_MATCH - 1; - register ush scan_start = *(ush*)scan; - register ush scan_end = *(ush*)(scan+best_len-1); -#else - register uch *strend = gz1->window + gz1->strstart + MAX_MATCH; - register uch scan_end1 = scan[best_len-1]; - register uch scan_end = scan[best_len]; -#endif - - if (gz1->prev_length >= gz1->good_match) { - chain_length >>= 2; - } - - do { - match = gz1->window + cur_match; - -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - - if (*(ush*)(match+best_len-1) != scan_end || - *(ush*)match != scan_start) continue; - - scan++, match++; - do { - } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && - *(ush*)(scan+=2) == *(ush*)(match+=2) && - *(ush*)(scan+=2) == *(ush*)(match+=2) && - *(ush*)(scan+=2) == *(ush*)(match+=2) && - scan < strend); - - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); -#else - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - scan += 2, match++; - - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; -#endif - if (len > best_len) { - gz1->match_start = cur_match; - best_len = len; - if (len >= gz1->nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ush*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & WMASK]) > limit - && --chain_length != 0); - - return best_len; -} -#endif - -void send_bits( -PGZ1 gz1, -int value, -int length -) -{ - if ( gz1->bi_valid > (int) BUFSIZE - length ) - { - gz1->bi_buf |= (value << gz1->bi_valid); - - put_short(gz1->bi_buf); - - gz1->bi_buf = (ush)value >> (BUFSIZE - gz1->bi_valid); - gz1->bi_valid += length - BUFSIZE; - } - else - { - gz1->bi_buf |= value << gz1->bi_valid; - gz1->bi_valid += length; - } -} - -void build_tree( -PGZ1 gz1, -tree_desc *desc -) -{ - int elems = desc->elems; - ct_data *tree = desc->dyn_tree; - ct_data *stree = desc->static_tree; - - int n; - int m; - int max_code = -1; - int node = elems; - int new1; - - gz1->heap_len = 0, gz1->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].fc.freq != 0) { - gz1->heap[++gz1->heap_len] = max_code = n; - gz1->depth[n] = 0; - } else { - tree[n].dl.len = 0; - } - } - - while (gz1->heap_len < 2) { - new1 = gz1->heap[++gz1->heap_len] = (max_code < 2 ? ++max_code : 0); - tree[new1].fc.freq = 1; - gz1->depth[new1] = 0; - gz1->opt_len--; if (stree) gz1->static_len -= stree[new1].dl.len; - } - desc->max_code = max_code; - - for (n = gz1->heap_len/2; n >= 1; n--) pqdownheap(gz1, tree, n); - - do { - n = gz1->heap[SMALLEST]; - gz1->heap[SMALLEST] = gz1->heap[gz1->heap_len--]; - pqdownheap(gz1, tree, SMALLEST); - m = gz1->heap[SMALLEST]; - gz1->heap[--gz1->heap_max] = n; - gz1->heap[--gz1->heap_max] = m; - tree[node].fc.freq = tree[n].fc.freq + tree[m].fc.freq; - gz1->depth[node] = (uch) (GZ1_MAX(gz1->depth[n], gz1->depth[m]) + 1); - tree[n].dl.dad = tree[m].dl.dad = (ush)node; - gz1->heap[SMALLEST] = node++; - pqdownheap(gz1, tree, SMALLEST); - - } while (gz1->heap_len >= 2); - - gz1->heap[--gz1->heap_max] = gz1->heap[SMALLEST]; - - gen_bitlen(gz1,(tree_desc *)desc); - - gen_codes(gz1,(ct_data *)tree, max_code); -} - -int build_bl_tree( PGZ1 gz1 ) -{ - int max_blindex; - - scan_tree( gz1, (ct_data *)gz1->dyn_ltree, gz1->l_desc.max_code ); - scan_tree( gz1, (ct_data *)gz1->dyn_dtree, gz1->d_desc.max_code ); - - build_tree( gz1, (tree_desc *)(&gz1->bl_desc) ); - - for ( max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex-- ) - { - if (gz1->bl_tree[bl_order[max_blindex]].dl.len != 0) break; - } - - gz1->opt_len += 3*(max_blindex+1) + 5+5+4; - - return max_blindex; -} - -void gen_codes( -PGZ1 gz1, -ct_data *tree, -int max_code -) -{ - ush next_code[MAX_BITS+1]; - ush code = 0; - int bits; - int n; - - for ( bits = 1; bits <= MAX_BITS; bits++ ) - { - next_code[bits] = code = (code + gz1->bl_count[bits-1]) << 1; - } - - for ( n = 0; n <= max_code; n++ ) - { - int len = tree[n].dl.len; - if (len == 0) continue; - - tree[n].fc.code = bi_reverse( gz1, next_code[len]++, len ); - } - - return; -} - -void gen_bitlen( -PGZ1 gz1, -tree_desc *desc -) -{ - ct_data *tree = desc->dyn_tree; - int *extra = desc->extra_bits; - int base = desc->extra_base; - int max_code = desc->max_code; - int max_length = desc->max_length; - ct_data *stree = desc->static_tree; - int h; - int n, m; - int bits; - int xbits; - ush f; - int overflow = 0; - - for (bits = 0; bits <= MAX_BITS; bits++) gz1->bl_count[bits] = 0; - - tree[gz1->heap[gz1->heap_max]].dl.len = 0; - - for (h = gz1->heap_max+1; h < HEAP_SIZE; h++) { - n = gz1->heap[h]; - bits = tree[tree[n].dl.dad].dl.len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].dl.len = (ush)bits; - - if (n > max_code) continue; - - gz1->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].fc.freq; - gz1->opt_len += (ulg)f * (bits + xbits); - if (stree) gz1->static_len += (ulg)f * (stree[n].dl.len + xbits); - } - if (overflow == 0) return; - - do { - bits = max_length-1; - while (gz1->bl_count[bits] == 0) bits--; - gz1->bl_count[bits]--; - gz1->bl_count[bits+1] += 2; - gz1->bl_count[max_length]--; - - overflow -= 2; - } while (overflow > 0); - - for (bits = max_length; bits != 0; bits--) { - n = gz1->bl_count[bits]; - while (n != 0) { - m = gz1->heap[--h]; - if (m > max_code) continue; - if (tree[m].dl.len != (unsigned) bits) { - gz1->opt_len += ((long)bits-(long)tree[m].dl.len)*(long)tree[m].fc.freq; - tree[m].dl.len = (ush)bits; - } - n--; - } - } -} - -void copy_block( -PGZ1 gz1, -char *buf, -unsigned len, -int header -) -{ - #ifdef CRYPT - int t; - #endif - - bi_windup( gz1 ); - - if ( header ) - { - put_short((ush)len); - put_short((ush)~len); - } - - while( len-- ) - { - #ifdef CRYPT - if (key) zencode(*buf, t); - #endif - - put_byte(*buf++); - } -} - -int file_read( PGZ1 gz1, char *buf, unsigned size ) -{ - unsigned len = 0; - unsigned bytes_to_copy = 0; - - if ( gz1->input_ismem ) - { - if ( gz1->input_bytesleft > 0 ) - { - bytes_to_copy = size; - - if ( bytes_to_copy > (unsigned) gz1->input_bytesleft ) - { - bytes_to_copy = (unsigned) gz1->input_bytesleft; - } - - memcpy( buf, gz1->input_ptr, bytes_to_copy ); - - gz1->input_ptr += bytes_to_copy; - gz1->input_bytesleft -= bytes_to_copy; - - len = bytes_to_copy; - } - else - { - len = 0; - } - } - else - { - len = read( gz1->ifd, buf, size ); - } - - if ( len == (unsigned)(-1) || len == 0 ) - { - gz1->crc = gz1->crc ^ 0xffffffffL; - /* XXX - Do we need to do something with Adler CRC's here? - * I don't think so--they don't seem to need postprocessing. */ - return (int)len; - } - - if (gz1->compression_format != DEFLATE_FORMAT) - { - updcrc( gz1, (uch*)buf, len ); - } - else - { - gz1->adler = adler32(gz1->adler, (uch*)buf, len); - } - - gz1->bytes_in += (ulg)len; - - return (int)len; -} - -void bi_windup( PGZ1 gz1 ) -{ - if ( gz1->bi_valid > 8 ) - { - put_short(gz1->bi_buf); - } - else if ( gz1->bi_valid > 0 ) - { - put_byte(gz1->bi_buf); - } - - gz1->bi_buf = 0; - gz1->bi_valid = 0; -} - -void send_all_trees( -PGZ1 gz1, -int lcodes, -int dcodes, -int blcodes -) -{ - int rank; - - send_bits(gz1,lcodes-257, 5); - send_bits(gz1,dcodes-1, 5); - send_bits(gz1,blcodes-4, 4); - - for ( rank = 0; rank < blcodes; rank++ ) - { - send_bits(gz1,gz1->bl_tree[bl_order[rank]].dl.len, 3 ); - } - - send_tree(gz1,(ct_data *)gz1->dyn_ltree, lcodes-1); - send_tree(gz1,(ct_data *)gz1->dyn_dtree, dcodes-1); -} - -void send_tree( -PGZ1 gz1, -ct_data *tree, -int max_code -) -{ - int n; - int prevlen = -1; - int curlen; - int nextlen = tree[0].dl.len; - int count = 0; - int max_count = 7; - int min_count = 4; - - if (nextlen == 0) max_count = 138, min_count = 3; - - for ( n = 0; n <= max_code; n++ ) - { - curlen = nextlen; - nextlen = tree[n+1].dl.len; - - if (++count < max_count && curlen == nextlen) - { - continue; - } - else if (count < min_count) - { - do { send_code(curlen, gz1->bl_tree); } while (--count != 0); - } - else if (curlen != 0) - { - if ( curlen != prevlen ) - { - send_code(curlen, gz1->bl_tree); count--; - } - - send_code( REP_3_6, gz1->bl_tree ); send_bits(gz1,count-3, 2); - } - else if (count <= 10) - { - send_code(REPZ_3_10, gz1->bl_tree); send_bits(gz1,count-3, 3); - } - else - { - send_code(REPZ_11_138, gz1->bl_tree); send_bits(gz1,count-11, 7); - } - - count = 0; - prevlen = curlen; - - if (nextlen == 0) - { - max_count = 138, min_count = 3; - } - else if (curlen == nextlen) - { - max_count = 6, min_count = 3; - } - else - { - max_count = 7, min_count = 4; - } - } -} - -void scan_tree( -PGZ1 gz1, -ct_data *tree, -int max_code -) -{ - int n; - int prevlen = -1; - int curlen; - int nextlen = tree[0].dl.len; - int count = 0; - int max_count = 7; - int min_count = 4; - - if (nextlen == 0) max_count = 138, min_count = 3; - - tree[max_code+1].dl.len = (ush)0xffff; - - for ( n = 0; n <= max_code; n++ ) - { - curlen = nextlen; - nextlen = tree[n+1].dl.len; - - if ( ++count < max_count && curlen == nextlen ) - { - continue; - } - else if ( count < min_count ) - { - gz1->bl_tree[curlen].fc.freq += count; - } - else if ( curlen != 0 ) - { - if ( curlen != prevlen ) gz1->bl_tree[curlen].fc.freq++; - gz1->bl_tree[REP_3_6].fc.freq++; - } - else if ( count <= 10 ) - { - gz1->bl_tree[REPZ_3_10].fc.freq++; - } - else - { - gz1->bl_tree[REPZ_11_138].fc.freq++; - } - - count = 0; - prevlen = curlen; - - if ( nextlen == 0 ) - { - max_count = 138; - min_count = 3; - } - else if (curlen == nextlen) - { - max_count = 6; - min_count = 3; - } - else - { - max_count = 7; - min_count = 4; - } - } -} - -void pqdownheap( -PGZ1 gz1, -ct_data *tree, -int k -) -{ - int v = gz1->heap[k]; - int j = k << 1; - - while( j <= gz1->heap_len ) - { - if (j < gz1->heap_len && smaller(tree, gz1->heap[j+1], gz1->heap[j])) j++; - - if (smaller(tree, v, gz1->heap[j])) break; - - gz1->heap[k] = gz1->heap[j]; k = j; - - j <<= 1; - } - - gz1->heap[k] = v; -} - - -#define GZS_ZIP1 1 -#define GZS_ZIP2 2 -#define GZS_DEFLATE1 3 -#define GZS_DEFLATE2 4 - -int gzs_fsp ( PGZ1 gz1 ); -int gzs_zip1 ( PGZ1 gz1 ); -int gzs_zip2 ( PGZ1 gz1 ); -int gzs_deflate1( PGZ1 gz1 ); -int gzs_deflate2( PGZ1 gz1 ); - -int gzp_main( GZP_CONTROL *gzp ) -{ - PGZ1 gz1 = 0; - int rc = 0; - int final_exit_code = 0; - int ofile_flags = O_RDWR | O_CREAT | O_TRUNC | O_BINARY; - - gzp->result_code = 0; - gzp->bytes_out = 0; - - gz1 = (PGZ1) gz1_init(); - - if ( gz1 == 0 ) - { - return 0; - } - - gz1->decompress = gzp->decompress; - gz1->compression_format = gzp->compression_format; - - strcpy( gz1->ifname, gzp->input_filename ); - strcpy( gz1->ofname, gzp->output_filename ); - - gz1->input_ismem = gzp->input_ismem; - gz1->input_ptr = gzp->input_ismem_ibuf; - gz1->input_bytesleft = gzp->input_ismem_ibuflen; - - gz1->output_ismem = gzp->output_ismem; - gz1->output_ptr = gzp->output_ismem_obuf; - gz1->output_maxlen = gzp->output_ismem_obuflen; - - if ( gz1->no_time < 0 ) gz1->no_time = gz1->decompress; - if ( gz1->no_name < 0 ) gz1->no_name = gz1->decompress; - - work = zip; - - if ( !gz1->input_ismem ) - { - errno = 0; - - rc = stat( gz1->ifname, &gz1->istat ); - - if ( rc != 0 ) - { - gz1_cleanup( gz1 ); - - return 0; - } - - gz1->ifile_size = gz1->istat.st_size; - - gz1->ifd = - OPEN( - gz1->ifname, - gz1->ascii && !gz1->decompress ? O_RDONLY : O_RDONLY | O_BINARY, - RW_USER - ); - - if ( gz1->ifd == -1 ) - { - gz1_cleanup( gz1 ); - - return 0; - } - } - - if ( !gz1->output_ismem ) - { - if ( gz1->ascii && gz1->decompress ) - { - ofile_flags &= ~O_BINARY; - } - - gz1->ofd = OPEN( gz1->ofname, ofile_flags, RW_USER ); - - if ( gz1->ofd == -1 ) - { - if ( gz1->ifd ) - { - close( gz1->ifd ); - gz1->ifd = 0; - } - - gz1_cleanup( gz1 ); - - return 0; - } - } - - gz1->outcnt = 0; - gz1->insize = 0; - gz1->inptr = 0; - gz1->bytes_in = 0L; - gz1->bytes_out = 0L; - gz1->part_nb = 0; - - if ( gz1->decompress ) - { - gz1->method = get_header( gz1, gz1->ifd ); - - if ( gz1->method < 0 ) - { - if ( gz1->ifd ) - { - close( gz1->ifd ); - gz1->ifd = 0; - } - - if ( gz1->ofd ) - { - close( gz1->ofd ); - gz1->ofd = 0; - } - - return 0; - } - } - - gz1->save_orig_name = 0; - - gz1->state = GZS_ZIP1; - - for (;;) - { - gzs_fsp( gz1 ); - - if ( gz1->done == 1 ) break; - } - - if ( gz1->ifd ) - { - close( gz1->ifd ); - gz1->ifd = 0; - } - - if ( gz1->ofd ) - { - close( gz1->ofd ); - gz1->ofd = 0; - } - - gzp->result_code = gz1->exit_code; - gzp->bytes_out = gz1->bytes_out; - - final_exit_code = (int) gz1->exit_code; - - gz1_cleanup( gz1 ); - - return final_exit_code; -} - -int gzs_fsp( PGZ1 gz1 ) -{ - int rc=0; - - switch( gz1->state ) - { - case GZS_ZIP1: - - rc = gzs_zip1( gz1 ); - - break; - - case GZS_ZIP2: - - rc = gzs_zip2( gz1 ); - - break; - - case GZS_DEFLATE1: - - rc = gzs_deflate1( gz1 ); - - break; - - case GZS_DEFLATE2: - - rc = gzs_deflate2( gz1 ); - - break; - - default: - - gz1->done = 1; - - break; - } - - return( rc ); -} - - -int gzs_zip1( PGZ1 gz1 ) -{ - uch flags = 0; - ush attr = 0; - ush deflate_flags = 0; - - gz1->outcnt = 0; - - gz1->method = DEFLATED; - - if (gz1->compression_format != DEFLATE_FORMAT) - { - put_byte(GZIP_MAGIC[0]); - put_byte(GZIP_MAGIC[1]); - put_byte(DEFLATED); - } - else - { - /* Yes, I know RFC 1951 doesn't mention any header at the start of - * a deflated document, but zlib absolutely requires one. And since nearly - * all "deflate" implementations use zlib, we need to play along with this - * brain damage. */ - put_byte(ZLIB_HEADER[0]); - put_byte(ZLIB_HEADER[1]); - } - - if ( gz1->save_orig_name ) - { - flags |= ORIG_NAME; - } - - if (gz1->compression_format != DEFLATE_FORMAT) - { - put_byte(flags); - put_long(gz1->time_stamp); - - gz1->crc = -1; - updcrc( gz1, NULL, 0 ); - } - else - { - /* Deflate compression uses an Adler32 CRC, not a CRC32. */ - gz1->adler = 1L; - } - - gz1->state = GZS_ZIP2; - - return 0; -} - -int gzs_zip2( PGZ1 gz1 ) -{ - uch flags = 0; - ush attr = 0; - ush deflate_flags = 0; - - bi_init( gz1, gz1->ofd ); - ct_init( gz1, &attr, &gz1->method ); - lm_init( gz1, gz1->level, &deflate_flags ); - - if (gz1->compression_format != DEFLATE_FORMAT) - { - put_byte((uch)deflate_flags); - put_byte(OS_CODE); - if ( gz1->save_orig_name ) - { - char *p = gz1_basename( gz1, gz1->ifname ); - - do { - put_char(*p); - - } while (*p++); - } - } - - gz1->header_bytes = (long)gz1->outcnt; - - gz1->state = GZS_DEFLATE1; - - return 0; -} - -int gzs_deflate1( PGZ1 gz1 ) -{ - if ( !gz1->deflate1_initialized ) - { - gz1->deflate1_match_available = 0; - gz1->deflate1_match_length = MIN_MATCH-1; - gz1->deflate1_initialized = 1; - } - - if ( gz1->compr_level <= 3 ) - { - gz1->done = 1; - - return 0; - } - - if ( gz1->lookahead == 0 ) - { - if ( gz1->deflate1_match_available ) - { - ct_tally( gz1, 0, gz1->window[gz1->strstart-1] ); - } - - gz1->state = GZS_DEFLATE2; - - return (int) FLUSH_BLOCK(1); - } - - #ifdef STAY_HERE_FOR_A_CERTAIN_AMOUNT_OF_ITERATIONS - - while( iterations < max_iterations_per_yield ) - { - #endif - - gz1->ins_h = - (((gz1->ins_h)<window[gz1->strstart+MIN_MATCH-1])) & HASH_MASK; - - prev[ gz1->strstart & WMASK ] = gz1->deflate1_hash_head = head[ gz1->ins_h ]; - - head[ gz1->ins_h ] = gz1->strstart; - - gz1->prev_length = gz1->deflate1_match_length, gz1->deflate1_prev_match = gz1->match_start; - gz1->deflate1_match_length = MIN_MATCH-1; - - if ( gz1->deflate1_hash_head != NIL && gz1->prev_length < gz1->max_lazy_match && - gz1->strstart - gz1->deflate1_hash_head <= MAX_DIST) - { - gz1->deflate1_match_length = longest_match( gz1, gz1->deflate1_hash_head ); - - if ( gz1->deflate1_match_length > gz1->lookahead ) - { - gz1->deflate1_match_length = gz1->lookahead; - } - - if (gz1->deflate1_match_length == MIN_MATCH && gz1->strstart-gz1->match_start > TOO_FAR) - { - gz1->deflate1_match_length--; - } - } - - if ( gz1->prev_length >= MIN_MATCH && gz1->deflate1_match_length <= gz1->prev_length ) - { - gz1->deflate1_flush = - ct_tally(gz1,gz1->strstart-1-gz1->deflate1_prev_match, gz1->prev_length - MIN_MATCH); - - gz1->lookahead -= ( gz1->prev_length - 1 ); - gz1->prev_length -= 2; - - do { - gz1->strstart++; - - gz1->ins_h = - (((gz1->ins_h)<window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK; - - prev[ gz1->strstart & WMASK ] = gz1->deflate1_hash_head = head[gz1->ins_h]; - - head[ gz1->ins_h ] = gz1->strstart; - - } while (--gz1->prev_length != 0); - - gz1->deflate1_match_available = 0; - gz1->deflate1_match_length = MIN_MATCH-1; - - gz1->strstart++; - - if (gz1->deflate1_flush) FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; - } - - else - { - if ( gz1->deflate1_match_available ) - { - if ( ct_tally( gz1, 0, gz1->window[gz1->strstart-1] ) ) - { - FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; - } - - gz1->strstart++; - gz1->lookahead--; - } - else - { - gz1->deflate1_match_available = 1; - gz1->strstart++; - gz1->lookahead--; - } - - while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile ) - { - fill_window(gz1); - } - } - - return 0; -} - -int gzs_deflate2( PGZ1 gz1 ) -{ - #if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO) - if (gz1->ifile_size != -1L && gz1->isize != (ulg)gz1->ifile_size) - { - } - #endif - - if (gz1->compression_format != DEFLATE_FORMAT) - { - put_long( gz1->crc ); - put_long( gz1->bytes_in ); - gz1->header_bytes += 2*sizeof(long); - } - else - { - /* Append an Adler32 CRC to our deflated data. - * Yes, I know RFC 1951 doesn't mention any CRC at the end of a - * deflated document, but zlib absolutely requires one. And since nearly - * all "deflate" implementations use zlib, we need to play along with this - * brain damage. */ - put_byte( (gz1->adler >> 24) ); - put_byte( (gz1->adler >> 16) & 0xFF ); - put_byte( (gz1->adler >> 8) & 0xFF ); - put_byte( (gz1->adler ) & 0xFF ); - gz1->header_bytes += 4*sizeof(uch); - } - - flush_outbuf( gz1 ); - - gz1->done = 1; - - return OK; -} - - -/* ========================================================================= - adler32 -- compute the Adler-32 checksum of a data stream - Copyright (C) 1995-1998 Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Modified by Eric Kidd to play nicely with mod_gzip. - */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -ulg adler32(ulg adler, uch *buf, unsigned len) -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - buf += 16; - k -= 16; - } - if (k != 0) do { - s1 += *buf++; - s2 += s1; - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} - - -/* END OF FILE */ - - diff --git a/trunk/tools/turbocharger/mod_gzip.c.diff b/trunk/tools/turbocharger/mod_gzip.c.diff deleted file mode 100644 index a2c500063..000000000 --- a/trunk/tools/turbocharger/mod_gzip.c.diff +++ /dev/null @@ -1,365 +0,0 @@ ---- mod_gzip.c-old Fri Jan 26 10:50:05 2001 -+++ mod_gzip.c Fri Jan 26 15:08:26 2001 -@@ -575,10 +575,15 @@ - * The GZP request control structure... - */ - -+#define GZIP_FORMAT (0) -+#define DEFLATE_FORMAT (1) -+ - typedef struct _GZP_CONTROL { - - int decompress; /* 0=Compress 1=Decompress */ - -+ int compression_format; /* GZIP_FORMAT or DEFLATE_FORMAT */ -+ - /* Input control... */ - - int input_ismem; /* Input source is memory buffer, not file */ -@@ -2209,10 +2214,11 @@ - mod_gzip_printf( "%s: Checking for 'gzip' designator...\n",cn); - #endif - -- if ( strstr( has_encoding, "gzip" ) ) -+ if ( strstr( has_encoding, "gzip" ) || -+ strstr( has_encoding, "deflate" ) ) - { - #ifdef MOD_GZIP_DEBUG1 -- mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' designator...\n",cn); -+ mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' or 'deflate' designator...\n",cn); - mod_gzip_printf( "%s: Pre-compression is assumed.\n",cn); - mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); - #endif -@@ -2237,7 +2243,7 @@ - else /* 'gzip' designator not found... */ - { - #ifdef MOD_GZIP_DEBUG1 -- mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' designator...\n",cn); -+ mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' or 'deflate' designator...\n",cn); - mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); - #endif - } -@@ -2347,10 +2353,21 @@ - if ( accept_encoding ) - { - /* ...and if it has the right 'gzip' indicator... */ -- -+ /* We record the compression format in a request note, so we -+ * can get it again later, and so it can potentially be logged. -+ */ - if ( strstr( accept_encoding, "gzip" ) ) - { - process = 1; /* ...set the 'process' flag TRUE */ -+ ap_table_setn( r->notes,"mod_gzip_compression_format", -+ ap_pstrdup(r->pool,"gzip")); -+ -+ } -+ else if ( strstr( accept_encoding, "deflate" ) ) -+ { -+ process = 1; /* ...set the 'process' flag TRUE */ -+ ap_table_setn( r->notes,"mod_gzip_compression_format", -+ ap_pstrdup(r->pool,"deflate")); - } - - }/* End 'if( accept_encoding )' */ -@@ -2388,7 +2405,7 @@ - else /* 'gzip' designator was seen in 'Accept-Encoding:' field */ - { - #ifdef MOD_GZIP_DEBUG1 -- mod_gzip_printf( "%s: 'gzip' capability specified by user-agent.\n",cn); -+ mod_gzip_printf( "%s: 'gzip' or 'deflate' capability specified by user-agent.\n",cn); - mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); - #endif - } -@@ -4093,7 +4110,8 @@ - - char tmp[ MOD_GZIP_LARGE_BUFFER_SIZE + 2 ]; /* Scratch buffer */ - -- char actual_content_encoding_name[] = "gzip"; /* Adjustable */ -+ char *actual_content_encoding_name = "gzip"; /* Adjustable */ -+ const char *compression_format; - - #ifdef MOD_GZIP_DEBUG1 - char cn[]="mod_gzip_encode_and_transmit()"; -@@ -4470,6 +4488,18 @@ - - gzp->decompress = 0; /* Perform encoding */ - -+ /* Recover the compression format we're supposed to use. */ -+ compression_format = ap_table_get(r->notes, "mod_gzip_compression_format"); -+ if (compression_format && strcmp(compression_format, "deflate") == 0) -+ { -+ actual_content_encoding_name = "deflate"; -+ gzp->compression_format = DEFLATE_FORMAT; -+ } -+ else -+ { -+ gzp->compression_format = GZIP_FORMAT; -+ } -+ - if ( input_size <= (long) conf->maximum_inmem_size ) - { - /* The input source is small enough to compress directly */ -@@ -4591,6 +4621,7 @@ - - #ifdef MOD_GZIP_DEBUG1 - mod_gzip_printf( "%s: gzp->decompress = %d\n" ,cn,gzp->decompress); -+ mod_gzip_printf( "%s: gzp->compression_format = %d\n",cn,gzp->compression_format); - mod_gzip_printf( "%s: gzp->input_ismem = %d\n", cn,gzp->input_ismem); - mod_gzip_printf( "%s: gzp->output_ismem = %d\n", cn,gzp->output_ismem); - mod_gzip_printf( "%s: gzp->input_filename = [%s]\n",cn,gzp->input_filename); -@@ -7256,6 +7287,8 @@ - }; - - typedef struct _GZ1 { -+ long compression_format; -+ - long versionid1; - int state; - int done; -@@ -7345,6 +7378,7 @@ - int dbits; - ulg window_size; - ulg crc; -+ ulg adler; - - uch dist_code[512]; - uch length_code[MAX_MATCH-MIN_MATCH+1]; -@@ -7449,6 +7483,15 @@ - - void error( char *msg ); - -+/* XXX - Precomputed zlib header. If you change the window size or -+ * compression level from the defaults, this will break badly. The -+ * algorithm to build this is fairly complex; you can find it in -+ * the file deflate.c from the zlib distribution. -+ */ -+#define ZLIB_HEADER "\170œ" -+ -+ulg adler32(ulg adler, uch *buf, unsigned len); -+ - int zip( - PGZ1 gz1, - int in, -@@ -9088,10 +9131,20 @@ - if ( len == (unsigned)(-1) || len == 0 ) - { - gz1->crc = gz1->crc ^ 0xffffffffL; -+ /* XXX - Do we need to do something with Adler CRC's here? -+ * I don't think so--they don't seem to need postprocessing. */ - return (int)len; - } - -- updcrc( gz1, (uch*)buf, len ); -+ if (gz1->compression_format != DEFLATE_FORMAT) -+ { -+ updcrc( gz1, (uch*)buf, len ); -+ } -+ else -+ { -+ gz1->adler = adler32(gz1->adler, (uch*)buf, len); -+ } -+ - gz1->bytes_in += (ulg)len; - - return (int)len; -@@ -9288,6 +9341,7 @@ - gz1->heap[k] = v; - } - -+ - #define GZS_ZIP1 1 - #define GZS_ZIP2 2 - #define GZS_DEFLATE1 3 -@@ -9317,6 +9371,7 @@ - } - - gz1->decompress = gzp->decompress; -+ gz1->compression_format = gzp->compression_format; - - strcpy( gz1->ifname, gzp->input_filename ); - strcpy( gz1->ofname, gzp->output_filename ); -@@ -9489,6 +9544,7 @@ - return( rc ); - } - -+ - int gzs_zip1( PGZ1 gz1 ) - { - uch flags = 0; -@@ -9499,21 +9555,40 @@ - - gz1->method = DEFLATED; - -- put_byte(GZIP_MAGIC[0]); -- put_byte(GZIP_MAGIC[1]); -- put_byte(DEFLATED); -+ if (gz1->compression_format != DEFLATE_FORMAT) -+ { -+ put_byte(GZIP_MAGIC[0]); -+ put_byte(GZIP_MAGIC[1]); -+ put_byte(DEFLATED); -+ } -+ else -+ { -+ /* Yes, I know RFC 1951 doesn't mention any header at the start of -+ * a deflated document, but zlib absolutely requires one. And since nearly -+ * all "deflate" implementations use zlib, we need to play along with this -+ * brain damage. */ -+ put_byte(ZLIB_HEADER[0]); -+ put_byte(ZLIB_HEADER[1]); -+ } - - if ( gz1->save_orig_name ) - { - flags |= ORIG_NAME; - } - -- put_byte(flags); -- put_long(gz1->time_stamp); -- -- gz1->crc = -1; -+ if (gz1->compression_format != DEFLATE_FORMAT) -+ { -+ put_byte(flags); -+ put_long(gz1->time_stamp); - -- updcrc( gz1, NULL, 0 ); -+ gz1->crc = -1; -+ updcrc( gz1, NULL, 0 ); -+ } -+ else -+ { -+ /* Deflate compression uses an Adler32 CRC, not a CRC32. */ -+ gz1->adler = 1L; -+ } - - gz1->state = GZS_ZIP2; - -@@ -9529,18 +9604,20 @@ - bi_init( gz1, gz1->ofd ); - ct_init( gz1, &attr, &gz1->method ); - lm_init( gz1, gz1->level, &deflate_flags ); -- put_byte((uch)deflate_flags); -- -- put_byte(OS_CODE); - -- if ( gz1->save_orig_name ) -+ if (gz1->compression_format != DEFLATE_FORMAT) - { -- char *p = gz1_basename( gz1, gz1->ifname ); -+ put_byte((uch)deflate_flags); -+ put_byte(OS_CODE); -+ if ( gz1->save_orig_name ) -+ { -+ char *p = gz1_basename( gz1, gz1->ifname ); - -- do { -- put_char(*p); -+ do { -+ put_char(*p); - -- } while (*p++); -+ } while (*p++); -+ } - } - - gz1->header_bytes = (long)gz1->outcnt; -@@ -9674,10 +9751,25 @@ - } - #endif - -- put_long( gz1->crc ); -- put_long( gz1->bytes_in ); -- -- gz1->header_bytes += 2*sizeof(long); -+ if (gz1->compression_format != DEFLATE_FORMAT) -+ { -+ put_long( gz1->crc ); -+ put_long( gz1->bytes_in ); -+ gz1->header_bytes += 2*sizeof(long); -+ } -+ else -+ { -+ /* Append an Adler32 CRC to our deflated data. -+ * Yes, I know RFC 1951 doesn't mention any CRC at the end of a -+ * deflated document, but zlib absolutely requires one. And since nearly -+ * all "deflate" implementations use zlib, we need to play along with this -+ * brain damage. */ -+ put_byte( (gz1->adler >> 24) ); -+ put_byte( (gz1->adler >> 16) & 0xFF ); -+ put_byte( (gz1->adler >> 8) & 0xFF ); -+ put_byte( (gz1->adler ) & 0xFF ); -+ gz1->header_bytes += 4*sizeof(uch); -+ } - - flush_outbuf( gz1 ); - -@@ -9685,6 +9777,67 @@ - - return OK; - } -+ -+ -+/* ========================================================================= -+ adler32 -- compute the Adler-32 checksum of a data stream -+ Copyright (C) 1995-1998 Mark Adler -+ -+ This software is provided 'as-is', without any express or implied -+ warranty. In no event will the authors be held liable for any damages -+ arising from the use of this software. -+ -+ Permission is granted to anyone to use this software for any purpose, -+ including commercial applications, and to alter it and redistribute it -+ freely, subject to the following restrictions: -+ -+ 1. The origin of this software must not be misrepresented; you must not -+ claim that you wrote the original software. If you use this software -+ in a product, an acknowledgment in the product documentation would be -+ appreciated but is not required. -+ 2. Altered source versions must be plainly marked as such, and must not be -+ misrepresented as being the original software. -+ 3. This notice may not be removed or altered from any source distribution. -+ -+ Modified by Eric Kidd to play nicely with mod_gzip. -+ */ -+ -+#define BASE 65521L /* largest prime smaller than 65536 */ -+#define NMAX 5552 -+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ -+ -+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} -+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -+#define DO16(buf) DO8(buf,0); DO8(buf,8); -+ -+ulg adler32(ulg adler, uch *buf, unsigned len) -+{ -+ unsigned long s1 = adler & 0xffff; -+ unsigned long s2 = (adler >> 16) & 0xffff; -+ int k; -+ -+ if (buf == NULL) return 1L; -+ -+ while (len > 0) { -+ k = len < NMAX ? len : NMAX; -+ len -= k; -+ while (k >= 16) { -+ DO16(buf); -+ buf += 16; -+ k -= 16; -+ } -+ if (k != 0) do { -+ s1 += *buf++; -+ s2 += s1; -+ } while (--k); -+ s1 %= BASE; -+ s2 %= BASE; -+ } -+ return (s2 << 16) | s1; -+} -+ - - /* END OF FILE */ - diff --git a/trunk/tools/xml-rpc-api2cpp/DataType.cpp b/trunk/tools/xml-rpc-api2cpp/DataType.cpp deleted file mode 100644 index 8571f8036..000000000 --- a/trunk/tools/xml-rpc-api2cpp/DataType.cpp +++ /dev/null @@ -1,268 +0,0 @@ -#include -#include -#include -#include -#include - -#include "xmlrpc-c/oldcppwrapper.hpp" -#include "DataType.hpp" - -using namespace std; - - - -//========================================================================= -// abstract class DataType -//========================================================================= -// Instances of DataType know how generate code fragments for manipulating -// a specific XML-RPC data type. - -string -DataType::defaultParameterBaseName(unsigned int const position) const { - - ostringstream nameStream; - - nameStream << typeName() << position; - - return nameStream.str(); -} - - - -class RawDataType : public DataType { -public: - RawDataType(string const& typeName) : DataType(typeName) {} - - virtual string - parameterFragment(string const& baseName) const; - - virtual string - inputConversionFragment(string const& baseName) const; - - virtual string - returnTypeFragment() const; - - virtual string - outputConversionFragment(string const& varName) const; -}; - - - -string -RawDataType::parameterFragment(string const& baseName) const { - return "XmlRpcValue /*" + typeName() + "*/ " + baseName; -} - - - -string -RawDataType::inputConversionFragment(string const& baseName) const { - - return baseName; -} - - - -string -RawDataType::returnTypeFragment() const { - return "XmlRpcValue /*" + typeName() + "*/"; -} - - - -string -RawDataType::outputConversionFragment(string const& varName) const { - - return varName; -} - - - -class SimpleDataType : public DataType { - string mNativeType; - string mMakerFunc; - string mGetterFunc; - -public: - SimpleDataType(string const& typeName, - string const& nativeType, - string const& makerFunc, - string const& getterFunc); - - virtual string - parameterFragment(string const& baseName) const; - - virtual string - inputConversionFragment(string const& baseName) const; - - virtual string - returnTypeFragment() const; - - virtual string - outputConversionFragment(string const& varName) const; -}; - - - -SimpleDataType::SimpleDataType(string const& typeName, - string const& nativeType, - string const& makerFunc, - string const& getterFunc) - : DataType(typeName), - mNativeType(nativeType), - mMakerFunc(makerFunc), - mGetterFunc(getterFunc) { -} - - - -string -SimpleDataType::parameterFragment(string const& baseName) const { - - return mNativeType + " const " + baseName; -} - - - -string -SimpleDataType::inputConversionFragment(string const& baseName) const { - - return mMakerFunc + "(" + baseName + ")"; -} - - - -string -SimpleDataType::returnTypeFragment() const { - - return mNativeType; -} - - - -string -SimpleDataType::outputConversionFragment(string const& varName) const { - return varName + "." + mGetterFunc + "()"; -} - - - -class VoidDataType : public DataType { -public: - VoidDataType() : DataType("void") {} - - virtual string - parameterFragment(string const& baseName) const; - - virtual string - inputConversionFragment(string const& baseName) const; - - virtual string - returnTypeFragment() const; - - virtual string - outputConversionFragment(string const& varName) const; -}; - - - -string -VoidDataType::parameterFragment(string const&) const { - - throw domain_error("Can't handle functions with 'void' arguments'"); -} - - - -string -VoidDataType::inputConversionFragment(string const&) const { - - throw domain_error("Can't handle functions with 'void' arguments'"); -} - - - -string -VoidDataType::returnTypeFragment () const { - - return "void"; -} - - - -string -VoidDataType::outputConversionFragment(string const&) const { - return "/* Return value ignored. */"; -} - - - -static SimpleDataType const intType ("int", "XmlRpcValue::int32", - "XmlRpcValue::makeInt", - "getInt"); -static SimpleDataType const boolType ("bool", "bool", - "XmlRpcValue::makeBool", - "getBool"); -static SimpleDataType const doubleType ("double", "double", - "XmlRpcValue::makeDouble", - "getDouble"); -static SimpleDataType const stringType ("string", "std::string", - "XmlRpcValue::makeString", - "getString"); - -static RawDataType const dateTimeType ("dateTime"); -static RawDataType const base64Type ("base64"); -static RawDataType const structType ("struct"); -static RawDataType const arrayType ("array"); - -static VoidDataType const voidType; - - - -const DataType& -findDataType(string const& name) { -/*---------------------------------------------------------------------------- - Given the name of an XML-RPC data type, try to find a corresponding - DataType object. ------------------------------------------------------------------------------*/ - if (name == "int" || name == "i4") - return intType; - else if (name == "boolean") - return boolType; - else if (name == "double") - return doubleType; - else if (name == "string") - return stringType; - else if (name == "dateTime.iso8601") - return dateTimeType; - else if (name == "base64") - return base64Type; - else if (name == "struct") - return structType; - else if (name == "array") - return arrayType; - else if (name == "void") - return voidType; - else if (name == "INT") - return intType; - else if (name == "BOOLEAN") - return boolType; - else if (name == "DOUBLE") - return doubleType; - else if (name == "STRING") - return stringType; - else if (name == "DATETIME.ISO8601") - return dateTimeType; - else if (name == "BASE64") - return base64Type; - else if (name == "STRUCT") - return structType; - else if (name == "ARRAY") - return arrayType; - else if (name == "VOID") - return voidType; - else if (name == "NIL") - return voidType; - else - throw domain_error("Unknown XML-RPC type name '" + name + "'"); -} diff --git a/trunk/tools/xml-rpc-api2cpp/DataType.hpp b/trunk/tools/xml-rpc-api2cpp/DataType.hpp deleted file mode 100644 index 0945961ba..000000000 --- a/trunk/tools/xml-rpc-api2cpp/DataType.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -class DataType { - std::string mTypeName; - - DataType(DataType const&) { assert(false); } - - DataType& operator= (DataType const&) { - assert(false); - return *this; - } - -public: - DataType(const std::string& type_name) : mTypeName(type_name) {} - - virtual ~DataType () {} - - // Return the name for this XML-RPC type. - virtual std::string - typeName() const { return mTypeName; } - - // Given a parameter position, calculate a unique base name for all - // parameter-related variables. - virtual std::string - defaultParameterBaseName(unsigned int const position) const; - - // Virtual functions for processing parameters. - virtual std::string - parameterFragment(std::string const& base_name) const = 0; - - virtual std::string - inputConversionFragment(std::string const& base_name) const = 0; - - // Virtual functions for processing return values. - virtual std::string - returnTypeFragment () const = 0; - - virtual std::string - outputConversionFragment(std::string const& var_name) const = 0; -}; - -const DataType& findDataType(const std::string& name); diff --git a/trunk/tools/xml-rpc-api2cpp/Makefile b/trunk/tools/xml-rpc-api2cpp/Makefile deleted file mode 100644 index 4e3b7a363..000000000 --- a/trunk/tools/xml-rpc-api2cpp/Makefile +++ /dev/null @@ -1,73 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - TOOLSDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(TOOLSDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools/xml-rpc-api2cpp - -default: all - -include $(BLDDIR)/config.mk - -PROGS := xml-rpc-api2cpp -PROGRAMS_TO_INSTALL := $(PROGS) -MAN_FILES_TO_INSTALL := xml-rpc-api2cpp.1 - -all: $(PROGS) - -include $(SRCDIR)/tools/common.mk - -# in Glibc 2.2 has a bug that results in inlining failure, -# so we disable warnings for that: -CFLAGS_LOCAL = $(CFLAGS_NO_INLINE_WARNING) - -INCLUDES = -I$(BLDDIR) -I$(BLDDIR)/include -Isrcdir/include - -CLIENT_LDLIBS += $(SOCKETLIBOPT) - -LDLIBS = -L$(BLDDIR)/src/cpp -lxmlrpc_cpp -L$(BLDDIR)/src -lxmlrpc_server \ - $(CLIENT_LDLIBS) - -OBJECTS = \ - xml-rpc-api2cpp.o \ - DataType.o \ - XmlRpcFunction.o \ - XmlRpcClass.o \ - SystemProxy.o \ - -xml-rpc-api2cpp: \ - $(OBJECTS) \ - $(LIBXMLRPC_CPP) \ - $(CLIENT_LIBS_DEP) \ - $(LIBXMLRPC_SERVER) \ - $(LIBXMLRPC) \ - $(LIBXMLRPC_XML) \ - $(LIBXMLRPC_UTIL) - $(CXXLD) -o $@ $(LDFLAGS_ALL) $(OBJECTS) $(LDLIBS) - -%.o:%.cpp - $(CXX) -c $(CXXFLAGS_ALL) $< - -# This common.mk dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/tools/common.mk: srcdir blddir - -include depend.mk - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean -clean: clean-common - rm -f $(PROGS) - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: dep -dep: dep-common diff --git a/trunk/tools/xml-rpc-api2cpp/SystemProxy.cpp b/trunk/tools/xml-rpc-api2cpp/SystemProxy.cpp deleted file mode 100644 index f24fadc64..000000000 --- a/trunk/tools/xml-rpc-api2cpp/SystemProxy.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// SystemProxy.cc - xmlrpc-c C++ proxy class -// Auto-generated by xml-rpc-api2cpp. -// But for now, this file is maintained manually. When someone figures -// out how stuff in this directory works, maybe we'll make it an automatically -// generated file. -Bryan 2005.06.05. - -#include - -#include "xmlrpc-c/oldcppwrapper.hpp" -#include "SystemProxy.hpp" - -using namespace std; - -XmlRpcValue /*array*/ SystemProxy::listMethods () { - XmlRpcValue params = XmlRpcValue::makeArray(); - XmlRpcValue result = this->mClient.call("system.listMethods", params); - return result; -} - -XmlRpcValue /*array*/ SystemProxy::methodSignature (string string1) { - XmlRpcValue params = XmlRpcValue::makeArray(); - params.arrayAppendItem(XmlRpcValue::makeString(string1)); - XmlRpcValue result = this->mClient.call("system.methodSignature", params); - return result; -} - -string SystemProxy::methodHelp (string string1) { - XmlRpcValue params = XmlRpcValue::makeArray(); - params.arrayAppendItem(XmlRpcValue::makeString(string1)); - XmlRpcValue result = this->mClient.call("system.methodHelp", params); - return result.getString(); -} - -XmlRpcValue /*array*/ SystemProxy::multicall (XmlRpcValue /*array*/ array1) { - XmlRpcValue params = XmlRpcValue::makeArray(); - params.arrayAppendItem(array1); - XmlRpcValue result = this->mClient.call("system.multicall", params); - return result; -} diff --git a/trunk/tools/xml-rpc-api2cpp/SystemProxy.hpp b/trunk/tools/xml-rpc-api2cpp/SystemProxy.hpp deleted file mode 100644 index f7e80a273..000000000 --- a/trunk/tools/xml-rpc-api2cpp/SystemProxy.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// SystemProxy.h - xmlrpc-c C++ proxy class -// Auto-generated by xml-rpc-api2cpp. - -#ifndef _SystemProxy_H_ -#define _SystemProxy_H_ 1 - -#include - -#include "xmlrpc-c/oldcppwrapper.hpp" - -class SystemProxy { - XmlRpcClient mClient; - -public: - SystemProxy (const XmlRpcClient& client) - : mClient(client) {} - SystemProxy (const std::string& server_url) - : mClient(XmlRpcClient(server_url)) {} - SystemProxy (const SystemProxy& o) - : mClient(o.mClient) {} - - SystemProxy& operator= (const SystemProxy& o) { - if (this != &o) mClient = o.mClient; - return *this; - } - - /* Return an array of all available XML-RPC methods on this server. */ - XmlRpcValue /*array*/ listMethods (); - - /* Given the name of a method, return an array of legal - signatures. Each signature is an array of strings. The first item of - each signature is the return type, and any others items are - parameter types. */ - XmlRpcValue /*array*/ methodSignature (std::string string1); - - /* Given the name of a method, return a help string. */ - std::string methodHelp (std::string string1); - - /* Process an array of calls, and return an array of results. Calls - should be structs of the form {'methodName': string, 'params': - array}. Each result will either be a single-item array containg the - result value, or a struct of the form {'faultCode': int, - 'faultString': string}. This is useful when you need to make lots of - small calls without lots of round trips. */ - XmlRpcValue /*array*/ multicall (XmlRpcValue /*array*/ array1); -}; - -#endif /* _SystemProxy_H_ */ diff --git a/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.cpp b/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.cpp deleted file mode 100644 index 2678560ff..000000000 --- a/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include -#include - -using namespace std; - -#include "xmlrpc-c/oldcppwrapper.hpp" - -#include "DataType.hpp" -#include "XmlRpcFunction.hpp" -#include "XmlRpcClass.hpp" - - -XmlRpcClass::XmlRpcClass(string const& className) : - mClassName(className) {} - - - -XmlRpcClass::XmlRpcClass(XmlRpcClass const& c) : - mClassName(c.mClassName), - mFunctions(c.mFunctions) {} - - - -XmlRpcClass& -XmlRpcClass::operator= (XmlRpcClass const& c) { - - if (this != &c) { - this->mClassName = c.mClassName; - this->mFunctions = c.mFunctions; - } - return *this; -} - - - -void -XmlRpcClass::addFunction(XmlRpcFunction const& function) { - - mFunctions.push_back(function); -} - - - -void -XmlRpcClass::printDeclaration(ostream & out) const { - - out << "class " << mClassName << " {" << endl; - out << " XmlRpcClient mClient;" << endl; - out << endl; - out << "public:" << endl; - out << " " << mClassName << " (const XmlRpcClient& client)" << endl; - out << " : mClient(client) {}" << endl; - out << " " << mClassName << " (const std::string& server_url)" << endl; - out << " : mClient(XmlRpcClient(server_url)) {}" << endl; - out << " " << mClassName << " (const " << mClassName << "& o)" << endl; - out << " : mClient(o.mClient) {}" << endl; - out << endl; - out << " " << mClassName << "& operator= (const " - << mClassName << "& o) {" << endl; - out << " if (this != &o) mClient = o.mClient;" << endl; - out << " return *this;" << endl; - out << " }" << endl; - - vector::const_iterator f; - for (f = mFunctions.begin(); f < mFunctions.end(); ++f) { - f->printDeclarations(out); - } - - out << "};" << endl; -} - - - -void -XmlRpcClass::printDefinition(ostream & out) const { - - vector::const_iterator f; - - for (f = mFunctions.begin(); f < mFunctions.end(); ++f) { - f->printDefinitions(out, mClassName); - } -} - diff --git a/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.hpp b/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.hpp deleted file mode 100644 index e13c96fc4..000000000 --- a/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#include - -class XmlRpcClass { - // An object of this class contains information about a proxy - // class, and knows how to generate code. - - std::string mClassName; - std::vector mFunctions; - - -public: - XmlRpcClass (std::string const& className); - XmlRpcClass(XmlRpcClass const&); - XmlRpcClass& operator= (XmlRpcClass const&); - - std::string className () const { return mClassName; } - - void addFunction (const XmlRpcFunction& function); - - void printDeclaration (ostream& out) const; - void printDefinition (ostream& out) const; -}; diff --git a/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.cpp b/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.cpp deleted file mode 100644 index 85751a515..000000000 --- a/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include -#include -#include - -#include "xmlrpc-c/oldcppwrapper.hpp" -#include "DataType.hpp" -#include "XmlRpcFunction.hpp" - -using namespace std; - - -XmlRpcFunction::XmlRpcFunction(string const& functionName, - string const& methodName, - string const& help, - XmlRpcValue const signatureList) : - mFunctionName(functionName), - mMethodName(methodName), - mHelp(help), - mSynopsis(signatureList) {} - - - -XmlRpcFunction::XmlRpcFunction(XmlRpcFunction const& f) : - mFunctionName(f.mFunctionName), - mMethodName(f.mMethodName), - mHelp(f.mHelp), - mSynopsis(f.mSynopsis) {} - - - -XmlRpcFunction& -XmlRpcFunction::operator= (XmlRpcFunction const& f) { - - if (this != &f) { - this->mFunctionName = f.mFunctionName; - this->mMethodName = f.mMethodName; - this->mHelp = f.mHelp; - this->mSynopsis = f.mSynopsis; - } - return *this; -} - - - -void -XmlRpcFunction::printDeclarations(ostream & out) const { - - try { - // Print the method help as a comment - - out << endl << " /* " << mHelp << " */" << endl; - - size_t end; - - try { - end = mSynopsis.arraySize(); - } catch (XmlRpcFault const& fault) { - throw(logic_error("Failed to get size of signature array for " - "method " + this->mFunctionName + ". " + - fault.getFaultString())); - } - // Print the declarations for all the signatures of this - // XML-RPC method. - - for (size_t i = 0; i < end; ++i) - printDeclaration(out, i); - - } catch (exception const& e) { - throw(logic_error("Failed to generate declarations for method " + - this->mFunctionName + ". " + e.what())); - } -} - - - -void -XmlRpcFunction::printDefinitions(ostream & out, - string const& className) const { - - try { - size_t const end(mSynopsis.arraySize()); - - for (size_t i = 0; i < end; ++i) { - out << endl; - printDefinition(out, className, i); - } - } catch (XmlRpcFault const& fault) { - throw(logic_error("Failed to generate definitions for class " + - this->mFunctionName + ". " + - fault.getFaultString())); - } -} - - - -void -XmlRpcFunction::printParameters(ostream & out, - size_t const synopsisIndex) const { -/*---------------------------------------------------------------------------- - Print the parameter declarations. ------------------------------------------------------------------------------*/ - size_t const end(parameterCount(synopsisIndex)); - - bool first; - - first = true; - - for (size_t i = 0; i < end; ++i) { - if (!first) - out << ", "; - - DataType const& ptype(parameterType(synopsisIndex, i)); - string const basename(ptype.defaultParameterBaseName(i + 1)); - out << ptype.parameterFragment(basename); - - first = false; - } -} - - - -void -XmlRpcFunction::printDeclaration(ostream & out, - size_t const synopsisIndex) const { - - try { - DataType const& rtype(returnType(synopsisIndex)); - - out << " " << rtype.returnTypeFragment() << " " - << mFunctionName << " ("; - - printParameters(out, synopsisIndex); - - out << ");" << endl; - } catch (XmlRpcFault const& fault) { - ostringstream msg; - - msg << "Failed to generate header for signature " - << synopsisIndex - << " . " - << fault.getFaultString(); - - throw(logic_error(msg.str())); - } -} - - - -void -XmlRpcFunction::printDefinition(ostream & out, - string const& className, - size_t const synopsisIndex) const { - - DataType const& rtype(returnType(synopsisIndex)); - - out << rtype.returnTypeFragment() << " " - << className << "::" << mFunctionName << " ("; - - printParameters(out, synopsisIndex); - - out << ") {" << endl; - out << " XmlRpcValue params(XmlRpcValue::makeArray());" << endl; - - /* Emit code to convert the parameters into an array of XML-RPC objects. */ - size_t const end(parameterCount(synopsisIndex)); - for (size_t i = 0; i < end; ++i) { - DataType const& ptype(parameterType(synopsisIndex, i)); - string const basename(ptype.defaultParameterBaseName(i + 1)); - out << " params.arrayAppendItem(" - << ptype.inputConversionFragment(basename) << ");" << endl; - } - - /* Emit the function call.*/ - out << " XmlRpcValue result(this->mClient.call(\"" - << mMethodName << "\", params));" << endl; - - /* Emit the return statement. */ - out << " return " << rtype.outputConversionFragment("result") - << ";" << endl; - out << "}" << endl; -} - - - -const DataType& -XmlRpcFunction::returnType(size_t const synopsisIndex) const { - - XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex)); - - return findDataType(funcSynop.arrayGetItem(0).getString()); -} - - - -size_t -XmlRpcFunction::parameterCount(size_t const synopsisIndex) const { - - XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex)); - size_t const size(funcSynop.arraySize()); - - if (size < 1) - throw domain_error("Synopsis contained no items"); - return size - 1; -} - - - -DataType const& -XmlRpcFunction::parameterType(size_t const synopsisIndex, - size_t const parameterIndex) const { - - XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex)); - XmlRpcValue const param(funcSynop.arrayGetItem(parameterIndex + 1)); - - return findDataType(param.getString()); -} diff --git a/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.hpp b/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.hpp deleted file mode 100644 index bdef5b0e3..000000000 --- a/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include - -using std::string; -using std::ostream; - -class XmlRpcFunction { - // An object of this class contains everything we know about a - // given XML-RPC method, and knows how to print local bindings. - - string mFunctionName; - string mMethodName; - string mHelp; - XmlRpcValue mSynopsis; - -public: - XmlRpcFunction(const string& function_name, - const string& method_name, - const string& help, - XmlRpcValue synopsis); - - XmlRpcFunction (const XmlRpcFunction&); - XmlRpcFunction& operator= (const XmlRpcFunction&); - - void printDeclarations (ostream& out) const; - void printDefinitions (ostream& out, const string& className) const; - -private: - void printParameters (ostream& out, size_t synopsis_index) const; - void printDeclaration (ostream& out, size_t synopsis_index) const; - void printDefinition (ostream& out, - const string& className, - size_t synopsis_index) const; - - const DataType& returnType (size_t synopsis_index) const; - size_t parameterCount (size_t synopsis_index) const; - const DataType& parameterType (size_t synopsis_index, - size_t parameter_index) const; -}; diff --git a/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1 b/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1 deleted file mode 100644 index a1c8b8068..000000000 --- a/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1 +++ /dev/null @@ -1,62 +0,0 @@ -.\" Hey, EMACS: -*- nroff -*- -.\" First parameter, NAME, should be all caps -.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection -.\" other parameters are allowed: see man(7), man(1) -.TH XML-RPC-API2CPP 1 "June 27, 2001" -.\" Please adjust this date whenever revising the manpage. -.\" -.\" Some roff macros, for reference: -.\" .nh disable hyphenation -.\" .hy enable hyphenation -.\" .ad l left justify -.\" .ad b justify to both left and right margins -.\" .nf disable filling -.\" .fi enable filling -.\" .br insert line break -.\" .sp insert n+1 empty lines -.\" for manpage-specific macros, see man(7) -.SH NAME -xml-rpc-api2cpp \- Make a C++ wrapper class for an XML-RPC API -.SH SYNOPSIS -.B xml-rpc-api2cpp -\fIserver-url\fR \fIremote-method-prefix\fR \fIc++-class-name\fR -.SH DESCRIPTION -xml-rpc-api2cpp queries an XML-RPC server using the XML-RPC -Instrospection API designed by Edd Dumbill. It then prints a C++ -wrapper class to standard output. This class can be used with -xmlrpc-c's C++ API. -.PP -You can find a list of supported XML-RPC server libraries (and patches -for many others) at \fBhttp://xmlrpc-c.sourceforge.net/hacks.php\fR. -.SH OPTIONS -.TP -.I server-url -The name of the server to query. Try -\fBhttp://xmlrpc-c.sourceforge.net/cgi-bin/interop.cgi\fR. -.TP -.I remote-method-prefix -The prefix of the methods to wrap. For example, to wrap all the -system.* calls, you could specify "system". -.TP -.I c++-class-name -The name of the C++ class to generate. Try "SystemProxy". -.SH BUGS -xml-rpc-api2cpp can't talk to certain PHP servers based on Edd -Dumbill's PHP library, because the trailing bytes of the XML-RPC -message get truncated in HTTP pipelining mode. It's not clear whether -this is a PHP, Apache or w3c-libwww bug. -.PP -xml-rpc-api2cpp assumes that method descriptions are ASCII text, not -HTML as specified in the standard. (In practice, both conventions are -often seen.) It may also get unhappy if method descriptions contain -"*/". -.PP -In general, error messages and diagnostics are still fairly poor. -.SH SEE ALSO -.BR xmlrpc-c (7), -.BR xml-rpc-api2txt (1). -.PP -This program is part of xmlrpc-c. -.SH AUTHOR -This manual page was written by Eric Kidd . -It may be distributed under the same terms as the rest of xmlrpc-c. diff --git a/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp b/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp deleted file mode 100644 index adb63057d..000000000 --- a/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#include -#include - -#include "xmlrpc-c/oldcppwrapper.hpp" - -#include "DataType.hpp" -#include "XmlRpcFunction.hpp" -#include "XmlRpcClass.hpp" -#include "SystemProxy.hpp" - -using namespace std; - -#define NAME "xml-rpc-api2cpp" -#define VERSION "0.1" - - -/*---------------------------------------------------------------------------- - Command line ------------------------------------------------------------------------------*/ - -class cmdlineInfo { -public: - string serverUrl; - string methodPrefix; - string localClass; - - cmdlineInfo(int const argc, - const char ** const argv); - -private: - cmdlineInfo(); -}; - - - -cmdlineInfo::cmdlineInfo(int const argc, - const char ** const argv) { - - if (argc-1 != 3) { - cerr << argv[0] << ": Usage:" << endl - << " xml-rpc-api2cpp " - << endl << endl - << "Sample arguments:" << endl - << " server_url = http://localhost/RPC2" << endl - << " method_prefix = system" << endl - << " local_class = SystemProxy" << endl; - exit(1); - } - this->serverUrl = string(argv[1]); - this->methodPrefix = string(argv[2]); - this->localClass = string(argv[3]); -} - - - -static XmlRpcClass -getClassInfo(string const& serverUrl, - string const& classPrefix, - string const& className) { -/*---------------------------------------------------------------------------- - Connect to a remote server and extract the information we'll need to - build a proxy class. ------------------------------------------------------------------------------*/ - XmlRpcClass info(className); - - SystemProxy system(serverUrl); - - XmlRpcValue const methods(system.listMethods()); - - size_t const end = methods.arraySize(); - - for (size_t i = 0; i < end; ++i) { - - // Break the method name into two pieces. - string const methodName(methods.arrayGetItem(i).getString()); - size_t const lastDot(methodName.rfind('.')); - - string methodPrefix; - string functionName; - - if (lastDot == string::npos) { - methodPrefix = ""; - functionName = methodName; - } else { - methodPrefix = string(methodName, 0, lastDot); - functionName = string(methodName, lastDot + 1); - } - - if (methodPrefix == classPrefix) { - // It's a method User cares about - - string const help(system.methodHelp(methodName)); - XmlRpcValue const signatureList( - system.methodSignature(methodName)); - - if (signatureList.getType() != XMLRPC_TYPE_ARRAY) { - // It must be the string "undef", meaning the server - // won't tell us any signatures. - cerr << "Skipping method " << methodName << " " - << "because server does not report any signatures " - << "for it (via system.methodSignature method)" - << endl; - } else { - // Add this function to our class information. - XmlRpcFunction const method(functionName, - methodName, - help, - signatureList); - info.addFunction(method); - } - } - } - return info; -} - - - -static void -printHeader(ostream & out, - XmlRpcClass const& classInfo) { -/*---------------------------------------------------------------------------- - Print a complete header for the specified class. ------------------------------------------------------------------------------*/ - string const className(classInfo.className()); - - try { - out << "// " << className << ".h - xmlrpc-c C++ proxy class" << endl; - out << "// Auto-generated by xml-rpc-api2cpp." << endl; - out << endl; - - string const headerSymbol("_" + className + "_H_"); - - out << "#ifndef " << headerSymbol << endl; - out << "#define " << headerSymbol << " 1" << endl; - out << endl; - out << "#include " << endl; - out << endl; - - classInfo.printDeclaration(cout); - - out << endl; - out << "#endif /* " << headerSymbol << " */" << endl; - } catch (exception const& e) { - throw(logic_error("Failed to generate header for class " + - className + ". " + e.what())); - } -} - - - -static void -printCppFile(ostream & out, - XmlRpcClass const& classInfo) { -/*---------------------------------------------------------------------------- - Print a complete definition for the specified class. ------------------------------------------------------------------------------*/ - string const className(classInfo.className()); - - try { - out << "// " << className << ".cc - xmlrpc-c C++ proxy class" << endl; - out << "// Auto-generated by xml-rpc-api2cpp." << endl; - out << endl; - - out << "#include " << endl; - out << "#include \"" << className << ".h\"" << endl; - - classInfo.printDefinition(cout); - } catch (XmlRpcFault const& fault) { - throw(logic_error("Failed to generate definition for class " + - className + ". " + fault.getFaultString())); - } -} - - - -int -main(int const argc, - const char ** const argv) { - - string const progName(argv[0]); - - cmdlineInfo const cmdline(argc, argv); - - int retval; - - XmlRpcClient::Initialize(NAME, VERSION); - - try { - XmlRpcClass system = getClassInfo(cmdline.serverUrl, - cmdline.methodPrefix, - cmdline.localClass); - printHeader(cout, system); - cout << endl; - printCppFile(cout, system); - retval = 0; - } catch (XmlRpcFault& fault) { - cerr << progName << ": XML-RPC fault #" << fault.getFaultCode() - << ": " << fault.getFaultString() << endl; - retval = 1; - } catch (logic_error& err) { - cerr << progName << ": " << err.what() << endl; - retval = 1; - } catch (...) { - cerr << progName << ": Unknown exception" << endl; - retval = 1; - } - - XmlRpcClient::Terminate(); - - return retval; -} - diff --git a/trunk/tools/xml-rpc-api2txt/Makefile b/trunk/tools/xml-rpc-api2txt/Makefile deleted file mode 100644 index b4dd64678..000000000 --- a/trunk/tools/xml-rpc-api2txt/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - TOOLSDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(TOOLSDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools/xml-rpc-api2txt - -default: all - -include $(BLDDIR)/config.mk - -PROGS := -PROGRAMS_TO_INSTALL := xml-rpc-api2txt -MAN_FILES_TO_INSTALL := xml-rpc-api2txt.1 - -all: $(PROGS) - -include $(SRCDIR)/tools/common.mk - -# This common.mk dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/tools/common.mk: srcdir blddir - -include depend.mk - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean -clean: clean-common - rm -f $(PROGS) - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: dep -dep: dep-common diff --git a/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt b/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt deleted file mode 100644 index e771463bd..000000000 --- a/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/perl -w -# -# A handy little program to get the documentation of the available -# methods from an XML-RPC service (via XML-RPC Introspection) and -# print it out nicely formatted. -# -# (I wrote this in Perl because of all the spiffy report-generation -# features.) -# -# You'll need to get Ken MacLeod's Frontier::RPC2 module from CPAN to use -# this. -# -# Eric Kidd -# -# This script is part of xmlrpc-c, and may be used and distributed under -# the same terms as the rest of the package. - -use strict; - -# One global variable for use with Perl's format routines, and one for -# use inside an 'exec' block. -use vars qw/$helptext $method_list/; - -# Try to load our Perl XML-RPC bindings, but fail gracefully. -eval { - require Frontier::Client; -}; -if ($@) { - print STDERR <<"EOD"; -This script requires Ken MacLeod\'s Frontier::RPC2 module. You can get this -from CPAN or from his website at http://bitsko.slc.ut.us/~ken/xml-rpc/ . - -For installation instructions, see the XML-RPC HOWTO at: - http://www.linuxdoc.org/HOWTO/XML-RPC-HOWTO/index.html - -EOD - exit 1; -} - -# Parse our command-line arguments. -if (@ARGV != 1 || $ARGV[0] eq "--help") { - print STDERR "Usage: xml-rpc-api2txt serverURL\n"; - exit 1; -} - -my $server = Frontier::Client->new(url => $ARGV[0]); - -# Try (very carefully) to get our a list of methods from the server. -local $method_list; -eval { - $method_list = $server->call('system.listMethods'); -}; -if ($@) { - print STDERR <<"EOD"; -An error occurred while trying to talk to the XML-RPC server: - - $@ - -This may have been caused by several things--the server might not support -introspection, it might not be an XML-RPC server, or your network might be -down. Try the following: - - xml-rpc-api2txt http://xmlrpc-c.sourceforge.net/api/sample.php - -EOD - exit 1; -} - -# Enter the methods into a hashtable. -my @methods = sort @$method_list; -my %method_table; -foreach my $method (@methods) { - $method_table{$method} = {}; -} - -# Get more information for the hash table. Since we need to make lots and -# lots of very small XML-RPC calls, we'd like to use system.multicall to -# reduce the latency. -if (defined $method_table{'system.multicall'}) { - - # This is messy but fast. Everybody hates HTTP round-trip lag, right? - my @call; - foreach my $method (@methods) { - push @call, {methodName => 'system.methodSignature', - params => [$method]}; - push @call, {methodName => 'system.methodHelp', - params => [$method]}; - } - my @result = @{$server->call('system.multicall', \@call)}; - for (my $i = 0; $i < @methods; $i++) { - my $method = $methods[$i]; - $method_table{$method}->{'signatures'} = $result[2*$i]->[0]; - $method_table{$method}->{'help'} = $result[2*$i+1]->[0]; - } -} else { - - # This is easy but slow (especially over backbone links). - foreach my $method (@methods) { - my $signature = $server->call('system.methodSignature', $method); - my $help = $server->call('system.methodHelp', $method); - $method_table{$method}->{'signatures'} = $signature; - $method_table{$method}->{'help'} = $help; - } -} - -# Now, we need to dump the API. -print <<"EOD"; -XML-RPC API for $ARGV[0] - -See http://www.linuxdoc.org/HOWTO/XML-RPC-HOWTO/index.html for instructions -on using XML-RPC with Perl, Python, Java, C, C++, PHP, etc. -EOD -foreach my $method (@methods) { - print "\n"; - - # Print a synopsis of the function. - if ($method_table{$method}->{'signatures'} eq 'undef') { - # No documentation. Bad server. No biscuit. - print "unknown $method (...)\n"; - } else { - for my $signature (@{$method_table{$method}->{'signatures'}}) { - my $return_type = shift @$signature; - my $arguments = join(", ", @$signature); - print "$return_type $method ($arguments)\n"; - } - } - print "\n"; - - my $help = $method_table{$method}->{'help'}; - if ($help =~ /\n/) { - # Text has already been broken into lines by the server, so just - # indent it by two spaces and hope for the best. - my @lines = split(/\n/, $help); - my $help = " " . join("\n ", @lines); - print "$help\n"; - } else { - # Print our help text in a nicely-wrapped fashion using Perl's - # formatting routines. - $helptext = $method_table{$method}->{'help'}; - write; - } -} - -format STDOUT = - ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~ - $helptext -. diff --git a/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt.1 b/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt.1 deleted file mode 100644 index a9e1ee322..000000000 --- a/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt.1 +++ /dev/null @@ -1,47 +0,0 @@ -.\" Hey, EMACS: -*- nroff -*- -.\" First parameter, NAME, should be all caps -.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection -.\" other parameters are allowed: see man(7), man(1) -.TH XML-RPC-API2TXT 1 "June 27, 2001" -.\" Please adjust this date whenever revising the manpage. -.\" -.\" Some roff macros, for reference: -.\" .nh disable hyphenation -.\" .hy enable hyphenation -.\" .ad l left justify -.\" .ad b justify to both left and right margins -.\" .nf disable filling -.\" .fi enable filling -.\" .br insert line break -.\" .sp insert n+1 empty lines -.\" for manpage-specific macros, see man(7) -.SH NAME -xml-rpc-api2txt \- Print out a description of an XML-RPC API as text -.SH SYNOPSIS -.B xml-rpc-api2txt -\fIserver-url\fR -.SH DESCRIPTION -xml-rpc-api2txt queries an XML-RPC server using the XML-RPC -Instrospection API designed by Edd Dumbill. It then prints the -results to standard output in a nicely formatted form, suitable for -sending via e-mail. -.PP -You can find a list of supported XML-RPC server libraries (and patches -for many others) at \fBhttp://xmlrpc-c.sourceforge.net/hacks.php\fR. -.SH OPTIONS -.TP -.I server-url -The name of the server to query. Try -\fBhttp://xmlrpc-c.sourceforge.net/cgi-bin/interop.cgi\fR. -.SH BUGS -xml-rpc-api2txt assumes that method descriptions are ASCII text, not -HTML as specified in the standard. (In practice, both conventions are -often seen.) -.SH SEE ALSO -.BR xmlrpc-c (7), -.BR xml-rpc-api2cpp (1). -.PP -This program is part of xmlrpc-c. -.SH AUTHOR -This manual page was written by Eric Kidd . -It may be distributed under the same terms as the rest of xmlrpc-c. diff --git a/trunk/tools/xml/Makefile b/trunk/tools/xml/Makefile deleted file mode 100644 index 70e05e8a3..000000000 --- a/trunk/tools/xml/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - TOOLSDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(TOOLSDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools/xml - -default: all - -include $(BLDDIR)/config.mk - -PROGS := xmlrpc_parsecall - -PROGRAMS_TO_INSTALL = $(PROGS) - -include $(SRCDIR)/tools/common.mk - -INCLUDES = \ - -I../lib/include \ - -Iblddir \ - -Iblddir/include \ - -Isrcdir/include \ - -Isrcdir/lib/util/include - -all: $(PROGS) - -UTIL_OBJS = \ - casprintf.o \ - -UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) - -DUMPVALUE = blddir/tools/lib/dumpvalue.o - -# Can we just use $(LIBS) in the link? - -LIBS = $(LIBXMLRPC) $(LIBXMLRPC_XML) $(LIBXMLRPC_UTIL) - -PARSECALL_OBJS = xmlrpc_parsecall.o $(DUMPVALUE) - -xmlrpc_parsecall: $(PARSECALL_OBJS) $(LIBS) $(UTILS) - $(CCLD) -o $@ $(LDFLAGS_ALL) $^ - -%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h - $(CC) -c $(CFLAGS_ALL) $< - -# This common.mk dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/tools/common.mk: srcdir blddir - -include depend.mk - -.PHONY: dep -dep: dep-common - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean -clean: clean-common - rm -f $(PROGS) - -.PHONY: distclean -distclean: clean distclean-common diff --git a/trunk/tools/xml/xmlrpc_parsecall.c b/trunk/tools/xml/xmlrpc_parsecall.c deleted file mode 100644 index ac576f212..000000000 --- a/trunk/tools/xml/xmlrpc_parsecall.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -#include "casprintf.h" -#include "dumpvalue.h" - - -static void -die_if_fault_occurred (xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "Error: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -static void -readFile(xmlrpc_env * const envP, - FILE * const ifP, - xmlrpc_mem_block ** const fileContentsPP) { - - xmlrpc_mem_block * fileContentsP; - - fileContentsP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - - while (!envP->fault_occurred && !feof(ifP)) { - char buffer[4096]; - size_t bytesRead; - - bytesRead = fread(buffer, 1, sizeof(buffer), ifP); - XMLRPC_MEMBLOCK_APPEND(char, envP, - fileContentsP, buffer, bytesRead); - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, fileContentsP); - - *fileContentsPP = fileContentsP; -} - - - -int -main(int argc, const char ** argv) { - - xmlrpc_env env; - const char * methodName; - xmlrpc_value * paramArrayP; - xmlrpc_mem_block * callXmlP; - - if (argc-1 > 0) { - fprintf(stderr, "No arguments. Input is from Standard Input\n"); - if (argv){} /* defeat compiler warning */ - exit(99); - } - - xmlrpc_env_init(&env); - - fprintf(stderr, "Reading call data from Standard Input...\n"); - - readFile(&env, stdin, &callXmlP); - die_if_fault_occurred(&env); - - xmlrpc_parse_call(&env, - XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP), - XMLRPC_MEMBLOCK_SIZE(char, callXmlP), - &methodName, - ¶mArrayP); - - if (env.fault_occurred) - printf("Invalid call. %s\n", env.fault_string); - else { - printf("Parsed successfully as XML-RPC call.\n"); - - printf("Method name: '%s'\n", methodName); - - printf("Parameter array:\n"); - - dumpValue(" ", paramArrayP); - - strfree(methodName); - xmlrpc_DECREF(paramArrayP); - } - XMLRPC_MEMBLOCK_FREE(char, callXmlP); - - xmlrpc_env_clean(&env); - - return 0; -} diff --git a/trunk/tools/xmlrpc/Makefile b/trunk/tools/xmlrpc/Makefile deleted file mode 100644 index 3e322ce66..000000000 --- a/trunk/tools/xmlrpc/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - TOOLSDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(TOOLSDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools/xmlrpc - -default: all - -include $(BLDDIR)/config.mk - -PROGRAMS_TO_INSTALL = xmlrpc - -include $(SRCDIR)/tools/common.mk - -INCLUDES = \ - -I../lib/include \ - -Iblddir \ - -Iblddir/include \ - -Isrcdir/include \ - -Isrcdir/lib/util/include - -all: xmlrpc - -UTIL_OBJS = \ - casprintf.o \ - cmdline_parser.o \ - getoptx.o \ - stripcaseeq.o \ - string_parser.o \ - -UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) - -DUMPVALUE = blddir/tools/lib/dumpvalue.o - -XMLRPC_OBJS = xmlrpc.o $(DUMPVALUE) - -CLIENT_LDLIBS += $(SOCKETLIBOPT) $(THREAD_LIBS) - -xmlrpc: $(XMLRPC_OBJS) $(CLIENT_LIBS_DEP) $(UTILS) - $(CCLD) -o $@ $(LDFLAGS_ALL) $(XMLRPC_OBJS) $(UTILS) $(CLIENT_LDLIBS) - -%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h - $(CC) -c $(CFLAGS_ALL) $< - -# This common.mk dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/tools/common.mk: srcdir blddir - -include depend.mk - -.PHONY: dep -dep: dep-common - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean -clean: clean-common - rm -f xmlrpc - -.PHONY: distclean -distclean: clean distclean-common diff --git a/trunk/tools/xmlrpc/xmlrpc.c b/trunk/tools/xmlrpc/xmlrpc.c deleted file mode 100644 index 8d45bdb98..000000000 --- a/trunk/tools/xmlrpc/xmlrpc.c +++ /dev/null @@ -1,945 +0,0 @@ -/* Make an XML-RPC call. - - User specifies details of the call on the command line. - - We print the result on Standard Output. - - Example: - - $ xmlrpc http://localhost:8080/RPC2 sample.add i/3 i/5 - Result: - Integer: 8 - - $ xmlrpc localhost:8080 sample.add i/3 i/5 - Result: - Integer: 8 -*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" /* information about this build environment */ -#include "bool.h" -#include "int.h" -#include "mallocvar.h" -#include "girstring.h" -#include "casprintf.h" -#include "string_parser.h" -#include "cmdline_parser.h" -#include "dumpvalue.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/client.h" -#include "xmlrpc-c/string_int.h" - -#define NAME "xmlrpc command line program" -#define VERSION "1.0" - -struct cmdlineInfo { - const char * url; - const char * username; - const char * password; - const char * methodName; - unsigned int paramCount; - const char ** params; - /* Array of parameters, in order. Has 'paramCount' entries. */ - const char * transport; - /* Name of XML transport he wants to use. NULL if he has no - preference. - */ - const char * curlinterface; - /* "network interface" parameter for the Curl transport. (Not - valid if 'transport' names a non-Curl transport). - */ - xmlrpc_bool curlnoverifypeer; - xmlrpc_bool curlnoverifyhost; - const char * curluseragent; - bool xmlsizelimitSpec; - unsigned int xmlsizelimit; -}; - - - -static void -die_if_fault_occurred (xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "Failed. %s\n", envP->fault_string); - exit(1); - } -} - - - -static void GNU_PRINTF_ATTR(2,3) -setError(xmlrpc_env * const envP, const char format[], ...) { - va_list args; - const char * faultString; - - va_start(args, format); - - cvasprintf(&faultString, format, args); - va_end(args); - - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, faultString); - - strfree(faultString); -} - - - -static void -processArguments(xmlrpc_env * const envP, - cmdlineParser const cp, - struct cmdlineInfo * const cmdlineP) { - - if (cmd_argumentCount(cp) < 2) - setError(envP, "Not enough arguments. Need at least a URL and " - "method name."); - else { - unsigned int i; - - cmdlineP->url = cmd_getArgument(cp, 0); - cmdlineP->methodName = cmd_getArgument(cp, 1); - cmdlineP->paramCount = cmd_argumentCount(cp) - 2; - MALLOCARRAY_NOFAIL(cmdlineP->params, cmdlineP->paramCount); - for (i = 0; i < cmdlineP->paramCount; ++i) - cmdlineP->params[i] = cmd_getArgument(cp, i+2); - } -} - - - -static void -chooseTransport(xmlrpc_env * const envP ATTR_UNUSED, - cmdlineParser const cp, - const char ** const transportPP) { - - const char * transportOpt = cmd_getOptionValueString(cp, "transport"); - - if (transportOpt) { - *transportPP = transportOpt; - } else { - if (cmd_optionIsPresent(cp, "curlinterface") || - cmd_optionIsPresent(cp, "curlnoverifypeer") || - cmd_optionIsPresent(cp, "curlnoverifyhost") || - cmd_optionIsPresent(cp, "curluseragent")) - - *transportPP = strdup("curl"); - else - *transportPP = NULL; - } -} - - - -static void -parseCommandLine(xmlrpc_env * const envP, - int const argc, - const char ** const argv, - struct cmdlineInfo * const cmdlineP) { - - cmdlineParser const cp = cmd_createOptionParser(); - - const char * error; - - cmd_defineOption(cp, "transport", OPTTYPE_STRING); - cmd_defineOption(cp, "username", OPTTYPE_STRING); - cmd_defineOption(cp, "password", OPTTYPE_STRING); - cmd_defineOption(cp, "curlinterface", OPTTYPE_STRING); - cmd_defineOption(cp, "curlnoverifypeer", OPTTYPE_STRING); - cmd_defineOption(cp, "curlnoverifyhost", OPTTYPE_STRING); - cmd_defineOption(cp, "curluseragent", OPTTYPE_STRING); - cmd_defineOption(cp, "xmlsizelimit", OPTTYPE_BINUINT); - - cmd_processOptions(cp, argc, argv, &error); - - if (error) { - setError(envP, "Command syntax error. %s", error); - strfree(error); - } else { - if (cmd_optionIsPresent(cp, "xmlsizelimit")) { - cmdlineP->xmlsizelimitSpec = true; - cmdlineP->xmlsizelimit = - cmd_getOptionValueUint(cp, "xmlsizelimit"); - } else - cmdlineP->xmlsizelimitSpec = false; - - cmdlineP->username = cmd_getOptionValueString(cp, "username"); - cmdlineP->password = cmd_getOptionValueString(cp, "password"); - - if (cmdlineP->username && !cmdlineP->password) - setError(envP, "When you specify -username, you must also " - "specify -password."); - else { - chooseTransport(envP, cp, &cmdlineP->transport); - - cmdlineP->curlinterface = - cmd_getOptionValueString(cp, "curlinterface"); - cmdlineP->curlnoverifypeer = - cmd_optionIsPresent(cp, "curlnoverifypeer"); - cmdlineP->curlnoverifyhost = - cmd_optionIsPresent(cp, "curlnoverifyhost"); - cmdlineP->curluseragent = - cmd_getOptionValueString(cp, "curluseragent"); - - if ((!cmdlineP->transport || - !streq(cmdlineP->transport, "curl")) - && - (cmdlineP->curlinterface || - cmdlineP->curlnoverifypeer || - cmdlineP->curlnoverifyhost || - cmdlineP->curluseragent)) - setError(envP, "You may not specify a Curl transport " - "option unless you also specify -transport=curl"); - - processArguments(envP, cp, cmdlineP); - } - } - cmd_destroyOptionParser(cp); -} - - - -static void -freeCmdline(struct cmdlineInfo const cmdline) { - - unsigned int i; - - strfree(cmdline.url); - strfree(cmdline.methodName); - if (cmdline.transport) - strfree(cmdline.transport); - if (cmdline.curlinterface) - strfree(cmdline.curlinterface); - if (cmdline.curluseragent) - strfree(cmdline.curluseragent); - if (cmdline.username) - strfree(cmdline.username); - if (cmdline.password) - strfree(cmdline.password); - for (i = 0; i < cmdline.paramCount; ++i) - strfree(cmdline.params[i]); -} - - - -static void -computeUrl(const char * const urlArg, - const char ** const urlP) { - - if (strstr(urlArg, "://") != 0) - casprintf(urlP, "%s", urlArg); - else - casprintf(urlP, "http://%s/RPC2", urlArg); -} - - -enum TokenType {COMMA, COLON, LEFTPAREN, RIGHTPAREN, - LEFTBRACE, RIGHTBRACE, END}; - -static const char * -tokenTypeName(enum TokenType const type) { - - switch (type) { - case COMMA: return "comma"; - case COLON: return "colon"; - case LEFTPAREN: return "left parenthesis"; - case RIGHTPAREN: return "right parenthesis"; - case LEFTBRACE: return "left brace"; - case RIGHTBRACE: return "right brace"; - case END: return "end of string"; - } - return NULL; /* defeat bogus compiler warning */ -} - - - -static void -getDelimiter(xmlrpc_env * const envP, - const char ** const cursorP, - enum TokenType * const typeP) { - - const char * cursor; - enum TokenType tokenType; - - cursor = *cursorP; - - switch (*cursor) { - case ',': tokenType = COMMA; break; - case ':': tokenType = COLON; break; - case '(': tokenType = LEFTPAREN; break; - case ')': tokenType = RIGHTPAREN; break; - case '{': tokenType = LEFTBRACE; break; - case '}': tokenType = RIGHTBRACE; break; - case '\0': tokenType = END; break; - default: - setError(envP, "Unrecognized delimiter character '%c'", *cursor); - } - - if (!envP->fault_occurred && tokenType != END) - ++cursor; - - *cursorP = cursor; - *typeP = tokenType; -} - - - -static void -getCdata(xmlrpc_env * const envP, - const char ** const cursorP, - const char ** const cdataP) { - - size_t const cdataSizeBound = strlen(*cursorP) + 1; - - char * text; - - MALLOCARRAY(text, cdataSizeBound); - - if (text == NULL) - setError(envP, "Failed to allocate a buffer of size %u " - "to compute cdata", (unsigned)cdataSizeBound); - else { - unsigned int textCursor; - bool end; - const char * cursor; - - cursor = *cursorP; /* initial value */ - - for (textCursor = 0, end = false; !end; ) { - switch (*cursor) { - case ',': - case ':': - case '(': - case ')': - case '{': - case '}': - case '\0': - end = true; - break; - case '\\': { - ++cursor; // skip backslash escape character - if (!*cursor) - setError(envP, "Nothing after escape character ('\\')"); - else - text[textCursor++] = *cursor++; - }; break; - default: - text[textCursor++]= *cursor++; - } - assert(textCursor <= cdataSizeBound); - } - text[textCursor++] = '\0'; - - assert(textCursor <= cdataSizeBound); - - *cdataP = text; - *cursorP = cursor; - } -} - - - -static void -buildValue(xmlrpc_env * const envP, - const char ** const cursorP, - xmlrpc_value ** const valuePP); // for recursion - - -static void -buildString(xmlrpc_env * const envP, - const char * const valueString, - xmlrpc_value ** const paramPP) { - - *paramPP = xmlrpc_string_new(envP, valueString); -} - - - -static void -interpretHex(xmlrpc_env * const envP, - const char * const valueString, - size_t const valueStringSize, - unsigned char * const byteString) { - - size_t bsCursor; - size_t strCursor; - - for (strCursor = 0, bsCursor = 0; - strCursor < valueStringSize && !envP->fault_occurred; - ) { - int rc; - - rc = sscanf(&valueString[strCursor], "%2hhx", - &byteString[bsCursor++]); - - if (rc != 1) - xmlrpc_faultf(envP, "Invalid hex data '%s'", - &valueString[strCursor]); - else - strCursor += 2; - } -} - - - -static void -buildBytestring(xmlrpc_env * const envP, - const char * const valueString, - xmlrpc_value ** const paramPP) { - - size_t const valueStringSize = strlen(valueString); - - if (valueStringSize / 2 * 2 != valueStringSize) - xmlrpc_faultf(envP, "Hexadecimal text is not an even " - "number of characters (it is %u characters)", - (unsigned)strlen(valueString)); - else { - size_t const byteStringSize = strlen(valueString)/2; - - unsigned char * byteString; - - MALLOCARRAY(byteString, byteStringSize); - - if (byteString == NULL) - xmlrpc_faultf(envP, "Failed to allocate %u-byte buffer", - (unsigned)byteStringSize); - else { - interpretHex(envP, valueString, valueStringSize, byteString); - - if (!envP->fault_occurred) - *paramPP = xmlrpc_base64_new(envP, byteStringSize, byteString); - - free(byteString); - } - } -} - - - -static void -buildInt(xmlrpc_env * const envP, - const char * const valueString, - xmlrpc_value ** const paramPP) { - - if (strlen(valueString) < 1) - setError(envP, "Integer argument has nothing after the 'i/'"); - else { - int value; - const char * error; - - interpretInt(valueString, &value, &error); - - if (error) { - setError(envP, "'%s' is not a valid 32-bit integer. %s", - valueString, error); - strfree(error); - } else - *paramPP = xmlrpc_int_new(envP, value); - } -} - - - -static void -buildBool(xmlrpc_env * const envP, - const char * const valueString, - xmlrpc_value ** const paramPP) { - - if (streq(valueString, "t") || streq(valueString, "true")) - *paramPP = xmlrpc_bool_new(envP, true); - else if (streq(valueString, "f") || streq(valueString, "false")) - *paramPP = xmlrpc_bool_new(envP, false); - else - setError(envP, "Boolean argument has unrecognized value '%s'. " - "recognized values are 't', 'f', 'true', and 'false'.", - valueString); -} - - - -static void -buildDouble(xmlrpc_env * const envP, - const char * const valueString, - xmlrpc_value ** const paramPP) { - - if (strlen(valueString) < 1) - setError(envP, "\"Double\" argument has nothing after the 'd/'"); - else { - double value; - char * tailptr; - - value = strtod(valueString, &tailptr); - - if (*tailptr != '\0') - setError(envP, - "\"Double\" argument has non-decimal crap in it: '%s'", - tailptr); - else - *paramPP = xmlrpc_double_new(envP, value); - } -} - - - -static void -buildNil(xmlrpc_env * const envP, - const char * const valueString, - xmlrpc_value ** const paramPP) { - - if (strlen(valueString) > 0) - setError(envP, "Nil argument has something after the 'n/'"); - else { - *paramPP = xmlrpc_nil_new(envP); - } -} - - - -static void -buildI8(xmlrpc_env * const envP, - const char * const valueString, - xmlrpc_value ** const paramPP) { - - if (strlen(valueString) < 1) - setError(envP, "Integer argument has nothing after the 'I/'"); - else { - int64_t value; - const char * error; - - interpretLl(valueString, &value, &error); - - if (error) { - setError(envP, "'%s' is not a valid 64-bit integer. %s", - valueString, error); - strfree(error); - } else - *paramPP = xmlrpc_i8_new(envP, value); - } -} - - - -static void -addArrayItem(xmlrpc_env * const envP, - const char ** const cursorP, - xmlrpc_value * const arrayP, - bool * const endP) { - - xmlrpc_value * itemP; - - buildValue(envP, cursorP, &itemP); - - if (!envP->fault_occurred) { - xmlrpc_array_append_item(envP, arrayP, itemP); - - if (!envP->fault_occurred) { - enum TokenType delim; - - getDelimiter(envP, cursorP, &delim); - - if (!envP->fault_occurred) { - switch (delim) { - case COMMA: break; - case RIGHTPAREN: *endP = true; break; - default: - setError(envP, "Array specifier has garbage where " - "there should be a comma " - "(element separator) " - "or close parenthesis " - "(marking the end of the element list)"); - } - } - } - xmlrpc_DECREF(itemP); - } -} - - - -static void -buildArray(xmlrpc_env * const envP, - const char ** const cursorP, - xmlrpc_value ** const valuePP) { - - enum TokenType tokenType; - - getDelimiter(envP, cursorP, &tokenType); - - if (!envP->fault_occurred) { - if (tokenType != LEFTPAREN) - setError(envP, "Array specifier value starts with %s instead of " - "left parenthesis", tokenTypeName(tokenType)); - else { - xmlrpc_value * const arrayP = xmlrpc_array_new(envP); - - if (!envP->fault_occurred) { - bool end; /* We've reached the end of the array elements */ - for (end = false; !end && !envP->fault_occurred; ) - addArrayItem(envP, cursorP, arrayP, &end); - - if (envP->fault_occurred) - xmlrpc_DECREF(arrayP); - else - *valuePP = arrayP; - } - } - } -} - - - -static void -addStructMember(xmlrpc_env * const envP, - const char ** const cursorP, - xmlrpc_value * const structP, - bool * const endP) { - - const char * key; - - getCdata(envP, cursorP, &key); - - if (!envP->fault_occurred) { - enum TokenType delim; - - getDelimiter(envP, cursorP, &delim); - - if (!envP->fault_occurred) { - if (delim != COLON) - setError(envP, "Something other than a colon follows the " - "key value '%s' in a structure member.", key); - else { - xmlrpc_value * valueP; - - buildValue(envP, cursorP, &valueP); - - if (!envP->fault_occurred) { - xmlrpc_struct_set_value(envP, structP, key, valueP); - - if (!envP->fault_occurred) { - enum TokenType delim; - - getDelimiter(envP, cursorP, &delim); - - if (!envP->fault_occurred) { - switch (delim) { - case COMMA: break; - case RIGHTBRACE: *endP = true; break; - default: - setError(envP, "Struct specifier " - "has garbage where " - "there should be a comma " - "(member separator) " - "or close brace " - "(marking the end of the " - "member list)"); - } - } - } - xmlrpc_DECREF(valueP); - } - } - } - strfree(key); - } -} - - - - -static void -buildStruct(xmlrpc_env * const envP, - const char ** const cursorP, - xmlrpc_value ** const valuePP) { - - enum TokenType tokenType; - - getDelimiter(envP, cursorP, &tokenType); - - if (!envP->fault_occurred) { - if (tokenType != LEFTBRACE) - setError(envP, "Struct specifier value starts with %s instead of " - "left brace", tokenTypeName(tokenType)); - else { - xmlrpc_value * const structP = xmlrpc_struct_new(envP); - - if (!envP->fault_occurred) { - bool end; /* We've reached the end of the struct members */ - for (end = false; !end && !envP->fault_occurred; ) - addStructMember(envP, cursorP, structP, &end); - - if (envP->fault_occurred) - xmlrpc_DECREF(structP); - else - *valuePP = structP; - } - } - } -} - - - -static void -buildValue(xmlrpc_env * const envP, - const char ** const cursorP, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Parse the text at *cursorP as a specification of an XML-RPC value - (e.g. "i/4" or "array/(i/0,i/2,i/2)") - - Stop parsing at the end of the specification of one value. Advance - *cursorP to that spot. ------------------------------------------------------------------------------*/ - const char * cdata; - - getCdata(envP, cursorP, &cdata); - /* This should get e.g. "i/492" or "hello" or "array/" */ - - if (!envP->fault_occurred) { - if (strlen(cdata) == 0) - setError(envP, "Expected value type specifier such as 'i/' or " - "'array/' but found '%s'", *cursorP); - - if (xmlrpc_strneq(cdata, "s/", 2)) - buildString(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "h/", 2)) - buildBytestring(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "i/", 2)) - buildInt(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "I/", 2)) - buildI8(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "d/", 2)) - buildDouble(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "b/", 2)) - buildBool(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "n/", 2)) - buildNil(envP, &cdata[2], valuePP); - else if (xmlrpc_strneq(cdata, "array/", 6)) { - if (cdata[6] != '\0') - setError(envP, "Junk after 'array/' instead of " - "left parenthesis: '%s'", &cdata[6]); - else - buildArray(envP, cursorP, valuePP); - } else if (xmlrpc_strneq(cdata, "struct/", 7)) { - if (cdata[7] != '\0') - setError(envP, "Junk after 'struct/' instead of " - "left brace: '%s'", &cdata[7]); - else - buildStruct(envP, cursorP, valuePP); - } else { - /* It's not in normal type/value format, so we take it to be - the shortcut string notation - */ - buildString(envP, cdata, valuePP); - } - strfree(cdata); - } -} - - - -static void -computeParam(xmlrpc_env * const envP, - const char * const paramArg, - xmlrpc_value ** const paramPP) { - - const char * cursor; - - cursor = ¶mArg[0]; - - buildValue(envP, &cursor, paramPP); - - if (!envP->fault_occurred) { - if (*cursor != '\0') - setError(envP, "Junk after parameter specification: '%s'", cursor); - } -} - - - -static void -computeParamArray(xmlrpc_env * const envP, - unsigned int const paramCount, - const char ** const params, - xmlrpc_value ** const paramArrayPP) { - - unsigned int i; - - xmlrpc_value * paramArrayP; - - paramArrayP = xmlrpc_array_new(envP); - - for (i = 0; i < paramCount && !envP->fault_occurred; ++i) { - xmlrpc_value * paramP; - xmlrpc_env paramEnv; - - xmlrpc_env_init(¶mEnv); - - computeParam(¶mEnv, params[i], ¶mP); - - if (!paramEnv.fault_occurred) { - xmlrpc_array_append_item(¶mEnv, paramArrayP, paramP); - - xmlrpc_DECREF(paramP); - } - if (paramEnv.fault_occurred) - setError(envP, "Invalid specification of parameter %u " - "(starting at zero). %s", i, paramEnv.fault_string); - - xmlrpc_env_clean(¶mEnv); - } - *paramArrayPP = paramArrayP; -} - - - -static void -dumpResult(xmlrpc_value * const resultP) { - - printf("Result:\n\n"); - - dumpValue("", resultP); -} - - - -static void -callWithClient(xmlrpc_env * const envP, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const resultPP) { - - xmlrpc_env env; - xmlrpc_env_init(&env); - *resultPP = xmlrpc_client_call_server_params( - &env, serverInfoP, methodName, paramArrayP); - - if (env.fault_occurred) - xmlrpc_faultf(envP, "Call failed. %s. (XML-RPC fault code %d)", - env.fault_string, env.fault_code); - xmlrpc_env_clean(&env); -} - - - -static void -doCall(xmlrpc_env * const envP, - const char * const transport, - const char * const curlinterface, - xmlrpc_bool const curlnoverifypeer, - xmlrpc_bool const curlnoverifyhost, - const char * const curluseragent, - const xmlrpc_server_info * const serverInfoP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const resultPP) { - - struct xmlrpc_clientparms clientparms; - - XMLRPC_ASSERT(xmlrpc_value_type(paramArrayP) == XMLRPC_TYPE_ARRAY); - - clientparms.transport = transport; - - if (transport && streq(transport, "curl")) { - struct xmlrpc_curl_xportparms * curlXportParmsP; - MALLOCVAR(curlXportParmsP); - - curlXportParmsP->network_interface = curlinterface; - curlXportParmsP->no_ssl_verifypeer = curlnoverifypeer; - curlXportParmsP->no_ssl_verifyhost = curlnoverifyhost; - curlXportParmsP->user_agent = curluseragent; - - clientparms.transportparmsP = curlXportParmsP; - clientparms.transportparm_size = XMLRPC_CXPSIZE(user_agent); - } else { - clientparms.transportparmsP = NULL; - clientparms.transportparm_size = 0; - } - xmlrpc_client_init2(envP, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, - &clientparms, XMLRPC_CPSIZE(transportparm_size)); - if (!envP->fault_occurred) { - callWithClient(envP, serverInfoP, methodName, paramArrayP, resultPP); - - xmlrpc_client_cleanup(); - } - if (clientparms.transportparmsP) - free((void*)clientparms.transportparmsP); -} - - - -static void -createServerInfo(xmlrpc_env * const envP, - const char * const serverUrl, - const char * const userName, - const char * const password, - xmlrpc_server_info ** const serverInfoPP) { - - xmlrpc_server_info * serverInfoP; - - serverInfoP = xmlrpc_server_info_new(envP, serverUrl); - if (!envP->fault_occurred) { - if (userName) { - xmlrpc_server_info_set_basic_auth( - envP, serverInfoP, userName, password); - } - } - *serverInfoPP = serverInfoP; -} - - - -int -main(int const argc, - const char ** const argv) { - - struct cmdlineInfo cmdline; - xmlrpc_env env; - xmlrpc_value * paramArrayP; - xmlrpc_value * resultP; - const char * url; - xmlrpc_server_info * serverInfoP; - - xmlrpc_env_init(&env); - - parseCommandLine(&env, argc, argv, &cmdline); - die_if_fault_occurred(&env); - - if (cmdline.xmlsizelimitSpec) - xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, cmdline.xmlsizelimit); - - computeUrl(cmdline.url, &url); - - computeParamArray(&env, cmdline.paramCount, cmdline.params, ¶mArrayP); - die_if_fault_occurred(&env); - - createServerInfo(&env, url, cmdline.username, cmdline.password, - &serverInfoP); - die_if_fault_occurred(&env); - - doCall(&env, cmdline.transport, cmdline.curlinterface, - cmdline.curlnoverifypeer, cmdline.curlnoverifyhost, - cmdline.curluseragent, - serverInfoP, - cmdline.methodName, paramArrayP, - &resultP); - die_if_fault_occurred(&env); - - dumpResult(resultP); - - strfree(url); - - xmlrpc_DECREF(resultP); - - freeCmdline(cmdline); - - xmlrpc_env_clean(&env); - - return 0; -} diff --git a/trunk/tools/xmlrpc_cpp_proxy/Makefile b/trunk/tools/xmlrpc_cpp_proxy/Makefile deleted file mode 100644 index 8bf1f7f23..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - TOOLSDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(TOOLSDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools/xmlrpc_cpp_proxy - -default: all - -include $(BLDDIR)/config.mk - -PROGRAMS_TO_INSTALL = xmlrpc_cpp_proxy - -include $(SRCDIR)/tools/common.mk - -# in Glibc 2.2 has a bug that results in inlining failure, -# so we disable warnings for that: -CFLAGS_LOCAL = $(CFLAGS_NO_INLINE_WARNING) - -INCLUDES = -I$(BLDDIR) -I$(BLDDIR)/include -Isrcdir/include - -all: xmlrpc_cpp_proxy - -OBJECTS = \ - xmlrpc_cpp_proxy.o \ - xmlrpcMethod.o \ - xmlrpcType.o \ - proxyClass.o \ - systemProxy.o \ - -LIBS = \ - $(LIBXMLRPC_CLIENTPP) \ - $(LIBXMLRPCPP) \ - $(CLIENT_LIBS_DEP) \ - $(LIBXMLRPC) \ - $(LIBXMLRPC_XML) \ - $(LIBXMLRPC_UTILPP) \ - $(LIBXMLRPC_UTIL) \ - -LDLIBS = $(CLIENTPP_LDLIBS) $(CLIENT_LDLIBS) $(SOCKETLIBOPT) $(THREAD_LIBS) - -xmlrpc_cpp_proxy: $(OBJECTS) $(LIBS) - $(CXXLD) -o $@ $(LDFLAGS_ALL) $(OBJECTS) $(LDLIBS) $(LADD) - -%.o:%.cpp $(BLDDIR)/include/xmlrpc-c/config.h - $(CXX) -c $(CXXFLAGS_ALL) $< - -# This common.mk dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/tools/common.mk: srcdir blddir - -include depend.mk - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean -clean: clean-common - rm -f xmlrpc_cpp_proxy - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: dep -dep: dep-common diff --git a/trunk/tools/xmlrpc_cpp_proxy/proxyClass.cpp b/trunk/tools/xmlrpc_cpp_proxy/proxyClass.cpp deleted file mode 100644 index 295b4824f..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/proxyClass.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include - -using namespace std; - -#include "xmlrpc-c/client_simple.hpp" - -#include "xmlrpcType.hpp" -#include "xmlrpcMethod.hpp" - -#include "proxyClass.hpp" - - -proxyClass::proxyClass(string const& className) : - _className(className) {} - - - -proxyClass::proxyClass(proxyClass const& c) : - _className(c._className), - functions(c.functions) {} - - - -string -proxyClass::className() const { - - return this->_className; -} - - - -void -proxyClass::addFunction(xmlrpcMethod const& function) { - - functions.push_back(function); -} - - - -void -proxyClass::printDeclaration(ostream & out) const { - - out << "class " << this->_className << " {" << endl; - out << endl; - out << "public:" << endl; - - // emit the constructor prototype: - out << " " << this->_className << "(std::string const& serverUrl) " - << endl - << " : serverUrl(serverUrl) {}" - << endl; - - // emit the XML-RPC method method prototypes: - vector::const_iterator f; - for (f = this->functions.begin(); f < this->functions.end(); ++f) { - f->printDeclarations(out); - } - - // emit the private data: - - out << "private:" << endl; - - out << " xmlrpc_c::clientSimple client;" << endl; - - out << " std::string const serverUrl;" << endl; - out << " // The URL for the server for which we are proxy" << endl; - - // emit the class closing: - out << "};" << endl; -} - - - -void -proxyClass::printDefinition(ostream & out) const { - - vector::const_iterator f; - - for (f = this->functions.begin(); f < this->functions.end(); ++f) { - f->printDefinitions(out, this->_className); - } -} - diff --git a/trunk/tools/xmlrpc_cpp_proxy/proxyClass.hpp b/trunk/tools/xmlrpc_cpp_proxy/proxyClass.hpp deleted file mode 100644 index 572f44451..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/proxyClass.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -#include "xmlrpcMethod.hpp" - -class proxyClass { - // An object of this class contains information about a proxy - // class, and knows how to generate code. - -public: - proxyClass(std::string const& className); - - proxyClass(proxyClass const&); - - std::string - className() const; - - void - addFunction(xmlrpcMethod const& function); - - void - printDeclaration(std::ostream& out) const; - - void - printDefinition(std::ostream& out) const; - -private: - - std::string const _className; - - std::vector functions; -}; diff --git a/trunk/tools/xmlrpc_cpp_proxy/systemProxy.cpp b/trunk/tools/xmlrpc_cpp_proxy/systemProxy.cpp deleted file mode 100644 index 51556873b..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/systemProxy.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/*============================================================================= - systemProxy -=============================================================================== - - This is a proxy class for the introspection system methods of the server. - - Note that you can use 'xmlrpc_cpp_proxy' itself to generate this - file, but we hand-edit it to make it easier to read. - -=============================================================================*/ - -#include "systemProxy.hpp" - -using namespace std; - -xmlrpc_c::value // array -systemProxy::listMethods(string const& serverUrl) { - - xmlrpc_c::paramList params; - xmlrpc_c::value result; - - this->call(serverUrl, "system.listMethods", &result); - - return result; -} - - - -xmlrpc_c::value // array -systemProxy::methodSignature(string const& serverUrl, - string const& methodName) { - - xmlrpc_c::paramList params; - params.add(xmlrpc_c::value_string(methodName)); - - xmlrpc_c::value result; - - this->call(serverUrl, "system.methodSignature", params, &result); - - return result; -} - - - -string -systemProxy::methodHelp(string const& serverUrl, - string const& methodName) { - - xmlrpc_c::paramList params; - params.add(xmlrpc_c::value_string(methodName)); - - xmlrpc_c::value result; - - this->call(serverUrl, "system.methodHelp", params, &result); - - return xmlrpc_c::value_string(result); -} diff --git a/trunk/tools/xmlrpc_cpp_proxy/systemProxy.hpp b/trunk/tools/xmlrpc_cpp_proxy/systemProxy.hpp deleted file mode 100644 index db4808b12..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/systemProxy.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef SYSTEMPROXY_HPP_INCLUDED -#define SYSTEMPROXY_HPP_INCLUDED - -#include -#include - -class systemProxy : public xmlrpc_c::clientSimple { - -public: - systemProxy() {} - - xmlrpc_c::value /*array*/ - listMethods(std::string const& serverUrl); - - xmlrpc_c::value /*array*/ - methodSignature(std::string const& serverUrl, - std::string const& methodName); - - std::string - methodHelp(std::string const& serverUrl, - std::string const& methodName); -}; - -#endif - diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp deleted file mode 100644 index 544648b65..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include -#include -#include - -#include "xmlrpcType.hpp" - -#include "xmlrpcMethod.hpp" - -using namespace std; - - -xmlrpcMethod::xmlrpcMethod(string const& functionName, - string const& methodName, - string const& help, - xmlrpc_c::value_array const& signatureList) : - mFunctionName(functionName), - mMethodName(methodName), - mHelp(help), - mSynopsis(signatureList) {} - - - -xmlrpcMethod::xmlrpcMethod(xmlrpcMethod const& f) : - mFunctionName(f.mFunctionName), - mMethodName(f.mMethodName), - mHelp(f.mHelp), - mSynopsis(f.mSynopsis) {} - - - -xmlrpcMethod& -xmlrpcMethod::operator= (xmlrpcMethod const& f) { - - if (this != &f) { - this->mFunctionName = f.mFunctionName; - this->mMethodName = f.mMethodName; - this->mHelp = f.mHelp; - this->mSynopsis = f.mSynopsis; - } - return *this; -} - - - - - - -size_t -xmlrpcMethod::parameterCount(size_t const synopsisIndex) const { - - xmlrpc_c::value_array const funcSynop( - mSynopsis.vectorValueValue()[synopsisIndex]); - size_t const size(funcSynop.size()); - - if (size < 1) - throw domain_error("Synopsis contains no items"); - - return size - 1; -} - - - -xmlrpcType const& -xmlrpcMethod::parameterType(size_t const synopsisIndex, - size_t const parameterIndex) const { - - xmlrpc_c::value_array const funcSynop( - mSynopsis.vectorValueValue()[synopsisIndex]); - xmlrpc_c::value_string const param( - funcSynop.vectorValueValue()[parameterIndex + 1]); - - return findXmlrpcType(static_cast(param)); -} - - - -const xmlrpcType& -xmlrpcMethod::returnType(size_t const synopsisIndex) const { - - xmlrpc_c::value_array const funcSynop( - mSynopsis.vectorValueValue()[synopsisIndex]); - - xmlrpc_c::value_string datatype(funcSynop.vectorValueValue()[0]); - return findXmlrpcType(static_cast(datatype)); -} - - - -void -xmlrpcMethod::printParameters(ostream & out, - size_t const synopsisIndex) const { -/*---------------------------------------------------------------------------- - Print the parameter declarations. ------------------------------------------------------------------------------*/ - size_t const end(parameterCount(synopsisIndex)); - - bool first; - - first = true; - - for (size_t i = 0; i < end; ++i) { - if (!first) - out << ", "; - - xmlrpcType const& ptype(parameterType(synopsisIndex, i)); - - string const localName(ptype.defaultParameterBaseName(i + 1)); - out << ptype.parameterFragment(localName); - - first = false; - } -} - - - -void -xmlrpcMethod::printDeclaration(ostream & out, - size_t const synopsisIndex) const { - - try { - xmlrpcType const& rtype(returnType(synopsisIndex)); - - out << " " << rtype.returnTypeFragment() << " " - << mFunctionName << " ("; - - printParameters(out, synopsisIndex); - - out << ");" << endl; - } catch (xmlrpc_c::fault const& f) { - ostringstream msg; - - msg << "Failed to generate header for signature " - << synopsisIndex - << " . " - << f.getDescription(); - - throw(logic_error(msg.str())); - } -} - - - -void -xmlrpcMethod::printDeclarations(ostream & out) const { - - try { - // Print the method help as a comment - - out << endl << " /* " << mHelp << " */" << endl; - - size_t end; - - try { - end = mSynopsis.size(); - } catch (xmlrpc_c::fault const& f) { - throw(logic_error("Failed to get size of signature array for " - "method " + this->mFunctionName + ". " + - f.getDescription())); - } - // Print the declarations for all the signatures of this - // XML-RPC method. - - for (size_t i = 0; i < end; ++i) - printDeclaration(out, i); - - } catch (exception const& e) { - throw(logic_error("Failed to generate declarations for method " + - this->mFunctionName + ". " + e.what())); - } -} - - - -void -xmlrpcMethod::printDefinition(ostream & out, - string const& className, - size_t const synopsisIndex) const { - - xmlrpcType const& rtype(returnType(synopsisIndex)); - - out << rtype.returnTypeFragment() << " " - << className << "::" << mFunctionName << " ("; - - printParameters(out, synopsisIndex); - - out << ") {" << endl; - - size_t const end(parameterCount(synopsisIndex)); - if (end > 0){ - // Emit code to generate the parameter list object - out << " xmlrpc_c::paramList params;" << endl; - for (size_t i = 0; i < end; ++i) { - xmlrpcType const& ptype(parameterType(synopsisIndex, i)); - string const basename(ptype.defaultParameterBaseName(i + 1)); - out << " params.add(" - << ptype.inputConversionFragment(basename) << ");" << endl; - } - } - - // Emit result holder declaration. - out << " xmlrpc_c::value result;" << endl; - - // Emit the call to the XML-RPC call method - out << " this->client.call(" - << "this->serverUrl, " - << "\"" << mMethodName << "\", "; - - if (end > 0) - out << "params, "; - - out << "&result);" << endl; - - // Emit the return statement. - out << " return " << rtype.outputConversionFragment("result") - << ";" << endl; - out << "}" << endl; -} - - - -void -xmlrpcMethod::printDefinitions(ostream & out, - string const& className) const { - - try { - size_t const end(mSynopsis.size()); - - for (size_t i = 0; i < end; ++i) { - out << endl; - printDefinition(out, className, i); - } - } catch (xmlrpc_c::fault const& f) { - throw(logic_error("Failed to generate definitions for class " + - this->mFunctionName + ". " + - f.getDescription())); - } -} - - - diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp deleted file mode 100644 index 276899703..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef XMLRPCMETHOD_HPP -#define XMLRPCMETHOD_HPP - -#include -#include -#include - -class xmlrpcMethod { - // An object of this class contains everything we know about a - // given XML-RPC method, and knows how to print local bindings. - - std::string mFunctionName; - std::string mMethodName; - std::string mHelp; - xmlrpc_c::value_array mSynopsis; - -public: - xmlrpcMethod(std::string const& function_name, - std::string const& method_name, - std::string const& help, - xmlrpc_c::value_array const& signatureList); - - xmlrpcMethod(xmlrpcMethod const& f); - - xmlrpcMethod& operator= (xmlrpcMethod const& f); - - void - printDeclarations(std::ostream& out) const; - - void - printDefinitions(std::ostream & out, - std::string const& className) const; - -private: - void - printParameters(std::ostream & out, - size_t const synopsis_index) const; - - void - printDeclaration(std::ostream & out, - size_t const synopsis_index) const; - - void - printDefinition(std::ostream & out, - std::string const& className, - size_t const synopsis_index) const; - - const xmlrpcType& - returnType(size_t const synopsis_index) const; - - size_t - parameterCount(size_t const synopsis_index) const; - - const xmlrpcType& - parameterType(size_t const synopsis_index, - size_t const parameter_index) const; -}; - -#endif diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp deleted file mode 100644 index f884ee419..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp +++ /dev/null @@ -1,270 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include "xmlrpcType.hpp" - -using namespace std; - - - -//========================================================================= -// abstract class xmlrpcType -//========================================================================= -// Instances of xmlrpcType know how generate code fragments for manipulating -// a specific XML-RPC data type. - -string -xmlrpcType::defaultParameterBaseName(unsigned int const position) const { - - ostringstream nameStream; - - nameStream << typeName() << position; - - return nameStream.str(); -} - - - -class rawXmlrpcType : public xmlrpcType { -public: - rawXmlrpcType(string const& typeName) : xmlrpcType(typeName) {} - - virtual string - parameterFragment(string const& baseName) const; - - virtual string - inputConversionFragment(string const& baseName) const; - - virtual string - returnTypeFragment() const; - - virtual string - outputConversionFragment(string const& varName) const; -}; - - - -string -rawXmlrpcType::parameterFragment(string const& baseName) const { - return "xmlrpc_c::value /*" + typeName() + "*/ " + baseName; -} - - - -string -rawXmlrpcType::inputConversionFragment(string const& baseName) const { - - return baseName; -} - - - -string -rawXmlrpcType::returnTypeFragment() const { - return "xmlrpc_c::value /*" + typeName() + "*/"; -} - - - -string -rawXmlrpcType::outputConversionFragment(string const& varName) const { - - return varName; -} - - - -class simpleXmlrpcType : public xmlrpcType { - - string mNativeType; - string mMakerFunc; - string mGetterFunc; - -public: - simpleXmlrpcType(string const& typeName, - string const& nativeType, - string const& makerFunc, - string const& getterFunc); - - virtual string - parameterFragment(string const& baseName) const; - - virtual string - inputConversionFragment(string const& baseName) const; - - virtual string - returnTypeFragment() const; - - virtual string - outputConversionFragment(string const& varName) const; -}; - - - -simpleXmlrpcType::simpleXmlrpcType(string const& typeName, - string const& nativeType, - string const& makerFunc, - string const& getterFunc) - : xmlrpcType(typeName), - mNativeType(nativeType), - mMakerFunc(makerFunc), - mGetterFunc(getterFunc) { -} - - - -string -simpleXmlrpcType::parameterFragment(string const& baseName) const { - - return mNativeType + " const " + baseName; -} - - - -string -simpleXmlrpcType::inputConversionFragment(string const& baseName) const { - - return mMakerFunc + "(" + baseName + ")"; -} - - - -string -simpleXmlrpcType::returnTypeFragment() const { - - return mNativeType; -} - - - -string -simpleXmlrpcType::outputConversionFragment(string const& varName) const { - return mMakerFunc + "(" + varName + ")"; -} - - - -class voidXmlrpcType : public xmlrpcType { -public: - voidXmlrpcType() : xmlrpcType("void") {} - - virtual string - parameterFragment(string const& baseName) const; - - virtual string - inputConversionFragment(string const& baseName) const; - - virtual string - returnTypeFragment() const; - - virtual string - outputConversionFragment(string const& varName) const; -}; - - - -string -voidXmlrpcType::parameterFragment(string const&) const { - - throw domain_error("Can't handle functions with 'void' arguments'"); -} - - - -string -voidXmlrpcType::inputConversionFragment(string const&) const { - - throw domain_error("Can't handle functions with 'void' arguments'"); -} - - - -string -voidXmlrpcType::returnTypeFragment () const { - - return "void"; -} - - - -string -voidXmlrpcType::outputConversionFragment(string const&) const { - return "/* Return value ignored. */"; -} - - - -static simpleXmlrpcType const intType ("int", "int", - "xmlrpc_c::value_int", - "getInt"); -static simpleXmlrpcType const boolType ("bool", "bool", - "xmlrpc_c::value_boolean", - "getBool"); -static simpleXmlrpcType const doubleType ("double", "double", - "xmlrpc_c::value_double", - "getDouble"); -static simpleXmlrpcType const stringType ("string", "std::string", - "xmlrpc_c::value_string", - "getString"); - -static rawXmlrpcType const dateTimeType ("dateTime"); -static rawXmlrpcType const base64Type ("base64"); -static rawXmlrpcType const structType ("struct"); -static rawXmlrpcType const arrayType ("array"); - -static voidXmlrpcType const voidType; - - - -const xmlrpcType& -findXmlrpcType(string const& name) { -/*---------------------------------------------------------------------------- - Given the name of an XML-RPC data type, try to find a corresponding - xmlrpcType object. ------------------------------------------------------------------------------*/ - if (name == "int" || name == "i4") - return intType; - else if (name == "boolean") - return boolType; - else if (name == "double") - return doubleType; - else if (name == "string") - return stringType; - else if (name == "dateTime.iso8601") - return dateTimeType; - else if (name == "base64") - return base64Type; - else if (name == "struct") - return structType; - else if (name == "array") - return arrayType; - else if (name == "void") - return voidType; - else if (name == "INT") - return intType; - else if (name == "BOOLEAN") - return boolType; - else if (name == "DOUBLE") - return doubleType; - else if (name == "STRING") - return stringType; - else if (name == "DATETIME.ISO8601") - return dateTimeType; - else if (name == "BASE64") - return base64Type; - else if (name == "STRUCT") - return structType; - else if (name == "ARRAY") - return arrayType; - else if (name == "VOID") - return voidType; - else if (name == "NIL") - return voidType; - else - throw domain_error("Unknown XML-RPC type name '" + name + "'"); -} diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp deleted file mode 100644 index 2b026f153..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -class xmlrpcType { - std::string mTypeName; - - xmlrpcType(xmlrpcType const&) { assert(false); } - - xmlrpcType& operator= (xmlrpcType const&) { - assert(false); - return *this; - } - -public: - xmlrpcType(const std::string& type_name) : mTypeName(type_name) {} - - virtual ~xmlrpcType () {} - - // Return the name for this XML-RPC type. - virtual std::string - typeName() const { return mTypeName; } - - // Given a parameter position, calculate a unique base name for all - // parameter-related variables. - virtual std::string - defaultParameterBaseName(unsigned int const position) const; - - // Virtual functions for processing parameters. - virtual std::string - parameterFragment(std::string const& base_name) const = 0; - - virtual std::string - inputConversionFragment(std::string const& base_name) const = 0; - - // Virtual functions for processing return values. - virtual std::string - returnTypeFragment () const = 0; - - virtual std::string - outputConversionFragment(std::string const& var_name) const = 0; -}; - -const xmlrpcType& findXmlrpcType(const std::string& name); diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp deleted file mode 100644 index 7ec8a477f..000000000 --- a/trunk/tools/xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#include -#include -#include - -#include "xmlrpcType.hpp" -#include "xmlrpcMethod.hpp" -#include "proxyClass.hpp" -#include "systemProxy.hpp" - -using namespace std; - - -/*---------------------------------------------------------------------------- - Command line ------------------------------------------------------------------------------*/ - -class cmdlineInfo { -public: - string serverUrl; - string methodPrefix; - string localClass; - - cmdlineInfo(int const argc, - const char ** const argv); - -private: - cmdlineInfo(); -}; - - - -cmdlineInfo::cmdlineInfo(int const argc, - const char ** const argv) { - - if (argc-1 != 3) { - cerr << "There are 3 arguments: server URL, " - << "prefix for the methods to include (null to include all), " - << "and name to give the generated proxy class. " - << "You specified " << argc-1 << " arguments." - << endl - << "Example: " - << "xmlrpc_cpp_proxy http://localhost/RPC2 system systemProxy" - << endl; - exit(1); - } - this->serverUrl = string(argv[1]); - this->methodPrefix = string(argv[2]); - this->localClass = string(argv[3]); -} - - - -static proxyClass -getClassInfo(string const& serverUrl, - string const& classPrefix, - string const& className) { -/*---------------------------------------------------------------------------- - Connect to a remote server and extract the information we'll need to - build a proxy class. ------------------------------------------------------------------------------*/ - proxyClass theClass(className); - - systemProxy system; - - xmlrpc_c::value_array methods(system.listMethods(serverUrl)); - - unsigned int arraySize = methods.size(); - - for (size_t i = 0; i < arraySize; ++i) { - - // Break the method name into two pieces. - xmlrpc_c::value_string val = (methods.vectorValueValue())[i]; - string const methodName(static_cast(val)); - size_t const lastDot(methodName.rfind('.')); - - string methodPrefix; - string functionName; - - if (lastDot == string::npos) { - methodPrefix = ""; - functionName = methodName; - } else { - methodPrefix = string(methodName, 0, lastDot); - functionName = string(methodName, lastDot + 1); - } - - if (methodPrefix == classPrefix) { - // It's a method User cares about - - string const help(system.methodHelp(serverUrl, methodName)); - xmlrpc_c::value const signatureList( - system.methodSignature(serverUrl, methodName)); - - if (signatureList.type() != xmlrpc_c::value::TYPE_ARRAY) { - // It must be the string "undef", meaning the server - // won't tell us any signatures. - cerr << "Skipping method " << methodName << " " - << "because server does not report any signatures " - << "for it (via system.methodSignature method)" - << endl; - } else { - // Add this function to our class information. - xmlrpcMethod const method( - functionName, - methodName, - help, - xmlrpc_c::value_array(signatureList)); - theClass.addFunction(method); - } - } - } - return theClass; -} - - - -static void -printHeader(ostream & out, - proxyClass const& classInfo) { -/*---------------------------------------------------------------------------- - Print a complete header for the specified class. ------------------------------------------------------------------------------*/ - string const className(classInfo.className()); - - try { - out << "// Interface definition for " << className << " class, " - << "an XML-RPC FOR C/C++ proxy class" << endl; - out << "// Generated by 'xmlrpc_cpp_proxy'" << endl; - out << endl; - - string const headerSymbol("_" + className + "_H_"); - - out << "#ifndef " << headerSymbol << endl; - out << "#define " << headerSymbol << " 1" << endl; - out << endl; - out << "#include " << endl; - out << "#include " << endl; - out << endl; - - classInfo.printDeclaration(cout); - - out << endl; - out << "#endif /* " << headerSymbol << " */" << endl; - } catch (exception const& e) { - throw(logic_error("Failed to generate header for class " + - className + ". " + e.what())); - } -} - - - -static void -printCppFile(ostream & out, - proxyClass const& classInfo) { -/*---------------------------------------------------------------------------- - Print a complete definition for the specified class. ------------------------------------------------------------------------------*/ - string const className(classInfo.className()); - - try { - out << "// " << className << " - " - << "an XML-RPC FOR C/C++ proxy class" << endl; - out << "// Generated by 'xmlrpc_cpp_proxy'" << endl; - out << endl; - - out << "#include \"" << className << ".h\"" << endl; - - classInfo.printDefinition(cout); - } catch (xmlrpc_c::fault const& f) { - throw(logic_error("Failed to generate definition for class " + - className + ". " + f.getDescription())); - } -} - - - -int -main(int const argc, - const char ** const argv) { - - string const myName(argv[0]); - - cmdlineInfo const cmdline(argc, argv); - - int retval; - - try { - proxyClass system(getClassInfo(cmdline.serverUrl, - cmdline.methodPrefix, - cmdline.localClass)); - printHeader(cout, system); - cout << endl; - printCppFile(cout, system); - retval = 0; - } catch (xmlrpc_c::fault& f) { - cerr << myName << ": XML-RPC fault #" << f.getCode() - << ": " << f.getDescription() << endl; - retval = 1; - } catch (exception const& e) { - cerr << myName << ": " << e.what() << endl; - retval = 1; - } catch (...) { - cerr << myName << ": Unknown exception" << endl; - retval = 1; - } - - return retval; -} diff --git a/trunk/tools/xmlrpc_dumpserver/Makefile b/trunk/tools/xmlrpc_dumpserver/Makefile deleted file mode 100644 index c5cbf0098..000000000 --- a/trunk/tools/xmlrpc_dumpserver/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - TOOLSDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(TOOLSDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools/xmlrpc_dumpserver - -default: all - -include $(BLDDIR)/config.mk - -PROGS := xmlrpc_dumpserver - -PROGRAMS_TO_INSTALL = $(PROGS) - -include $(SRCDIR)/tools/common.mk - -INCLUDES = \ - -I../lib/include \ - -Iblddir \ - -Iblddir/include \ - -Isrcdir/include \ - -Isrcdir/lib/util/include - -all: xmlrpc_dumpserver - -# cmdline.parser.o references getoptx.o and string_parser.o. -# string_parser.o references stripcaseeq.o - -UTIL_OBJS = \ - casprintf.o \ - cmdline_parser.o \ - getoptx.o \ - string_parser.o \ - stripcaseeq.o \ - -UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) - -DUMPVALUE = blddir/tools/lib/dumpvalue.o - -XMLRPC_OBJS = xmlrpc_dumpserver.o $(DUMPVALUE) - -xmlrpc_dumpserver: $(XMLRPC_OBJS) $(SERVER_ABYSS_LIBS_DEP) $(UTILS) - $(CCLD) -o $@ $(LDFLAGS_ALL) $(XMLRPC_OBJS) $(UTILS) \ - $(SERVER_ABYSS_LDLIBS) - -%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h - $(CC) -c $(CFLAGS_ALL) $< - -# This common.mk dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/tools/common.mk: srcdir blddir - -include depend.mk - -.PHONY: dep -dep: dep-common - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean -clean: clean-common - rm -f $(PROGS) - -.PHONY: distclean -distclean: clean distclean-common diff --git a/trunk/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c b/trunk/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c deleted file mode 100644 index 562fd3e93..000000000 --- a/trunk/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c +++ /dev/null @@ -1,269 +0,0 @@ -/*============================================================================= - xmlrpc_dumpserver -=============================================================================== - - This program runs an XML-RPC server that does nothing but print to Standard - Output the contents of every call it receives, and send a failure response. - - You use this to test a client or to learn about XML-RPC. - - Example: - - $ xmlrpc_dumpserver -port=8080 & - - $ xmlrpc localhost:8080 dummymethod s/hello i/5 - -=============================================================================*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include -#include -#include - -#include "xmlrpc_config.h" /* information about this build environment */ -#include "bool.h" -#include "int.h" -#include "mallocvar.h" -#include "girstring.h" -#include "casprintf.h" -#include "cmdline_parser.h" -#include "dumpvalue.h" - -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/server_abyss.h" - -#define NAME "xmlrpc command line program" -#define VERSION "1.0" - -struct CmdlineInfo { - unsigned int port; -}; - - - -static void -parseCommandLine(int const argc, - const char ** const argv, - struct CmdlineInfo * const cmdlineP, - const char ** const errorP) { - - cmdlineParser const cp = cmd_createOptionParser(); - - const char * error; - - cmd_defineOption(cp, "port", OPTTYPE_UINT); - - cmd_processOptions(cp, argc, argv, &error); - - if (error) { - casprintf(errorP, "Command syntax error. %s", error); - strfree(error); - } else { - *errorP = NULL; /* initial assumption */ - - if (cmd_argumentCount(cp) > 0) - casprintf(errorP, "No non-option arguments are possible. " - "You specified %u", cmd_argumentCount(cp)); - - if (!*errorP) { - if (cmd_optionIsPresent(cp, "port")) { - cmdlineP->port = cmd_getOptionValueUint(cp, "port"); - } else { - casprintf(errorP, "You must specify the TCP port number " - "on which to listen for XML-RPC calls with -port"); - } - } - } - cmd_destroyOptionParser(cp); -} - - - -static void -freeCmdline(struct CmdlineInfo const cmdline ATTR_UNUSED) { - -} - - - -static void -dumpParameters(xmlrpc_value * const paramArrayP) { - - xmlrpc_env env; - int arraySize; - unsigned int paramSeq; - - xmlrpc_env_init(&env); - - arraySize = xmlrpc_array_size(&env, paramArrayP); - - assert(!env.fault_occurred); - assert(arraySize >= 0); - - { - unsigned int const paramCt = arraySize; - - printf("Number of parameters: %u\n", paramCt); - - printf("\n"); - - for (paramSeq = 0; paramSeq < paramCt; ++paramSeq) { - - xmlrpc_value * paramValueP; - - xmlrpc_array_read_item(&env, paramArrayP, paramSeq, ¶mValueP); - - assert(!env.fault_occurred); - - printf("Parameter %u:\n", paramSeq); - printf("\n"); - - dumpValue(" ", paramValueP); - - xmlrpc_DECREF(paramValueP); - - printf("\n"); - } - } - xmlrpc_env_clean(&env); -} - - - -static xmlrpc_value * -defaultMethod(xmlrpc_env * const envP, - const char * const callInfoP ATTR_UNUSED, - const char * const methodName, - xmlrpc_value * const paramArrayP, - void * const serverInfo ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - This is a *xmlrpc_default_method, i.e. a default method for an Xmlrpc-c - registry, which is meant to be called by an XML-RPC server when it receives - a call for a method that is not registered by name. ------------------------------------------------------------------------------*/ - printf("Server has received a call of method '%s'\n", methodName); - - printf("\n"); - - assert(xmlrpc_value_type(paramArrayP) == XMLRPC_TYPE_ARRAY); - - dumpParameters(paramArrayP); - - xmlrpc_faultf(envP, - "This XML-RPC server is a test server that fails all " - "RPCs. But the fact that it failed this way tells you that " - "the call _was_ valid in XML-RPC terms. The server " - "printed to Standard Output a description of the valid " - "call."); - - /* Return value is irrelevant because we failed the RPC, but to prevent - a compiler warning: - */ - return NULL; -} - - - -static void -setServerParm(xmlrpc_server_abyss_parms * const serverparmP, - xmlrpc_registry * const registryP, - unsigned int const portNum, - size_t * const lengthP) { - - serverparmP->config_file_name = NULL; - serverparmP->registryP = registryP; - serverparmP->port_number = portNum; - serverparmP->log_file_name = NULL; - serverparmP->keepalive_timeout = 0; - serverparmP->keepalive_max_conn = 0; - serverparmP->timeout = 0; - serverparmP->dont_advertise = false; - serverparmP->socket_bound = false; - serverparmP->uri_path = NULL; - serverparmP->chunk_response = false; - serverparmP->enable_shutdown = true; - - *lengthP = XMLRPC_APSIZE(enable_shutdown); -} - - - -static void -runServer(unsigned int const portNum, - const char ** const errorP) { - - xmlrpc_registry * registryP; - xmlrpc_env env; - - xmlrpc_env_init(&env); - - registryP = xmlrpc_registry_new(&env); - if (env.fault_occurred) - casprintf(errorP, "xmlrpc_registry_new() failed. %s", - env.fault_string); - else { - xmlrpc_registry_set_default_method(&env, registryP, - &defaultMethod, NULL); - - if (env.fault_occurred) - casprintf(errorP, "xmlrpc_registry_add_method3() failed. %s", - env.fault_string); - else { - xmlrpc_server_abyss_parms serverparm; - size_t parmLength; - - setServerParm(&serverparm, registryP, portNum, &parmLength); - - printf("Running XML-RPC server on TCP Port %u...\n", portNum); - - xmlrpc_server_abyss(&env, &serverparm, parmLength); - - if (env.fault_occurred) - casprintf(errorP, "xmlrpc_server_abyss() failed. %s", - env.fault_string); - - /* xmlrpc_server_abyss() never returns unless it fails */ - *errorP = NULL; - } - } -} - - - -int -main(int const argc, - const char ** const argv) { - - int exitCode; - struct CmdlineInfo cmdline; - const char * error; - - parseCommandLine(argc, argv, &cmdline, &error); - - if (error) { - fprintf(stderr, "Command syntax error. %s\n", error); - strfree(error); - exitCode = 10; - } else { - const char * error; - - runServer(cmdline.port, &error); - - if (error) { - fprintf(stderr, "Server on port %u failed. %s\n", - cmdline.port, error); - strfree(error); - exitCode = 1; - } else - exitCode = 0; - - freeCmdline(cmdline); - } - return exitCode; -} - - - diff --git a/trunk/tools/xmlrpc_pstream/Makefile b/trunk/tools/xmlrpc_pstream/Makefile deleted file mode 100644 index 869a7f6b9..000000000 --- a/trunk/tools/xmlrpc_pstream/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - TOOLSDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(TOOLSDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools/xmlrpc_pstream - -READLINE_LDLIBS = -lreadline -lncurses - -default: all - -include $(BLDDIR)/config.mk - -PROGRAMS_TO_INSTALL = xmlrpc_pstream - -include $(SRCDIR)/tools/common.mk - -INCLUDES = \ - -I../lib/include \ - -Isrcdir/lib/util/include \ - -Iblddir \ - -Iblddir/include \ - -Isrcdir/include \ - -all: xmlrpc_pstream - -OBJECTS = \ - xmlrpc_pstream.o \ - blddir/tools/lib/dumpvalue.o \ - -LIBS = \ - $(LIBXMLRPC_CLIENTPP) \ - $(LIBXMLRPCPP) \ - $(CLIENT_LIBS_DEP) \ - $(LIBXMLRPC) \ - $(LIBXMLRPC_XML) \ - $(LIBXMLRPC_UTIL) \ - -LDLIBS = $(CLIENTPP_LDLIBS) $(CLIENT_LDLIBS) $(READLINE_LDLIBS) - -UTIL_OBJS = \ - casprintf.o \ - cmdline_parser_cpp.o \ - cmdline_parser.o \ - getoptx.o \ - string_parser.o \ - stripcaseeq.o \ - -UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) - -xmlrpc_pstream: $(OBJECTS) $(LIBS) $(UTILS) - $(CXXLD) -o $@ $(LDFLAGS_ALL) $(OBJECTS) $(UTILS) $(LDLIBS) $(LADD) - -%.o:%.cpp blddir/include/xmlrpc-c/config.h - $(CXX) -c $(CXXFLAGS_ALL) $< - -# This common.mk dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/tools/common.mk: srcdir blddir - -include depend.mk - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: clean -clean: clean-common - rm -f xmlrpc_pstream - -.PHONY: distclean -distclean: clean distclean-common - -.PHONY: dep -dep: dep-common diff --git a/trunk/tools/xmlrpc_pstream/test b/trunk/tools/xmlrpc_pstream/test deleted file mode 100755 index e618a19d0..000000000 --- a/trunk/tools/xmlrpc_pstream/test +++ /dev/null @@ -1,28 +0,0 @@ -#! /bin/sh - -# This is for testing and playing with Xmlrpc_pstream. - -# To use, first start a packet stream XML-RPC server. The -# 'pstream_inetd_server' program from examples/cpp is good: -# -# $ socketexec -accept -local_port=8080 -- pstream_inetd_server -# -# Then (in another shell), run this program: -# -# $ ./test -# > sample.add i/3 i/5 -# -# Result: -# Integer: 8 -# -# > [ctl-D] -# $ -# -# OR: -# -# $ ./test sample.add i/3 i/5 -# $ - -socketexec -connect -remote_host=localhost -remote_port=8080 --filedes=3 -- \ - ./xmlrpc_pstream $* - diff --git a/trunk/tools/xmlrpc_pstream/xmlrpc_pstream.cpp b/trunk/tools/xmlrpc_pstream/xmlrpc_pstream.cpp deleted file mode 100644 index d7a7097c9..000000000 --- a/trunk/tools/xmlrpc_pstream/xmlrpc_pstream.cpp +++ /dev/null @@ -1,507 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cmdline_parser.hpp" -#include "xmlrpc-c/girerr.hpp" -using girerr::throwf; - -#ifdef __cplusplus -extern "C" { -#endif - -#include "dumpvalue.h" /* An internal Xmlrpc-c header file ! */ - -#ifdef __cplusplus -} -#endif - -#include -#include -#include - -using namespace std; -using namespace xmlrpc_c; - -/*---------------------------------------------------------------------------- - Command line ------------------------------------------------------------------------------*/ - -class cmdlineInfo { -public: - int serverfd; - bool interactive; - - // Valid only if !interactive: - string methodName; - vector params; - - cmdlineInfo(int const argc, - const char ** const argv); - -private: - cmdlineInfo(); -}; - - - -static void -parseCommandLine(cmdlineInfo * const cmdlineP, - int const argc, - const char ** const argv) { - - CmdlineParser cp; - - cp.defineOption("serverfd", CmdlineParser::UINT); - - try { - cp.processOptions(argc, argv); - } catch (exception const& e) { - throwf("Command syntax error. %s", e.what()); - } - - if (cp.optionIsPresent("serverfd")) { - cmdlineP->serverfd = cp.getOptionValueUint("serverfd"); - } else - cmdlineP->serverfd = 3; - - if (cp.argumentCount() < 1) - cmdlineP->interactive = true; - else { - cmdlineP->interactive = false; - cmdlineP->methodName = cp.getArgument(0); - for (uint argI = 1; argI < cp.argumentCount(); ++argI) - cmdlineP->params.push_back(cp.getArgument(argI)); - } -} - - - -cmdlineInfo:: -cmdlineInfo(int const argc, - const char ** const argv) { - - try { - parseCommandLine(this, argc, argv); - } catch (exception const& e) { - throwf("Command syntax error. %s", e.what()); - } -} - - - -static value -bytestringValFromParm(string const& valueString) { - - value retval; - - if (valueString.length() / 2 * 2 != valueString.length()) - throwf("Hexadecimal text is not an even " - "number of characters (it is %u characters)", - (unsigned)valueString.length()); - else { - vector byteString(valueString.length() / 2); - size_t strCursor; - - strCursor = 0; - - while (strCursor < valueString.length()) { - string const hexByte(valueString.substr(strCursor, 2)); - - unsigned char byte; - int rc; - - rc = sscanf(hexByte.c_str(), "%2hhx", &byte); - - byteString.push_back(byte); - - if (rc != 1) - throwf("Invalid hex data '%s'", hexByte.c_str()); - else - strCursor += 2; - } - retval = value_bytestring(byteString); - } - return retval; -} - - - -static value -intValFromParm(string const& valueString) { - - value retval; - - if (valueString.length() < 1) - throwf("Integer argument has nothing after the 'i/'"); - else { - long longValue; - char * tailptr; - - errno = 0; - - longValue = strtol(valueString.c_str(), &tailptr, 10); - - if (errno == ERANGE) - throwf("'%s' is out of range for a 32 bit integer", - valueString.c_str()); - else if (errno != 0) - throwf("Mysterious failure of strtol(), errno=%d (%s)", - errno, strerror(errno)); - else { - if (*tailptr != '\0') - throwf("Integer argument has non-digit crap in it: '%s'", - tailptr); - else - retval = value_int(longValue); - } - } - return retval; -} - - - -static value -boolValFromParm(string const& valueString) { - - value retval; - - if (valueString == "t" || valueString == "true") - retval = value_boolean(true); - else if (valueString == "f" || valueString == "false") - retval = value_boolean(false); - else - throwf("Boolean argument has unrecognized value '%s'. " - "recognized values are 't', 'f', 'true', and 'false'.", - valueString.c_str()); - - return retval; -} - - - -static value -doubleValFromParm(string const& valueString) { - - value retval; - - if (valueString.length() < 1) - throwf("\"Double\" argument has nothing after the 'd/'"); - else { - double value; - char * tailptr; - - value = strtod(valueString.c_str(), &tailptr); - - if (*tailptr != '\0') - throwf("\"Double\" argument has non-decimal crap in it: '%s'", - tailptr); - else - retval = value_double(value); - } - return retval; -} - - - -static value -nilValFromParm(string const& valueString) { - - value retval; - - if (valueString.length() > 0) - throwf("Nil argument has something after the 'n/'"); - else - retval = value_nil(); - - return retval; -} - - - -static value -i8ValFromParm(string const& valueString) { - - value retval; - - if (valueString.length() < 1) - throwf("Integer argument has nothing after the 'I/'"); - else { - long long value; - char * tailptr; - - errno = 0; - - value = strtoll(valueString.c_str(), &tailptr, 10); - - if (errno == ERANGE) - throwf("'%s' is out of range for a 64 bit integer", - valueString.c_str()); - else if (errno != 0) - throwf("Mysterious failure of strtoll(), errno=%d (%s)", - errno, strerror(errno)); - else { - if (*tailptr != '\0') - throwf("64 bit integer argument has non-digit crap " - "in it: '%s'", - tailptr); - else - retval = value_i8(value); - } - } - return retval; -} - - - -static value -parameterFromArg(string const& paramArg) { - - value param; - - try { - if (paramArg.substr(0, 2) == "s/") - param = value_string(paramArg.substr(2)); - else if (paramArg.substr(0, 2) == "h/") - param = bytestringValFromParm(paramArg.substr(2)); - else if (paramArg.substr(0, 2) == "i/") - param = intValFromParm(paramArg.substr(2)); - else if (paramArg.substr(0, 2) == "I/") - param = i8ValFromParm(paramArg.substr(2)); - else if (paramArg.substr(0, 2) == "d/") - param = doubleValFromParm(paramArg.substr(2)); - else if (paramArg.substr(0, 2) == "b/") - param = boolValFromParm(paramArg.substr(2)); - else if (paramArg.substr(0, 2) == "n/") - param = nilValFromParm(paramArg.substr(2)); - else { - /* It's not in normal type/value format, so we take it to be - the shortcut string notation - */ - param = value_string(paramArg); - } - } catch (exception const& e) { - throwf("Failed to interpret parameter argument '%s'. %s", - paramArg.c_str(), e.what()); - } - return param; -} - - - -static paramList -paramListFromParamArgs(vector const& params) { - - paramList paramList; - - for (vector::const_iterator p = params.begin(); - p != params.end(); ++p) - paramList.add(parameterFromArg(*p)); - - return paramList; -} - - - -static void -callWithClient(client * const clientP, - string const& methodName, - paramList const& paramList, - value * const resultP) { - - rpcPtr myRpcP(methodName, paramList); - - carriageParm_pstream myCarriageParm; // Empty - no parm needed - - try { - myRpcP->call(clientP, &myCarriageParm); - } catch (exception const& e) { - throwf("RPC failed. %s", e.what()); - } - *resultP = myRpcP->getResult(); -} - - - -static void -dumpResult(value const& result) { - - cout << "Result:" << endl << endl; - - /* Here we borrow code from inside Xmlrpc-c, and also use an - internal interface of xmlrpc_c::value. This sliminess is one - reason that this is Bryan's private code instead of part of the - Xmlrpc-c package. - - Note that you must link with the dumpvalue.o object module from - inside an Xmlrpc-c build tree. - */ - - dumpValue("", result.cValueP); -} - - - -static list -parseWordList(string const& wordString) { - - list retval; - - unsigned int pos; - - pos = 0; - - while (pos < wordString.length()) { - pos = wordString.find_first_not_of(' ', pos); - - if (pos < wordString.length()) { - unsigned int const end = wordString.find_first_of(' ', pos); - - retval.push_back(wordString.substr(pos, end - pos)); - - pos = end; - } - } - return retval; -} - - - -static void -parseCommand(string const& cmd, - string * const methodNameP, - vector * const paramListP) { - - list const wordList(parseWordList(cmd)); - - list::const_iterator cmdWordP; - - cmdWordP = wordList.begin(); - - if (cmdWordP == wordList.end()) - throwf("Command '%s' does not have a method name", cmd.c_str()); - else { - *methodNameP = *cmdWordP++; - - *paramListP = vector(); // Start empty - - while (cmdWordP != wordList.end()) - paramListP->push_back(*cmdWordP++); - } -} - - - -static void -doCommand(client_xml * const clientP, - string const& methodName, - vector const& paramArgs) { - - value result; - - callWithClient(clientP, methodName, paramListFromParamArgs(paramArgs), - &result); - - try { - dumpResult(result); - } catch(exception const& e) { - throwf("Error showing result after RPC completed normally. %s", - e.what()); - } -} - - - -static void -getCommand(string * const cmdP, - bool* const eofP) { - - const char * cmd; - - cmd = readline(">"); - - *eofP = (cmd == NULL); - - if (cmd != NULL) { - *cmdP = string(cmd); - - free(const_cast(cmd)); - } -} - - - -static void -doInteractive(client_xml * const clientP) { - - bool quitRequested; - - quitRequested = false; - - while (!quitRequested) { - string cmd; - bool eof; - - getCommand(&cmd, &eof); - - if (eof) { - quitRequested = true; - cout << endl; - } else { - try { - string methodName; - vector paramArgs; - - parseCommand(cmd, &methodName, ¶mArgs); - - doCommand(clientP, methodName, paramArgs); - } catch (exception const& e) { - cout << "Command failed. " << e.what() << endl; - } - } - } -} - - - -int -main(int const argc, - const char ** const argv) { - - try { - cmdlineInfo cmdline(argc, argv); - - signal(SIGPIPE, SIG_IGN); - - clientXmlTransport_pstream myTransport( - clientXmlTransport_pstream::constrOpt() - .fd(cmdline.serverfd)); - - client_xml myClient(&myTransport); - - if (cmdline.interactive) { - if (cmdline.serverfd == STDIN_FILENO || - cmdline.serverfd == STDOUT_FILENO) - throwf("Can't use Stdin or Stdout for the server fd when " - "running interactively."); - doInteractive(&myClient); - } else - doCommand(&myClient, cmdline.methodName, cmdline.params); - - } catch (exception const& e) { - cerr << "Failed. " << e.what() << endl; - } catch (...) { - cerr << "Code threw unrecognized exception" << endl; - abort(); - } - return 0; -} diff --git a/trunk/tools/xmlrpc_transport/Makefile b/trunk/tools/xmlrpc_transport/Makefile deleted file mode 100644 index 59c56b691..000000000 --- a/trunk/tools/xmlrpc_transport/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -ifeq ($(SRCDIR),) - updir = $(shell echo $(dir $(1)) | sed 's/.$$//') - TOOLSDIR := $(call updir,$(CURDIR)) - SRCDIR := $(call updir,$(TOOLSDIR)) - BLDDIR := $(SRCDIR) -endif -SUBDIR := tools/xmlrpc_transport - -default: all - -include $(BLDDIR)/config.mk - -PROGRAMS_TO_INSTALL = xmlrpc_transport - -include $(SRCDIR)/tools/common.mk - -INCLUDES = \ - -I$(BLDDIR) \ - -I$(BLDDIR)/include \ - -Isrcdir/include \ - -Isrcdir/lib/util/include - -all: xmlrpc_transport - -CLIENT_LDLIBS += $(SOCKETLIBOPT) $(THREAD_LIBS) - -UTIL_OBJS = \ - casprintf.o \ - cmdline_parser.o \ - getoptx.o \ - stripcaseeq.o \ - string_parser.o \ - -UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) - -xmlrpc_transport:%:%.o $(CLIENT_LIBS_DEP) $(UTILS) - $(CCLD) -o $@ $(LDFLAGS_ALL) $< $(CLIENT_LDLIBS) $(UTILS) - -%.o:%.c - $(CC) -c $(CFLAGS_ALL) $< - -# This common.mk dependency makes sure the symlinks get built before -# this make file is used for anything. - -$(SRCDIR)/tools/common.mk: srcdir blddir - -include depend.mk - -.PHONY: install -install: install-common - -.PHONY: uninstall -uninstall: uninstall-common - -.PHONY: dep -dep: dep-common - -.PHONY: clean -clean: clean-common - rm -f xmlrpc_transport config.h - -.PHONY: distclean -distclean: clean distclean-common diff --git a/trunk/tools/xmlrpc_transport/xmlrpc_transport.c b/trunk/tools/xmlrpc_transport/xmlrpc_transport.c deleted file mode 100644 index 80770e905..000000000 --- a/trunk/tools/xmlrpc_transport/xmlrpc_transport.c +++ /dev/null @@ -1,290 +0,0 @@ -/* Transport some XML to a server and get the response back, as if doing - an XML-RPC call. -*/ - -#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ - -#include -#include -#include - -#include "xmlrpc_config.h" /* information about this build environment */ -#include "casprintf.h" -#include "mallocvar.h" -#include "cmdline_parser.h" - -#include "xmlrpc-c/util_int.h" -#include "xmlrpc-c/base.h" -#include "xmlrpc-c/client.h" - -#define NAME "xmlrpc_transport command line program" -#define VERSION "1.0" - -struct cmdlineInfo { - const char * url; - const char * username; - const char * password; - const char * transport; - /* Name of XML transport he wants to use. NULL if he has no - preference. - */ -}; - - - -static void -die_if_fault_occurred (xmlrpc_env * const envP) { - if (envP->fault_occurred) { - fprintf(stderr, "Error: %s (%d)\n", - envP->fault_string, envP->fault_code); - exit(1); - } -} - - - -static void GNU_PRINTF_ATTR(2,3) -setError(xmlrpc_env * const envP, const char format[], ...) { - va_list args; - const char * faultString; - - va_start(args, format); - - cvasprintf(&faultString, format, args); - va_end(args); - - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, faultString); - - strfree(faultString); -} - - - -static void -processArguments(xmlrpc_env * const envP, - cmdlineParser const cp, - struct cmdlineInfo * const cmdlineP) { - - if (cmd_argumentCount(cp) < 1) - setError(envP, "Not enough arguments. Need a URL."); - else { - cmdlineP->url = cmd_getArgument(cp, 0); - } -} - - - -static void -parseCommandLine(xmlrpc_env * const envP, - int const argc, - const char ** const argv, - struct cmdlineInfo * const cmdlineP) { - - cmdlineParser const cp = cmd_createOptionParser(); - - const char * error; - - cmd_defineOption(cp, "transport", OPTTYPE_STRING); - cmd_defineOption(cp, "username", OPTTYPE_STRING); - cmd_defineOption(cp, "password", OPTTYPE_STRING); - - cmd_processOptions(cp, argc, argv, &error); - - if (error) { - setError(envP, "Command syntax error. %s", error); - strfree(error); - } else { - cmdlineP->username = cmd_getOptionValueString(cp, "username"); - cmdlineP->password = cmd_getOptionValueString(cp, "password"); - - if (cmdlineP->username && !cmdlineP->password) - setError(envP, "When you specify -username, you must also " - "specify -password."); - else { - cmdlineP->transport = cmd_getOptionValueString(cp, "transport"); - - processArguments(envP, cp, cmdlineP); - } - } - cmd_destroyOptionParser(cp); -} - - - -static void -freeCmdline(struct cmdlineInfo const cmdline) { - - strfree(cmdline.url); - if (cmdline.username) - strfree(cmdline.username); - if (cmdline.password) - strfree(cmdline.password); - if (cmdline.transport) - strfree(cmdline.transport); -} - - - -static void -computeUrl(const char * const urlArg, - const char ** const urlP) { - - if (strstr(urlArg, "://") != 0) { - *urlP = strdup(urlArg); - } else { - casprintf(urlP, "http://%s/RPC2", urlArg); - } -} - - - -static void -doCall(xmlrpc_env * const envP, - const char * const transport, - const xmlrpc_server_info * const serverInfoP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block ** const respXmlPP) { - - struct xmlrpc_clientparms clientparms; - - clientparms.transport = transport; - - clientparms.transportparmsP = NULL; - clientparms.transportparm_size = 0; - - xmlrpc_client_init2(envP, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, - &clientparms, XMLRPC_CPSIZE(transportparm_size)); - if (!envP->fault_occurred) { - xmlrpc_client_transport_call(envP, NULL, serverInfoP, - callXmlP, respXmlPP); - - xmlrpc_client_cleanup(); - } -} - - - -static void -createServerInfo(xmlrpc_env * const envP, - const char * const serverUrl, - const char * const userName, - const char * const password, - xmlrpc_server_info ** const serverInfoPP) { - - xmlrpc_server_info * serverInfoP; - - serverInfoP = xmlrpc_server_info_new(envP, serverUrl); - if (!envP->fault_occurred) { - if (userName) { - xmlrpc_server_info_set_basic_auth( - envP, serverInfoP, userName, password); - } - } - *serverInfoPP = serverInfoP; -} - - - -static void -readFile(xmlrpc_env * const envP, - FILE * const ifP, - xmlrpc_mem_block ** const fileContentsPP) { - - xmlrpc_mem_block * fileContentsP; - - fileContentsP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - - while (!envP->fault_occurred && !feof(ifP)) { - char buffer[4096]; - size_t bytesRead; - - bytesRead = fread(buffer, 1, sizeof(buffer), ifP); - XMLRPC_MEMBLOCK_APPEND(char, envP, - fileContentsP, buffer, bytesRead); - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, fileContentsP); - - *fileContentsPP = fileContentsP; -} - - - -static void -writeFile(xmlrpc_env * const envP, - FILE * const ofP, - xmlrpc_mem_block * const fileContentsP) { - - size_t totalWritten; - - totalWritten = 0; - - while (!envP->fault_occurred && - totalWritten < XMLRPC_MEMBLOCK_SIZE(char, fileContentsP)) { - size_t bytesWritten; - - bytesWritten = fwrite( - XMLRPC_MEMBLOCK_CONTENTS(char, fileContentsP) + totalWritten, - 1, - XMLRPC_MEMBLOCK_SIZE(char, fileContentsP) - totalWritten, - ofP); - - if (bytesWritten < 1) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Error writing output"); - - totalWritten -= bytesWritten; - } -} - - - -int -main(int const argc, - const char ** const argv) { - - struct cmdlineInfo cmdline; - xmlrpc_env env; - xmlrpc_mem_block * callXmlP; - xmlrpc_mem_block * respXmlP; - const char * url; - xmlrpc_server_info * serverInfoP; - - xmlrpc_env_init(&env); - - parseCommandLine(&env, argc, argv, &cmdline); - die_if_fault_occurred(&env); - - computeUrl(cmdline.url, &url); - - createServerInfo(&env, url, cmdline.username, cmdline.password, - &serverInfoP); - die_if_fault_occurred(&env); - - fprintf(stderr, "Reading call data from Standard Input...\n"); - - readFile(&env, stdin, &callXmlP); - die_if_fault_occurred(&env); - - fprintf(stderr, "Making call...\n"); - - doCall(&env, cmdline.transport, serverInfoP, callXmlP, - &respXmlP); - die_if_fault_occurred(&env); - - fprintf(stderr, "Writing response data to Standard Output\n"); - writeFile(&env, stdout, respXmlP); - die_if_fault_occurred(&env); - - XMLRPC_MEMBLOCK_FREE(char, callXmlP); - XMLRPC_MEMBLOCK_FREE(char, respXmlP); - - strfree(url); - - freeCmdline(cmdline); - - xmlrpc_env_clean(&env); - - return 0; -} diff --git a/trunk/tools/xmlrpc_transport/xmlrpc_transport.html b/trunk/tools/xmlrpc_transport/xmlrpc_transport.html deleted file mode 100644 index f244408d6..000000000 --- a/trunk/tools/xmlrpc_transport/xmlrpc_transport.html +++ /dev/null @@ -1,93 +0,0 @@ - -Xmlrpc_transport User Manual - - -

xmlrpc_transport transports data to a server as if to make an -XML-RPC remote procedure call and displays the response from the server. - -

You supply the call in XML form on Standard Input and get the response -in XML form on Standard Output. xmlrpc_transport doesn't really know -anything about XML; it sends the characters you supply and displays the -characters it gets back. - -

xmlrpc_transport uses the lower levels of the XML-RPC For C/C++ -client libraries. - -

This program is mainly useful for debugging and learning about -XML-RPC servers and the XML-RPC For C/C++ client XML transports. - - -

Examples

- -
-
-     $ xmlrpc_transport http://localhost:8080/RPC2 <<EOF
-        <?xml version="1.0" encoding="UTF-8"?>
-        <methodCall>
-        <methodName>sample.add</methodName>
-        <params>
-        <param><value><i4>5</i4></value></param>
-        <param><value><i4>7</i4></value></param>
-        </params>
-        </methodCall>
-        EOF
-     <?xml version="1.0" encoding="UTF-8"?>
-     <methodResponse>
-     <params>
-     <param><value><i4>12</i4></value></param>
-     </params>
-     </methodResponse>
-
-
- -

Overview

-

-xmlrpc_transport -url -[-transport=transportname] -[-username=username -password=password] - -

Minimum unique abbreviation of option is acceptable. You may use double -hyphens instead of single hyphen to denote options. You may use white -space in place of the equals sign to separate an option name from its value. - - -

Arguments

- -
-
url - -
This is the URL of the XML-RPC server. As XML-RPC uses HTTP, this -must be an HTTP url. However, if you don't specify a type ("http:") -in the URL, xmlrpc_transport assumes an "http://" prefix and a -"/RPC2" suffix. RPC2 is the conventional file name for -an XML-RPC responder. - -
- - -

Options

- -
-
-transport=transportname - -
This selects the XML transport facility (e.g. libwww) that -xmlrpc_transport uses to perform the RPC. - -

The name transportname is one that the Xmlrpc-c programming -library recognizes. This is typically libwww, curl, and -wininet. - -

By default, xmlrpc_transport lets the Xmlrpc-c library choose. - -

-username=username -
-password=password - -
These options, which must be used together, cause the client to -authenticate itself to the server, if the server requires it, using -HTTP Basic Authentication and the specified username and password. - -
- - - diff --git a/trunk/transport_config.mk b/trunk/transport_config.mk deleted file mode 100644 index 5791af6f8..000000000 --- a/trunk/transport_config.mk +++ /dev/null @@ -1,39 +0,0 @@ -# -*-makefile-*- <-- an Emacs control - - -# The make variables herein come from config.mk, which is included -# by the make file that includes us. - -transport_config.h: $(BLDDIR)/config.mk - rm -f $@ - echo '/* This file was generated by a make rule */' >>$@ -ifeq ($(MUST_BUILD_WININET_CLIENT),yes) - echo '#define MUST_BUILD_WININET_CLIENT 1' >>$@ -else - echo '#define MUST_BUILD_WININET_CLIENT 0' >>$@ -endif -ifeq ($(MUST_BUILD_CURL_CLIENT),yes) - echo '#define MUST_BUILD_CURL_CLIENT 1' >>$@ -else - echo '#define MUST_BUILD_CURL_CLIENT 0' >>$@ -endif -ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) - echo '#define MUST_BUILD_LIBWWW_CLIENT 1' >>$@ -else - echo '#define MUST_BUILD_LIBWWW_CLIENT 0' >>$@ -endif - echo "static const char * const XMLRPC_DEFAULT_TRANSPORT =" >>$@ -ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) - echo '"libwww";' >>$@ -else - ifeq ($(MUST_BUILD_CURL_CLIENT),yes) - echo '"curl";' >>$@ - else - ifeq ($(MUST_BUILD_WININET_CLIENT),yes) - echo '"wininet";' >>$@ - else - @echo 'ERROR: no client XML transport configured'; rm $@; false - endif - endif -endif - diff --git a/trunk/unix-common.mk b/trunk/unix-common.mk deleted file mode 100644 index 6954faf52..000000000 --- a/trunk/unix-common.mk +++ /dev/null @@ -1,104 +0,0 @@ -# -*-makefile-*- <-- an Emacs control - -# The including make file must define these make variables: -# -# SHARED_LIBS_TO_BUILD: List of the shared libraries that need to be -# built -- just the basic library names. E.g. "libfoo libbar" -# -# SHARED_LIBS_TO_INSTALL: List of the shared libraries that need to be -# installed -- just the basic library names. E.g. "libfoo libbar" -# -# SHLIB_SUFFIX: Shared library filename suffix, e.g. "so". -# -# MAJ: Library major version number, e.g. "3" in file name "libfoo.3.1" -# -# MIN: Library minor version number, e.g. "1" in file name "libfoo.3.1" -# -# LDFLAGS_SHLIB: linker (Ld) flags needed to link object files together into -# a shared library. May use $(SONAME) for the soname of the library. -# Include -lc if appropriate. -# -# LADD: Additional linker flags (normally set on the make command line). -# -# INSTALL_DATA: beginning of shell command to install a library file. -# -# DESTDIR: main installation directory -# -# LIBINST_DIR: directory in which to install libraries, relative to DESTDIR. -# -# LN_S: beginning of shell command to make symbolic link (e.g. "ln -s"). -# -# CXXLD: beginning of shell command to link, e.g. "g++". - -# This make file defines these make variables that the including make file -# can use: -# -# SHLIB_CMD: a command to build a shared library for C linkage -# You can use this in a rule to build a shared library -# SHLIBPP_CMD: Same, but for C++ linkage - -# Including make file must contain a rule to build each library file -# (e.g. libfoo.3.1) - -# This make file provides these rules: -# -# install-shared-libraries: install all shared libraries and the necessary -# symbolic links. - -# uninstall-shared-libraries: remove what would be installed by -# install-shared-libraries - -# SONAME is to be referenced by $(LDFLAGS_SHLIB) in the rule to make -# a shared library (in common.mk). I.e. $@ is the name of the shared -# library file. - -# SONAME is the name of the library file being built, with the minor -# version number cut off. E.g. if we're building libfoo.so.1.2, SONAME -# is libfoo.so.1 . -SONAME = $(@:%.$(MIN)=%) - -SHLIB_CMD = $(CCLD) $(LADD) $(LDFLAGS_SHLIB) -o $@ $^ - -SHLIB_LE_TARGETS = $(call shliblefn, $(SHARED_LIBS_TO_BUILD)) - -$(SHLIB_LE_TARGETS):%:%.$(MAJ) - rm -f $@ - $(LN_S) $< $@ - -SONAME_TARGETS = $(SHLIB_LE_TARGETS:%=%.$(MAJ)) - -$(SONAME_TARGETS):%:%.$(MIN) - rm -f $@ - $(LN_S) $< $@ - -.PHONY: $(SHLIB_INSTALL_TARGETS) -.PHONY: install-shared-libraries - -SHLIB_INSTALL_TARGETS = $(SHARED_LIBS_TO_INSTALL:%=%/install) - -#SHLIB_INSTALL_TARGETS is like "libfoo/install libbar/install" - -install-shared-libraries: $(SHLIB_INSTALL_TARGETS) - -LIBDESTDIR = $(DESTDIR)$(LIBINST_DIR) - -$(SHLIB_INSTALL_TARGETS):%/install:%.$(SHLIB_SUFFIX).$(MAJ).$(MIN) -# $< is a library file name, e.g. libfoo.so.3.1 . - $(INSTALL_SHLIB) $< $(LIBDESTDIR)/$< - cd $(LIBDESTDIR); \ - rm -f $(<:%.$(MIN)=%); \ - $(LN_S) $< $(<:%.$(MIN)=%) - cd $(LIBDESTDIR); \ - rm -f $(<:%.$(MAJ).$(MIN)=%); \ - $(LN_S) $(<:%.$(MIN)=%) $(<:%.$(MAJ).$(MIN)=%) - -.PHONY: uninstall-shared-libraries -uninstall-shared-libraries: - @list='$(SHARED_LIBS_TO_INSTALL)'; \ - for p in $$list; do \ - echo "Uninstalling $$p shared library"; \ - cd $(LIBDESTDIR); \ - rm -f $$p.$(SHLIB_SUFFIX); \ - rm -f $$p.$(SHLIB_SUFFIX).$(MAJ); \ - rm -f $$p.$(SHLIB_SUFFIX).$(MAJ).$(MIN); \ - done diff --git a/trunk/version.mk b/trunk/version.mk deleted file mode 100644 index 31e61d2e3..000000000 --- a/trunk/version.mk +++ /dev/null @@ -1,11 +0,0 @@ -############################################################################### -# This is not only a make file inclusion, but a source file for the program -# 'mkvers' in the Windows build system. The latter is very particular about -# the format of this file. Do not change white space, add comment lines, or -# anything! -# -# -############################################################################### -XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 55 -XMLRPC_POINT_RELEASE = 0 diff --git a/trunk/xmlrpc-c-config.main b/trunk/xmlrpc-c-config.main deleted file mode 100644 index d37be4eaf..000000000 --- a/trunk/xmlrpc-c-config.main +++ /dev/null @@ -1,207 +0,0 @@ -usage="Usage: xmlrpc-c-config ...
" + SERVER_HTML_INFO + "\r\n\r\n"); + + return retval; +} + + + +static void +sendDirectoryDocumentHeading(TSession * const sessionP, + const char * const uri, + bool const text) { + + char z[4096]; + + if (text) { + size_t i; + char * p; + + sprintf(z, "Index of %s\r\n", uri); + i = strlen(z)-2; + p = z + i + 2; + + while (i > 0) { + *(p++) = '-'; + --i; + } + + *p = '\0'; + strcat(z, "\r\n\r\n" + "Name Size " + "Date-Time Type\r\n" + "------------------------------------" + "--------------------------------------------\r\n"); + } else { + sprintf(z, "Index of %s" + "

Index of %s

",
+                uri, uri);
+        strcat(z, "Name                      Size      "
+               "Date-Time             Type
\r\n"); + } + + HTTPWriteBodyChunk(sessionP, z, strlen(z)); +} + + + +static void +sendDirectoryDocument(TList * const listP, + bool const ascending, + uint16_t const sort, + bool const text, + const char * const uri, + MIMEType * const mimeTypeP, + TSession * const sessionP) { + + char z[4096]; + char *p,z1[26],z2[20],z3[9],u; + const char * z4; + int16_t i; + uint32_t k; + + sendDirectoryDocumentHeading(sessionP, uri, text); + + /* Sort the files */ + qsort(listP->item, listP->size, sizeof(void *), + (TQSortProc)(sort == 1 ? cmpfilenames : cmpfiledates)); + + /* Write the listing */ + if (ascending) + i = 0; + else + i = listP->size - 1; + + while ((i < listP->size) && (i >= 0)) { + TFileInfo * fi; + struct tm ftm; + + fi = listP->item[i]; + + if (ascending) + ++i; + else + --i; + + strcpy(z, fi->name); + + k = strlen(z); + + if (fi->attrib & A_SUBDIR) { + z[k++] = '/'; + z[k] = '\0'; + } + + if (k > 24) { + z[10] = '\0'; + strcpy(z1, z); + strcat(z1, "..."); + strcat(z1, z + k - 11); + k = 24; + p = z1 + 24; + } else { + strcpy(z1, z); + + ++k; + p = z1 + k; + while (k < 25) + z1[k++] = ' '; + + z1[25] = '\0'; + } + + xmlrpc_gmtime(fi->time_write, &ftm); + sprintf(z2, "%02u/%02u/%04u %02u:%02u:%02u",ftm.tm_mday,ftm.tm_mon+1, + ftm.tm_year+1900,ftm.tm_hour,ftm.tm_min,ftm.tm_sec); + + if (fi->attrib & A_SUBDIR) { + strcpy(z3, " -- "); + z4 = "Directory"; + } else { + if (fi->size < 9999) + u = 'b'; + else { + fi->size /= 1024; + if (fi->size < 9999) + u = 'K'; + else { + fi->size /= 1024; + if (fi->size < 9999) + u = 'M'; + else + u = 'G'; + } + } + + sprintf(z3, "%5" PRIu64 " %c", fi->size, u); + + if (xmlrpc_streq(fi->name, "..")) + z4 = ""; + else + z4 = MIMETypeFromFileName2(mimeTypeP, fi->name); + + if (!z4) + z4 = "Unknown"; + } + + if (text) + sprintf(z, "%s%s %s %s %s\r\n", z1, p, z3, z2, z4); + else + sprintf(z, "%s%s %s %s %s\r\n", + fi->name, fi->attrib & A_SUBDIR ? "/" : "", + z1, p, z3, z2, z4); + + HTTPWriteBodyChunk(sessionP, z, strlen(z)); + } + + { + const char * const tail = text ? plainTail() : htmlTail(); + + HTTPWriteBodyChunk(sessionP, tail, strlen(tail)); + + xmlrpc_strfree(tail); + } +} + + + +static bool +notRecentlyModified(TSession * const sessionP, + time_t const fileModTime) { + + bool retval; + const char * imsHdr; + + imsHdr = RequestHeaderValue(sessionP, "if-modified-since"); + if (imsHdr) { + bool valid; + time_t datetime; + DateDecode(imsHdr, &valid, &datetime); + if (valid) { + if (MIN(fileModTime, sessionP->date) <= datetime) + retval = true; + else + retval = false; + } else + retval = false; + } else + retval = false; + + return retval; +} + + + +static void +addLastModifiedHeader(TSession * const sessionP, + time_t const fileModTime) { + + const char * lastModifiedValue; + + DateToString(MIN(fileModTime, sessionP->date), &lastModifiedValue); + + if (lastModifiedValue) { + ResponseAddField(sessionP, "Last-Modified", lastModifiedValue); + xmlrpc_strfree(lastModifiedValue); + } +} + + + +static void +handleDirectory(TSession * const sessionP, + const char * const dirName, + time_t const fileModTime, + MIMEType * const mimeTypeP) { + + bool text; + bool ascending; + uint16_t sort; /* 1=by name, 2=by date */ + const char * error; + + determineSortType(sessionP->requestInfo.query, + &ascending, &sort, &text, &error); + + if (error) { + ResponseStatus(sessionP, 400); + xmlrpc_strfree(error); + } else if (notRecentlyModified(sessionP, fileModTime)) { + ResponseStatus(sessionP, 304); + ResponseWriteStart(sessionP); + } else { + TPool pool; + bool succeeded; + succeeded = PoolCreate(&pool, 1024); + if (!succeeded) + ResponseStatus(sessionP, 500); + else { + TList list; + uint16_t responseStatus; + const char * error; + generateListing(&list, dirName, sessionP->requestInfo.uri, + &pool, &error, &responseStatus); + if (error) { + ResponseStatus(sessionP, responseStatus); + xmlrpc_strfree(error); + } else { + ResponseStatus(sessionP, 200); + ResponseContentType(sessionP, + text ? "text/plain" : "text/html"); + + addLastModifiedHeader(sessionP, fileModTime); + + ResponseChunked(sessionP); + ResponseWriteStart(sessionP); + + if (sessionP->requestInfo.method!=m_head) + sendDirectoryDocument(&list, ascending, sort, text, + sessionP->requestInfo.uri, mimeTypeP, + sessionP); + + ResponseWriteEnd(sessionP); + + ListFree(&list); + } + PoolFree(&pool); + } + } +} + + + +static void +composeEntityHeader(const char ** const entityHeaderP, + const char * const mediatype, + uint64_t const start, + uint64_t const end, + uint64_t const filesize) { + + xmlrpc_asprintf(entityHeaderP, "Content-type: %s\r\n" + "Content-range: " + "bytes %" PRIu64 "-%" PRIu64 "/%" PRIu64 "\r\n" + "Content-length: %" PRIu64 "\r\n\r\n", + mediatype, start, end, filesize, end-start+1); +} + + + +#define BOUNDARY "##123456789###BOUNDARY" + +static void +sendBody(TSession * const sessionP, + const TFile * const fileP, + uint64_t const filesize, + const char * const mediatype, + uint64_t const start0, + uint64_t const end0) { +/*---------------------------------------------------------------------------- + 'start0' and 'end0' are meaningful only if the session has ranges. +-----------------------------------------------------------------------------*/ + char buffer[4096]; + + if (sessionP->ranges.size == 0) + ConnWriteFromFile(sessionP->connP, fileP, 0, filesize - 1, + buffer, sizeof(buffer), 0); + else if (sessionP->ranges.size == 1) + ConnWriteFromFile(sessionP->connP, fileP, start0, end0, + buffer, sizeof(buffer), 0); + else { + uint64_t i; + for (i = 0; i <= sessionP->ranges.size; ++i) { + ConnWrite(sessionP->connP, "--", 2); + ConnWrite(sessionP->connP, BOUNDARY, strlen(BOUNDARY)); + ConnWrite(sessionP->connP, "\r\n", 2); + + if (i < sessionP->ranges.size) { + uint64_t start; + uint64_t end; + bool decoded; + + decoded = RangeDecode((char *)(sessionP->ranges.item[i]), + filesize, + &start, &end); + if (decoded) { + /* Entity header, not response header */ + const char * entityHeader; + + composeEntityHeader(&entityHeader, mediatype, + start, end, filesize); + + ConnWrite(sessionP->connP, + entityHeader, strlen(entityHeader)); + + xmlrpc_strfree(entityHeader); + + ConnWriteFromFile(sessionP->connP, fileP, start, end, + buffer, sizeof(buffer), 0); + } + } + } + } +} + + + +static void +sendFileAsResponse(TSession * const sessionP, + TFile * const fileP, + const char * const fileName, + time_t const fileModTime, + MIMEType * const mimeTypeP) { + + uint64_t const filesize = FileSize(fileP); + const char * const mediatype = MIMETypeGuessFromFile2(mimeTypeP, fileName); + + uint64_t start; /* Defined only if session has one range */ + uint64_t end; /* Defined only if session has one range */ + + switch (sessionP->ranges.size) { + case 0: + ResponseStatus(sessionP, 200); + break; + + case 1: { + bool decoded; + decoded = RangeDecode((char *)(sessionP->ranges.item[0]), filesize, + &start, &end); + if (!decoded) { + ListFree(&sessionP->ranges); + ResponseStatus(sessionP, 200); + } else { + const char * contentRange; + xmlrpc_asprintf(&contentRange, + "bytes %" PRIu64 "-%" PRIu64 "/%" PRIu64, + start, end, filesize); + ResponseAddField(sessionP, "Content-range", contentRange); + xmlrpc_strfree(contentRange); + + ResponseContentLength(sessionP, end - start + 1); + ResponseStatus(sessionP, 206); + } + } break; + + default: + ResponseContentType(sessionP, + "multipart/ranges; boundary=" BOUNDARY); + ResponseStatus(sessionP, 206); + break; + } + + if (sessionP->ranges.size == 0) { + ResponseContentLength(sessionP, filesize); + ResponseContentType(sessionP, mediatype); + } + + addLastModifiedHeader(sessionP, fileModTime); + + ResponseWriteStart(sessionP); + + if (sessionP->requestInfo.method != m_head) + sendBody(sessionP, fileP, filesize, mediatype, start, end); +} + + + +static void +handleFile(TSession * const sessionP, + const char * const fileName, + time_t const fileModTime, + MIMEType * const mimeTypeP) { +/*---------------------------------------------------------------------------- + This is an HTTP request handler for a GET. It does the classic + web server thing: send the file named in the URL to the client. +-----------------------------------------------------------------------------*/ + TFile * fileP; + bool success; + + success = FileOpen(&fileP, fileName, O_BINARY | O_RDONLY); + if (!success) + ResponseStatusErrno(sessionP); + else { + if (notRecentlyModified(sessionP, fileModTime)) { + ResponseStatus(sessionP, 304); + ResponseWriteStart(sessionP); + } else + sendFileAsResponse(sessionP, fileP, + fileName, fileModTime, mimeTypeP); + + FileClose(fileP); + } +} + + + +static void +convertToNativeFileName(char * const fileName ATTR_UNUSED) { + +#if MSVCRT + char * p; + p = &fileName[0]; + while (*p) { + if ((*p) == '/') + *p= '\\'; + + ++p; + } +#endif +} + + + +abyss_bool +HandlerDefaultBuiltin(TSession * const sessionP) { + + BIHandler * const handlerP = SessionGetDefaultHandlerCtx(sessionP); + + char * p; + char z[4096]; + TFileStat fs; + bool endingslash; + + endingslash = false; /* initial value */ + + if (!HTTPRequestHasValidUriPath(sessionP)) { + ResponseStatus(sessionP, 400); + return true; + } + + /* Must check for * (asterisk uri) in the future */ + if (sessionP->requestInfo.method == m_options) { + ResponseAddField(sessionP, "Allow", "GET, HEAD"); + ResponseContentLength(sessionP, 0); + ResponseStatus(sessionP, 200); + return true; + } + + if ((sessionP->requestInfo.method != m_get) && + (sessionP->requestInfo.method != m_head)) { + ResponseAddField(sessionP, "Allow", "GET, HEAD"); + ResponseStatus(sessionP, 405); + return true; + } + + strcpy(z, handlerP->filesPath); + strcat(z, sessionP->requestInfo.uri); + + p = z + strlen(z) - 1; + if (*p == '/') { + endingslash = true; + *p = '\0'; + } + + convertToNativeFileName(z); + + if (!FileStat(z, &fs)) { + ResponseStatusErrno(sessionP); + return true; + } + + if (fs.st_mode & S_IFDIR) { + /* Redirect to the same directory but with the ending slash + ** to avoid problems with some browsers (IE for examples) when + ** they generate relative urls */ + if (!endingslash) { + strcpy(z, sessionP->requestInfo.uri); + p = z+strlen(z); + *p = '/'; + *(p+1) = '\0'; + ResponseAddField(sessionP, "Location", z); + ResponseStatus(sessionP, 302); + ResponseWriteStart(sessionP); + return true; + } + + *p = DIRECTORY_SEPARATOR[0]; + ++p; + { + unsigned int i; + i = handlerP->defaultFileNames.size; + while (i-- > 0) { + *p = '\0'; + strcat(z, (handlerP->defaultFileNames.item[i])); + if (FileStat(z, &fs)) { + if (!(fs.st_mode & S_IFDIR)) + handleFile(sessionP, z, fs.st_mtime, + handlerP->mimeTypeP); + } + } + } + + *(p-1) = '\0'; + + if (!FileStat(z, &fs)) { + ResponseStatusErrno(sessionP); + return true; + } + handleDirectory(sessionP, z, fs.st_mtime, handlerP->mimeTypeP); + } else + handleFile(sessionP, z, fs.st_mtime, handlerP->mimeTypeP); + + return true; +} + + + +size_t const HandlerDefaultBuiltinStack = 1024; + + +/****************************************************************************** +** +** server.c +** +** This file is part of the ABYSS Web server project. +** +** Copyright (C) 2000 by Moez Mahfoudh . +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +******************************************************************************/ diff --git a/trunk/lib/abyss/src/handler.h b/trunk/lib/abyss/src/handler.h new file mode 100644 index 000000000..a8f2f3edc --- /dev/null +++ b/trunk/lib/abyss/src/handler.h @@ -0,0 +1,33 @@ +#ifndef HANDLER_H_INCLUDED +#define HANDLER_H_INCLUDED + +#include "bool.h" +#include "xmlrpc-c/abyss.h" + +typedef struct BIHandler BIHandler; + +BIHandler * +HandlerCreate(void); + +void +HandlerDestroy(BIHandler * const handlerP); + + +void +HandlerSetMimeType(BIHandler * const handlerP, + MIMEType * const mimeTypeP); + +void +HandlerSetFilesPath(BIHandler * const handlerP, + const char * const filesPath); + +void +HandlerAddDefaultFN(BIHandler * const handlerP, + const char * const fileName); + +abyss_bool +HandlerDefaultBuiltin(TSession * const sessionP); + +extern size_t const HandlerDefaultBuiltinStack; + +#endif diff --git a/trunk/lib/abyss/src/http.c b/trunk/lib/abyss/src/http.c new file mode 100644 index 000000000..f61c9928c --- /dev/null +++ b/trunk/lib/abyss/src/http.c @@ -0,0 +1,400 @@ +/* Copyright information is at the end of the file */ + +#define _XOPEN_SOURCE 600 /* For strdup() */ +#define _BSD_SOURCE /* For xmlrpc_strcaseeq() */ + +#include +#include +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "bool.h" +#include "mallocvar.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/base64_int.h" +#include "xmlrpc-c/abyss.h" + +#include "server.h" +#include "session.h" +#include "conn.h" +#include "token.h" +#include "date.h" +#include "data.h" + +#include "http.h" + + + +const char * +RequestHeaderValue(TSession * const sessionP, + const char * const name) { + + return TableValue(&sessionP->requestHeaderFields, name); +} + + + +const char * +HTTPMethodName(TMethod const method) { + + switch (method) { + case m_unknown: return "UNKNOWN"; + case m_get: return "GET"; + case m_put: return "PUT"; + case m_head: return "HEAD"; + case m_post: return "POST"; + case m_delete: return "DELETE"; + case m_trace: return "TRACE"; + case m_options: return "OPTIONS"; + } + assert(false); /* Compiler ought to know this, but doesn't */ + return 0; /* quiet compiler warning */ +} + + + +bool +HTTPRequestHasValidUri(TSession * const sessionP) { + + if (!sessionP->requestInfo.uri) + return false; + + if (xmlrpc_streq(sessionP->requestInfo.uri, "*")) + return (sessionP->requestInfo.method != m_options); + + if (strchr(sessionP->requestInfo.uri, '*')) + return false; + + return true; +} + + + +bool +HTTPRequestHasValidUriPath(TSession * const sessionP) { + + uint32_t i; + const char * p; + + p = sessionP->requestInfo.uri; + + i = 0; + + if (*p == '/') { + i = 1; + while (*p) + if (*(p++) == '/') { + if (*p == '/') + break; + else if ((xmlrpc_strneq(p,"./", 2)) || (xmlrpc_streq(p, "."))) + ++p; + else if ((xmlrpc_strneq(p, "../", 2)) || + (xmlrpc_streq(p, ".."))) { + p += 2; + --i; + if (i == 0) + break; + } + /* Prevent accessing hidden files (starting with .) */ + else if (*p == '.') + return false; + else + if (*p) + ++i; + } + } + return (*p == 0 && i > 0); +} + + + +abyss_bool +RequestAuth(TSession * const sessionP, + const char * const credential, + const char * const user, + const char * const pass) { +/*---------------------------------------------------------------------------- + Authenticate requester, in a very simplistic fashion. + + If the request executing on session *sessionP specifies basic + authentication (via Authorization header) with username 'user', password + 'pass', then return true. Else, return false and set up an authorization + failure response (HTTP response status 401) that says user must supply an + identity in the 'credential' domain. + + When we return true, we also set the username in the request info for the + session to 'user' so that a future SessionGetRequestInfo can get it. +-----------------------------------------------------------------------------*/ + bool authorized; + const char * authValue; + + authValue = RequestHeaderValue(sessionP, "authorization"); + if (authValue) { + char * const valueBuffer = malloc(strlen(authValue)); + /* A buffer we can mangle as we parse the authorization: value */ + + if (!authValue) + /* Should return error, but we have no way to do that */ + authorized = false; + else { + const char * authType; + char * authHdrPtr; + + strcpy(valueBuffer, authValue); + authHdrPtr = &valueBuffer[0]; + + NextToken((const char **)&authHdrPtr); + GetTokenConst(&authHdrPtr, &authType); + if (authType) { + if (xmlrpc_strcaseeq(authType, "basic")) { + const char * userPass; + char userPassEncoded[80]; + + NextToken((const char **)&authHdrPtr); + + xmlrpc_asprintf(&userPass, "%s:%s", user, pass); + xmlrpc_base64Encode(userPass, userPassEncoded); + xmlrpc_strfree(userPass); + + if (xmlrpc_streq(authHdrPtr, userPassEncoded)) { + sessionP->requestInfo.user = xmlrpc_strdupsol(user); + authorized = true; + } else + authorized = false; + } else + authorized = false; + } else + authorized = false; + + free(valueBuffer); + } + } else + authorized = false; + + if (!authorized) { + const char * hdrValue; + xmlrpc_asprintf(&hdrValue, "Basic realm=\"%s\"", credential); + ResponseAddField(sessionP, "WWW-Authenticate", hdrValue); + + xmlrpc_strfree(hdrValue); + + ResponseStatus(sessionP, 401); + } + return authorized; +} + + + +/********************************************************************* +** Range +*********************************************************************/ + +abyss_bool +RangeDecode(char * const strArg, + xmlrpc_uint64_t const filesize, + xmlrpc_uint64_t * const start, + xmlrpc_uint64_t * const end) { + + char *str; + char *ss; + + str = strArg; /* initial value */ + + *start=0; + *end=filesize-1; + + if (*str=='-') + { + *start=filesize-strtol(str+1,&ss,10); + return ((ss!=str) && (!*ss)); + }; + + *start=strtol(str,&ss,10); + + if ((ss==str) || (*ss!='-')) + return false; + + str=ss+1; + + if (!*str) + return true; + + *end=strtol(str,&ss,10); + + if ((ss==str) || (*ss) || (*end<*start)) + return false; + + return true; +} + +/********************************************************************* +** HTTP +*********************************************************************/ + +const char * +HTTPReasonByStatus(uint16_t const code) { + + struct _HTTPReasons { + uint16_t status; + const char * reason; + }; + + static struct _HTTPReasons const reasons[] = { + { 100,"Continue" }, + { 101,"Switching Protocols" }, + { 200,"OK" }, + { 201,"Created" }, + { 202,"Accepted" }, + { 203,"Non-Authoritative Information" }, + { 204,"No Content" }, + { 205,"Reset Content" }, + { 206,"Partial Content" }, + { 300,"Multiple Choices" }, + { 301,"Moved Permanently" }, + { 302,"Moved Temporarily" }, + { 303,"See Other" }, + { 304,"Not Modified" }, + { 305,"Use Proxy" }, + { 400,"Bad Request" }, + { 401,"Unauthorized" }, + { 402,"Payment Required" }, + { 403,"Forbidden" }, + { 404,"Not Found" }, + { 405,"Method Not Allowed" }, + { 406,"Not Acceptable" }, + { 407,"Proxy Authentication Required" }, + { 408,"Request Timeout" }, + { 409,"Conflict" }, + { 410,"Gone" }, + { 411,"Length Required" }, + { 412,"Precondition Failed" }, + { 413,"Request Entity Too Large" }, + { 414,"Request-URI Too Long" }, + { 415,"Unsupported Media Type" }, + { 500,"Internal Server Error" }, + { 501,"Not Implemented" }, + { 502,"Bad Gateway" }, + { 503,"Service Unavailable" }, + { 504,"Gateway Timeout" }, + { 505,"HTTP Version Not Supported" }, + { 000, NULL } + }; + const struct _HTTPReasons * reasonP; + + reasonP = &reasons[0]; + + while (reasonP->status <= code) + if (reasonP->status == code) + return reasonP->reason; + else + ++reasonP; + + return "No Reason"; +} + + + +bool +HTTPWriteBodyChunk(TSession * const sessionP, + const char * const buffer, + uint32_t const len) { + + bool succeeded; + + if (sessionP->chunkedwrite && sessionP->chunkedwritemode) { + char chunkHeader[16]; + + sprintf(chunkHeader, "%x\r\n", len); + + succeeded = + ConnWrite(sessionP->connP, chunkHeader, strlen(chunkHeader)); + if (succeeded) { + succeeded = ConnWrite(sessionP->connP, buffer, len); + if (succeeded) + succeeded = ConnWrite(sessionP->connP, "\r\n", 2); + } + } else + succeeded = ConnWrite(sessionP->connP, buffer, len); + + return succeeded; +} + + + +bool +HTTPWriteEndChunk(TSession * const sessionP) { + + bool retval; + + if (sessionP->chunkedwrite && sessionP->chunkedwritemode) { + /* May be one day trailer dumping will be added */ + sessionP->chunkedwritemode = false; + retval = ConnWrite(sessionP->connP, "0\r\n\r\n", 5); + } else + retval = true; + + return retval; +} + + + +bool +HTTPKeepalive(TSession * const sessionP) { +/*---------------------------------------------------------------------------- + Return value: the connection should be kept alive after the session + *sessionP is over. +-----------------------------------------------------------------------------*/ + return (sessionP->requestInfo.keepalive && + !sessionP->serverDeniesKeepalive && + sessionP->status < 400); +} + + + +bool +HTTPWriteContinue(TSession * const sessionP) { + + char const continueStatus[] = "HTTP/1.1 100 continue\r\n\r\n"; + /* This is a status line plus an end-of-header empty line */ + + return ConnWrite(sessionP->connP, continueStatus, strlen(continueStatus)); +} + + + +/****************************************************************************** +** +** http.c +** +** Copyright (C) 2000 by Moez Mahfoudh . +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +******************************************************************************/ diff --git a/trunk/lib/abyss/src/http.h b/trunk/lib/abyss/src/http.h new file mode 100644 index 000000000..e7fac458f --- /dev/null +++ b/trunk/lib/abyss/src/http.h @@ -0,0 +1,33 @@ +#ifndef HTTP_H_INCLUDED +#define HTTP_H_INCLUDED + +#include +#include "xmlrpc-c/abyss.h" + +const char * +HTTPMethodName(TMethod const method); + +bool +HTTPRequestHasValidUri(TSession * const sessionP); + +bool +HTTPRequestHasValidUriPath(TSession * const sessionP); + +const char * +HTTPReasonByStatus(uint16_t const code); + +bool +HTTPWriteBodyChunk(TSession * const sessionP, + const char * const buffer, + uint32_t const len); + +bool +HTTPWriteEndChunk(TSession * const sessionP); + +bool +HTTPKeepalive(TSession * const sessionP); + +bool +HTTPWriteContinue(TSession * const sessionP); + +#endif diff --git a/trunk/lib/abyss/src/init.c b/trunk/lib/abyss/src/init.c new file mode 100644 index 000000000..b4e4a788e --- /dev/null +++ b/trunk/lib/abyss/src/init.c @@ -0,0 +1,101 @@ +/*============================================================================= + The functions handle static stuff -- the functions do not operate on + any particular Abyss object, but rather on the global environment of + the program that uses the Abyss library. abyssInit() is essentially + and extension of the program loader. + + The intent is for any program that uses the Abyss library to call + AbyssInit() just as it starts up, and AbyssTerm() just as it exits. + It should do both when the program is only one thread, because they + are not thread-safe. + + These functions do the bare minimum they can get away with; we prefer + context to be local to invidual objects. +=============================================================================*/ + +#include + +#include "xmlrpc-c/string_int.h" + +#include "chanswitch.h" +#include "channel.h" + +#include "xmlrpc-c/abyss.h" + + +static unsigned int AbyssInitCount = 0; + +static void +initAbyss(const char ** const errorP) { + + const char * error; + + DateInit(); + MIMETypeInit(); + + ChanSwitchInit(&error); + + if (error) { + xmlrpc_asprintf(errorP, + "Could not initialize channel swtich class. %s", + error); + + xmlrpc_strfree(error); + } else { + const char * error; + ChannelInit(&error); + + if (error) { + xmlrpc_asprintf(errorP, "Could not initialize Channel class. %s", + error); + + xmlrpc_strfree(error); + } else { + AbyssInitCount = 1; + *errorP = NULL; + + if (*errorP) + ChannelTerm(); + } + if (*errorP) + ChanSwitchTerm(); + } +} + + + +void +AbyssInit(const char ** const errorP) { + + if (AbyssInitCount > 0) { + *errorP = NULL; + ++AbyssInitCount; + } else { + initAbyss(errorP); + if (!*errorP) + AbyssInitCount = 1; + } +} + + + +static void +termAbyss(void) { + + ChannelTerm(); + ChanSwitchTerm(); + MIMETypeTerm(); +} + + + +void +AbyssTerm(void) { + + assert(AbyssInitCount > 0); + + --AbyssInitCount; + + if (AbyssInitCount == 0) + termAbyss(); +} diff --git a/trunk/lib/abyss/src/main.c b/trunk/lib/abyss/src/main.c new file mode 100644 index 000000000..90f39f382 --- /dev/null +++ b/trunk/lib/abyss/src/main.c @@ -0,0 +1,254 @@ +/****************************************************************************** +** +** main.c +** +** This file is part of the ABYSS Web server project. +** +** Copyright (C) 2000 by Moez Mahfoudh . +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +******************************************************************************/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include + +#if MSVCRT +#include +#endif + +#ifdef _UNIX +#include +#include +#endif + +#include "xmlrpc-c/abyss.h" + +void Answer(TSession *r, uint16_t statuscode, char *buffer) +{ + ResponseChunked(r); + + ResponseStatus(r,statuscode); + + ResponseContentType(r,"text/html"); + + ResponseWriteStart(r); + + HTTPWrite(r,"",12); + + HTTPWrite(r,buffer,strlen(buffer)); + + HTTPWrite(r,"",14); + + HTTPWriteEnd(r); +} + +abyss_bool HandleTime(TSession *r) +{ + char z[50]; + time_t ltime; + TDate date; + const char * dateString; + const char * answer; + + if (!xmlrpc_streq(r->uri,"/time")) + return FALSE; + + if (!RequestAuth(r,"Mot de passe","moez","hello")) + return TRUE; + + time(<ime); + DateFromGMT(&date, ltime); + + DateToString(&date, &dateString); + + xmlrpc_asprintf(&answer, "The time is %s", dateString); + + Answer(r, 200, answer); + + xmlrpc_strfree(dateString); + xmlrpc_strfree(answer); + + return TRUE; +} + +abyss_bool HandleDump(TSession *r) +{ + char z[50]; + + if (!xmlrpc_streq(r->uri,"/name")) + return FALSE; + + sprintf(z,"Server name is %s", (r->server)->name ); + Answer(r,200,z); + + return TRUE; +} + +abyss_bool HandleStatus(TSession *r) +{ + uint32_t status; + + if (sscanf(r->uri,"/status/%d",&status)<=0) + return FALSE; + + ResponseStatus(r,(uint16_t)status); + + return TRUE; +} + +abyss_bool HandleMIMEType(TSession *r) +{ + char *m; + + if (!xmlrpc_strneq(r->uri, "/mime/", 6)) + return FALSE; + + m=MIMETypeFromExt(r->uri+6); + if (!m) + m="(none)"; + + Answer(r,200,m); + + return TRUE; +} + +#ifdef _UNIX +static void sigterm(int sig) +{ + TraceExit("Signal %d received. Exiting...\n",sig); +} + + + +static void +sigchld(int const signalClass) { + + bool childrenLeft; + bool error; + + childrenLeft = true; + error = false; + + /* Reap defunct children until there aren't any more. */ + while (childrenLeft && !error) { + int status; + pid_t rc; + rc = waitpid((pid_t) -1, &status, WNOHANG); + + if (rc == 0) + childrenLeft = false; + else if (rc < 0) { + /* because of ptrace */ + if (errno == EINTR) { + /* ptrace causes this */ + } else + error = true; + } else { + /* We reaped a child. */ + pid_t const pid = rc; + ThreadHandleSigchld(pid); + } + } +} +#endif _UNIX + + + +int main(int argc,char **argv) +{ + const char * const name = argv[0]; + TServer srv; + char * p; + const char * conffile; + bool err; + + conffile = DEFAULT_CONF_FILE; /* initial value */ + err = FALSE; /* initial value */ + + while (p=*(++argv)) + { + if ((*p=='-') && (*(p+1))) + if (*(p+2)=='\0') + switch (*(p+1)) + { + case 'c': + argv++; + if (*argv) + conffile=*argv; + else + err=TRUE; + break; + default: + err=TRUE; + } + else + err=TRUE; + else + err=TRUE; + }; + + if (err) + { + help(name); + exit(1); + }; + + DateInit(); + + MIMETypeInit(); + + ServerCreate(&srv,"HTTPServer",80,DEFAULT_DOCS,NULL); + + ConfReadServerFile(conffile,&srv); + + ServerAddHandler(&srv,HandleTime); + ServerAddHandler(&srv,HandleDump); + ServerAddHandler(&srv,HandleStatus); + ServerAddHandler(&srv,HandleMIMEType); + + ServerInit(&srv); + +#ifdef _UNIX + /* Catch various termination signals. */ + signal(SIGTERM,sigterm); + signal(SIGINT,sigterm); + signal(SIGHUP,sigterm); + signal(SIGUSR1,sigterm); + + /* Catch defunct children. */ + signal(SIGCHLD,sigchld); +#endif + + ServerDaemonize(srv); + + ServerRun(&srv); + + return 0; +} diff --git a/trunk/lib/abyss/src/response.c b/trunk/lib/abyss/src/response.c new file mode 100644 index 000000000..cc0980a23 --- /dev/null +++ b/trunk/lib/abyss/src/response.c @@ -0,0 +1,826 @@ +/*============================================================================= + response +=============================================================================== + This module contains callbacks from and services for a request handler. + + Copyright information is at the end of the file +=============================================================================*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "bool.h" +#include "int.h" +#include "version.h" +#include "mallocvar.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/abyss.h" + +#include "trace.h" +#include "server.h" +#include "session.h" +#include "file.h" +#include "conn.h" +#include "token.h" +#include "date.h" +#include "data.h" +#include "abyss_info.h" +#include "http.h" + + + +void +ResponseError2(TSession * const sessionP, + const char * const explanation) { + + const char * errorDocument; + + ResponseAddField(sessionP, "Content-type", "text/html"); + + ResponseWriteStart(sessionP); + + xmlrpc_asprintf(&errorDocument, + "Error %d" + "" + "

Error %d

" + "

%s

" SERVER_HTML_INFO + "" + "", + sessionP->status, sessionP->status, explanation); + + ConnWrite(sessionP->connP, errorDocument, strlen(errorDocument)); + + xmlrpc_strfree(errorDocument); +} + + + +void +ResponseError(TSession * const sessionP) { + + ResponseError2(sessionP, HTTPReasonByStatus(sessionP->status)); +} + + + + +abyss_bool +ResponseChunked(TSession * const sessionP) { +/*---------------------------------------------------------------------------- + Make the response chunked. + + This is only a hope, things will be real only after a call of + ResponseWriteStart() +-----------------------------------------------------------------------------*/ + assert(!sessionP->responseStarted); + + sessionP->chunkedwrite = + (sessionP->version.major > 1) || + (sessionP->version.major == 1 && (sessionP->version.minor >= 1)); + + sessionP->chunkedwritemode = true; + + return true; +} + + + +void +ResponseStatus(TSession * const sessionP, + unsigned short const code) { +/*---------------------------------------------------------------------------- + Set the status code for the response to 'code'. +-----------------------------------------------------------------------------*/ + sessionP->status = code; +} + + + +xmlrpc_uint16_t +ResponseStatusFromErrno(int const errnoArg) { +/*---------------------------------------------------------------------------- + The appropriate HTTP status code for a POSIX errno of 'errnoArg'. +-----------------------------------------------------------------------------*/ + uint16_t code; + + switch (errnoArg) { + case EACCES: + code=403; + break; + case ENOENT: + code=404; + break; + default: + code=500; + } + return code; +} + + + +void +ResponseStatusErrno(TSession * const sessionP) { +/*---------------------------------------------------------------------------- + Set the response state from the global 'errno' value (i.e. the result + of the last system call Caller made). +-----------------------------------------------------------------------------*/ + ResponseStatus(sessionP, ResponseStatusFromErrno(errno)); +} + + + +static bool +isValidHttpToken(const char * const token) { + + char const separators[] = "()<>@,;:\\\"/[]?={} \t"; + const char * p; + bool valid; + + for (p = &token[0], valid = true; *p; ++p) { + if (!isprint(*p) || strchr(separators, *p)) + valid = false; + } + return valid; +} + + + + +static bool +isValidHttpText(const char * const text) { + + const char * p; + bool valid; + + for (p = &text[0], valid = true; *p; ++p) { + if (!isprint(*p)) + valid = false; + } + return valid; +} + + + +abyss_bool +ResponseAddField(TSession * const sessionP, + const char * const name, + const char * const value) { + + abyss_bool succeeded; + + if (!isValidHttpToken(name)) { + TraceMsg("Supplied HTTP header field name is not a valid HTTP token"); + succeeded = false; + } else if (!isValidHttpText(value)) { + TraceMsg("Supplied HTTP header field value is not valid HTTP text"); + succeeded = false; + } else { + succeeded = TableAdd(&sessionP->responseHeaderFields, name, value); + } + return succeeded; +} + + + +static void +addConnectionHeaderFld(TSession * const sessionP) { + + struct _TServer * const srvP = ConnServer(sessionP->connP)->srvP; + + if (HTTPKeepalive(sessionP)) { + const char * keepaliveValue; + + ResponseAddField(sessionP, "Connection", "Keep-Alive"); + + xmlrpc_asprintf(&keepaliveValue, "timeout=%u, max=%u", + srvP->keepalivetimeout, srvP->keepalivemaxconn); + + ResponseAddField(sessionP, "Keep-Alive", keepaliveValue); + + xmlrpc_strfree(keepaliveValue); + } else + ResponseAddField(sessionP, "Connection", "close"); +} + + + +static void +addDateHeaderFld(TSession * const sessionP) { + + if (sessionP->status >= 200) { + const char * dateValue; + + DateToString(sessionP->date, &dateValue); + + if (dateValue) { + ResponseAddField(sessionP, "Date", dateValue); + xmlrpc_strfree(dateValue); + } + } +} + + + +static void +addServerHeaderFld(TSession * const sessionP) { + + const char * serverValue; + + xmlrpc_asprintf(&serverValue, "Xmlrpc-c_Abyss/%s", XMLRPC_C_VERSION); + + ResponseAddField(sessionP, "Server", serverValue); + + xmlrpc_strfree(serverValue); +} + + + +static unsigned int +leadingWsCt(const char * const arg) { + + unsigned int i; + + for (i = 0; arg[i] && isspace(arg[i]); ++i); + + return i; +} + + + +static unsigned int +trailingWsPos(const char * const arg) { + + unsigned int i; + + for (i = strlen(arg); i > 0 && isspace(arg[i-1]); --i); + + return i; +} + + + +static const char * +formatFieldValue(const char * const unformatted) { +/*---------------------------------------------------------------------------- + Return the string of characters that goes after the colon on the + HTTP header field line, given that 'unformatted' is its basic value. +-----------------------------------------------------------------------------*/ + const char * retval; + + /* An HTTP header field value may not have leading or trailing white + space. + */ + char * buffer; + + buffer = malloc(strlen(unformatted) + 1); + + if (buffer == NULL) + retval = xmlrpc_strnomemval(); + else { + unsigned int const lead = leadingWsCt(unformatted); + unsigned int const trail = trailingWsPos(unformatted); + assert(trail >= lead); + strncpy(buffer, &unformatted[lead], trail - lead); + buffer[trail - lead] = '\0'; + retval = buffer; + } + return retval; +} + + + +static void +sendHeader(TConn * const connP, + TTable const fields) { +/*---------------------------------------------------------------------------- + Send the HTTP response header whose fields are fields[]. + + Don't include the blank line that separates the header from the body. + + fields[] contains syntactically valid HTTP header field names and values. + But to the extent that int contains undefined field names or semantically + invalid values, the header we send is invalid. +-----------------------------------------------------------------------------*/ + unsigned int i; + + for (i = 0; i < fields.size; ++i) { + TTableItem * const fieldP = &fields.item[i]; + const char * const fieldValue = formatFieldValue(fieldP->value); + + const char * line; + + xmlrpc_asprintf(&line, "%s: %s\r\n", fieldP->name, fieldValue); + ConnWrite(connP, line, strlen(line)); + xmlrpc_strfree(line); + xmlrpc_strfree(fieldValue); + } +} + + +void +ResponseWriteStart(TSession * const sessionP) { +/*---------------------------------------------------------------------------- + Begin the process of sending the response for an HTTP transaction + (i.e. Abyss session). + + As part of this, send the entire HTTP header for the response. +-----------------------------------------------------------------------------*/ + struct _TServer * const srvP = ConnServer(sessionP->connP)->srvP; + + assert(!sessionP->responseStarted); + + if (sessionP->status == 0) { + /* Handler hasn't set status. That's an error */ + TraceMsg("Abyss client called ResponseWriteStart() on " + "a session for which he has not set the request status " + "('status' member of TSession). Using status 500\n"); + sessionP->status = 500; + } + + sessionP->responseStarted = true; + + { + const char * const reason = HTTPReasonByStatus(sessionP->status); + const char * line; + xmlrpc_asprintf(&line,"HTTP/1.1 %u %s\r\n", sessionP->status, reason); + ConnWrite(sessionP->connP, line, strlen(line)); + xmlrpc_strfree(line); + } + + addConnectionHeaderFld(sessionP); + + if (sessionP->chunkedwrite && sessionP->chunkedwritemode) + ResponseAddField(sessionP, "Transfer-Encoding", "chunked"); + + addDateHeaderFld(sessionP); + + if (srvP->advertise) + addServerHeaderFld(sessionP); + + /* Note that sessionP->responseHeaderFields is defined to contain + syntactically but not necessarily semantically valid header + field names and values. + */ + sendHeader(sessionP->connP, sessionP->responseHeaderFields); + + ConnWrite(sessionP->connP, "\r\n", 2); +} + + + +abyss_bool +ResponseWriteBody(TSession * const sessionP, + const char * const data, + xmlrpc_uint32_t const len) { + + return HTTPWriteBodyChunk(sessionP, data, len); +} + + + +abyss_bool +ResponseWriteEnd(TSession * const sessionP) { + + return HTTPWriteEndChunk(sessionP); +} + + + +abyss_bool +ResponseContentType(TSession * const serverP, + const char * const type) { + + return ResponseAddField(serverP, "Content-type", type); +} + + + +abyss_bool +ResponseContentLength(TSession * const sessionP, + xmlrpc_uint64_t const len) { + + char contentLengthValue[32]; + + sprintf(contentLengthValue, "%" PRIu64, len); + + return ResponseAddField(sessionP, "Content-length", contentLengthValue); +} + + + +void +ResponseAccessControl(TSession * const abyssSessionP, + ResponseAccessCtl const accessControl) { + + if (accessControl.allowOrigin) { + ResponseAddField(abyssSessionP, "Access-Control-Allow-Origin", + accessControl.allowOrigin); + ResponseAddField(abyssSessionP, "Access-Control-Allow-Methods", + "POST"); + ResponseAddField(abyssSessionP, "Access-Control-Allow-Headers", + "Content-Type"); + ResponseAddField(abyssSessionP, "Access-Control-Allow-Headers", + "Content-Length"); + if (accessControl.expires) { + char buffer[64]; + sprintf(buffer, "%u", accessControl.maxAge); + ResponseAddField(abyssSessionP, "Access-Control-Max-Age", buffer); + } + } +} + + + +/********************************************************************* +** MIMEType +*********************************************************************/ + +struct MIMEType { + TList typeList; + TList extList; + TPool pool; +}; + + +static MIMEType * globalMimeTypeP = NULL; + + + +MIMEType * +MIMETypeCreate(void) { + + MIMEType * MIMETypeP; + + MALLOCVAR(MIMETypeP); + + if (MIMETypeP) { + ListInit(&MIMETypeP->typeList); + ListInit(&MIMETypeP->extList); + PoolCreate(&MIMETypeP->pool, 1024); + } + return MIMETypeP; +} + + + +void +MIMETypeDestroy(MIMEType * const MIMETypeP) { + + PoolFree(&MIMETypeP->pool); + + free(MIMETypeP); +} + + + +void +MIMETypeInit(void) { + + if (globalMimeTypeP != NULL) + abort(); + + globalMimeTypeP = MIMETypeCreate(); +} + + + +void +MIMETypeTerm(void) { + + if (globalMimeTypeP == NULL) + abort(); + + MIMETypeDestroy(globalMimeTypeP); + + globalMimeTypeP = NULL; +} + + + +static void +mimeTypeAdd(MIMEType * const MIMETypeP, + const char * const type, + const char * const ext, + bool * const successP) { + + uint16_t index; + void * mimeTypesItem; + bool typeIsInList; + + assert(MIMETypeP != NULL); + + typeIsInList = ListFindString(&MIMETypeP->typeList, type, &index); + if (typeIsInList) + mimeTypesItem = MIMETypeP->typeList.item[index]; + else + mimeTypesItem = (void*)PoolStrdup(&MIMETypeP->pool, type); + + if (mimeTypesItem) { + bool extIsInList; + extIsInList = ListFindString(&MIMETypeP->extList, ext, &index); + if (extIsInList) { + MIMETypeP->typeList.item[index] = mimeTypesItem; + *successP = true; + } else { + void * extItem = (void*)PoolStrdup(&MIMETypeP->pool, ext); + if (extItem) { + bool addedToMimeTypes; + + addedToMimeTypes = + ListAdd(&MIMETypeP->typeList, mimeTypesItem); + if (addedToMimeTypes) { + bool addedToExt; + + addedToExt = ListAdd(&MIMETypeP->extList, extItem); + *successP = addedToExt; + if (!*successP) + ListRemove(&MIMETypeP->typeList); + } else + *successP = false; + if (!*successP) + PoolReturn(&MIMETypeP->pool, extItem); + } else + *successP = false; + } + } else + *successP = false; +} + + + + +abyss_bool +MIMETypeAdd2(MIMEType * const MIMETypeArg, + const char * const type, + const char * const ext) { + + MIMEType * MIMETypeP = MIMETypeArg ? MIMETypeArg : globalMimeTypeP; + + bool success; + + if (MIMETypeP == NULL) + success = false; + else + mimeTypeAdd(MIMETypeP, type, ext, &success); + + return success; +} + + + +abyss_bool +MIMETypeAdd(const char * const type, + const char * const ext) { + + return MIMETypeAdd2(globalMimeTypeP, type, ext); +} + + + +static const char * +mimeTypeFromExt(MIMEType * const MIMETypeP, + const char * const ext) { + + const char * retval; + uint16_t extindex; + bool extIsInList; + + assert(MIMETypeP != NULL); + + extIsInList = ListFindString(&MIMETypeP->extList, ext, &extindex); + if (!extIsInList) + retval = NULL; + else + retval = MIMETypeP->typeList.item[extindex]; + + return retval; +} + + + +const char * +MIMETypeFromExt2(MIMEType * const MIMETypeArg, + const char * const ext) { + + const char * retval; + + MIMEType * MIMETypeP = MIMETypeArg ? MIMETypeArg : globalMimeTypeP; + + if (MIMETypeP == NULL) + retval = NULL; + else + retval = mimeTypeFromExt(MIMETypeP, ext); + + return retval; +} + + + +const char * +MIMETypeFromExt(const char * const ext) { + + return MIMETypeFromExt2(globalMimeTypeP, ext); +} + + + +static void +findExtension(const char * const fileName, + const char ** const extP) { + + unsigned int extPos = 0; /* stifle unset variable warning */ + /* Running estimation of where in fileName[] the extension starts */ + bool extFound; + unsigned int i; + + /* We're looking for the last dot after the last slash */ + for (i = 0, extFound = false; fileName[i]; ++i) { + char const c = fileName[i]; + + if (c == '.') { + extFound = true; + extPos = i + 1; + } + if (c == '/') + extFound = false; + } + + if (extFound) + *extP = &fileName[extPos]; + else + *extP = NULL; +} + + + +static const char * +mimeTypeFromFileName(MIMEType * const MIMETypeP, + const char * const fileName) { + + const char * retval; + const char * ext; + + assert(MIMETypeP != NULL); + + findExtension(fileName, &ext); + + if (ext) + retval = MIMETypeFromExt2(MIMETypeP, ext); + else + retval = "application/octet-stream"; + + return retval; +} + + + +const char * +MIMETypeFromFileName2(MIMEType * const MIMETypeArg, + const char * const fileName) { + + const char * retval; + + MIMEType * MIMETypeP = MIMETypeArg ? MIMETypeArg : globalMimeTypeP; + + if (MIMETypeP == NULL) + retval = NULL; + else + retval = mimeTypeFromFileName(MIMETypeP, fileName); + + return retval; +} + + + +const char * +MIMETypeFromFileName(const char * const fileName) { + + return MIMETypeFromFileName2(globalMimeTypeP, fileName); +} + + + +static bool +fileContainsText(const char * const fileName) { +/*---------------------------------------------------------------------------- + Return true iff we can read the contents of the file named 'fileName' + and see that it appears to be composed of plain text characters. +-----------------------------------------------------------------------------*/ + bool retval; + bool fileOpened; + TFile * fileP; + + fileOpened = FileOpen(&fileP, fileName, O_BINARY | O_RDONLY); + if (fileOpened) { + char const ctlZ = 26; + unsigned char buffer[80]; + int32_t readRc; + unsigned int i; + + readRc = FileRead(fileP, buffer, sizeof(buffer)); + + if (readRc >= 0) { + unsigned int bytesRead = readRc; + bool nonTextFound; + + nonTextFound = false; /* initial value */ + + for (i = 0; i < bytesRead; ++i) { + char const c = buffer[i]; + if (c < ' ' && !isspace(c) && c != ctlZ) + nonTextFound = true; + } + retval = !nonTextFound; + } else + retval = false; + FileClose(fileP); + } else + retval = false; + + return retval; +} + + + +static const char * +mimeTypeGuessFromFile(MIMEType * const MIMETypeP, + const char * const fileName) { + + const char * retval; + const char * ext; + + findExtension(fileName, &ext); + + retval = NULL; + + if (ext && MIMETypeP) + retval = MIMETypeFromExt2(MIMETypeP, ext); + + if (!retval) { + if (fileContainsText(fileName)) + retval = "text/plain"; + else + retval = "application/octet-stream"; + } + return retval; +} + + + +const char * +MIMETypeGuessFromFile2(MIMEType * const MIMETypeArg, + const char * const fileName) { + + return mimeTypeGuessFromFile(MIMETypeArg ? MIMETypeArg : globalMimeTypeP, + fileName); +} + + + +const char * +MIMETypeGuessFromFile(const char * const fileName) { + + return mimeTypeGuessFromFile(globalMimeTypeP, fileName); +} + + + +/****************************************************************************** +** +** http.c +** +** Copyright (C) 2000 by Moez Mahfoudh . +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +******************************************************************************/ diff --git a/trunk/lib/abyss/src/server.c b/trunk/lib/abyss/src/server.c new file mode 100644 index 000000000..5c7f83839 --- /dev/null +++ b/trunk/lib/abyss/src/server.c @@ -0,0 +1,1828 @@ +/* Copyright information is at end of file */ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ +#define _BSD_SOURCE /* Make sure setgroups()is in */ + +#include "xmlrpc_config.h" + +#include +#include +#include +#if MSVCRT + #include +#else + #include +#endif +#include +#include +#include +#if !MSVCRT + #include +#endif + +#include "bool.h" +#include "girmath.h" +#include "mallocvar.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/sleep_int.h" +#include "xmlrpc-c/lock.h" +#include "xmlrpc-c/lock_platform.h" + +#include "xmlrpc-c/abyss.h" +#include "trace.h" +#include "thread.h" +#include "session.h" +#include "file.h" +#include "conn.h" +#include "chanswitch.h" +#include "channel.h" +#include "socket.h" +#if MSVCRT + #include "socket_win.h" +#else + #include "socket_unix.h" +#endif +#include "http.h" +#include "handler.h" +#include "sessionReadRequest.h" + +#include "server.h" + + +struct uriHandler { + initHandlerFn init; + termHandlerFn term; + handleReq3Fn handleReq3; + handleReq2Fn handleReq2; + URIHandler handleReq1; + void * userdata; +}; + + + +void +ServerTerminate(TServer * const serverP) { + + struct _TServer * const srvP = serverP->srvP; + + srvP->terminationRequested = true; + + if (srvP->chanSwitchP) + ChanSwitchInterrupt(srvP->chanSwitchP); +} + + + +void +ServerResetTerminate(TServer * const serverP) { + + struct _TServer * const srvP = serverP->srvP; + + srvP->terminationRequested = false; +} + + + +static void +initUnixStuff(struct _TServer * const srvP) { +#if !MSVCRT + srvP->pidfileP = NULL; + srvP->uid = srvP->gid = -1; +#endif +} + + + +static void +logOpen(struct _TServer * const srvP, + const char ** const errorP) { + + bool success; + + success = FileOpenCreate(&srvP->logfileP, srvP->logfilename, + O_WRONLY | O_APPEND); + if (success) { + srvP->logLockP = xmlrpc_lock_create(); + *errorP = NULL; + + srvP->logfileisopen = true; + + if (*errorP) + FileClose(srvP->logfileP); + } else + xmlrpc_asprintf(errorP, "Can't open log file '%s'", srvP->logfilename); +} + + + +static void +logClose(struct _TServer * const srvP) { + + if (srvP->logfileisopen) { + FileClose(srvP->logfileP); + srvP->logLockP->destroy(srvP->logLockP); + srvP->logfileisopen = false; + } +} + + + +static void +setupTrace(struct _TServer * const srvP) { + + srvP->tracer.traceIsActive = (getenv("ABYSS_TRACE_SERVER") != NULL); + + if (srvP->tracer.traceIsActive) + fprintf(stderr, "Abyss server will trace " + "basic server activity " + "because of ABYSS_TRACE_SERVER environment variable\n"); +} + + + +static void +tracev(const char * const fmt, + va_list argptr) { + + vfprintf(stderr, fmt, argptr); + + fprintf(stderr, "\n"); +} + + + +static void +trace(struct Tracer * const tracerP, + const char * const fmt, + ...) { + + if (tracerP->traceIsActive) { + va_list argptr; + + va_start(argptr, fmt); + tracev(fmt, argptr); + va_end(argptr); + } +} + + + +static void +initChanSwitchStuff(struct _TServer * const srvP, + bool const noAccept, + TChanSwitch * const chanSwitchP, + bool const userChanSwitch, + unsigned short const port, + const char ** const errorP) { + + + if (chanSwitchP) { + *errorP = NULL; + srvP->serverAcceptsConnections = true; + srvP->chanSwitchP = chanSwitchP; + srvP->weCreatedChanSwitch = !userChanSwitch; + } else if (noAccept) { + *errorP = NULL; + srvP->serverAcceptsConnections = false; + srvP->chanSwitchP = NULL; + srvP->weCreatedChanSwitch = false; + } else { + *errorP = NULL; + srvP->serverAcceptsConnections = true; + srvP->chanSwitchP = NULL; + srvP->weCreatedChanSwitch = false; + srvP->port = port; + } + srvP->readyToAccept = false; +} + + + +static void +createServer(struct _TServer ** const srvPP, + bool const noAccept, + TChanSwitch * const chanSwitchP, + bool const userChanSwitch, + unsigned short const portNumber, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Create a server object and return it as *srvPP. +-----------------------------------------------------------------------------*/ + struct _TServer * srvP; + + MALLOCVAR(srvP); + + if (srvP == NULL) { + xmlrpc_asprintf(errorP, + "Unable to allocate space for server descriptor"); + } else { + setupTrace(srvP); + + srvP->terminationRequested = false; + + initChanSwitchStuff(srvP, noAccept, chanSwitchP, userChanSwitch, + portNumber, errorP); + + if (!*errorP) { + srvP->builtinHandlerP = HandlerCreate(); + if (!srvP->builtinHandlerP) + xmlrpc_asprintf(errorP, "Unable to allocate space for " + "builtin handler descriptor"); + else { + srvP->defaultHandler = HandlerDefaultBuiltin; + srvP->defaultHandlerContext = srvP->builtinHandlerP; + + srvP->name = strdup("unnamed"); + srvP->logfilename = NULL; + srvP->keepalivetimeout = 15; + srvP->keepalivemaxconn = 30; + srvP->timeout = 15; + srvP->advertise = true; + srvP->useSigchld = false; + srvP->uriHandlerStackSize = 0; + srvP->maxConn = 15; + srvP->maxConnBacklog = 15; + srvP->maxSessionMem = 0; + + initUnixStuff(srvP); + + ListInitAutoFree(&srvP->handlers); + + srvP->logfileisopen = false; + + *errorP = NULL; + + if (*errorP) + HandlerDestroy(srvP->builtinHandlerP); + } + } + if (*errorP) + free(srvP); + } + *srvPP = srvP; +} + + + +static void +setNamePathLog(TServer * const serverP, + const char * const name, + const char * const filesPath, + const char * const logFileName) { +/*---------------------------------------------------------------------------- + This odd function exists to help with backward compatibility. + Today, we have the expandable model where you create a server with + default parameters, then use ServerSet... functions to choose + non-default parameters. But before, you specified these three + parameters right in the arguments of various create functions. +-----------------------------------------------------------------------------*/ + if (name) + ServerSetName(serverP, name); + if (filesPath) + ServerSetFilesPath(serverP, filesPath); + if (logFileName) + ServerSetLogFileName(serverP, logFileName); +} + + + +abyss_bool +ServerCreate(TServer * const serverP, + const char * const name, + xmlrpc_uint16_t const portNumber, + const char * const filesPath, + const char * const logFileName) { +/*---------------------------------------------------------------------------- + Create a server that will listen for and accept client connections on TCP + port 'portNumber'. Those connections will be raw TCP connections. + + Set *serverP to represent that server. +-----------------------------------------------------------------------------*/ + + bool const noAcceptFalse = false; + bool const userChanSwitchFalse = false; + + bool success; + const char * error; + + createServer(&serverP->srvP, noAcceptFalse, + NULL, userChanSwitchFalse, + portNumber, &error); + + if (error) { + TraceMsg(error); + xmlrpc_strfree(error); + success = false; + } else { + success = true; + + setNamePathLog(serverP, name, filesPath, logFileName); + } + + return success; +} + + + +static void +createSwitchFromOsSocket(TOsSocket const osSocket, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + +#if MSVCRT + ChanSwitchWinCreateWinsock(osSocket, chanSwitchPP, errorP); +#else + ChanSwitchUnixCreateFd(osSocket, chanSwitchPP, errorP); +#endif +} + + + +static void +createChannelFromOsSocket(TOsSocket const osSocket, + TChannel ** const channelPP, + void ** const channelInfoPP, + const char ** const errorP) { + +#if MSVCRT + ChannelWinCreateWinsock(osSocket, channelPP, + (struct abyss_win_chaninfo**)channelInfoPP, + errorP); +#else + ChannelUnixCreateFd(osSocket, channelPP, + (struct abyss_unix_chaninfo**)channelInfoPP, + errorP); +#endif +} + + + +abyss_bool +ServerCreateSocket(TServer * const serverP, + const char * const name, + TOsSocket const socketFd, + const char * const filesPath, + const char * const logFileName) { +/*---------------------------------------------------------------------------- + Create a server that will listen for and accept client connections on + socket 'socketFd'. Those connections will be raw TCP connections. + + Set *serverP to represent that server. +-----------------------------------------------------------------------------*/ + bool success; + TChanSwitch * chanSwitchP; + const char * error; + + createSwitchFromOsSocket(socketFd, &chanSwitchP, &error); + + if (error) { + TraceMsg(error); + success = false; + xmlrpc_strfree(error); + } else { + bool const noAcceptFalse = false; + bool const userChanSwitchFalse = false; + + const char * error; + + createServer(&serverP->srvP, noAcceptFalse, + chanSwitchP, userChanSwitchFalse, + 0, &error); + + if (error) { + TraceMsg(error); + success = false; + xmlrpc_strfree(error); + } else { + success = true; + + setNamePathLog(serverP, name, filesPath, logFileName); + } + if (!success) + ChanSwitchDestroy(chanSwitchP); + } + + return success; +} + + + +abyss_bool +ServerCreateNoAccept(TServer * const serverP, + const char * const name, + const char * const filesPath, + const char * const logFileName) { +/*---------------------------------------------------------------------------- + Create a server that will not get client connections; the user will have to + get the client connections and use server methods that take an existing + connection as an argument. + + Set *serverP to represent that server. +-----------------------------------------------------------------------------*/ + bool const noAcceptTrue = true; + bool const userChanSwitchFalse = false; + + bool success; + const char * error; + + createServer(&serverP->srvP, noAcceptTrue, + NULL, userChanSwitchFalse, + 0, &error); + + if (error) { + TraceMsg(error); + success = false; + xmlrpc_strfree(error); + } else { + success = true; + + setNamePathLog(serverP, name, filesPath, logFileName); + } + return success; +} + + + +void +ServerCreateSwitch(TServer * const serverP, + TChanSwitch * const chanSwitchP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Create a server that will get client connections from channel switch + *chanSwitchP. Those connections would typically be raw TCP connections, + but could be anything that can be abstracted by a Channel object. For + example, an SSL encrypted TCP connection. + + Set *serverP to represent that server. +-----------------------------------------------------------------------------*/ + bool const noAcceptFalse = false; + bool const userChanSwitchTrue = true; + + assert(serverP); + assert(chanSwitchP); + + createServer(&serverP->srvP, noAcceptFalse, + chanSwitchP, userChanSwitchTrue, + 0, errorP); +} + + + +void +ServerCreateSocket2(TServer * const serverP, + TSocket * const socketP, + const char ** const errorP) { + + TChanSwitch * const chanSwitchP = SocketGetChanSwitch(socketP); + + assert(socketP); + + if (!chanSwitchP) + xmlrpc_asprintf( + errorP, "Socket is not a listening socket. " + "You should use ServerCreateSwitch() instead, anyway."); + else + ServerCreateSwitch(serverP, chanSwitchP, errorP); +} + + + +static void +terminateHandlers(TList * const handlersP) { +/*---------------------------------------------------------------------------- + Terminate all handlers in the list '*handlersP'. + + I.e. call each handler's terminate function. +-----------------------------------------------------------------------------*/ + if (handlersP->item) { + unsigned int i; + for (i = handlersP->size; i > 0; --i) { + struct uriHandler * const handlerP = handlersP->item[i-1]; + if (handlerP->term) + handlerP->term(handlerP->userdata); + } + } +} + + + +void +ServerFree(TServer * const serverP) { + + struct _TServer * const srvP = serverP->srvP; + + if (srvP->weCreatedChanSwitch) + ChanSwitchDestroy(srvP->chanSwitchP); + + xmlrpc_strfree(srvP->name); + + terminateHandlers(&srvP->handlers); + + ListFree(&srvP->handlers); + + HandlerDestroy(srvP->builtinHandlerP); + + logClose(srvP); + + if (srvP->logfilename) + xmlrpc_strfree(srvP->logfilename); + + free(srvP); +} + + + +void +ServerSetName(TServer * const serverP, + const char * const name) { + + xmlrpc_strfree(serverP->srvP->name); + + serverP->srvP->name = strdup(name); +} + + + +void +ServerSetFilesPath(TServer * const serverP, + const char * const filesPath) { + + HandlerSetFilesPath(serverP->srvP->builtinHandlerP, filesPath); +} + + + +void +ServerSetLogFileName(TServer * const serverP, + const char * const logFileName) { + + struct _TServer * const srvP = serverP->srvP; + + if (srvP->logfilename) + xmlrpc_strfree(srvP->logfilename); + + srvP->logfilename = strdup(logFileName); +} + + + +void +ServerSetKeepaliveTimeout(TServer * const serverP, + xmlrpc_uint32_t const keepaliveTimeout) { + + serverP->srvP->keepalivetimeout = MAX(keepaliveTimeout, 1); +} + + + +void +ServerSetKeepaliveMaxConn(TServer * const serverP, + xmlrpc_uint32_t const keepaliveMaxConn) { + + serverP->srvP->keepalivemaxconn = MAX(keepaliveMaxConn, 1); +} + + + +void +ServerSetTimeout(TServer * const serverP, + xmlrpc_uint32_t const timeout) { + + serverP->srvP->timeout = timeout; +} + + + +void +ServerSetAdvertise(TServer * const serverP, + abyss_bool const advertise) { + + serverP->srvP->advertise = advertise; +} + + + +void +ServerSetMimeType(TServer * const serverP, + MIMEType * const mimeTypeP) { + + HandlerSetMimeType(serverP->srvP->builtinHandlerP, mimeTypeP); +} + + + +void +ServerSetMaxConn(TServer * const serverP, + unsigned int const maxConn) { + + if (maxConn > 0) { + serverP->srvP->maxConn = maxConn; + } +} + + + +void +ServerSetMaxConnBacklog(TServer * const serverP, + unsigned int const maxConnBacklog) { + + if (maxConnBacklog > 0) { + serverP->srvP->maxConnBacklog = maxConnBacklog; + } +} + + + +void +ServerSetMaxSessionMem(TServer * const serverP, + size_t const size) { + + if (size > 0) + serverP->srvP->maxSessionMem = size; +} + + + +static URIHandler2 +makeUriHandler2(const struct uriHandler * const handlerP) { + + URIHandler2 retval; + + retval.init = handlerP->init; + retval.term = handlerP->term; + retval.handleReq2 = handlerP->handleReq2; + retval.handleReq1 = handlerP->handleReq1; + retval.userdata = handlerP->userdata; + + return retval; +} + + + +static void +runUserHandler(TSession * const sessionP, + struct _TServer * const srvP) { + + abyss_bool handled; + int i; + + for (i = srvP->handlers.size-1, handled = false; + i >= 0 && !handled; + --i) { + const struct uriHandler * const handlerP = srvP->handlers.item[i]; + + if (handlerP->handleReq3) + handlerP->handleReq3(handlerP->userdata, sessionP, &handled); + if (handlerP->handleReq2) { + URIHandler2 handler2 = makeUriHandler2(handlerP); + handlerP->handleReq2(&handler2, sessionP, &handled); + } else if (handlerP->handleReq1) + handled = handlerP->handleReq1(sessionP); + } + + assert(srvP->defaultHandler); + + if (!handled) + srvP->defaultHandler(sessionP); +} + + + +static void +handleReqTooNewHttpVersion(TSession * const sessionP) { + + const char * msg; + + ResponseStatus(sessionP, 505); + + xmlrpc_asprintf(&msg, "Request is in HTTP Version %u" + "We understand only HTTP 1", + sessionP->version.major); + + ResponseError2(sessionP, msg); + + xmlrpc_strfree(msg); +} + + + +static void +handleReqInvalidURI(TSession * const sessionP) { + + ResponseStatus(sessionP, 400); + + ResponseError2(sessionP, "Invalid URI"); +} + + + +static void +traceRequestStart(struct Tracer * const tracerP, + TSession * const sessionP) { + + if (sessionP->requestInfo.uri) { + trace(tracerP, "Processing request with URI '%s', method %s", + sessionP->requestInfo.uri, + HTTPMethodName(sessionP->requestInfo.method)); + } +} + + + +static void +processRequestFromClient(TConn * const connectionP, + bool const lastReqOnConn, + uint32_t const timeout, + struct Tracer * const tracerP, + bool * const keepAliveP) { +/*---------------------------------------------------------------------------- + Get and execute one HTTP request from client connection *connectionP, + through the connection buffer. I.e. Some of the request may already be in + the connection buffer, and we may leave some of later requests in the + connection buffer. + + In fact, because of timing considerations, we assume the client has begun + sending the request, which as a practical matter means Caller has already + deposited some of it in the connection buffer. + + If there isn't one full request in the buffer now, we wait for one full + request to come through the buffer, up to 'timeout'. + + We return as *keepAliveP whether Caller should keep the connection + alive for a while for possible future requests from the client, based + on 'lastReqOnConn' and the content of the HTTP request. + + Executing the request consists primarily of calling the URI handlers that + are associated with the connection (*connectionP), passing each the request + information we read. Each handler can respond according to the HTTP method + (GET, POST, etc) and URL etc, and that response may be either to + execute the request and send the response or refuse the request and let + us call the next one in the list. +-----------------------------------------------------------------------------*/ + TSession session; + const char * error; + uint16_t httpErrorCode; + + SessionInit(&session, connectionP); + + session.serverDeniesKeepalive = lastReqOnConn; + + SessionReadRequest(&session, timeout, &error, &httpErrorCode); + + if (error) { + ResponseStatus(&session, httpErrorCode); + ResponseError2(&session, error); + xmlrpc_strfree(error); + } else { + traceRequestStart(tracerP, &session); + if (session.version.major >= 2) + handleReqTooNewHttpVersion(&session); + else if (!HTTPRequestHasValidUri(&session)) + handleReqInvalidURI(&session); + else + runUserHandler(&session, connectionP->server->srvP); + } + + assert(session.status != 0); + + if (session.responseStarted) + ResponseWriteEnd(&session); + else + ResponseError(&session); + + *keepAliveP = HTTPKeepalive(&session); + + SessionLog(&session); + + SessionTerm(&session); +} + + + +static TThreadProc serverFunc; + +static void +serverFunc(void * const userHandle) { +/*---------------------------------------------------------------------------- + Do server stuff on one connection. At its simplest, this means do + one HTTP request. But with keepalive, it can be many requests. +-----------------------------------------------------------------------------*/ + TConn * const connectionP = userHandle; + struct _TServer * const srvP = connectionP->server->srvP; + + unsigned int requestCount; + /* Number of requests we've handled so far on this connection */ + bool connectionDone; + /* No more need for this HTTP connection */ + + trace(&srvP->tracer, + "Thread starting to handle requests on a new connection. " + "PID = %d", XMLRPC_GETPID()); + + requestCount = 0; + connectionDone = false; + + while (!connectionDone) { + bool timedOut, eof; + const char * readError; + + /* Wait for and get beginning (at least ) of next request. We do + this separately from getting the rest of the request because we + treat dead time between requests differently from dead time in + the middle of a request. + */ + ConnRead(connectionP, srvP->keepalivetimeout, + &timedOut, &eof, &readError); + + if (srvP->terminationRequested) { + connectionDone = true; + } else if (readError) { + TraceMsg("Failed to read from Abyss connection. %s", readError); + xmlrpc_strfree(readError); + connectionDone = true; + } else if (timedOut) { + connectionDone = true; + } else if (eof) { + connectionDone = true; + } else { + bool const lastReqOnConn = + requestCount + 1 >= srvP->keepalivemaxconn; + + bool keepalive; + + trace(&srvP->tracer, + "HTTP request %u at least partially received. " + "Receiving the rest and processing", requestCount); + + processRequestFromClient(connectionP, lastReqOnConn, srvP->timeout, + &srvP->tracer, &keepalive); + + trace(&srvP->tracer, + "Done processing the HTTP request. Keepalive = %s", + keepalive ? "YES" : "NO"); + + ++requestCount; + + if (!keepalive) + connectionDone = true; + + /**************** Must adjust the read buffer *****************/ + ConnReadInit(connectionP); + } + } + trace(&srvP->tracer, "PID %d done with connection", XMLRPC_GETPID()); +} + + + +/* This is the maximum amount of stack space, in bytes, serverFunc() + itself requires -- not counting what the user's request handler + (which serverFunc() calls) requires. +*/ +#define SERVER_FUNC_STACK 1024 + + + +static void +createSwitchFromPortNum(unsigned short const portNumber, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + +#if MSVCRT + ChanSwitchWinCreate(portNumber, chanSwitchPP, errorP); +#else + ChanSwitchUnixCreate(portNumber, chanSwitchPP, errorP); +#endif +} + + + +static void +createChanSwitch(struct _TServer * const srvP, + const char ** const errorP) { + + TChanSwitch * chanSwitchP; + const char * error; + + /* Not valid to call this when channel switch already exists: */ + assert(srvP->chanSwitchP == NULL); + + createSwitchFromPortNum(srvP->port, &chanSwitchP, &error); + + if (error) { + xmlrpc_asprintf(errorP, + "Can't create channel switch. %s", error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + + srvP->weCreatedChanSwitch = true; + srvP->chanSwitchP = chanSwitchP; + } +} + + + +void +ServerInit2(TServer * const serverP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Initialize a server to accept connections. + + Do not confuse this with creating the server -- ServerCreate(). + + Not necessary or valid with a server that doesn't accept connections (i.e. + user supplies the channels (TCP connections)). +-----------------------------------------------------------------------------*/ + struct _TServer * const srvP = serverP->srvP; + + if (!srvP->serverAcceptsConnections) + xmlrpc_asprintf(errorP, + "ServerInit() is not valid on a server that doesn't " + "accept connections " + "(i.e. created with ServerCreateNoAccept)"); + else { + *errorP = NULL; /* initial value */ + + if (!srvP->chanSwitchP) { + const char * error; + createChanSwitch(srvP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Unable to create a channel switch " + "for the server. %s", error); + xmlrpc_strfree(error); + } + } + + if (!*errorP) { + const char * error; + + assert(srvP->chanSwitchP); + + ChanSwitchListen(srvP->chanSwitchP, srvP->maxConnBacklog, &error); + + if (error) { + xmlrpc_asprintf(errorP, + "Failed to listen on bound socket. %s", + error); + xmlrpc_strfree(error); + } else { + srvP->readyToAccept = true; + } + } + } +} + + + +void +ServerInit(TServer * const serverP) { + + const char * error; + + ServerInit2(serverP, &error); + + if (error) { + TraceExit("ServerInit() failed. %s", error); + xmlrpc_strfree(error); + } +} + + + +/* We don't do any locking on the outstanding connections list, so + we must make sure that only the master thread (the one that listens + for connections) ever accesses it. + + That's why when a thread completes, it places the connection in + "finished" status, but doesn't destroy the connection. +*/ + +typedef struct { + + TConn * firstP; + unsigned int count; + /* Redundant with 'firstP', for quick access */ +} outstandingConnList; + + + +static void +createOutstandingConnList(outstandingConnList ** const listPP) { + + outstandingConnList * listP; + + MALLOCVAR_NOFAIL(listP); + + listP->firstP = NULL; /* empty list */ + listP->count = 0; + + *listPP = listP; +} + + + +static void +destroyOutstandingConnList(outstandingConnList * const listP) { + + assert(listP->firstP == NULL); + assert(listP->count == 0); + + free(listP); +} + + + +static void +addToOutstandingConnList(outstandingConnList * const listP, + TConn * const connectionP) { + + connectionP->nextOutstandingP = listP->firstP; + + listP->firstP = connectionP; + + ++listP->count; +} + + + +static void +freeFinishedConns(outstandingConnList * const listP) { +/*---------------------------------------------------------------------------- + Garbage-collect the resources associated with connections that are + finished with their jobs. Thread resources, connection pool + descriptor, etc. +-----------------------------------------------------------------------------*/ + TConn ** pp; + + pp = &listP->firstP; + + while (*pp) { + TConn * const connectionP = (*pp); + + ThreadUpdateStatus(connectionP->threadP); + + if (connectionP->finished) { + /* Take it out of the list */ + *pp = connectionP->nextOutstandingP; + --listP->count; + + ConnWaitAndRelease(connectionP); + } else { + /* Move to next connection in list */ + pp = &connectionP->nextOutstandingP; + } + } +} + + + +static void +waitForConnectionFreed(outstandingConnList * const outstandingConnListP + ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + Wait for a connection descriptor in 'connectionPool' to be probably + freed. +-----------------------------------------------------------------------------*/ + + /* TODO: We should do something more sophisticated here. For pthreads, + we can have a thread signal us by semaphore when it terminates. + For fork, we might be able to use the "done" handler argument + to ConnCreate() to get interrupted when the death of a child + signal happens. + */ + + xmlrpc_millisecond_sleep(2000); +} + + + +static void +waitForNoConnections(outstandingConnList * const outstandingConnListP) { + + while (outstandingConnListP->firstP) { + freeFinishedConns(outstandingConnListP); + + if (outstandingConnListP->firstP) + waitForConnectionFreed(outstandingConnListP); + } +} + + + +static void +waitForConnectionCapacity(outstandingConnList * const outstandingConnListP, + unsigned int const maxConn) { +/*---------------------------------------------------------------------------- + Wait until there are fewer than 'maxConn' connections in progress. +-----------------------------------------------------------------------------*/ + while (outstandingConnListP->count >= maxConn) { + freeFinishedConns(outstandingConnListP); + if (outstandingConnListP->firstP) + waitForConnectionFreed(outstandingConnListP); + } +} + + + +static void +interruptChannels(outstandingConnList * const outstandingConnListP) { +/*---------------------------------------------------------------------------- + Get every thread that is waiting to read a request or write a response + for a connection to stop waiting. +-----------------------------------------------------------------------------*/ + TConn * connP; + + for (connP = outstandingConnListP->firstP; + connP; connP = connP->nextOutstandingP) { + + if (connP->finished) { + /* The connection couldn't be waiting on the channel, and the + channel probably doesn't even exit anymore. + */ + } else + ChannelInterrupt(connP->channelP); + } +} + + + +#if !MSVCRT +void +ServerHandleSigchld(pid_t const pid) { + + ThreadHandleSigchld(pid); +} +#endif + + + +void +ServerUseSigchld(TServer * const serverP) { + + struct _TServer * const srvP = serverP->srvP; + + srvP->useSigchld = true; +} + + + +static TThreadDoneFn destroyChannel; + +static void +destroyChannel(void * const userHandle) { +/*---------------------------------------------------------------------------- + This is a "connection done" function for the connection the server + serves. It gets called some time after the connection has done its + thing. Its job is to clean up stuff the server created for use by + the connection, but the server can't clean up because the + connection might be processed asynchronously in a background + thread. + + To wit, we destroy the connection's channel and release the memory + for the information about that channel. +-----------------------------------------------------------------------------*/ + TConn * const connectionP = userHandle; + + ChannelDestroy(connectionP->channelP); + free(connectionP->channelInfoP); +} + + + +static void +processNewChannel(TServer * const serverP, + TChannel * const channelP, + void * const channelInfoP, + outstandingConnList * const outstandingConnListP, + const char ** const errorP) { + + struct _TServer * const srvP = serverP->srvP; + + TConn * connectionP; + const char * error; + + freeFinishedConns(outstandingConnListP); + + trace(&srvP->tracer, "Waiting for there to be fewer than the maximum " + "%u sessions in progress", + srvP->maxConn); + + waitForConnectionCapacity(outstandingConnListP, srvP->maxConn); + + ConnCreate(&connectionP, serverP, channelP, channelInfoP, + &serverFunc, + SERVER_FUNC_STACK + srvP->uriHandlerStackSize, + &destroyChannel, ABYSS_BACKGROUND, + srvP->useSigchld, + &error); + if (!error) { + addToOutstandingConnList(outstandingConnListP, connectionP); + ConnProcess(connectionP); + /* When connection is done (which could be later, courtesy of a + background thread), destroyChannel() will destroy *channelP. + */ + *errorP = NULL; + } else { + xmlrpc_asprintf( + errorP, "Failed to create an Abyss connection. %s", error); + xmlrpc_strfree(error); + } +} + + + +static void +acceptAndProcessNextConnection( + TServer * const serverP, + outstandingConnList * const outstandingConnListP, + const char ** const errorP) { + + struct _TServer * const srvP = serverP->srvP; + + const char * error; + TChannel * channelP; + void * channelInfoP; + + trace(&srvP->tracer, "Waiting for a new channel from channel switch"); + + assert(srvP->readyToAccept); + assert(srvP->chanSwitchP); + + ChanSwitchAccept(srvP->chanSwitchP, &channelP, &channelInfoP, &error); + + if (error) { + xmlrpc_asprintf(errorP, + "Failed to accept the next connection from a client " + "at the channel level. %s", error); + xmlrpc_strfree(error); + } else { + if (channelP) { + const char * error; + + trace(&srvP->tracer, "Got a new channel from channel switch"); + + processNewChannel(serverP, channelP, channelInfoP, + outstandingConnListP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Failed to use new channel %lx", + (unsigned long) channelP); + ChannelDestroy(channelP); + free(channelInfoP); + } else { + trace(&srvP->tracer, + "successfully processed newly accepted channel"); + /* Connection created above will destroy *channelP + and *channelInfoP as it terminates. + */ + } + } else { + /* Accept function was interrupted before it got a connection */ + trace(&srvP->tracer, + "Wait for new channel from switch was interrupted"); + *errorP = NULL; + } + } +} + + + +static void +serverRun2(TServer * const serverP, + const char ** const errorP) { + + struct _TServer * const srvP = serverP->srvP; + outstandingConnList * outstandingConnListP; + + createOutstandingConnList(&outstandingConnListP); + + *errorP = NULL; /* initial value */ + + trace(&srvP->tracer, "Starting main connection accepting loop"); + + while (!srvP->terminationRequested && !*errorP) + acceptAndProcessNextConnection(serverP, outstandingConnListP, errorP); + + trace(&srvP->tracer, "Main connection accepting loop is done"); + + if (!*errorP) { + trace(&srvP->tracer, + "Interrupting and waiting for %u existing connections " + "to finish", + outstandingConnListP->count); + + interruptChannels(outstandingConnListP); + + waitForNoConnections(outstandingConnListP); + + trace(&srvP->tracer, "No connections left"); + + destroyOutstandingConnList(outstandingConnListP); + } +} + + + +void +ServerRun(TServer * const serverP) { + + struct _TServer * const srvP = serverP->srvP; + + trace(&srvP->tracer, "%s entered", __FUNCTION__); + + if (!srvP->serverAcceptsConnections) + TraceMsg("This server is not set up to accept connections " + "on its own, so you can't use ServerRun(). " + "Try ServerRunConn()"); + else if (!srvP->readyToAccept) + TraceMsg("You cannot run this server until you initialize it to " + "accept connections, with ServerInit()"); + else { + const char * error; + + serverRun2(serverP, &error); + + if (error) { + TraceMsg("Server failed. %s", error); + + xmlrpc_strfree(error); + } + } + trace(&srvP->tracer, "%s exiting", __FUNCTION__); +} + + + +static void +serverRunChannel(TServer * const serverP, + TChannel * const channelP, + void * const channelInfoP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Do the HTTP transaction on the channel 'channelP'. + (channel must be at the beginning of the HTTP request -- nothing having + been read or written yet). + + channelInfoP == NULL means no channel info supplied. +-----------------------------------------------------------------------------*/ + struct _TServer * const srvP = serverP->srvP; + + TConn * connectionP; + const char * error; + + trace(&srvP->tracer, "%s entered", __FUNCTION__); + + srvP->keepalivemaxconn = 1; + + ConnCreate(&connectionP, + serverP, channelP, channelInfoP, + &serverFunc, SERVER_FUNC_STACK + srvP->uriHandlerStackSize, + NULL, ABYSS_FOREGROUND, srvP->useSigchld, + &error); + if (error) { + xmlrpc_asprintf(errorP, "Couldn't create HTTP connection out of " + "channel (connected socket). %s", error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + + ConnProcess(connectionP); + + ConnWaitAndRelease(connectionP); + } + trace(&srvP->tracer, "%s exiting", __FUNCTION__); +} + + + +void +ServerRunChannel(TServer * const serverP, + TChannel * const channelP, + void * const channelInfoP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Do the HTTP transaction on the channel 'channelP'. + + (channel must be at the beginning of the HTTP request -- nothing having + been read or written yet). +-----------------------------------------------------------------------------*/ + struct _TServer * const srvP = serverP->srvP; + + trace(&srvP->tracer, "%s entered", __FUNCTION__); + + if (srvP->serverAcceptsConnections) + xmlrpc_asprintf(errorP, + "This server is configured to accept connections on " + "its own socket. " + "Try ServerRun() or ServerCreateNoAccept()."); + else + serverRunChannel(serverP, channelP, channelInfoP, errorP); + + trace(&srvP->tracer, "%s exiting", __FUNCTION__); +} + + + +void +ServerRunConn2(TServer * const serverP, + TSocket * const connectedSocketP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Do the HTTP transaction on the TCP connection on the socket + *connectedSocketP. + (socket must be connected state, with nothing having been read or + written on the connection yet). +-----------------------------------------------------------------------------*/ + TChannel * const channelP = SocketGetChannel(connectedSocketP); + + if (!channelP) + xmlrpc_asprintf(errorP, "The socket supplied is not a connected " + "socket. You should use ServerRunChannel() instead, " + "anyway."); + else + ServerRunChannel(serverP, + channelP, SocketGetChannelInfo(connectedSocketP), + errorP); +} + + + +void +ServerRunConn(TServer * const serverP, + TOsSocket const connectedOsSocket) { + + TChannel * channelP; + void * channelInfoP; + const char * error; + + createChannelFromOsSocket(connectedOsSocket, + &channelP, &channelInfoP, &error); + if (error) { + TraceExit("Unable to use supplied socket"); + xmlrpc_strfree(error); + } else { + const char * error; + + ServerRunChannel(serverP, channelP, channelInfoP, &error); + + if (error) { + TraceExit("Failed to run server on connection on file " + "descriptor %d. %s", connectedOsSocket, error); + xmlrpc_strfree(error); + } + ChannelDestroy(channelP); + free(channelInfoP); + } +} + + + +void +ServerRunOnce(TServer * const serverP) { +/*---------------------------------------------------------------------------- + Accept a connection from the channel switch and do the HTTP transaction + that comes over it. + + If no connection is presently waiting at the switch, wait for one. But + return immediately if we receive a signal during the wait. +-----------------------------------------------------------------------------*/ + struct _TServer * const srvP = serverP->srvP; + + trace(&srvP->tracer, "%s entered", __FUNCTION__); + + if (!srvP->serverAcceptsConnections) + TraceMsg("This server is not set up to accept connections " + "on its own, so you can't use ServerRun(). " + "Try ServerRunConn()"); + else if (!srvP->readyToAccept) + TraceMsg("You cannot run this server until you initialize it to " + "accept connections, with ServerInit()"); + else { + const char * error; + TChannel * channelP; + void * channelInfoP; + + srvP->keepalivemaxconn = 1; + + assert(srvP->chanSwitchP); + + ChanSwitchAccept(srvP->chanSwitchP, &channelP, &channelInfoP, &error); + if (error) { + TraceMsg("Failed to accept the next connection from a client " + "at the channel level. %s", error); + xmlrpc_strfree(error); + } else { + if (channelP) { + const char * error; + + serverRunChannel(serverP, channelP, channelInfoP, &error); + + if (error) { + const char * peerDesc; + ChannelFormatPeerInfo(channelP, &peerDesc); + TraceExit("Got a connection from '%s', but failed to " + "run server on it. %s", peerDesc, error); + xmlrpc_strfree(peerDesc); + xmlrpc_strfree(error); + } + ChannelDestroy(channelP); + free(channelInfoP); + } + } + } + trace(&srvP->tracer, "%s exiting", __FUNCTION__); +} + + + +void +ServerRunOnce2(TServer * const serverP, + enum abyss_foreback const foregroundBackground ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + This is a backward compatibility interface to ServerRunOnce(). + + 'foregroundBackground' is meaningless. We always process the + connection in the foreground. The parameter exists because we once + thought we could do them in the background, but we really can't do + that in any clean way. If Caller wants background execution, he can + spin his own thread or process to call us. It makes much more sense + in Caller's context. +-----------------------------------------------------------------------------*/ + ServerRunOnce(serverP); +} + + + +static void +setGroups(const char ** const errorP) { + +#if HAVE_SETGROUPS + if (setgroups(0, NULL) == -1) + xmlrpc_asprintf(errorP, "setgroups() errno = %d (%s)", + errno, strerror(errno)); +#else + *errorP = NULL; +#endif +} + + + +void +ServerDaemonize(TServer * const serverP) { +/*---------------------------------------------------------------------------- + Turn Caller into a daemon (i.e. fork a child, then exit; the child + returns to Caller). + + NOTE: It's ridiculous, but conventional, for us to do this. It's + ridiculous because the task of daemonizing is not something + particular to Abyss. It ought to be done by a higher level. In + fact, it should be done before the Abyss server program is even + execed. The user should run a "daemonize" program that creates a + daemon which execs the Abyss server program. +-----------------------------------------------------------------------------*/ + struct _TServer * const srvP = serverP->srvP; + +#if !MSVCRT + /* Become a daemon */ + switch (fork()) { + case 0: + break; + case -1: + TraceExit("Unable to become a daemon"); + default: + /* We are the parent */ + exit(0); + } + + setsid(); + + /* Change the current user if we are root */ + if (getuid()==0) { + const char * error; + if (srvP->uid == (uid_t)-1) + TraceExit("Can't run under root privileges. " + "Please add a User option in your " + "Abyss configuration file."); + + setGroups(&error); + + if (error) { + TraceExit("Failed to set groups. %s", error); + xmlrpc_strfree(error); + } + + if (srvP->gid != (gid_t)-1) + if (setgid(srvP->gid)==(-1)) + TraceExit("Failed to change the group."); + + if (setuid(srvP->uid) == -1) + TraceExit("Failed to change the user."); + } + + if (srvP->pidfileP) { + char z[16]; + + sprintf(z, "%d", XMLRPC_GETPID()); + FileWrite(srvP->pidfileP, z, strlen(z)); + FileClose(srvP->pidfileP); + } +#endif /* MSVCRT */ +} + + + +static void +serverAddHandler(TServer * const serverP, + initHandlerFn init, + termHandlerFn term, + URIHandler handleReq1, + handleReq2Fn handleReq2, + handleReq3Fn handleReq3, + void * const userdata, + size_t const handleReqStackSizeReq, + abyss_bool * const successP) { + + struct _TServer * const srvP = serverP->srvP; + size_t handleReqStackSize = + handleReqStackSizeReq ? handleReqStackSizeReq : 128*1024; + + struct uriHandler * handlerP; + + MALLOCVAR(handlerP); + if (handlerP == NULL) + *successP = false; + else { + handlerP->init = init; + handlerP->term = term; + handlerP->handleReq1 = handleReq1; + handlerP->handleReq2 = handleReq2; + handlerP->handleReq3 = handleReq3; + handlerP->userdata = userdata; + + srvP->uriHandlerStackSize = + MAX(srvP->uriHandlerStackSize, handleReqStackSize); + + if (handlerP->init == NULL) + *successP = true; + else { + URIHandler2 handler2 = makeUriHandler2(handlerP); + handlerP->init(&handler2, successP); + } + if (*successP) + *successP = ListAdd(&serverP->srvP->handlers, handlerP); + + if (!*successP) + free(handlerP); + } +} + + + +void +ServerAddHandler3(TServer * const serverP, + const struct ServerReqHandler3 * const handlerP, + abyss_bool * const successP) { + + serverAddHandler(serverP, NULL, handlerP->term, NULL, NULL, + handlerP->handleReq, handlerP->userdata, + handlerP->handleReqStackSize, successP); +} + + + +void +ServerAddHandler2(TServer * const serverP, + URIHandler2 * const handlerArgP, + abyss_bool * const successP) { + + /* This generation of the URI handler interface is strange because + it went through an unfortunate evolution. So it halfway looks like + the use supplies a handler object and Abyss calls its methods, and + halfway looks like the user simply describes his handler. + + Abyss calls handleReq2 with a pointer to a URIHandler2 like the + one which is our argument, but it isn't the same one. User can + discard *handlerArgP as soon as we return. + */ + + serverAddHandler(serverP, + handlerArgP->init, + handlerArgP->term, + NULL, + handlerArgP->handleReq2, + NULL, + handlerArgP->userdata, + 0, + successP); +} + + + +abyss_bool +ServerAddHandler(TServer * const serverP, + URIHandler const function) { + + URIHandler2 handler; + abyss_bool success; + + handler.init = NULL; + handler.term = NULL; + handler.userdata = NULL; + handler.handleReq2 = NULL; + handler.handleReq1 = function; + + ServerAddHandler2(serverP, &handler, &success); + + return success; +} + + + +/* This is the maximum amount of stack we allow a user's default URI + handler to use. (If he exceeds this, results are undefined). + + We really ought to provide user a way to set this, as he can for + his non-default URI handlers. +*/ +#define USER_DEFAULT_HANDLER_STACK 128*1024 + +void +ServerDefaultHandler(TServer * const serverP, + URIHandler const handler) { + + struct _TServer * const srvP = serverP->srvP; + + if (handler) { + srvP->defaultHandler = handler; + srvP->uriHandlerStackSize = + MAX(srvP->uriHandlerStackSize, USER_DEFAULT_HANDLER_STACK); + } else { + srvP->defaultHandler = HandlerDefaultBuiltin; + srvP->defaultHandlerContext = srvP->builtinHandlerP; + srvP->uriHandlerStackSize = + MAX(srvP->uriHandlerStackSize, HandlerDefaultBuiltinStack); + } +} + + + +void +LogWrite(TServer * const serverP, + const char * const msg) { + + struct _TServer * const srvP = serverP->srvP; + + if (!srvP->logfileisopen && srvP->logfilename) { + const char * error; + logOpen(srvP, &error); + + if (error) { + TraceMsg("Failed to open log file. %s", error); + + xmlrpc_strfree(error); + } + } + if (srvP->logfileisopen) { + const char * const lbr = "\n"; + srvP->logLockP->acquire(srvP->logLockP); + FileWrite(srvP->logfileP, msg, strlen(msg)); + FileWrite(srvP->logfileP, lbr, strlen(lbr)); + + srvP->logLockP->release(srvP->logLockP); + } +} +/******************************************************************************* +** +** server.c +** +** This file is part of the ABYSS Web server project. +** +** Copyright (C) 2000 by Moez Mahfoudh . +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +******************************************************************************/ diff --git a/trunk/lib/abyss/src/server.h b/trunk/lib/abyss/src/server.h new file mode 100644 index 000000000..0462e74c9 --- /dev/null +++ b/trunk/lib/abyss/src/server.h @@ -0,0 +1,123 @@ +#ifndef SERVER_H_INCLUDED +#define SERVER_H_INCLUDED + +#include + +#include "xmlrpc_config.h" +#include "bool.h" +#include "xmlrpc-c/lock.h" +#include "xmlrpc-c/abyss.h" + +#include "data.h" + +struct TFile; + +struct Tracer { + bool traceIsActive; + /* We should report to Standard Error our internal activities */ +}; + +struct _TServer { + struct Tracer tracer; + + bool terminationRequested; + /* User wants this server to terminate as soon as possible, + in particular before accepting any more connections and without + waiting for any. + */ + bool chanSwitchBound; + /* The channel switch exists and is bound to a local address + (may already be listening as well) + */ + TChanSwitch * chanSwitchP; + /* Meaningful only when 'chanSwitchBound' is true: the channel + switch which directs connections from clients to this server. + */ + bool weCreatedChanSwitch; + /* We created the channel switch 'chanSwitchP', as + opposed to 1) User supplied it; or 2) there isn't one. + */ + const char * logfilename; + bool logfileisopen; + struct TFile * logfileP; + struct lock * logLockP; + const char * name; + bool serverAcceptsConnections; + /* We listen for and accept TCP connections for HTTP transactions. + (The alternative is the user supplies a TCP-connected socket + for each transaction) + */ + bool readyToAccept; + /* We are the kind of server that listens for TCP connections and the + user has initialized us to do so (called ServerInit()). + */ + uint16_t port; + /* Meaningful only when 'chanSwitchBound' is false: TCP port + number to which we should bind the switch. + */ + uint32_t keepalivetimeout; + uint32_t keepalivemaxconn; + uint32_t timeout; + /* Maximum time in seconds the server will wait to read a header + or a data chunk from the channel. + */ + uint32_t maxConn; + /* Maximum number of connections the server allows to exist (i.e. + HTTP transactions in progress) at once. Server will not accept + a connection if it already has this many. + */ + uint32_t maxConnBacklog; + /* Maximum number of connections the server allows the OS to queue + waiting for the server to accept it. The OS accepts this many TCP + connections on the server's behalf and holds them waiting for the + server to accept them from the OS. + */ + size_t maxSessionMem; + /* The maximum memory the server can use for certain purposes for a + single session. These purposes consist of things where the size + of the memory is unpredictable, especially under the control of the + client. This limit stops clients from using too much memory and + consequently denying service to other clients. + + Zero means no limit. + */ + TList handlers; + /* Ordered list of HTTP request handlers. For each HTTP request, + Server calls each one in order until one reports that it handled + it. + + Each item in the list of of type 'uriHandler'. + */ + URIHandler defaultHandler; + /* The handler for HTTP requests that aren't claimed by any handler + in the list 'handlers'. This can't be null; if user doesn't + supply anything better, it is a built-in basic web server + handler. */ + void * defaultHandlerContext; + /* This is opaque data to be given to the default handler when it + requests it. + */ + void * builtinHandlerP; + bool advertise; + bool useSigchld; + /* Meaningless if not using forking for threads. + TRUE means user will call ServerHandleSigchld to indicate that + a SIGCHLD signal was received, and server shall use that as its + indication that a child has died. FALSE means server will not + be aware of SIGCHLD and will instead poll for existence of PIDs + to determine if a child has died. + */ + size_t uriHandlerStackSize; + /* The maximum amount of stack any URI handler request handler + function will use. Note that this is just the requirement + of the function itself, not the stack size for the thread + that runs it. + */ +#if !MSVCRT + uid_t uid; + gid_t gid; +#endif + struct TFile * pidfileP; +}; + +#endif diff --git a/trunk/lib/abyss/src/session.c b/trunk/lib/abyss/src/session.c new file mode 100644 index 000000000..2fac2d970 --- /dev/null +++ b/trunk/lib/abyss/src/session.c @@ -0,0 +1,726 @@ +#include +#include +#include +#include +#include +#include + +#include "bool.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/abyss.h" +#include "server.h" +#include "http.h" +#include "conn.h" + +#include "session.h" + + + +static void +refillBuffer(TSession * const sessionP, + const char ** const errorP) { + + struct _TServer * const srvP = sessionP->connP->server->srvP; + + /* Reset our read buffer and flush data from previous reads. */ + ConnReadInit(sessionP->connP); + + *errorP = NULL; /* initial assumption */ + + if (sessionP->continueRequired) { + bool succeeded; + succeeded = HTTPWriteContinue(sessionP); + if (!succeeded) + xmlrpc_asprintf(errorP, "Failed to send a Continue header " + "to the client to tell it to go ahead with " + "sending the body"); + } + if (!*errorP) { + const char * error; + + sessionP->continueRequired = false; + + /* Read more network data into our buffer. Fail if we time out + before client sends any data or client closes the connection or + there's some network error. We're very forgiving about the + timeout here. We allow a full timeout per network read, which + would allow somebody to keep a connection alive nearly + indefinitely. But it's hard to do anything intelligent here + without very complicated code. + */ + ConnRead(sessionP->connP, srvP->timeout, NULL, NULL, &error); + if (error) { + xmlrpc_asprintf(errorP, "Failed to get more data from " + "the client. %s", error); + xmlrpc_strfree(error); + } + } +} + + + +abyss_bool +SessionRefillBuffer(TSession * const sessionP) { +/*---------------------------------------------------------------------------- + Get the next piece of HTTP request body from the connection into the + buffer. Add at least a byte to the buffer; wait for the data (subject to + the server's timeout parameters) as necessary. + + I.e. read data from the socket. + + "piece" is not any formal part of the body - its just some arbitrary + amount of data - at least one byte - that we choose to read. + + We fail if the session is in a failed state. Because the methods that + extract data from the buffer were designed without the ability to fail, + this is often the only way we have to communicate to the Abyss user that + things have gone pear-shape. And even with this, we are unable to tell + the user why - we just have a binary "failed" return value. +-----------------------------------------------------------------------------*/ + bool succeeded; + + if (sessionP->failureReason) + succeeded = false; + else { + const char * error; + + refillBuffer(sessionP, &error); + + if (error) { + sessionP->failureReason = error; + succeeded = false; + } else + succeeded = true; + } + return succeeded; +} + + + +size_t +SessionReadDataAvail(TSession * const sessionP) { + + return sessionP->connP->buffersize - sessionP->connP->bufferpos; + +} + + + +static const char * +firstLfPos(TConn * const connectionP) { +/*---------------------------------------------------------------------------- + Return a pointer in the connection's receive buffer to the first + LF (linefeed aka newline) character in the buffer. + + If there is no LF in the buffer, return NULL. +-----------------------------------------------------------------------------*/ + const char * const bufferStart = + connectionP->buffer.t + connectionP->bufferpos; + const char * const bufferEnd = + connectionP->buffer.t + connectionP->buffersize; + + const char * p; + + for (p = bufferStart; p < bufferEnd && *p != '\n'; ++p); + + if (p < bufferEnd) + return p; + else + return NULL; +} + + + +static void +getLine(TConn * const connectionP, + const char ** const lineP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Extract one line from the connection buffer. + + If there is a full line in the buffer now, including line end delimiter, at + the current position, return it as *lineP in newly malloced storage and + advance the current buffer position past the line. + + Do not include the line end delimiter in the returned line. + + If there is no full line, return NULL as *lineP. + + But if there is no full line and the connection buffer is full (so that + there won't ever be a full line), fail. +-----------------------------------------------------------------------------*/ + const char * lfPos; + + lfPos = firstLfPos(connectionP); + + if (lfPos) { + unsigned int const lfIdx = lfPos - connectionP->buffer.t; + + char * line; + assert(lfIdx > connectionP->bufferpos); + line = malloc(lfIdx - connectionP->bufferpos + 1); + if (!line) + xmlrpc_asprintf(errorP, "Memory allocation failed for small " + "buffer to read a line from the client"); + else { + unsigned int i, j; + for (i = connectionP->bufferpos, j = 0; i < lfIdx; ++i, ++j) + line[j] = connectionP->buffer.t[i]; + line[j] = '\0'; + + /* Chop off the CR */ + if (j > 1 && line[j-1] == '\r') + line[j-1] = '\0'; + + connectionP->bufferpos = lfIdx + 1; + + *errorP = NULL; + *lineP = line; + } + } else { + unsigned int const usedByteCt = + connectionP->buffersize - connectionP->bufferpos; + + if (usedByteCt + 1 >= BUFFER_SIZE) { + /* + 1 for a NUL. + + We don't have a full line yet, and a buffer refill won't + help because the buffer is full. + */ + xmlrpc_asprintf(errorP, "Line received from client does not " + "fit in the server's connection buffer."); + } else { + *errorP = NULL; + *lineP = NULL; + } + } +} + + + +static void +parseHexDigit(char const digit, + unsigned int * const valueP, + const char ** const errorP) { + + *errorP = NULL; /* initial assumption */ + + switch (toupper(digit)) { + case '0': *valueP = 0x0; break; + case '1': *valueP = 0x1; break; + case '2': *valueP = 0x2; break; + case '3': *valueP = 0x3; break; + case '4': *valueP = 0x4; break; + case '5': *valueP = 0x5; break; + case '6': *valueP = 0x6; break; + case '7': *valueP = 0x7; break; + case '8': *valueP = 0x8; break; + case '9': *valueP = 0x9; break; + case 'A': *valueP = 0xA; break; + case 'B': *valueP = 0xB; break; + case 'C': *valueP = 0xC; break; + case 'D': *valueP = 0xD; break; + case 'E': *valueP = 0xE; break; + case 'F': *valueP = 0xF; break; + default: + xmlrpc_asprintf(errorP, "Invalid hex digit: 0x%02x", (unsigned)digit); + } +} + + + +static void +parseChunkHeader(const char * const line, + uint32_t * const chunkSizeP, + const char ** const errorP) { + + /* The chunk header is normally just a hexadecimal coding of the chunk + size, but that can theoretically be followed by a semicolon, and then a + "chunk extension." The standard says a server must ignore a chunk + extension it does not understand, which for us is all chunk extensions. + */ + + char * const semPos = strchr(line, ';'); + + const char * const end = semPos ? semPos : line + strlen(line); + /* Points just past the end of the chunk size */ + + unsigned int accum; + const char * p; + + for (accum = 0, p = &line[0], *errorP = NULL; + p < end && !*errorP; ++p) { + + unsigned int digitValue; + + parseHexDigit(*p, &digitValue, errorP); + + if (!*errorP) { + accum <<= 4; + accum += digitValue; + } + } + *chunkSizeP = accum; +} + + + +static void +getChunkHeader(TSession * const sessionP, + bool * const gotHeaderP, + uint32_t * const chunkSizeP, + const char ** const errorP) { +/*----------------------------------------------------------------------------- + Assuming the stream from the client is positioned to the beginning of a + chunk header (the line that contains the chunk size and chunk + extension), read off the line and return as *chunkSizeP the chunk size + it indicates. + + Iff a whole line is not in the buffer, leave the stream alone and return + *gotHeaderP == false. +-----------------------------------------------------------------------------*/ + const char * line; + const char * error; + + getLine(sessionP->connP, &line, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Failed trying to process a chunk header. %s", + error); + xmlrpc_strfree(error); + } else { + if (line) { + parseChunkHeader(line, chunkSizeP, errorP); + + if (!*errorP) { + *gotHeaderP = true; + } + xmlrpc_strfree(line); + } else { + *errorP = NULL; + *gotHeaderP = false; + } + } +} + + + +static void +processChunkDelimIfThere(TSession * const sessionP, + const char ** const errorP) { +/*----------------------------------------------------------------------------- + Read off a chunk delimiter (CRLF) from the connection buffer, if there + is one there. + + Fail if there is something inconsistent with CRLF there. + + Do nothing if there is nothing or just part of CRLF there; Caller can + try again later when there is more data. +-----------------------------------------------------------------------------*/ + uint32_t const byteCt = + sessionP->connP->buffersize - sessionP->connP->bufferpos; + + if (byteCt < 1) { + *errorP = NULL; + } else { + const char * const next = + &sessionP->connP->buffer.t[sessionP->connP->bufferpos]; + + if (next[0] != '\r') + xmlrpc_asprintf(errorP, "Garbage where chunk delimiter should be"); + if (byteCt < 2) + *errorP = NULL; + else { + if (next[1] != '\n') + xmlrpc_asprintf(errorP, + "Garbage where chunk delimiter should be"); + else { + *errorP = NULL; + sessionP->chunkState.position = CHUNK_ATHEADER; + sessionP->connP->bufferpos += 2; + } + } + } +} + + + +static void +processChunkHeaderIfThere(TSession * const sessionP, + const char ** const errorP) { + + bool gotHeader; + uint32_t chunkSize; + + getChunkHeader(sessionP, &gotHeader, &chunkSize, errorP); + + if (!*errorP) { + if (gotHeader) { + if (chunkSize == 0) + sessionP->chunkState.position = CHUNK_EOF; + else { + sessionP->chunkState.position = CHUNK_INCHUNK; + sessionP->chunkState.bytesLeftCt = chunkSize; + } + } + } +} + + + +static void +getChunkData(TSession * const sessionP, + size_t const max, + const char ** const outStartP, + size_t * const outLenP) { + + uint32_t const bufferPos = sessionP->connP->bufferpos; + + uint32_t const bytesInBufferCt = + sessionP->connP->buffersize - sessionP->connP->bufferpos; + + uint32_t const outLen = + MIN(MIN(sessionP->chunkState.bytesLeftCt, + bytesInBufferCt), + max); + + *outStartP = &sessionP->connP->buffer.t[bufferPos]; + + sessionP->connP->bufferpos += outLen; + + sessionP->chunkState.bytesLeftCt -= outLen; + + if (sessionP->chunkState.bytesLeftCt == 0) + sessionP->chunkState.position = CHUNK_AFTERCHUNK; + + *outLenP = outLen; +} + + + +static void +getSomeChunkedRequestBody(TSession * const sessionP, + size_t const max, + abyss_bool * const eofP, + const char ** const outStartP, + size_t * const outLenP, + const char ** const errorP) { +/*----------------------------------------------------------------------------- + Same as SessionGetReadData, but assuming the client is sending the body + in chunked form. + + Iff we encounter the end of body indication (a zero-size chunk), + return *eofP true and nothing as *outStartP or *outLenP. +-----------------------------------------------------------------------------*/ + /* In chunked form, the client sends a sequence of chunks. Each chunk is + introduced by a one-line header. That header tells the size of the + chunk. The end of the body is delimited by a zero-length chunk. + */ + if (sessionP->chunkState.position == CHUNK_EOF) { + xmlrpc_asprintf(errorP, "The client has previously sent an " + "end-of-data indication (zero-length chunk)"); + } else { + if (sessionP->chunkState.position == CHUNK_AFTERCHUNK) { + processChunkDelimIfThere(sessionP, errorP); + } + if (!*errorP) { + if (sessionP->chunkState.position == CHUNK_ATHEADER) { + processChunkHeaderIfThere(sessionP, errorP); + } + } + if (!*errorP) { + if (sessionP->chunkState.position == CHUNK_INCHUNK) { + *eofP = false; + getChunkData(sessionP, max, outStartP, outLenP); + } else if (sessionP->chunkState.position == CHUNK_EOF) { + *eofP = true; + } else { + *eofP = false; + *outLenP = 0; + *outStartP = NULL; + } + } + } +} + + + +static void +getSomeUnchunkedRequestBody(TSession * const sessionP, + size_t const max, + const char ** const outStartP, + size_t * const outLenP) { +/*----------------------------------------------------------------------------- + Same as SessionGetReadData, but assuming the client is just sending a + plain stream of bytes for the body; not chunked. +-----------------------------------------------------------------------------*/ + uint32_t const bufferPos = sessionP->connP->bufferpos; + + *outStartP = &sessionP->connP->buffer.t[bufferPos]; + + assert(bufferPos <= sessionP->connP->buffersize); + + *outLenP = MIN(max, sessionP->connP->buffersize - bufferPos); + + /* move pointer past the bytes we are returning */ + sessionP->connP->bufferpos += *outLenP; + + assert(sessionP->connP->bufferpos <= sessionP->connP->buffersize); +} + + + +void +SessionGetReadData(TSession * const sessionP, + size_t const max, + const char ** const outStartP, + size_t * const outLenP) { +/*---------------------------------------------------------------------------- + Extract some HTTP request body which the server has read and buffered for + the session. Don't get or wait for any data that has not yet arrived. Do + not return more than 'max'. + + We return a pointer to the first byte as *outStartP, and the length in + bytes as *outLenP. The memory pointed to belongs to the session. + + Iff the request body is chunked, we can be unable to do this (e.g. the + chunk header is invalid). But for historical reasons, we can't fail, so we + just put the session in a failed state and tell Caller there is no data, + and when Caller next calls SessionRefillBuffer, he will find out. +-----------------------------------------------------------------------------*/ + if (sessionP->requestIsChunked) { + abyss_bool eof; + getSomeChunkedRequestBody(sessionP, max, &eof, outStartP, outLenP, + &sessionP->failureReason); + if (eof) + xmlrpc_asprintf(&sessionP->failureReason, + "End of request body encountered"); + } else { + getSomeUnchunkedRequestBody(sessionP, max, outStartP, outLenP); + } +} + + + +void +SessionGetBody(TSession * const sessionP, + size_t const max, + abyss_bool * const eofP, + const char ** const outStartP, + size_t * const outLenP, + const char ** const errorP) { +/*----------------------------------------------------------------------------- + Get some of the HTTP request body. + + If there is some request body in the connection buffer already, return that + immediately. If not, wait for some to arrive and return that. Don't wait + for more than one byte (but return more if possible without waiting), and + don't return more than 'max' bytes. + + We return a pointer to the first byte as *outStartP, and the length in + bytes as *outLenP. The memory pointed to belongs to the session. + + Iff the data indicates end-of-body (possible only when the body is chunked), + return *eofP == true and nothing as *outStartP and *outLenP. + + Assume the session has already received and processed the HTTP header. +-----------------------------------------------------------------------------*/ + if (sessionP->failureReason) + xmlrpc_asprintf(errorP, "The session has previously failed: %s", + sessionP->failureReason); + else { + size_t outLen; + abyss_bool eof; + const char * error; + + for (outLen = 0, eof = false, error = NULL; + outLen == 0 && !eof && !error; ) { + if (sessionP->requestIsChunked) + getSomeChunkedRequestBody(sessionP, max, &eof, + outStartP, &outLen, + &error); + else { + getSomeUnchunkedRequestBody(sessionP, max, outStartP, &outLen); + error = NULL; + eof = false; + } + if (outLen == 0 && !eof && !error) + refillBuffer(sessionP, &error); + } + if (error) + sessionP->failureReason = xmlrpc_strdupsol(error); + + *errorP = error; + *eofP = eof; + *outLenP = outLen; + } +} + + + +void +SessionGetRequestInfo(TSession * const sessionP, + const TRequestInfo ** const requestInfoPP) { + + *requestInfoPP = &sessionP->requestInfo; +} + + + +void +SessionGetChannelInfo(TSession * const sessionP, + void ** const channelInfoPP) { + + *channelInfoPP = sessionP->connP->channelInfoP; +} + + + +abyss_bool +SessionLog(TSession * const sessionP) { + + const char * logline; + const char * user; + const char * date; + const char * peerInfo; + + if (sessionP->validRequest) { + if (sessionP->requestInfo.user) + user = sessionP->requestInfo.user; + else + user = "no_user"; + } else + user = "???"; + + DateToLogString(sessionP->date, &date); + + ConnFormatClientAddr(sessionP->connP, &peerInfo); + + xmlrpc_asprintf(&logline, "%s - %s - [%s] \"%s\" %d %u", + peerInfo, + user, + date, + sessionP->validRequest ? + sessionP->requestInfo.requestline : "???", + sessionP->status, + sessionP->connP->outbytes + ); + xmlrpc_strfree(peerInfo); + xmlrpc_strfree(date); + + LogWrite(sessionP->connP->server, logline); + + xmlrpc_strfree(logline); + + return true; +} + + + +void * +SessionGetDefaultHandlerCtx(TSession * const sessionP) { + + struct _TServer * const srvP = sessionP->connP->server->srvP; + + return srvP->defaultHandlerContext; +} + + + +void +SessionInit(TSession * const sessionP, + TConn * const connectionP) { + + sessionP->validRequest = false; /* Don't have valid request yet */ + + sessionP->failureReason = NULL; + + time(&sessionP->date); + + sessionP->connP = connectionP; + + sessionP->responseStarted = false; + + sessionP->chunkedwrite = false; + sessionP->chunkedwritemode = false; + + sessionP->continueRequired = false; + + sessionP->requestIsChunked = false; + + sessionP->chunkState.position = CHUNK_ATHEADER; + + sessionP->memPoolP = NULL; + + ListInit(&sessionP->cookies); + ListInit(&sessionP->ranges); + TableInit(&sessionP->requestHeaderFields); + TableInit(&sessionP->responseHeaderFields); + + sessionP->status = 0; /* No status from handler yet */ + + StringAlloc(&(sessionP->header)); +} + + + +static void +freeRequestInfo(TRequestInfo * const requestInfoP) { + + xmlrpc_strfreenull(requestInfoP->host); + + xmlrpc_strfreenull(requestInfoP->user); + + xmlrpc_strfree(requestInfoP->uri); + + xmlrpc_strfree(requestInfoP->requestline); +} + + + +void +SessionTerm(TSession * const sessionP) { + + if (sessionP->validRequest) + freeRequestInfo(&sessionP->requestInfo); + + ListFree(&sessionP->cookies); + ListFree(&sessionP->ranges); + TableFree(&sessionP->requestHeaderFields); + TableFree(&sessionP->responseHeaderFields); + StringFree(&(sessionP->header)); + + if (sessionP->memPoolP) + xmlrpc_mem_pool_free(sessionP->memPoolP); +} + + + +void +SessionMakeMemPool(TSession * const sessionP, + size_t const size, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Set up a memory pool for this session. All future allocations of memory + for certain purposes will come from this pool. + + The point of this is that the pool has limited size, so this puts a limit + on how much memory the session can use. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + + xmlrpc_env_init(&env); + + sessionP->memPoolP = xmlrpc_mem_pool_new(&env, size); + + if (env.fault_occurred) + *errorP = xmlrpc_strdupsol(env.fault_string); + else + *errorP = NULL; + + xmlrpc_env_clean(&env); +} + + + diff --git a/trunk/lib/abyss/src/session.h b/trunk/lib/abyss/src/session.h new file mode 100644 index 000000000..bfbaaf645 --- /dev/null +++ b/trunk/lib/abyss/src/session.h @@ -0,0 +1,146 @@ +#ifndef SESSION_H_INCLUDED +#define SESSION_H_INCLUDED + +#include "xmlrpc-c/abyss.h" +#include "xmlrpc-c/util_int.h" +#include "bool.h" +#include "date.h" +#include "data.h" +#include "conn.h" + +typedef struct { + uint8_t major; + uint8_t minor; +} httpVersion; + +typedef enum { + /* This tells what is supposed to be at the current read position + in the connection buffer. + */ + CHUNK_ATHEADER, /* A chunk header (including EOF marker) */ + CHUNK_INCHUNK, /* Somewhere in chunk data */ + CHUNK_AFTERCHUNK, /* The delimiter after a chunk */ + CHUNK_EOF /* Past EOF marker */ +} ChunkPosition; + +struct _TSession { + bool validRequest; + /* Client has sent, and server has recognized, a valid HTTP request. + This is false when the session is new. If and when the server + reads the request from the client and finds it to be valid HTTP, + it becomes true. + */ + xmlrpc_mem_pool * memPoolP; + /* The memory pool from which various memory needed for our processing + comes. We don't allocate all memory from here; just parts that + have unpredictable size that might allow a client to get more than + its share of system meomry if we didn't limit it. This pool has a + limited size. + + NULL means all memory comes from the general system pool and there + is therefore no protection of clients from each other. + */ + const char * failureReason; + /* This is non-null to indicate that we have encountered a protocol + error or other problem in the session and the session cannot + continue. The value is a text explanation of the problem. + */ + TRequestInfo requestInfo; + /* Some of the strings this references are in individually malloc'ed + memory, but some are pointers into arbitrary other data structures + that happen to live as long as the session. Some day, we will + fix that. + + 'requestInfo' is valid only if 'validRequest' is true. + */ + uint32_t nbfileds; + TList cookies; + TList ranges; + + uint16_t status; + /* Response status from handler. Zero means session is not ready + for a response yet. This can mean that we ran a handler and it + did not call ResponseStatus() to declare this fact. + */ + TString header; + + bool serverDeniesKeepalive; + /* Server doesn't want keepalive for this session, regardless of + what happens in the session. E.g. because the connection has + already been kept alive long enough. + */ + bool responseStarted; + /* Handler has at least started the response (i.e. called + ResponseWriteStart()) + */ + + struct _TConn * connP; + + httpVersion version; + + TTable requestHeaderFields; + /* All the fields of the header of the HTTP request. The key is the + field name in lower case. The value is the verbatim value from + the field. + */ + + TTable responseHeaderFields; + /* All the fields of the header of the HTTP response. + This gets successively computed; at any moment, it is the list of + fields the user has requested so far. It also includes fields + Abyss itself has decided to include. (Blechh. This needs to be + cleaned up). + + Each table item is an HTTP header field. The Name component of the + table item is the header field name (it is syntactically valid but + not necessarily a defined field name) and the Value component is the + header field value (it is syntactically valid but not necessarily + semantically valid). + */ + + time_t date; + + bool chunkedwrite; + bool chunkedwritemode; + + bool continueRequired; + /* This client must receive 100 (continue) status before it will + send more of the body of the request. + */ + + bool requestIsChunked; + /* The request body (PUT/POST data) is chunked. */ + + struct { + /* Meaningful only when 'requestIsChunked' is true */ + + ChunkPosition position; + + uint32_t bytesLeftCt; + /* Number of bytes left to read in the current chunk. Always + greater than zero except locally. + + Meaningful only when 'position' is INCHUNK. + */ + } chunkState; +}; + +/*---------------------------------------------------------------------------- + Following are methods of a TSession object private to Abyss. Other + methods are for use by user Uri handlers and are declared in the + external abyss.h header file. +-----------------------------------------------------------------------------*/ + +void +SessionInit(TSession * const sessionP, + TConn * const c); + +void +SessionTerm(TSession * const sessionP); + +void +SessionMakeMemPool(TSession * const sessionP, + size_t const size, + const char ** const errorP); + +#endif diff --git a/trunk/lib/abyss/src/sessionReadRequest.c b/trunk/lib/abyss/src/sessionReadRequest.c new file mode 100644 index 000000000..bad3f06f8 --- /dev/null +++ b/trunk/lib/abyss/src/sessionReadRequest.c @@ -0,0 +1,1210 @@ +#define _XOPEN_SOURCE 600 /* For strdup() */ +#define _BSD_SOURCE /* For xmlrpc_strcaseeq() */ + +#include +#include +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "bool.h" +#include "mallocvar.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/base64_int.h" +#include "xmlrpc-c/abyss.h" + +#include "server.h" +#include "session.h" +#include "conn.h" +#include "token.h" +#include "date.h" +#include "data.h" + +#include "sessionReadRequest.h" + + + +static void +initRequestInfo(TRequestInfo * const requestInfoP, + httpVersion const httpVersion, + const char * const requestLine, + TMethod const httpMethod, + const char * const host, + unsigned int const port, + const char * const path, + const char * const query) { +/*---------------------------------------------------------------------------- + Set up the request info structure. For information that is + controlled by the header, use the defaults -- I.e. the value that + applies if the request contains no applicable header field. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_PTR_OK(requestLine); + XMLRPC_ASSERT_PTR_OK(path); + + requestInfoP->requestline = xmlrpc_strdupsol(requestLine); + requestInfoP->method = httpMethod; + requestInfoP->host = xmlrpc_strdupnull(host); + requestInfoP->port = port; + requestInfoP->uri = strdup(path); + requestInfoP->query = xmlrpc_strdupnull(query); + requestInfoP->from = NULL; + requestInfoP->useragent = NULL; + requestInfoP->referer = NULL; + requestInfoP->user = NULL; + + if (httpVersion.major > 1 || + (httpVersion.major == 1 && httpVersion.minor >= 1)) + requestInfoP->keepalive = true; + else + requestInfoP->keepalive = false; +} + + + +static char * +firstLfPos(TConn * const connectionP, + char * const lineStart) { +/*---------------------------------------------------------------------------- + Return a pointer in the connection's receive buffer to the first + LF (linefeed aka newline) character in the buffer at or after 'lineStart'. + + If there is no LF in the buffer at or after 'lineStart', return NULL. +-----------------------------------------------------------------------------*/ + const char * const bufferEnd = + connectionP->buffer.t + connectionP->buffersize; + + char * p; + + for (p = lineStart; p < bufferEnd && *p != '\n'; ++p); + + if (p < bufferEnd) + return p; + else + return NULL; +} + + + +static void +getLineInBuffer(TConn * const connectionP, + char * const lineStart, + time_t const deadline, + char ** const lineEndP, + bool * const timedOutP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Get a line into the connection's read buffer, starting at position + 'lineStart', if there isn't one already there. 'lineStart' is either + within the buffer or just after it. + + Read the channel until we get a full line, except fail if we don't get + one by 'deadline'. +-----------------------------------------------------------------------------*/ + char * lfPos; + bool timedOut; + + assert(lineStart <= connectionP->buffer.t + connectionP->buffersize); + + for (*errorP = NULL, lfPos = NULL, timedOut = false; + !*errorP && !lfPos && !timedOut; + ) { + int const timeLeft = (int)(deadline - time(NULL)); + if (timeLeft <= 0) + timedOut = true; + else { + lfPos = firstLfPos(connectionP, lineStart); + if (!lfPos) { + if (ConnBufferSpace(connectionP) < 1) + xmlrpc_asprintf(errorP, "HTTP request header does not " + "fit in the server's connection buffer."); + else { + const char * readError; + ConnRead(connectionP, timeLeft, NULL, + &timedOut, &readError); + if (readError) { + xmlrpc_asprintf(errorP, "Failed to read from the " + "connection. %s", readError); + xmlrpc_strfree(readError); + } + } + } + } + } + *lineEndP = lfPos + 1; + *timedOutP = timedOut; +} + + + +static bool +isContinuationLine(const char * const line) { + + return (line[0] == ' ' || line[0] == '\t'); +} + + + +static bool +isEmptyLine(const char * const line) { + + return (line[0] == '\n' || (line[0] == '\r' && line[1] == '\n')); +} + + + +static void +convertLineEnd(char * const lineStart, + char * const prevLineStart, + char const newVal) { +/*---------------------------------------------------------------------------- + Assuming a line begins at 'lineStart' and the line before it (the + "previous line") begins at 'prevLineStart', replace the line + delimiter at the end of the previous line with the character 'newVal'. + + The line delimiter is either CRLF or LF. In the CRLF case, we replace + both CR and LF with 'newVal'. +-----------------------------------------------------------------------------*/ + assert(lineStart >= prevLineStart + 1); + *(lineStart-1) = newVal; + if (prevLineStart + 1 < lineStart && + *(lineStart-2) == '\r') + *(lineStart-2) = newVal; +} + + + +static void +getRestOfField(TConn * const connectionP, + char * const lineEnd, + time_t const deadline, + const char ** const fieldEndP, + bool * const timedOutP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Given that the read buffer for connection *connectionP contains (at + its current read position) the first line of an HTTP header field, which + ends at position 'lineEnd', find or get the rest of it. + + Some or all of the rest of the field may be in the buffer already; + we read more from the connection as necessary, but not if it takes past + 'deadline'. In the latter case, we fail. + + We return the location of the end of the whole field as *headerEndP. + We do not remove the field from the buffer, but we do modify the + buffer so as to join the multiple lines of the field into a single + line, and to NUL-terminate the field. +-----------------------------------------------------------------------------*/ + char * const fieldStart = connectionP->buffer.t + connectionP->bufferpos; + + char * fieldEnd; + /* End of the field lines we've seen at so far */ + bool gotWholeField; + bool timedOut; + + fieldEnd = lineEnd; /* initial value - end of 1st line */ + + for (gotWholeField = false, timedOut = false, *errorP = NULL; + !gotWholeField && !timedOut && !*errorP;) { + + char * nextLineEnd; + + /* Note that we are guaranteed, assuming the HTTP stream is + valid, that there is at least one more line in it. Worst + case, it's the empty line that marks the end of the header. + */ + getLineInBuffer(connectionP, fieldEnd, deadline, + &nextLineEnd, &timedOut, errorP); + if (!*errorP) { + if (isContinuationLine(fieldEnd)) { + /* Join previous line to this one */ + convertLineEnd(fieldEnd, fieldStart, ' '); + /* Add this line to the header */ + fieldEnd = nextLineEnd; + } else { + gotWholeField = true; + + /* NUL-terminate the whole field */ + convertLineEnd(fieldEnd, fieldStart, '\0'); + } + } + } + *fieldEndP = fieldEnd; + *timedOutP = timedOut; +} + + + +static void +readField(TConn * const connectionP, + time_t const deadline, + bool * const endOfHeaderP, + char ** const fieldP, + bool * const timedOutP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Read an HTTP header field, or the end of header empty line, on connection + *connectionP. + + An HTTP header field is basically a line, except that if a line starts + with white space, it's a continuation of the previous line. A line + is delimited by either LF or CRLF. + + The first line of an HTTP header field is never empty; an empty line + signals the end of the HTTP header and beginning of the HTTP body. We + call that empty line the EOH mark. + + We assume the connection is positioned to a header or EOH mark. + + In the course of reading, we read at least one character past the + line delimiter at the end of the field or EOH mark; we may read + much more. But we leave everything after the field or EOH (and + its line delimiter) in the internal buffer, with the buffer pointer + pointing to it. + + We use stuff already in the internal buffer (perhaps left by a + previous call to this subroutine) before reading any more from from + the channel. + + We return as *fieldP the next field as an ASCIIZ string, with no + line delimiter. That string is stored in the "unused" portion of + the connection's internal buffer. Iff there is no next field, we + return *endOfHeaderP == true and nothing meaningful as *fieldP. +-----------------------------------------------------------------------------*/ + char * const bufferStart = connectionP->buffer.t + connectionP->bufferpos; + + char * lineEnd; + const char * getLineError; + + getLineInBuffer(connectionP, bufferStart, deadline, &lineEnd, + timedOutP, &getLineError); + + if (getLineError) { + xmlrpc_asprintf(errorP, "Failed to get a line of HTTP header " + "from client. %s", getLineError); + xmlrpc_strfree(getLineError); + } else if (!*timedOutP) { + if (isContinuationLine(bufferStart)) + xmlrpc_asprintf(errorP, "Client sent continuation line when " + "we were expecting a new header"); + else if (isEmptyLine(bufferStart)) { + /* Consume the EOH mark from the buffer */ + connectionP->bufferpos = lineEnd - connectionP->buffer.t; + *endOfHeaderP = true; + *errorP = NULL; + } else { + /* We have the first line of a field; there may be more. */ + + const char * fieldEnd; + const char * error; + + *endOfHeaderP = false; + + getRestOfField(connectionP, lineEnd, deadline, + &fieldEnd, timedOutP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "After receiving the beginning of " + "an HTTP header field, failed to read " + "the rest of it. %s", error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + + if (!*timedOutP) { + *fieldP = bufferStart; + + /* Consume the header from the buffer (but be careful -- + you can't reuse that part of the buffer because the + string we will return is in it! + */ + connectionP->bufferpos = fieldEnd - connectionP->buffer.t; + } + } + } + } +} + + + +static void +skipToNonemptyLine(TConn * const connectionP, + time_t const deadline, + bool * const timedOutP, + const char ** const errorP) { + + char * const bufferStart = connectionP->buffer.t + connectionP->bufferpos; + + bool gotNonEmptyLine; + char * lineStart; + + for (lineStart = bufferStart, gotNonEmptyLine = false, *timedOutP = false, + *errorP = NULL; + !gotNonEmptyLine && !*timedOutP && !*errorP; ) { + + char * lineEnd; + + getLineInBuffer(connectionP, lineStart, deadline, &lineEnd, + timedOutP, errorP); + + if (!*errorP && !*timedOutP) { + if (!isEmptyLine(lineStart)) + gotNonEmptyLine = true; + else + lineStart = lineEnd; + } + } + if (!*errorP && !*timedOutP) { + /* Consume all the empty lines; advance buffer pointer to first + non-empty line. + */ + connectionP->bufferpos = lineStart - connectionP->buffer.t; + } +} + + + +static void +readRequestField(TSession * const sessionP, + time_t const deadline, + char ** const requestLineP, + bool * const timedOutP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Read the HTTP request field (POST, etc.) from session 'sessionP'. We read + through the session's internal buffer; i.e. we may get data that was + previously read from the network, or we may read more from the network. + + We assume the connection is presently positioned to the beginning of + the HTTP document. We leave it positioned after the request field. + + We ignore any empty lines at the beginning of the stream, per + RFC2616 Section 4.1. + + If we can't get the field before 'deadline', return *timedOutP = true. + + Return as *requestLineP the request field read. This ASCIIZ string is + in the session's internal buffer. +-----------------------------------------------------------------------------*/ + char * line; + bool endOfHeader; + const char * skipError; + + skipToNonemptyLine(sessionP->connP, deadline, timedOutP, &skipError); + + if (skipError) { + xmlrpc_asprintf(errorP, "Failed to find the request field, " + "i.e. a non-empty line. %s", skipError); + xmlrpc_strfree(skipError); + } else if (!*timedOutP) { + const char * error; + + readField(sessionP->connP, deadline, &endOfHeader, &line, + timedOutP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Got beginning of the request field, " + "but failed to get the rest. %s", error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + + if (!*timedOutP) { + /* End of header is delimited by an empty line, and we skipped + all the empty lines above, so readField() could not have + encountered EOH: + */ + assert(!endOfHeader); + + *requestLineP = line; + } + } + } +} + + + +static void +hexDigitValue(char const digit, + unsigned int * const valueP, + const char ** const errorP) { + + if (digit == '\0') + xmlrpc_asprintf(errorP, "string ends in the middle of a " + "%% escape sequence"); + else { + char const digitLc = tolower(digit); + + if ((digitLc >= '0') && (digitLc <= '9')) { + *valueP = digitLc - '0'; + *errorP = NULL; + } else if ((digitLc >= 'a') && (digitLc <= 'f')) { + *valueP = 10 + digitLc - 'a'; + *errorP = NULL; + } else + xmlrpc_asprintf(errorP, "Non-hexadecimal digit '%c' in " + "%%HH escape sequence", digit); + } +} + + + +static void +parsePerCentEscape(const char ** const srcP, + char * const unescapedP, + const char ** const errorP) { +/*----------------------------------------------------------------------------- + With *srcP pointing to a supposed %HH escape sequence in a buffer, set + *unescapedP to the character that the sequence represents and advance *srcP + past it. +-----------------------------------------------------------------------------*/ + unsigned int digit0; + + const char * src; + + src = *srcP; /* initial value */ + + ++src; /* Move past per cent sign */ + + if (!*src) + xmlrpc_asprintf(errorP, "URI ends after the %%"); + else { + *errorP = NULL; /* initial assumption */ + + hexDigitValue(*src++, &digit0, errorP); + + if (!*errorP) { + unsigned int digit1; + + if (!*src) + xmlrpc_asprintf(errorP, "URI ends after the first digit"); + else { + hexDigitValue(*src++, &digit1, errorP); + + if (!*errorP) + *unescapedP = ((digit0 << 4) | digit1); + } + } + } + *srcP = src; +} + + + +static void +unescapeUri(const char * const uriComponent, + const char ** const unescapedP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Unescape a component of a URI, e.g. the host name. That component may + have %HH encoding, especially of characters that are delimiters within + a URI like slash and colon. + + Return the unescaped version as *unescapedP in newly malloced storage. +-----------------------------------------------------------------------------*/ + char * buffer; + + buffer = strdup(uriComponent); + + if (!buffer) + xmlrpc_asprintf(errorP, "Couldn't get memory for URI unescape buffer"); + else { + const char * src; + char * dst; + + src = dst = buffer; + + *errorP = NULL; /* initial value */ + + while (*src && !*errorP) { + switch (*src) { + case '%': { + char unescaped; + const char * error; + + parsePerCentEscape(&src, &unescaped, &error); + + if (error) { + xmlrpc_asprintf(errorP, + "Invalid %%HH escape sequence. %s", + error); + xmlrpc_strfree(error); + } else + *dst++ = unescaped; + } break; + + default: + *dst++ = *src++; + break; + } + } + *dst = '\0'; + + if (*errorP) + xmlrpc_strfree(buffer); + else + *unescapedP = buffer; + } +} + + + +static void +parseHostPort(const char * const hostport, + const char ** const hostP, + unsigned short * const portP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Parse a 'hostport', a string in the form www.acme.com:8080 . + + Return the host name part (www.acme.com) as *hostP (in newly + malloced storage), and the port part (8080) as *portP. + + Default the port to 80 if 'hostport' doesn't have the port part. +-----------------------------------------------------------------------------*/ + char * buffer; + + buffer = strdup(hostport); + + if (!buffer) + xmlrpc_asprintf(errorP, "Couldn't get memory for host/port buffer"); + else { + /* Note that the host portion may contain colons. The old RFC says + it can't, but a newer one says the host may be an IPv6 address + in the form [x:x:x...]. But the port portion may contain only + digits, so we use the _last_ colon as the delimiter. + */ + char * const colonPos = strrchr(buffer, ':'); + + if (colonPos) { + const char * p; + uint32_t port; + + *colonPos = '\0'; /* Split hostport at the colon */ + + for (p = colonPos + 1, port = 0; + isdigit(*p) && port < 65535; + (port = port * 10 + (*p - '0')), ++p); + + if (*p || port == 0) { + xmlrpc_asprintf(errorP, "There is nothing, or something " + "non-numeric for the port number after the " + "colon in '%s'", hostport); + } else { + *hostP = xmlrpc_strdupsol(buffer); + *portP = port; + *errorP = NULL; + } + } else { + *hostP = xmlrpc_strdupsol(buffer); + *portP = 80; + *errorP = NULL; + } + free(buffer); + } +} + + + +static void +splitUriQuery(const char * const requestUri, + const char ** const queryP, + const char ** const noQueryP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Split 'requestUri' at the question mark, returning the stuff after + as *queryP and the stuff before as *noQueryP. +-----------------------------------------------------------------------------*/ + char * buffer; + + buffer = strdup(requestUri); + + if (!buffer) + xmlrpc_asprintf(errorP, "Couldn't get memory for URI buffer"); + else { + char * const qmark = strchr(buffer, '?'); + + if (qmark) { + *qmark = '\0'; + *queryP = xmlrpc_strdupsol(qmark + 1); + } else + *queryP = NULL; + + *errorP = NULL; + *noQueryP = buffer; + } +} + + + +static void +parseHttpHostPortPath(const char * const hostportpath, + const char ** const hostP, + unsigned short* const portP, + const char ** const pathP, + const char ** const errorP) { + + const char * path; + + char * buffer; + + buffer = strdup(hostportpath); + + if (!buffer) + xmlrpc_asprintf(errorP, + "Couldn't get memory for host/port/path buffer"); + else { + char * const slashPos = strchr(buffer, '/'); + + char * hostport; + + if (slashPos) { + path = xmlrpc_strdupsol(slashPos); /* Includes the initial slash */ + + *slashPos = '\0'; /* NUL termination for hostport */ + } else + path = strdup("*"); + + hostport = buffer; + + /* The following interprets the port field without taking into account + any %HH encoding, as the RFC says may be there. We ignore that + remote possibility out of laziness. + */ + parseHostPort(hostport, hostP, portP, errorP); + + if (*errorP) + xmlrpc_strfree(path); + else + *pathP = path; + + free(buffer); + } +} + + + +static void +unescapeHostPathQuery(const char * const host, + const char * const path, + const char * const query, + const char ** const hostP, + const char ** const pathP, + const char ** const queryP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Unescape each of the four components of a URI. + + Each may be NULL, in which case we return NULL. +-----------------------------------------------------------------------------*/ + if (host) + unescapeUri(host, hostP, errorP); + else + *hostP = NULL; + if (!*errorP) { + if (path) + unescapeUri(path, pathP, errorP); + else + *pathP = NULL; + if (!*errorP) { + if (query) + unescapeUri(query, queryP, errorP); + else + *queryP = NULL; + if (*errorP) + xmlrpc_strfree(*pathP); + } else { + if (*hostP) + xmlrpc_strfree(*hostP); + } + } +} + + + +static void +parseRequestUri(char * const requestUri, + const char ** const hostP, + unsigned short * const portP, + const char ** const pathP, + const char ** const queryP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Parse the request URI (in the request line + "GET http://www.myserver.com:8080/myfile.cgi?parm HTTP/1.1", + "http://www.myserver.com:8080/myfile.cgi?parm" is the request URI). + + Return as *hostP the "www.myserver.com" in the above example. If + that part of the URI doesn't exist, return *hostP == NULL. + + Return as *portP the 8080 in the above example. If it doesn't exist, + return 80. + + Return as *pathP the "/myfile.cgi" in the above example. If it + doesn't exist, return "*". + + Return as *queryP the "parm" in the above example. If it doesn't + exist, return *queryP == NULL. + + Return strings in newly malloc'ed storage. + + We can return syntactically invalid entities, e.g. a host name that + contains "<", if 'requestUri' is similarly invalid. We should fix that + some day. RFC 2396 lists a lot of characters as reserved for certain + use in the URI, such as colon, and totally disallowed, such as space. +-----------------------------------------------------------------------------*/ + const char * requestUriNoQuery; + /* The request URI with any query (the stuff marked by a question + mark at the end of a request URI) chopped off. + */ + const char * query; + const char * path; + const char * host; + unsigned short port; + + splitUriQuery(requestUri, &query, &requestUriNoQuery, errorP); + if (!*errorP) { + if (requestUriNoQuery[0] == '/') { + host = NULL; + path = xmlrpc_strdupsol(requestUriNoQuery); + port = 80; + *errorP = NULL; + } else { + if (!xmlrpc_strneq(requestUriNoQuery, "http://", 7)) + xmlrpc_asprintf(errorP, "Scheme is not http://"); + else + parseHttpHostPortPath(&requestUriNoQuery[7], + &host, &port, &path, errorP); + } + + if (!*errorP) { + *portP = port; + unescapeHostPathQuery(host, path, query, + hostP, pathP, queryP, errorP); + + if (host) + xmlrpc_strfree(host); + if (path) + xmlrpc_strfree(path); + } + + if (query) + xmlrpc_strfree(query); + xmlrpc_strfree(requestUriNoQuery); + } +} + + + +static TMethod +methodFromMethodName(const char * const httpMethodName) { + + if (xmlrpc_streq(httpMethodName, "GET")) + return m_get; + else if (xmlrpc_streq(httpMethodName, "PUT")) + return m_put; + else if (xmlrpc_streq(httpMethodName, "OPTIONS")) + return m_options; + else if (xmlrpc_streq(httpMethodName, "DELETE")) + return m_delete; + else if (xmlrpc_streq(httpMethodName, "POST")) + return m_post; + else if (xmlrpc_streq(httpMethodName, "TRACE")) + return m_trace; + else if (xmlrpc_streq(httpMethodName, "HEAD")) + return m_head; + else + return m_unknown; +} + + + +static void +parseHttpVersion(const char * const textFromReqLine, + httpVersion * const httpVersionP, + const char ** const errorP) { + + uint32_t vmin, vmaj; + + if (sscanf(textFromReqLine, "HTTP/%d.%d", &vmaj, &vmin) != 2) + xmlrpc_asprintf(errorP, "Does not have the form HTTP/n.n"); + else { + *errorP = NULL; + httpVersionP->major = vmaj; + httpVersionP->minor = vmin; + } +} + + + +static void +parseRequestLine(char * const requestLine, + TMethod * const httpMethodP, + httpVersion * const httpVersionP, + const char ** const hostP, + unsigned short * const portP, + const char ** const pathP, + const char ** const queryP, + bool * const moreLinesP, + const char ** const errorP) { + + char * const requestBuffer = strdup(requestLine); + + const char * httpMethodName; + char * p; + + if (requestBuffer == NULL) + xmlrpc_asprintf(errorP, "Couldn't get memory for working buffer"); + else { + p = requestBuffer; + + /* Jump over spaces */ + NextToken((const char **)&p); + + httpMethodName = GetToken(&p); + if (!httpMethodName) + xmlrpc_asprintf(errorP, "No method name (e.g. \"GET\")"); + else { + char * requestUri; + + *httpMethodP = methodFromMethodName(httpMethodName); + + /* URI and Query Decoding */ + NextToken((const char **)&p); + + requestUri = GetToken(&p); + if (!requestUri) + xmlrpc_asprintf(errorP, "No URI after the method name ('%s')", + httpMethodName); + else { + const char * host; + unsigned short port; + const char * path; + const char * query; + const char * error; + + parseRequestUri(requestUri, + &host, &port, &path, &query, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Invalid URI ('%s'). %s", + requestUri, error); + xmlrpc_strfree(error); + } else { + const char * httpVersion; + + NextToken((const char **)&p); + + /* HTTP Version Decoding */ + + httpVersion = GetToken(&p); + if (httpVersion) { + const char * error; + parseHttpVersion(httpVersion, httpVersionP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Invalid HTTP version " + "token ('%s'). %s", + httpVersion, error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + *moreLinesP = true; + } + } else { + /* There is no HTTP version, so this is a single + line request. + */ + *errorP = NULL; + *moreLinesP = false; + } + if (*errorP) { + xmlrpc_strfree(host); + xmlrpc_strfree(path); + xmlrpc_strfree(query); + } + *hostP = host; + *portP = port; + *pathP = path; + *queryP = query; + } + } + } + xmlrpc_strfree(requestBuffer); + } +} + + + +static void +strtolower(char * const s) { + + char * t; + + t = &s[0]; + while (*t) { + *t = tolower(*t); + ++t; + } +} + + + +static void +getFieldNameToken(char ** const pP, + char ** const fieldNameP, + const char ** const errorP, + uint16_t * const httpErrorCodeP) { +/*---------------------------------------------------------------------------- + Assuming that *pP points to the place in an HTTP header where the field + name belongs, return the field name and advance *pP past that token. + + The field name is the lower case representation of the value of the + field name token. + + If the field name is invalid, return a text explanation as *errorP + and a suitable HTTP status code as *httpErrorCodeP. If not, return + *errorP == NULL and nothing as *httpErrorCodeP. +-----------------------------------------------------------------------------*/ + char * fieldName; + + NextToken((const char **)pP); + + fieldName = GetToken(pP); + if (!fieldName) { + xmlrpc_asprintf(errorP, "The header has no field name token"); + *httpErrorCodeP = 400; /* Bad Request */ + } else { + if (fieldName[strlen(fieldName)-1] != ':') { + /* Not a valid field name */ + xmlrpc_asprintf(errorP, "The field name token '%s' " + "does not end with a colon (:)", fieldName); + *httpErrorCodeP = 400; /* Bad Request */ + } else { + fieldName[strlen(fieldName)-1] = '\0'; /* remove trailing colon */ + + strtolower(fieldName); + + *errorP = NULL; + } + } + *fieldNameP = fieldName; +} + + + +static void +processField(const char * const fieldName, + char * const fieldValue, + TSession * const sessionP, + const char ** const errorP, + uint16_t * const httpErrorCodeP) { +/*---------------------------------------------------------------------------- + We may modify *fieldValue, and we put pointers to *fieldValue and + *fieldName into *sessionP. + + We must fix this some day. *sessionP should point to individual + malloc'ed strings. +-----------------------------------------------------------------------------*/ + *errorP = NULL; /* initial assumption */ + + if (xmlrpc_streq(fieldName, "connection")) { + if (xmlrpc_strcaseeq(fieldValue, "keep-alive")) + sessionP->requestInfo.keepalive = true; + else + sessionP->requestInfo.keepalive = false; + } else if (xmlrpc_streq(fieldName, "host")) { + if (sessionP->requestInfo.host) { + xmlrpc_strfree(sessionP->requestInfo.host); + sessionP->requestInfo.host = NULL; + } + parseHostPort(fieldValue, &sessionP->requestInfo.host, + &sessionP->requestInfo.port, errorP); + } else if (xmlrpc_streq(fieldName, "from")) + sessionP->requestInfo.from = fieldValue; + else if (xmlrpc_streq(fieldName, "user-agent")) + sessionP->requestInfo.useragent = fieldValue; + else if (xmlrpc_streq(fieldName, "referer")) + sessionP->requestInfo.referer = fieldValue; + else if (xmlrpc_streq(fieldName, "range")) { + if (xmlrpc_strneq(fieldValue, "bytes=", 6)) { + bool succeeded; + succeeded = ListAddFromString(&sessionP->ranges, &fieldValue[6]); + if (!succeeded) { + xmlrpc_asprintf(errorP, "ListAddFromString() failed for " + "\"range: bytes=...\" header value '%s'", + &fieldValue[6]); + *httpErrorCodeP = 400; + } + } + } else if (xmlrpc_streq(fieldName, "cookies")) { + bool succeeded; + succeeded = ListAddFromString(&sessionP->cookies, fieldValue); + if (!succeeded) { + xmlrpc_asprintf(errorP, "ListAddFromString() failed for " + "cookies: header value '%s'", fieldValue); + *httpErrorCodeP = 400; + } + } else if (xmlrpc_streq(fieldName, "expect")) { + if (xmlrpc_strcaseeq(fieldValue, "100-continue")) + sessionP->continueRequired = true; + } else if (xmlrpc_streq(fieldName, "transfer-encoding")) { + if (xmlrpc_strcaseeq(fieldValue, "chunked")) + sessionP->requestIsChunked = true; + else if (xmlrpc_strcaseeq(fieldValue, "identity")) { + // Same as no transfer-encoding specified + } else { + xmlrpc_asprintf(errorP, "Server does not know '%s' transfer " + "encoding. It knows only 'chunked' and " + "'identity'", fieldValue); + *httpErrorCodeP = 501; + } + } +} + + + +static void +readAndProcessHeaderFields(TSession * const sessionP, + time_t const deadline, + const char ** const errorP, + uint16_t * const httpErrorCodeP) { +/*---------------------------------------------------------------------------- + Read all the HTTP header fields from the session *sessionP, which has at + least one field coming. Update *sessionP to reflect the information in the + fields. + + If we find an error in the fields or while trying to read them, we return + a text explanation of the problem as *errorP and an appropriate HTTP error + code as *httpErrorCodeP. Otherwise, we return *errorP = NULL and nothing + as *httpErrorCodeP. +-----------------------------------------------------------------------------*/ + bool endOfHeader; + bool timedOut; + + assert(!sessionP->validRequest); + /* Calling us doesn't make sense if there is already a valid request */ + + for (endOfHeader = false, *errorP = NULL, timedOut = false; + !endOfHeader && !*errorP && !timedOut; ) { + char * field; + const char * error; + readField(sessionP->connP, deadline, &endOfHeader, &field, + &timedOut, &error); + if (error) { + xmlrpc_asprintf(errorP, "Failed to read header from " + "client connection. %s", error); + *httpErrorCodeP = 500; /* Internal server error */ + xmlrpc_strfree(error); + } else if (timedOut) { + xmlrpc_asprintf(errorP, "Timed out wating for client to send " + "something"); + *httpErrorCodeP = 408; /* Request timed out */ + } else { + if (!endOfHeader) { + char * p; + char * fieldName; + + p = &field[0]; + getFieldNameToken(&p, &fieldName, errorP, httpErrorCodeP); + if (!*errorP) { + char * fieldValue; + + NextToken((const char **)&p); + + fieldValue = p; + + TableAdd(&sessionP->requestHeaderFields, + fieldName, fieldValue); + + processField(fieldName, fieldValue, sessionP, errorP, + httpErrorCodeP); + } + } + } + } +} + + + +void +SessionReadRequest(TSession * const sessionP, + uint32_t const timeout, + const char ** const errorP, + uint16_t * const httpErrorCodeP) { +/*---------------------------------------------------------------------------- + Read the header of a new HTTP request (assuming nothing has yet been + read on the session). + + Update *sessionP with the information from the header. + + Leave the connection positioned to the body of the request, ready + to be read by an HTTP request handler (via SessionRefillBuffer() and + SessionGetReadData()). + + If we are unable to read the header, we return a text description as + *errorP and a suitable HTTP status code as *httpErrorCodeP. + + If we successfully read the header, we return *errorP == NULL and + nothing as *httpErrorCodeP. +-----------------------------------------------------------------------------*/ + time_t const deadline = time(NULL) + timeout; + + bool timedOut; + const char * error; + char * requestLine; /* In connection's internal buffer */ + + readRequestField(sessionP, deadline, &requestLine, &timedOut, &error); + if (error) { + xmlrpc_asprintf(errorP, "Problem getting the request header. %s", + error); + *httpErrorCodeP = 500; /* Internal error */ + xmlrpc_strfree(error); + } else if (timedOut) { + xmlrpc_asprintf(errorP, "Timed out waiting for client to send " + "the request field"); + *httpErrorCodeP = 408; /* Request timed out */ + } else { + TMethod httpMethod; + const char * host; + const char * path; + const char * query; + unsigned short port; + bool moreFields; + const char * error; + + parseRequestLine(requestLine, &httpMethod, &sessionP->version, + &host, &port, &path, &query, + &moreFields, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Unable to parse the request header " + "'%s'. %s", requestLine, error); + *httpErrorCodeP = 400; /* Bad request */ + xmlrpc_strfree(error); + } else { + initRequestInfo(&sessionP->requestInfo, sessionP->version, + requestLine, + httpMethod, host, port, path, query); + + if (moreFields) { + readAndProcessHeaderFields(sessionP, deadline, + errorP, httpErrorCodeP); + } else + *errorP = NULL; + + if (!*errorP) + sessionP->validRequest = true; + + xmlrpc_strfreenull(host); + xmlrpc_strfree(path); + xmlrpc_strfreenull(query); + } + } +} + + + diff --git a/trunk/lib/abyss/src/sessionReadRequest.h b/trunk/lib/abyss/src/sessionReadRequest.h new file mode 100644 index 000000000..6b3107ef6 --- /dev/null +++ b/trunk/lib/abyss/src/sessionReadRequest.h @@ -0,0 +1,12 @@ +#ifndef SESSION_READ_REQUEST_H_INCLUDED +#define SESSION_READ_REQUEST_H_INCLUDED + +#include "session.h" + +void +SessionReadRequest(TSession * const sessionP, + uint32_t const timeout, + const char ** const errorP, + uint16_t * const httpErrorCodeP); + +#endif diff --git a/trunk/lib/abyss/src/socket.c b/trunk/lib/abyss/src/socket.c new file mode 100644 index 000000000..4724e6dfc --- /dev/null +++ b/trunk/lib/abyss/src/socket.c @@ -0,0 +1,127 @@ +/*============================================================================ + socket.c +============================================================================== + Implementation of obsolete TSocket class. + + Use TChannel and TChanSwitch instead for new work. +============================================================================*/ + +#include +#include + +#include "int.h" +#include "mallocvar.h" +#include "xmlrpc-c/abyss.h" +#include "channel.h" +#include "chanswitch.h" + +#include "socket.h" + + +/* SocketCreate...() is not exported to the Abyss user. It is meant to + be used by an implementation-specific TSocket generator which is + exported to the Abyss user, e.g. SocketCreateUnix() in + socket_unix.c + + The TSocket generator functions are the _only_ user-accessible + functions that are particular to an implementation. +*/ + +static unsigned int const socketSignature = 0x060609; + + +static void +socketCreate(TSocket ** const socketPP) { + + TSocket * socketP; + + MALLOCVAR(socketP); + + if (socketP) { + socketP->signature = socketSignature; + *socketPP = socketP; + } else + *socketPP = NULL; +} + + + +void +SocketCreateChannel(TChannel * const channelP, + void * const channelInfoP, + TSocket ** const socketPP) { + + TSocket * socketP; + + socketCreate(&socketP); + + if (socketP) { + socketP->channelP = channelP; + socketP->chanSwitchP = NULL; + socketP->channelInfoP = channelInfoP; + *socketPP = socketP; + } else + *socketPP = NULL; +} + + + +void +SocketCreateChanSwitch(TChanSwitch * const chanSwitchP, + TSocket ** const socketPP) { + + TSocket * socketP; + + socketCreate(&socketP); + + if (socketP) { + socketP->channelP = NULL; + socketP->chanSwitchP = chanSwitchP; + *socketPP = socketP; + } else + *socketPP = NULL; +} + + + +void +SocketDestroy(TSocket * const socketP) { + + assert(socketP->signature == socketSignature); + + if (socketP->channelP) { + ChannelDestroy(socketP->channelP); + free(socketP->channelInfoP); + } + + if (socketP->chanSwitchP) + ChanSwitchDestroy(socketP->chanSwitchP); + + socketP->signature = 0; /* For debuggability */ + + free(socketP); +} + + + +TChanSwitch * +SocketGetChanSwitch(TSocket * const socketP) { + + return socketP->chanSwitchP; +} + + + +TChannel * +SocketGetChannel(TSocket * const socketP) { + + return socketP->channelP; +} + + + +void * +SocketGetChannelInfo(TSocket * const socketP) { + + return socketP->channelInfoP; +} diff --git a/trunk/lib/abyss/src/socket.h b/trunk/lib/abyss/src/socket.h new file mode 100644 index 000000000..50e67ba6b --- /dev/null +++ b/trunk/lib/abyss/src/socket.h @@ -0,0 +1,60 @@ +#ifndef SOCKET_H_INCLUDED +#define SOCKET_H_INCLUDED + +/*============================================================================ + This is for backward compatibility. Abyss used to have a socket + concept modelled after POSIX sockets, in which a single class (TSocket) + contained two very different kinds of objects: some analogous to + a TChanSwitch and analogout to a TChannel. + + Now that we have TChanSwitch and TChannel, users should use those, + but there may be old programs that use TSocket, and we want them to + continue working. + + Actually, this may not be necessary. There was only one release + (1.06) that had the TSocket interface, and that release didn't + provide any incentive to upgrade an older program to use TSocket, + so there may be few or no users of TSocket. +============================================================================*/ + +#include "int.h" + +#include "xmlrpc-c/abyss.h" + +struct _TSocket { + unsigned int signature; + /* With both background and foreground use of sockets, and + background being both fork and pthread, it is very easy to + screw up socket lifetime and try to destroy twice. We use + this signature to help catch such bugs. + */ + + /* Exactly one of 'chanSwitchP' and 'channelP' is non-null. + That's how you know which of the two varieties of socket this is. + */ + TChanSwitch * chanSwitchP; + TChannel * channelP; + + void * channelInfoP; /* Defined only for a channel socket */ +}; + +void +SocketCreateChannel(TChannel * const channelP, + void * const channelInfoP, + TSocket ** const socketPP); + +void +SocketCreateChanSwitch(TChanSwitch * const chanSwitchP, + TSocket ** const socketPP); + +TChanSwitch * +SocketGetChanSwitch(TSocket * const socketP); + +TChannel * +SocketGetChannel(TSocket * const socketP); + +void * +SocketGetChannelInfo(TSocket * const socketP); + +#endif + diff --git a/trunk/lib/abyss/src/socket_openssl.c b/trunk/lib/abyss/src/socket_openssl.c new file mode 100644 index 000000000..1f35ec317 --- /dev/null +++ b/trunk/lib/abyss/src/socket_openssl.c @@ -0,0 +1,973 @@ +/*============================================================================= + socket_openssl.c +=============================================================================== + This is the implementation of TChanSwitch and TChannel + for an SSL (Secure Sockets Layer) connection based on an OpenSSL + connection object -- what you create with SSL_new(). +=============================================================================*/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" +#include "bool.h" +#include "mallocvar.h" +#include "trace.h" +#include "chanswitch.h" +#include "channel.h" +#include "socket.h" +#include "xmlrpc-c/abyss.h" +#include "xmlrpc-c/abyss_openssl.h" + +#include "sockutil.h" +#include "socket_openssl.h" + + + +/* We've seen Openssl from the year 2002 not have SSL_ERROR_WANT_ACCEPT. + In 2016, it is defined as a macro. +*/ +#ifdef SSL_ERROR_WANT_ACCEPT +#define HAVE_SSL_ERROR_WANT_ACCEPT 1 +#else +#define HAVE_SSL_ERROR_WANT_ACCEPT 0 +#endif + + + +static const char * +sslErrorMsg(void) { +/*---------------------------------------------------------------------------- + The information on the OpenSSL error stack, in human-readable (barely) + form. +-----------------------------------------------------------------------------*/ + const char * retval; + bool eof; + + retval = xmlrpc_strdupsol(""); + + for (eof = false; !eof; ) { + const char * sourceFileName; + int lineNum; + + int const errCode = ERR_get_error_line(&sourceFileName, &lineNum); + + if (errCode == 0) + eof = true; + else { + const char * newRetval; + + xmlrpc_asprintf(&newRetval, "%s %s (%s:%d); ", + retval, ERR_error_string(errCode, NULL), + sourceFileName, lineNum); + + xmlrpc_strfree(retval); + + retval = newRetval; + } + } + return retval; +} + + + +static const char * +sslResultMsg(int const resultCode) { +/*---------------------------------------------------------------------------- + English description of a result code such as OpenSSL's SSL_get_error + returns. +-----------------------------------------------------------------------------*/ + switch (resultCode) { + case SSL_ERROR_NONE: return "None"; + case SSL_ERROR_SSL: return "SSL"; + case SSL_ERROR_WANT_READ: return "Want Read"; + case SSL_ERROR_WANT_WRITE: return "Want Write"; + case SSL_ERROR_WANT_X509_LOOKUP: return "Want X509_LOOKUP"; + case SSL_ERROR_SYSCALL: return "Syscall"; + case SSL_ERROR_ZERO_RETURN: return "Zero Return"; + case SSL_ERROR_WANT_CONNECT: return "Want Connect"; +#if HAVE_SSL_ERROR_WANT_ACCEPT + case SSL_ERROR_WANT_ACCEPT: return "Want Accept"; +#endif + default: return "???"; + } +} + + + +static void +sslCreate(SSL_CTX * const sslCtxP, + SSL ** const sslPP, + const char ** const errorP) { + + *sslPP = SSL_new(sslCtxP); + + if (!*sslPP) { + const char * const sslMsg = sslErrorMsg(); + + xmlrpc_asprintf(errorP, "Failed to create SSL connection " + "object. SSL_new() failed. %s", sslMsg); + xmlrpc_strfree(sslMsg); + } else + *errorP = NULL; +} + + + +static void +sslSetFd(SSL * const sslP, + int const acceptedFd, + const char ** const errorP) { + + int succeeded; + + succeeded = SSL_set_fd(sslP, acceptedFd); + + if (!succeeded) { + const char * sslMsg; + + sslMsg = sslErrorMsg(); + + xmlrpc_asprintf(errorP, "SSL_set_fd(%d) failed. %s", + acceptedFd, sslMsg); + + xmlrpc_strfree(sslMsg); + } else + *errorP = NULL; +} + + + +static void +traceCipherList(SSL * const sslP) { + + int priority; + bool eof; + + fprintf(stderr, "SSL object will consider using the following " + "ciphers in priority order, if conditions are right to use " + "them and the client agrees: "); + + for (priority = 0, eof = false; !eof; ++priority) { + const char * const cipherName = SSL_get_cipher_list(sslP, priority); + + if (cipherName) + fprintf(stderr, "%s ", cipherName); + else + eof = true; + } + fprintf(stderr, "\n"); +} + + + +static void +sslAccept(SSL * const sslP, + const char ** const errorP) { + + int rc; + + if (SwitchTraceIsActive) + traceCipherList(sslP); + + rc = SSL_accept(sslP); + + if (rc == 1) + *errorP = NULL; + else { + int const resultCode = SSL_get_error(sslP, rc); + + const char * const errorStack = sslErrorMsg(); + + xmlrpc_asprintf(errorP, "SSL_accept() failed. rc=%d/%d: %s. " + "OpenSSL error stack: %s\n", + rc, resultCode, sslResultMsg(resultCode), errorStack); + + xmlrpc_strfree(errorStack); + } +} + + + +struct ChannelOpenSsl { +/*---------------------------------------------------------------------------- + The properties/state of a TChannel unique to the OpenSSL variety. +-----------------------------------------------------------------------------*/ + int fd; + /* File descriptor of the TCP connection underlying the SSL connection + */ + SSL * sslP; + /* SSL connection handle */ + bool userSuppliedSsl; + /* The SSL connection belongs to the user; we did not create it. */ +}; + + + +void +SocketOpenSslInit(const char ** const errorP) { + + SSL_load_error_strings(); + /* readable error messages, don't call this if memory is tight */ + SSL_library_init(); /* initialize library */ + + *errorP = NULL; +} + + + +void +SocketOpenSslTerm(void) { + + ERR_free_strings(); + +} + + + +/*============================================================================= + TChannel +=============================================================================*/ + +static ChannelDestroyImpl channelDestroy; + +static void +channelDestroy(TChannel * const channelP) { + + struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; + + if (!channelOpenSslP->userSuppliedSsl) + SSL_shutdown(channelOpenSslP->sslP); + + free(channelOpenSslP); +} + + + +static ChannelWriteImpl channelWrite; + +static void +channelWrite(TChannel * const channelP, + const unsigned char * const buffer, + uint32_t const len, + bool * const failedP) { + + struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; + + unsigned int bytesLeft; + bool error; + + assert(sizeof(int) >= sizeof(len)); + + for (bytesLeft = len, error = false; bytesLeft > 0 && !error; ) { + uint32_t const maxSend = (uint32_t)(-1) >> 1; + + int rc; + + rc = SSL_write(channelOpenSslP->sslP, &buffer[len-bytesLeft], + MIN(maxSend, bytesLeft)); + + if (ChannelTraceIsActive) { + if (rc <= 0) + fprintf(stderr, + "Abyss socket: SSL_write() failed. rc=%d/%d", + rc, SSL_get_error(channelOpenSslP->sslP, rc)); + else + fprintf(stderr, "Abyss socket: sent %u bytes: '%.*s'\n", + rc, rc, &buffer[len-bytesLeft]); + } + if (rc <= 0) + /* 0 means connection closed; < 0 means severe error */ + error = true; + else + bytesLeft -= rc; + } + *failedP = error; +} + + + +static ChannelReadImpl channelRead; + +static void +channelRead(TChannel * const channelP, + unsigned char * const buffer, + uint32_t const bufferSize, + uint32_t * const bytesReceivedP, + bool * const failedP) { + + struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; + + int rc; + rc = SSL_read(channelOpenSslP->sslP, buffer, bufferSize); + + if (rc < 0) { + *failedP = true; + if (ChannelTraceIsActive) + fprintf(stderr, "Failed to receive data from OpenSSL connection. " + "SSL_read() failed with rc %d/%d\n", + rc, SSL_get_error(channelOpenSslP->sslP, rc)); + } else { + *failedP = false; + *bytesReceivedP = rc; + + if (ChannelTraceIsActive) + fprintf(stderr, "Abyss channel: read %u bytes: '%.*s'\n", + *bytesReceivedP, (int)(*bytesReceivedP), buffer); + } +} + + + +static ChannelWaitImpl channelWait; + +static void +channelWait(TChannel * const channelP ATTR_UNUSED, + bool const waitForRead ATTR_UNUSED, + bool const waitForWrite ATTR_UNUSED, + uint32_t const timeoutMs ATTR_UNUSED, + bool * const readyToReadP, + bool * const readyToWriteP, + bool * const failedP) { +/*---------------------------------------------------------------------------- + See socket_unix.c for an explanation of the purpose of this + subroutine. + + We don't actually fulfill that purpose, though, because we don't know + how yet. Instead, we return immediately and hope that if Caller + subsequently does a read or write, it blocks until it can do its thing. +-----------------------------------------------------------------------------*/ + if (readyToReadP) + *readyToReadP = true; + if (readyToWriteP) + *readyToWriteP = true; + if (failedP) + *failedP = false; +} + + + +static ChannelInterruptImpl channelInterrupt; + +static void +channelInterrupt(TChannel * const channelP ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + Interrupt any waiting that a thread might be doing in channelWait() + now or in the future. +-----------------------------------------------------------------------------*/ + + /* This is trivial, since channelWait() doesn't actually wait */ +} + + + +static ChannelFormatPeerInfoImpl channelFormatPeerInfo; + +static void +channelFormatPeerInfo(TChannel * const channelP, + const char ** const peerStringP) { + + struct ChannelOpenSsl * const channelOpenSslP = channelP->implP; + + sockutil_formatPeerInfo(channelOpenSslP->fd, peerStringP); +} + + + +static struct TChannelVtbl const channelVtbl = { + &channelDestroy, + &channelWrite, + &channelRead, + &channelWait, + &channelInterrupt, + &channelFormatPeerInfo, +}; + + + +static void +getPeerAddrFromSsl(SSL * const sslP, + struct sockaddr * const peerAddrRetP, + size_t * const peerAddrLenRetP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + From the SSL connection with handle 'sslP', get the address (IP address, + normally) of the peer (the Abyss client). +-----------------------------------------------------------------------------*/ + int const sockFd = SSL_get_fd(sslP); + + struct sockaddr * peerAddrP; + size_t peerAddrLen; + const char * error; + + sockutil_getPeerName(sockFd, &peerAddrP, &peerAddrLen, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Could not get identity of client. %s", + error); + xmlrpc_strfree(error); + } else { + *errorP = NULL; + *peerAddrLenRetP = peerAddrLen; + *peerAddrRetP = *peerAddrP; + + free(peerAddrP); + } +} + + + +static void +makeChannelInfo(struct abyss_openSsl_chaninfo ** const channelInfoPP, + SSL * const sslP, + const char ** const errorP) { + + struct abyss_openSsl_chaninfo * channelInfoP; + + MALLOCVAR(channelInfoP); + + if (channelInfoP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory"); + else { + channelInfoP->sslP = sslP; + + getPeerAddrFromSsl(sslP, + &channelInfoP->peerAddr, + &channelInfoP->peerAddrLen, + errorP); + + if (*errorP) + free(channelInfoP); + else + *channelInfoPP = channelInfoP; + } +} + + + +static void +makeChannelFromSsl(SSL * const sslP, + bool const userSuppliedSsl, + TChannel ** const channelPP, + const char ** const errorP) { + + struct ChannelOpenSsl * channelOpenSslP; + + MALLOCVAR(channelOpenSslP); + + if (channelOpenSslP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for OpenSSL " + "socket descriptor"); + else { + TChannel * channelP; + + channelOpenSslP->sslP = sslP; + channelOpenSslP->userSuppliedSsl = userSuppliedSsl; + + /* This should be ok as far as I can tell */ + ChannelCreate(&channelVtbl, channelOpenSslP, &channelP); + + if (channelP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for " + "channel descriptor."); + else { + *channelPP = channelP; + *errorP = NULL; + } + if (*errorP) + free(channelOpenSslP); + } +} + + + +void +ChannelOpenSslCreateSsl(SSL * const sslP, + TChannel ** const channelPP, + struct abyss_openSsl_chaninfo ** const channelInfoPP, + const char ** const errorP) { + + assert(sslP); + + makeChannelInfo(channelInfoPP, sslP, errorP); + if (!*errorP) { + bool const userSuppliedTrue = true; + + makeChannelFromSsl(sslP, userSuppliedTrue, channelPP, errorP); + + if (*errorP) { + free(*channelInfoPP); + } + } +} + + + +/*============================================================================= + TChanSwitch +=============================================================================*/ + +struct ChanSwitchOpenSsl { +/*---------------------------------------------------------------------------- + The properties/state of a TChanSwitch uniqe to the OpenSSL variety. + + Note that OpenSSL deals only in connected sockets, so this switch + doesn't really have anything to do with OpenSSL except that it + creates OpenSSL TChannels. The switch is just a POSIX listening + socket, and is almost identical to the Abyss Unix channel switch. +-----------------------------------------------------------------------------*/ + int listenFd; + /* File descriptor of the POSIX socket (such as is created by + socket() in the C library) for the listening socket. + */ + bool userSuppliedFd; + /* The file descriptor and associated POSIX socket belong to the + user; we did not create it. + */ + SSL_CTX * sslCtxP; + /* The context in which we create all our OpenSSL connections */ + + sockutil_InterruptPipe interruptPipe; + /* We use this to interrupt a wait for the next client to arrive */ +}; + + + +static SwitchDestroyImpl chanSwitchDestroy; + +static void +chanSwitchDestroy(TChanSwitch * const chanSwitchP) { + + struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; + + sockutil_interruptPipeTerm(chanSwitchOpenSslP->interruptPipe); + + if (!chanSwitchOpenSslP->userSuppliedFd) + close(chanSwitchOpenSslP->listenFd); + + free(chanSwitchOpenSslP); +} + + + +static SwitchListenImpl chanSwitchListen; + +static void +chanSwitchListen(TChanSwitch * const chanSwitchP, + uint32_t const backlog, + const char ** const errorP) { + + struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; + + sockutil_listen(chanSwitchOpenSslP->listenFd, backlog, errorP); +} + + + +static void +createSslFromAcceptedConn(int const acceptedFd, + SSL_CTX * const sslCtxP, + SSL ** const sslPP, + const char ** const errorP) { + + SSL * sslP; + const char * error; + + sslCreate(sslCtxP, &sslP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Failed to create SSL connection " + "object. %s", error); + xmlrpc_strfree(error); + } else { + const char * error; + + sslSetFd(sslP, acceptedFd, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Failed to set file descriptor for SSL " + "connection. %s", error); + xmlrpc_strfree(error); + } else { + const char * error; + + sslAccept(sslP, &error); + + if (error) { + xmlrpc_asprintf(errorP, + "Failed to set up SSL communication on " + "working TCP connection. %s", error); + xmlrpc_strfree(error); + } else + *errorP = NULL; + } + if (*errorP) + SSL_free(sslP); + else { + *sslPP = sslP; + } + } +} + + + +static void +createChannelFromAcceptedConn(int const acceptedFd, + SSL_CTX * const sslCtxP, + TChannel ** const channelPP, + void ** const channelInfoPP, + const char ** const errorP) { + + struct ChannelOpenSsl * channelOpenSslP; + + MALLOCVAR(channelOpenSslP); + + if (!channelOpenSslP) + xmlrpc_asprintf(errorP, "Unable to allocate memory"); + else { + SSL * sslP; + const char * error; + + createSslFromAcceptedConn(acceptedFd, sslCtxP, &sslP, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Failed to create an OpenSSL connection " + "from the accepted TCP connection. %s", error); + xmlrpc_strfree(error); + } else { + struct abyss_openSsl_chaninfo * channelInfoP; + + makeChannelInfo(&channelInfoP, sslP, errorP); + if (!*errorP) { + bool const userSuppliedFalse = false; + + makeChannelFromSsl(sslP, userSuppliedFalse, + channelPP, errorP); + + if (*errorP) + free(channelInfoP); + else + *channelInfoPP = channelInfoP; + } + if (*errorP) + SSL_free(sslP); + else + channelOpenSslP->sslP = sslP; + } + if (*errorP) + free(channelOpenSslP); + } +} + + + +static SwitchAcceptImpl chanSwitchAccept; + +static void +chanSwitchAccept(TChanSwitch * const chanSwitchP, + TChannel ** const channelPP, + void ** const channelInfoPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Accept a connection via the channel switch *chanSwitchP. Return as + *channelPP the channel for the accepted connection. + + If no connection is waiting at *chanSwitchP, wait until one is. + + If we receive a signal while waiting, return immediately with + *channelPP == NULL. +-----------------------------------------------------------------------------*/ + struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; + + bool interrupted; + TChannel * channelP; + + interrupted = false; /* Haven't been interrupted yet */ + channelP = NULL; /* No connection yet */ + *errorP = NULL; /* No error yet */ + + while (!channelP && !*errorP && !interrupted) { + struct sockaddr peerAddr; + socklen_t peerAddrLen; + int rc; + + peerAddrLen = sizeof(peerAddr); /* initial value */ + + rc = accept(chanSwitchOpenSslP->listenFd, &peerAddr, &peerAddrLen); + + if (rc >= 0) { + int const acceptedFd = rc; + + const char * error; + + createChannelFromAcceptedConn( + acceptedFd, chanSwitchOpenSslP->sslCtxP, + &channelP, channelInfoPP, &error); + + if (error) { + close(acceptedFd); + + if (SwitchTraceIsActive) + fprintf(stderr, + "Failed to create a channel from the " + "TCP connection we accepted. %s. " + "Closing TCP connection, waiting for the " + "next one\n", error); + xmlrpc_strfree(error); + } + } else if (errno == EINTR) + interrupted = true; + else + xmlrpc_asprintf(errorP, "accept() failed, errno = %d (%s)", + errno, strerror(errno)); + } + *channelPP = channelP; +} + + + +static SwitchInterruptImpl chanSwitchInterrupt; + +static void +chanSwitchInterrupt(TChanSwitch * const chanSwitchP) { +/*---------------------------------------------------------------------------- + Interrupt any waiting that a thread might be doing in chanSwitchAccept() + now or in the future. + + TODO: Make a way to reset this so that future chanSwitchAccept()s can once + again wait. +-----------------------------------------------------------------------------*/ + struct ChanSwitchOpenSsl * const chanSwitchOpenSslP = chanSwitchP->implP; + + unsigned char const zero[1] = {0u}; + + write(chanSwitchOpenSslP->interruptPipe.interruptorFd, + &zero, sizeof(zero)); +} + + + +static struct TChanSwitchVtbl const chanSwitchVtbl = { + &chanSwitchDestroy, + &chanSwitchListen, + &chanSwitchAccept, + &chanSwitchInterrupt, +}; + + + +static void +createChanSwitch(int const fd, + bool const userSuppliedFd, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + struct ChanSwitchOpenSsl * chanSwitchOpenSslP; + + assert(!sockutil_connected(fd)); + + if (SwitchTraceIsActive) + fprintf(stderr, "Creating OpenSSL-based channel switch\n"); + + MALLOCVAR(chanSwitchOpenSslP); + + if (chanSwitchOpenSslP == NULL) + xmlrpc_asprintf(errorP, "unable to allocate memory for OpenSSL " + "channel switch descriptor."); + else { + TChanSwitch * chanSwitchP; + + chanSwitchOpenSslP->sslCtxP = sslCtxP; + + chanSwitchOpenSslP->listenFd = fd; + chanSwitchOpenSslP->userSuppliedFd = userSuppliedFd; + + sockutil_interruptPipeInit(&chanSwitchOpenSslP->interruptPipe, errorP); + + if (!*errorP) { + ChanSwitchCreate(&chanSwitchVtbl, chanSwitchOpenSslP, + &chanSwitchP); + if (*errorP) + sockutil_interruptPipeTerm(chanSwitchOpenSslP->interruptPipe); + + if (chanSwitchP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for " + "channel switch descriptor"); + else { + *chanSwitchPP = chanSwitchP; + *errorP = NULL; + } + } + if (*errorP) + free(chanSwitchOpenSslP); + } +} + + + +static void +switchCreateIpV4Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Create a POSIX-socket-based channel switch for an IPv4 endpoint. + + Set the socket's local address so that a subsequent "listen" will listen on + all interfaces, port number 'portNumber'. +-----------------------------------------------------------------------------*/ + int rc; + rc = socket(PF_INET, SOCK_STREAM, 0); + if (rc < 0) + xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + else { + int const socketFd = rc; + + sockutil_setSocketOptions(socketFd, errorP); + if (!*errorP) { + sockutil_bindSocketToPortInet(socketFd, portNumber, errorP); + + if (!*errorP) { + bool const userSupplied = false; + createChanSwitch(socketFd, userSupplied, sslCtxP, + chanSwitchPP, errorP); + } + } + if (*errorP) + close(socketFd); + } +} + + + +static void +switchCreateIpV6Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Same as switchCreateIpV4Port(), except for IPv6. +-----------------------------------------------------------------------------*/ + int rc; + rc = socket(PF_INET6, SOCK_STREAM, 0); + if (rc < 0) + xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + else { + int const socketFd = rc; + + sockutil_setSocketOptions(socketFd, errorP); + if (!*errorP) { + sockutil_bindSocketToPortInet6(socketFd, portNumber, errorP); + + if (!*errorP) { + bool const userSupplied = false; + createChanSwitch(socketFd, userSupplied, sslCtxP, + chanSwitchPP, errorP); + } + } + if (*errorP) + close(socketFd); + } +} + + + +void +ChanSwitchOpenSslCreate(int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + int rc; + rc = socket(protocolFamily, SOCK_STREAM, 0); + if (rc < 0) + xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + else { + int const socketFd = rc; + + if (SwitchTraceIsActive) + fprintf(stderr, "Created socket for protocol family %d\n", + protocolFamily); + + sockutil_setSocketOptions(socketFd, errorP); + if (!*errorP) { + sockutil_bindSocketToPort(socketFd, sockAddrP, sockAddrLen, + errorP); + + if (!*errorP) { + bool const userSupplied = false; + createChanSwitch(socketFd, userSupplied, sslCtxP, + chanSwitchPP, errorP); + } + } + if (*errorP) + close(socketFd); + } + +} + + + +void +ChanSwitchOpenSslCreateIpV4Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + switchCreateIpV4Port(portNumber, sslCtxP, chanSwitchPP, errorP); +} + + + +void +ChanSwitchOpenSslCreateIpV6Port(unsigned short const portNumber, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + switchCreateIpV6Port(portNumber, sslCtxP, chanSwitchPP, errorP); +} + + + +void +ChanSwitchOpenSslCreateFd(int const fd, + SSL_CTX * const sslCtxP, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + if (sockutil_connected(fd)) + xmlrpc_asprintf(errorP, + "Socket (file descriptor %d) is in connected " + "state.", fd); + else { + bool const userSupplied = true; + createChanSwitch(fd, userSupplied, sslCtxP, chanSwitchPP, errorP); + } +} + + diff --git a/trunk/lib/abyss/src/socket_openssl.h b/trunk/lib/abyss/src/socket_openssl.h new file mode 100644 index 000000000..a9662df65 --- /dev/null +++ b/trunk/lib/abyss/src/socket_openssl.h @@ -0,0 +1,14 @@ +#ifndef SOCKET_OPENSSL_H_INCLUDED +#define SOCKET_OPENSSL_H_INCLUDED + +#include + +#include + +void +SocketOpenSslInit(const char ** const errorP); + +void +SocketOpenSslTerm(void); + +#endif diff --git a/trunk/lib/abyss/src/socket_unix.c b/trunk/lib/abyss/src/socket_unix.c new file mode 100644 index 000000000..1848f6ac3 --- /dev/null +++ b/trunk/lib/abyss/src/socket_unix.c @@ -0,0 +1,873 @@ +/*============================================================================= + socket_unix.c +=============================================================================== + This is the implementation of TChanSwitch and TChannel (and + obsolete TSocket) for a standard Unix (POSIX) + stream socket -- what you create with a socket() C library call. +=============================================================================*/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_SYS_FILIO_H + #include +#endif + +#include "c_util.h" +#include "int.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" +#include "mallocvar.h" +#include "trace.h" +#include "chanswitch.h" +#include "channel.h" +#include "socket.h" +#include "netinet/in.h" +#include "xmlrpc-c/abyss.h" + +#include "sockutil.h" + +#include "socket_unix.h" + + + +struct socketUnix { +/*---------------------------------------------------------------------------- + The properties/state of a TChanSwitch or TChannel unique to the + Unix variety. +-----------------------------------------------------------------------------*/ + int fd; + /* File descriptor of the POSIX socket (such as is created by + socket() in the C library) for the socket. + */ + bool userSuppliedFd; + /* The file descriptor and associated POSIX socket belong to the + user; we did not create it. + */ + sockutil_InterruptPipe interruptPipe; + + bool isListening; + /* We've done a 'listen' on the socket */ +}; + + + +void +SocketUnixInit(const char ** const errorP) { + + *errorP = NULL; +} + + + +void +SocketUnixTerm(void) { + +} + + + +/*============================================================================= + TChannel +=============================================================================*/ + +static void +channelDestroy(TChannel * const channelP) { + + struct socketUnix * const socketUnixP = channelP->implP; + + sockutil_interruptPipeTerm(socketUnixP->interruptPipe); + + if (!socketUnixP->userSuppliedFd) + close(socketUnixP->fd); + + free(socketUnixP); +} + + + +static ChannelWriteImpl channelWrite; + +static void +channelWrite(TChannel * const channelP, + const unsigned char * const buffer, + uint32_t const len, + bool * const failedP) { + + struct socketUnix * const socketUnixP = channelP->implP; + + size_t bytesLeft; + bool error; + + assert(sizeof(size_t) >= sizeof(len)); + + for (bytesLeft = len, error = false; + bytesLeft > 0 && !error; + ) { + size_t const maxSend = (size_t)(-1) >> 1; + + ssize_t rc; + + // We'd like to use MSG_NOSIGNAL here, to prevent this send() from + // causing a SIGPIPE if the other end of the socket is closed, but + // MSG_NOSIGNAL is not standard enough. An SO_NOSIGPIPE socket + // option is another way, but even less standard. So instead, the + // thread simply must be set to ignore SIGPIPE. + + rc = send(socketUnixP->fd, &buffer[len-bytesLeft], + MIN(maxSend, bytesLeft), 0); + + if (ChannelTraceIsActive) { + if (rc < 0) + fprintf(stderr, "Abyss channel: send() failed. errno=%d (%s)", + errno, strerror(errno)); + else if (rc == 0) + fprintf(stderr, "Abyss channel: send() failed. " + "Socket closed.\n"); + else { + size_t const bytesTransferred = rc; + fprintf(stderr, "Abyss channel: sent %u bytes: '%.*s'\n", + (unsigned)bytesTransferred, + (int)(MIN(bytesTransferred, 4096)), + &buffer[len-bytesLeft]); + } + } + if (rc <= 0) + /* 0 means connection closed; < 0 means severe error */ + error = true; + else + bytesLeft -= rc; + } + *failedP = error; +} + + + +static ChannelReadImpl channelRead; + +static void +channelRead(TChannel * const channelP, + unsigned char * const buffer, + uint32_t const bufferSize, + uint32_t * const bytesReceivedP, + bool * const failedP) { + + struct socketUnix * const socketUnixP = channelP->implP; + + int rc; + rc = recv(socketUnixP->fd, buffer, bufferSize, 0); + + if (rc < 0) { + *failedP = true; + if (ChannelTraceIsActive) + fprintf(stderr, "Abyss channel: " + "Failed to receive data from socket. " + "recv() failed with errno %d (%s)\n", + errno, strerror(errno)); + } else { + *failedP = false; + *bytesReceivedP = rc; + + if (ChannelTraceIsActive) + fprintf(stderr, "Abyss channel: read %u bytes: '%.*s'\n", + *bytesReceivedP, (int)(*bytesReceivedP), buffer); + } +} + + + +static ChannelWaitImpl channelWait; + +static void +channelWait(TChannel * const channelP, + bool const waitForRead, + bool const waitForWrite, + uint32_t const timeoutMs, + bool * const readyToReadP, + bool * const readyToWriteP, + bool * const failedP) { +/*---------------------------------------------------------------------------- + Wait for the channel to be immediately readable or writable. + + Readable means there is at least one byte of data to read or the + partner has disconnected. Writable means the channel will take at + least one byte of data to send or the partner has disconnected. + + 'waitForRead' and 'waitForWrite' determine which of these + conditions for which to wait; if both are true, we wait for either + one. + + We return before the requested condition holds if 'timeoutMs' + milliseconds pass. timeoutMs == TIME_INFINITE means infinity. + + We return before the requested condition holds if the process receives + (and catches) a signal, but only if it receives that signal a certain + time after we start running. (That means this function isn't useful + for most purposes). + + Return *readyToReadP == true if the reason for returning is that + the channel is immediately readable. But only if 'readyToReadP' is + non-null. *readyToWriteP is analogous + for writable. Both may be true. + + Return *failedP true iff we fail to wait for the requested condition + because of some unusual problem and 'failedP' is non-null. Being + interrupted by a signal is not a failure. + + If one of these return value pointers is NULL, don't return that + value. +-----------------------------------------------------------------------------*/ + struct socketUnix * const socketUnixP = channelP->implP; + + /* Design note: some old systems may not have poll(). We're assuming + that we don't have to run on any such system. select() is more + universal, but can't handle a file descriptor with a high number. + + pselect() and ppoll() would allow us to be properly + interruptible by a signal -- we would add a signal mask to our + arguments. But ppoll() is fairly rare. pselect() is more + common, but in older Linux systems it doesn't actually work. + */ + bool readyToRead, readyToWrite, failed; + struct pollfd pollfds[2]; + int rc; + + pollfds[0].fd = socketUnixP->fd; + pollfds[0].events = + (waitForRead ? POLLIN : 0) | + (waitForWrite ? POLLOUT : 0); + + pollfds[1].fd = socketUnixP->interruptPipe.interrupteeFd; + pollfds[1].events = POLLIN; + + rc = poll(pollfds, ARRAY_SIZE(pollfds), + timeoutMs == TIME_INFINITE ? -1 : (int)timeoutMs); + + if (rc < 0) { + if (errno == EINTR) { + failed = false; + readyToRead = false; + readyToWrite = false; + } else { + failed = true; + readyToRead = false; /* quiet compiler warning */ + readyToWrite = false; /* quiet compiler warning */ + } + } else { + failed = false; + readyToRead = !!(pollfds[0].revents & POLLIN); + readyToWrite = !!(pollfds[0].revents & POLLOUT); + } + + if (failedP) + *failedP = failed; + if (readyToReadP) + *readyToReadP = readyToRead; + if (readyToWriteP) + *readyToWriteP = readyToWrite; +} + + + +static ChannelInterruptImpl channelInterrupt; + +static void +channelInterrupt(TChannel * const channelP) { +/*---------------------------------------------------------------------------- + Interrupt any waiting that a thread might be doing in channelWait() + now or in the future. + + TODO: Make a way to reset this so that future channelWait()s can once + again wait. +-----------------------------------------------------------------------------*/ + struct socketUnix * const socketUnixP = channelP->implP; + + sockutil_interruptPipeInterrupt(socketUnixP->interruptPipe); +} + + + +void +ChannelUnixGetPeerName(TChannel * const channelP, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP) { + + struct socketUnix * const socketUnixP = channelP->implP; + + sockutil_getPeerName(socketUnixP->fd, sockaddrPP, sockaddrLenP, errorP); +} + + + +static ChannelFormatPeerInfoImpl channelFormatPeerInfo; + +static void +channelFormatPeerInfo(TChannel * const channelP, + const char ** const peerStringP) { + + struct socketUnix * const socketUnixP = channelP->implP; + + sockutil_formatPeerInfo(socketUnixP->fd, peerStringP); +} + + + +static struct TChannelVtbl const channelVtbl = { + &channelDestroy, + &channelWrite, + &channelRead, + &channelWait, + &channelInterrupt, + &channelFormatPeerInfo, +}; + + + +static void +makeChannelInfo(struct abyss_unix_chaninfo ** const channelInfoPP, + struct sockaddr const peerAddr, + socklen_t const peerAddrLen, + const char ** const errorP) { + + struct abyss_unix_chaninfo * channelInfoP; + + MALLOCVAR(channelInfoP); + + if (channelInfoP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory"); + else { + channelInfoP->peerAddrLen = peerAddrLen; + channelInfoP->peerAddr = peerAddr; + + *errorP = NULL; + } + *channelInfoPP = channelInfoP; +} + + + +static void +makeChannelFromFd(int const fd, + TChannel ** const channelPP, + const char ** const errorP) { + + struct socketUnix * socketUnixP; + + MALLOCVAR(socketUnixP); + + if (socketUnixP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for Unix " + "channel descriptor"); + else { + TChannel * channelP; + + socketUnixP->fd = fd; + socketUnixP->userSuppliedFd = true; + + sockutil_interruptPipeInit(&socketUnixP->interruptPipe, errorP); + + if (!*errorP) { + ChannelCreate(&channelVtbl, socketUnixP, &channelP); + + if (channelP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for " + "channel descriptor."); + else { + *channelPP = channelP; + *errorP = NULL; + } + if (*errorP) + sockutil_interruptPipeTerm(socketUnixP->interruptPipe); + } + if (*errorP) + free(socketUnixP); + } +} + + + +void +ChannelUnixCreateFd(int const fd, + TChannel ** const channelPP, + struct abyss_unix_chaninfo ** const channelInfoPP, + const char ** const errorP) { + + if (!sockutil_connected(fd)) + xmlrpc_asprintf(errorP, "Socket on file descriptor %d is not in " + "connected state.", fd); + else { + struct sockaddr * peerAddrP; + size_t peerAddrLen; + const char * error; + + sockutil_getPeerName(fd, &peerAddrP, &peerAddrLen, &error); + + if (error) { + xmlrpc_asprintf(errorP, "Failed to get identity of client. %s", + error); + xmlrpc_strfree(error); + } else { + makeChannelInfo(channelInfoPP, *peerAddrP, peerAddrLen, errorP); + if (!*errorP) { + makeChannelFromFd(fd, channelPP, errorP); + + if (*errorP) + free(*channelInfoPP); + } + free(peerAddrP); + } + } +} + + + +/*============================================================================= + TChanSwitch +=============================================================================*/ + +static SwitchDestroyImpl chanSwitchDestroy; + +static void +chanSwitchDestroy(TChanSwitch * const chanSwitchP) { + + struct socketUnix * const socketUnixP = chanSwitchP->implP; + + sockutil_interruptPipeTerm(socketUnixP->interruptPipe); + + if (!socketUnixP->userSuppliedFd) + close(socketUnixP->fd); + + free(socketUnixP); +} + + + +static SwitchListenImpl chanSwitchListen; + +static void +chanSwitchListen(TChanSwitch * const chanSwitchP, + uint32_t const backlog, + const char ** const errorP) { + + struct socketUnix * const socketUnixP = chanSwitchP->implP; + + if (socketUnixP->isListening) + xmlrpc_asprintf(errorP, "Channel switch is already listening"); + else { + sockutil_listen(socketUnixP->fd, backlog, errorP); + + if (!*errorP) + socketUnixP->isListening = true; + } +} + + + +static void +createChannelForAccept(int const acceptedFd, + struct sockaddr const peerAddr, + TChannel ** const channelPP, + void ** const channelInfoPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Make a channel object (TChannel) out of a socket just created by + accept() on a listening socket -- i.e. a socket for a client connection. + + 'acceptedFd' is the file descriptor of the socket. + + 'peerAddr' is the address of the client, from accept(). +-----------------------------------------------------------------------------*/ + struct abyss_unix_chaninfo * channelInfoP; + + makeChannelInfo(&channelInfoP, peerAddr, sizeof(peerAddr), errorP); + if (!*errorP) { + struct socketUnix * acceptedSocketP; + + MALLOCVAR(acceptedSocketP); + + if (!acceptedSocketP) + xmlrpc_asprintf(errorP, "Unable to allocate memory"); + else { + acceptedSocketP->fd = acceptedFd; + acceptedSocketP->userSuppliedFd = false; + + sockutil_interruptPipeInit( + &acceptedSocketP->interruptPipe, errorP); + + if (!*errorP) { + TChannel * channelP; + + ChannelCreate(&channelVtbl, acceptedSocketP, &channelP); + if (!channelP) + xmlrpc_asprintf(errorP, + "Failed to create TChannel object."); + else { + *errorP = NULL; + *channelPP = channelP; + *channelInfoPP = channelInfoP; + } + if (*errorP) + sockutil_interruptPipeTerm(acceptedSocketP->interruptPipe); + } + if (*errorP) + free(acceptedSocketP); + } + if (*errorP) + free(channelInfoP); + } +} + + + +static SwitchAcceptImpl chanSwitchAccept; + +static void +chanSwitchAccept(TChanSwitch * const chanSwitchP, + TChannel ** const channelPP, + void ** const channelInfoPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Accept a connection via the channel switch *chanSwitchP. Return as + *channelPP the channel for the accepted connection. + + If no connection is waiting at *chanSwitchP, wait until one is. + + If we receive a signal while waiting, return immediately with + *channelPP == NULL. +-----------------------------------------------------------------------------*/ + struct socketUnix * const listenSocketP = chanSwitchP->implP; + + bool interrupted; + TChannel * channelP; + + interrupted = false; /* Haven't been interrupted yet */ + channelP = NULL; /* No connection yet */ + *errorP = NULL; /* No error yet */ + + while (!channelP && !*errorP && !interrupted) { + + sockutil_waitForConnection(listenSocketP->fd, + listenSocketP->interruptPipe, + &interrupted, errorP); + + if (!*errorP && !interrupted) { + struct sockaddr peerAddr; + socklen_t peerAddrLen; + int rc; + + peerAddrLen = sizeof(peerAddr); /* initial value */ + + rc = accept(listenSocketP->fd, &peerAddr, &peerAddrLen); + + if (rc >= 0) { + int const acceptedFd = rc; + + createChannelForAccept(acceptedFd, peerAddr, + &channelP, channelInfoPP, errorP); + + if (*errorP) + close(acceptedFd); + } else if (errno == EINTR) + interrupted = true; + else + xmlrpc_asprintf(errorP, "accept() failed, errno = %d (%s)", + errno, strerror(errno)); + } + } + *channelPP = channelP; +} + + + +static SwitchInterruptImpl chanSwitchInterrupt; + +static void +chanSwitchInterrupt(TChanSwitch * const chanSwitchP) { +/*---------------------------------------------------------------------------- + Interrupt any waiting that a thread might be doing in chanSwitchAccept() + now or in the future. + + TODO: Make a way to reset this so that future chanSwitchAccept()s can once + again wait. +-----------------------------------------------------------------------------*/ + struct socketUnix * const listenSocketP = chanSwitchP->implP; + + unsigned char const zero[1] = {0u}; + + write(listenSocketP->interruptPipe.interruptorFd, &zero, sizeof(zero)); +} + + + +static struct TChanSwitchVtbl const chanSwitchVtbl = { + &chanSwitchDestroy, + &chanSwitchListen, + &chanSwitchAccept, + &chanSwitchInterrupt, +}; + + + +static void +createChanSwitch(int const fd, + bool const userSuppliedFd, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Create a channel switch from the bound, but not yet listening, socket + with file descriptor 'fd'. + + Return the handle of the new channel switch as *chanSwitchPP. + + 'userSuppliedFd' means the file descriptor (socket) shall _not_ belong to + the channel switch, so destroying the channel switch does not close it. +-----------------------------------------------------------------------------*/ + struct socketUnix * socketUnixP; + + assert(!sockutil_connected(fd)); + + if (SwitchTraceIsActive) + fprintf(stderr, "Creating Unix listen-socket based channel switch\n"); + + MALLOCVAR(socketUnixP); + + if (socketUnixP == NULL) + xmlrpc_asprintf(errorP, "unable to allocate memory for Unix " + "channel switch descriptor."); + else { + TChanSwitch * chanSwitchP; + + socketUnixP->fd = fd; + socketUnixP->userSuppliedFd = userSuppliedFd; + socketUnixP->isListening = false; + + sockutil_interruptPipeInit(&socketUnixP->interruptPipe, errorP); + + if (!*errorP) { + ChanSwitchCreate(&chanSwitchVtbl, socketUnixP, &chanSwitchP); + if (*errorP) + sockutil_interruptPipeTerm(socketUnixP->interruptPipe); + + if (chanSwitchP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for " + "channel switch descriptor"); + else { + *chanSwitchPP = chanSwitchP; + *errorP = NULL; + } + } + if (*errorP) + free(socketUnixP); + } +} + + + +static void +switchCreateIpV4Port(unsigned short const portNumber, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Create a POSIX-socket-based channel switch for an IPv4 endpoint. + + Set the socket's local address so that a subsequent "listen" will listen on + all interfaces, port number 'portNumber'. +-----------------------------------------------------------------------------*/ + int rc; + rc = socket(PF_INET, SOCK_STREAM, 0); + if (rc < 0) + xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + else { + int const socketFd = rc; + + sockutil_setSocketOptions(socketFd, errorP); + if (!*errorP) { + sockutil_bindSocketToPortInet(socketFd, portNumber, errorP); + + if (!*errorP) { + bool const userSupplied = false; + createChanSwitch(socketFd, userSupplied, chanSwitchPP, errorP); + } + } + if (*errorP) + close(socketFd); + } +} + + + +static void +switchCreateIpV6Port(unsigned short const portNumber, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Same as switchCreateIpV4Port(), except for IPv6. +-----------------------------------------------------------------------------*/ + int rc; + rc = socket(PF_INET6, SOCK_STREAM, 0); + if (rc < 0) + xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + else { + int const socketFd = rc; + + sockutil_setSocketOptions(socketFd, errorP); + if (!*errorP) { + sockutil_bindSocketToPortInet6(socketFd, portNumber, errorP); + + if (!*errorP) { + bool const userSupplied = false; + createChanSwitch(socketFd, userSupplied, chanSwitchPP, errorP); + } + } + if (*errorP) + close(socketFd); + } +} + + + +void +ChanSwitchUnixCreate(unsigned short const portNumber, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + switchCreateIpV4Port(portNumber, chanSwitchPP, errorP); +} + + + +void +ChanSwitchUnixCreate2(int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + int rc; + rc = socket(protocolFamily, SOCK_STREAM, 0); + if (rc < 0) + xmlrpc_asprintf(errorP, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + else { + int const socketFd = rc; + + if (SwitchTraceIsActive) + fprintf(stderr, "Created socket for protocol family %d\n", + protocolFamily); + + sockutil_setSocketOptions(socketFd, errorP); + if (!*errorP) { + sockutil_bindSocketToPort(socketFd, sockAddrP, sockAddrLen, + errorP); + + if (!*errorP) { + bool const userSupplied = false; + createChanSwitch(socketFd, userSupplied, chanSwitchPP, errorP); + } + } + if (*errorP) + close(socketFd); + } + +} + + + +void +ChanSwitchUnixCreateIpV6Port(unsigned short const portNumber, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + switchCreateIpV6Port(portNumber, chanSwitchPP, errorP); +} + + + +void +ChanSwitchUnixCreateFd(int const fd, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + if (sockutil_connected(fd)) + xmlrpc_asprintf(errorP, + "Socket (file descriptor %d) is in connected " + "state.", fd); + else { + bool const userSupplied = true; + createChanSwitch(fd, userSupplied, chanSwitchPP, errorP); + } +} + + + +void +ChanSwitchUnixGetListenName(TChanSwitch * const chanSwitchP, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + The primary case where this is useful is where the user created the channel + switch with a parameters telling the OS to pick the TCP port. In that + case, this is the only way the user can find out what port the OS picked. +-----------------------------------------------------------------------------*/ + struct socketUnix * const socketUnixP = chanSwitchP->implP; + + if (!socketUnixP->isListening) + xmlrpc_asprintf(errorP, "Channel Switch is not listening"); + else + sockutil_getSockName(socketUnixP->fd, + sockaddrPP, sockaddrLenP, errorP); +} + + + +/*============================================================================= + obsolete TSocket interface +=============================================================================*/ + + +void +SocketUnixCreateFd(int const fd, + TSocket ** const socketPP) { + + TSocket * socketP; + const char * error; + + if (sockutil_connected(fd)) { + TChannel * channelP; + struct abyss_unix_chaninfo * channelInfoP; + ChannelUnixCreateFd(fd, &channelP, &channelInfoP, &error); + if (!error) + SocketCreateChannel(channelP, channelInfoP, &socketP); + } else { + TChanSwitch * chanSwitchP; + ChanSwitchUnixCreateFd(fd, &chanSwitchP, &error); + if (!error) + SocketCreateChanSwitch(chanSwitchP, &socketP); + } + if (error) { + *socketPP = NULL; + xmlrpc_strfree(error); + } else + *socketPP = socketP; +} + + + diff --git a/trunk/lib/abyss/src/socket_unix.h b/trunk/lib/abyss/src/socket_unix.h new file mode 100644 index 000000000..40094e306 --- /dev/null +++ b/trunk/lib/abyss/src/socket_unix.h @@ -0,0 +1,14 @@ +#ifndef SOCKET_UNIX_H_INCLUDED +#define SOCKET_UNIX_H_INCLUDED + +#include + +#include + +void +SocketUnixInit(const char ** const errorP); + +void +SocketUnixTerm(void); + +#endif diff --git a/trunk/lib/abyss/src/socket_win.c b/trunk/lib/abyss/src/socket_win.c new file mode 100644 index 000000000..3204a60c1 --- /dev/null +++ b/trunk/lib/abyss/src/socket_win.c @@ -0,0 +1,1083 @@ +/*============================================================================= + socket_win.c +=============================================================================== + This is the implementation of TChanSwitch and TChannel + for a Winsock socket. +=============================================================================*/ + +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" +#include "mallocvar.h" +#include "trace.h" +#include "chanswitch.h" +#include "channel.h" +#include "socket.h" +#include "xmlrpc-c/abyss.h" + +#include "socket_win.h" + +#ifndef socklen_t +typedef int socklen_t; +#endif + +/* ============================================================= + Provided nice error strings, NOT available in system errors. + ============================================================= */ + +typedef struct tagSOCKERRS { + int err; // WSAGetLastError() value + char * desc; // description of error +} SOCKERR; + +/* could/should perhaps be by the actual call, + but for now, just one big list, with some repeats +*/ + +SOCKERR sSockErr[] = { + { WSANOTINITIALISED, + "WSANOTINITIALISED - " + "WSAStartup must be called before using this function." }, + { WSAENETDOWN, + "WSAENETDOWN - " + "The network subsystem has failed." }, + { WSAEACCES, + "WSAEACCES - " + "Attempt to connect datagram socket to broadcast address failed " + "because setsockopt option SO_BROADCAST is not enabled." }, + { WSAEADDRINUSE, + "WSAEADDRINUSE - " + "A process on the computer is already bound to the same fully-qualified " + "address and the socket has not been marked to allow address reuse with " + "SO_REUSEADDR. For example, the IP address and port are bound in the " + "af_inet case). (See the SO_REUSEADDR socket option under setsockopt.)" }, + { WSAEADDRNOTAVAIL, + "WSAEADDRNOTAVAIL - " + "The specified address is not a valid address for this computer." }, + { WSAEFAULT, + "WSAEFAULT - " + "The name or namelen parameter is not a valid part of the user " + "address space, the namelen parameter is too small, the name parameter " + "contains an incorrect address format for the associated " + "address family, or the first two bytes of the memory block " + "specified by name does not match the address family associated with " + "the socket descriptor s." }, + { WSAEINPROGRESS, + "WSAEINPROGRESS - " + "A blocking Windows Sockets 1.1 call is in progress, or the " + "service provider is still processing a callback function." }, + { WSAEINVAL, + "WSAEINVAL - " + "The socket is already bound to an address." }, + { WSAENOBUFS, + "WSAENOBUFS - " + "Not enough buffers available, too many connections." }, + { WSAENOTSOCK, + "WSAENOTSOCK - " + "The descriptor is not a socket." }, + + // setsocketopt + { WSAENETRESET, + "WSAENETRESET - " + "Connection has timed out when SO_KEEPALIVE is set." }, + { WSAENOPROTOOPT, + "WSAENOPROTOOPT - " + "The option is unknown or the specified provider " + "or socket is not capable of implementing it " + "(see SO_GROUP_PRIORITY limitations)." }, + { WSAENOTCONN, + "WSAENOTCONN - " + "Connection has been reset when SO_KEEPALIVE is set." }, + + // WSAStartup + { WSASYSNOTREADY, + "WSASYSNOTREADY - " + "The underlying network subsystem is not ready for " + "network communication." }, + { WSAVERNOTSUPPORTED, + "WSAVERNOTSUPPORTED - " + "The version of Windows Sockets function requested is not provided " + "by this particular Windows Sockets implementation." }, + { WSAEINPROGRESS, + "WSAEINPROGRESS - " + "A blocking Windows Sockets 1.1 operation is in progress." }, + { WSAEPROCLIM, + "WSAEPROCLIM - " + "Limit on the number of tasks allowed by the Windows Sockets " + "implementation has been reached." }, + { WSAEFAULT, + "WSAEFAULT - " + "The lpWSAData is not a valid pointer." }, + // listen + { WSANOTINITIALISED, + "WSANOTINITIALISED - " + "A successful WSAStartup call must occur before using this function." }, + { WSAENETDOWN, + "WSAENETDOWN - " + "The network subsystem has failed." }, + { WSAEADDRINUSE, + "WSAEADDRINUSE - " + "The socket's local address is already in use and the socket " + "was not marked to allow address reuse with SO_REUSEADDR. " + "This error usually occurs during execution of the bind function, " + "but could be delayed until this function if the bind was to " + "a partially wildcard address (involving ADDR_ANY) " + "and if a specific address needs to be committed at the time " + "of this function call." }, + { WSAEINPROGRESS, + "WSAEINPROGRESS - " + "A blocking Windows Sockets 1.1 call is in progress, " + "or the service provider is still processing a callback function." }, + { WSAEINVAL, + "WSAEINVAL - " + "The socket has not been bound with bind." }, + { WSAEISCONN, + "WSAEISCONN - " + "The socket is already connected." }, + { WSAEMFILE, + "WSAEMFILE - " + "No more socket descriptors are available." }, + { WSAENOBUFS, + "WSAENOBUFS - " + "No buffer space is available." }, + { WSAENOTSOCK, + "WSAENOTSOCK - " + "The descriptor is not a socket." }, + { WSAEOPNOTSUPP, + "WSAEOPNOTSUPP - " + "The referenced socket is not of a type that has a listen operation." }, + + // getpeername + { WSANOTINITIALISED, + "WSANOTINITIALISED - " + "A successful WSAStartup call must occur before using this function." }, + { WSAENETDOWN, + "WSAENETDOWN - " + "The network subsystem has failed." }, + { WSAEFAULT, + "WSAEFAULT - " + "The name or the namelen parameter is not a valid part of the " + "user address space, or the namelen parameter is too small." }, + { WSAEINPROGRESS, + "WSAEINPROGRESS - " + "A blocking Windows Sockets 1.1 call is in progress, " + "or the service provider is still processing a callback function." }, + { WSAENOTCONN, + "WSAENOTCONN - " + "The socket is not connected." }, + { WSAENOTSOCK, + "WSAENOTSOCK - " + "The descriptor is not a socket." }, + + // accept + { WSANOTINITIALISED, + "WSANOTINITIALISED - " + "A successful WSAStartup call must occur before using this function." }, + { WSAENETDOWN, + "WSAENETDOWN - " + "The network subsystem has failed." }, + { WSAEFAULT, + "WSAEFAULT - " + "The addrlen parameter is too small or addr is not a valid part " + "of the user address space." }, + { WSAEINTR, + "WSAEINTR - " + "A blocking Windows Sockets 1.1 call was canceled through " + "WSACancelBlockingCall." }, + { WSAEINPROGRESS, + "WSAEINPROGRESS - " + "A blocking Windows Sockets 1.1 call is in progress, " + "or the service provider is still processing a callback function." }, + { WSAEINVAL, + "WSAEINVAL - " + "The listen function was not invoked prior to accept." }, + { WSAEMFILE, + "WSAEMFILE - " + "The queue is nonempty upon entry to accept and " + "there are no descriptors available." }, + { WSAENOBUFS, + "WSAENOBUFS - " + "No buffer space is available." }, + { WSAENOTSOCK, + "WSAENOTSOCK - " + "The descriptor is not a socket." }, + { WSAEOPNOTSUPP, + "WSAEOPNOTSUPP - " + "The referenced socket is not a type that offers connection-oriented " + "service." }, + { WSAEWOULDBLOCK, + "WSAEWOULDBLOCK - " + "The socket is marked as nonblocking and no connections are present " + "to be accepted." }, + + /* must be last entry */ + { 0, 0 } +}; + + + +static const char * +getWSAError(int const wsaErrno) { + + SOCKERR * pseP; + + pseP = &sSockErr[0]; // initial value + + while (pseP->desc) { + if (pseP->err == wsaErrno) + return pseP->desc; + + ++pseP; + } + + return "(no description available)"; +} + + + +struct socketWin { +/*---------------------------------------------------------------------------- + The properties/state of a TSocket unique to a Unix TSocket. +-----------------------------------------------------------------------------*/ + SOCKET winsock; + bool userSuppliedWinsock; + /* 'socket' was supplied by the user; it belongs to him */ + HANDLE interruptEvent; +}; + +static +bool +connected(SOCKET const fd) { +/*---------------------------------------------------------------------------- + Return TRUE iff the socket on file descriptor 'fd' is in the connected + state. + If 'fd' does not identify a stream socket or we are unable to determine + the state of the stream socket, the answer is "false". +-----------------------------------------------------------------------------*/ + bool connected; + struct sockaddr sockaddr; + socklen_t nameLen; + int rc; + + nameLen = sizeof(sockaddr); + + rc = getpeername(fd, &sockaddr, &nameLen); + + if (rc == 0) + connected = TRUE; + else + connected = FALSE; + + return connected; +} + + + +void +SocketWinInit(const char ** const errorP) { + + WORD wVersionRequested; + WSADATA wsaData; + int err; + + wVersionRequested = MAKEWORD(1, 0); + + err = WSAStartup(wVersionRequested, &wsaData); + + if (err != 0) { + int const lastError = WSAGetLastError(); + xmlrpc_asprintf(errorP, "WSAStartup() faild with error %d (%s)", + lastError, getWSAError(lastError)); + } else + *errorP = NULL; +} + + + +void +SocketWinTerm(void) { + + WSACleanup(); +} + + + +/*============================================================================= + TChannel +=============================================================================*/ + +static ChannelDestroyImpl channelDestroy; + +static void +channelDestroy(TChannel * const channelP) { + + struct socketWin * const socketWinP = channelP->implP; + + if (!socketWinP->userSuppliedWinsock) + closesocket(socketWinP->winsock); + + CloseHandle(socketWinP->interruptEvent); + + free(socketWinP); +} + + + +static ChannelWriteImpl channelWrite; + +static void +channelWrite(TChannel * const channelP, + const unsigned char * const buffer, + uint32_t const len, + bool * const failedP) { + + struct socketWin * const socketWinP = channelP->implP; + + size_t bytesLeft; + bool error; + + assert(sizeof(size_t) >= sizeof(len)); + + for (bytesLeft = len, error = FALSE; + bytesLeft > 0 && !error; + ) { + size_t const maxSend = (size_t)(-1) >> 1; + + int rc; + + rc = send(socketWinP->winsock, &buffer[len-bytesLeft], + MIN(maxSend, bytesLeft), 0); + + if (rc <= 0) + /* 0 means connection closed; < 0 means severe error */ + error = TRUE; + else + bytesLeft -= rc; + } + *failedP = error; +} + + + +static ChannelReadImpl channelRead; + +static void +channelRead(TChannel * const channelP, + unsigned char * const buffer, + uint32_t const bufferSize, + uint32_t * const bytesReceivedP, + bool * const failedP) { + + struct socketWin * const socketWinP = channelP->implP; + + int rc; + rc = recv(socketWinP->winsock, buffer, bufferSize, 0); + + if (rc < 0) { + *failedP = TRUE; + } else { + *failedP = FALSE; + *bytesReceivedP = rc; + } +} + + + +static ChannelWaitImpl channelWait; + +static void +channelWait(TChannel * const channelP, + bool const waitForRead, + bool const waitForWrite, + uint32_t const timems, + bool * const readyToReadP, + bool * const readyToWriteP, + bool * const failedP) { + + struct socketWin * const socketWinP = channelP->implP; + + fd_set rfds, wfds; + TIMEVAL tv; + bool failed, readRdy, writeRdy, timedOut; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + if (waitForRead) + FD_SET(socketWinP->winsock, &rfds); + + if (waitForWrite) + FD_SET(socketWinP->winsock, &wfds); + + tv.tv_sec = timems / 1000; + tv.tv_usec = timems % 1000; + + for (failed = FALSE, readRdy = FALSE, writeRdy = FALSE, timedOut = FALSE; + !failed && !readRdy && !writeRdy && !timedOut; + ) { + + int rc; + + rc = select(socketWinP->winsock + 1, &rfds, &wfds, NULL, + (timems == TIME_INFINITE ? NULL : &tv)); + + switch(rc) { + case 0: + timedOut = TRUE; + break; + case -1: /* socket error */ + if (WSAGetLastError() != WSAEINTR) + failed = TRUE; + break; + default: + if (FD_ISSET(socketWinP->winsock, &rfds)) + readRdy = TRUE; + if (FD_ISSET(socketWinP->winsock, &wfds)) + writeRdy = TRUE; + } + } + + if (failedP) + *failedP = failed; + if (readyToReadP) + *readyToReadP = readRdy; + if (readyToWriteP) + *readyToWriteP = writeRdy; +} + + + +static ChannelInterruptImpl channelInterrupt; + +static void +channelInterrupt(TChannel * const channelP) { +/*---------------------------------------------------------------------------- + Interrupt any waiting that a thread might be doing in channelWait() + now or in the future. + + Actually, this is just a no-op because we don't yet know how to + accomplish that. (But we could probably do it the same way + chanSwitchInterrupt() works -- no one has needed it enough yet to do that + work). +-----------------------------------------------------------------------------*/ + +} + + + +void +ChannelWinGetPeerName(TChannel * const channelP, + struct sockaddr_in * const inAddrP, + const char ** const errorP) { + + struct socketWin * const socketWinP = channelP->implP; + + socklen_t addrlen; + int rc; + struct sockaddr sockAddr; + + addrlen = sizeof(sockAddr); + + rc = getpeername(socketWinP->winsock, &sockAddr, &addrlen); + + if (rc != 0) { + int const lastError = WSAGetLastError(); + xmlrpc_asprintf(errorP, "getpeername() failed. WSA error = %d (%s)", + lastError, getWSAError(lastError)); + } else { + if (addrlen != sizeof(sockAddr)) + xmlrpc_asprintf(errorP, "getpeername() returned a socket address " + "of the wrong size: %u. Expected %u", + addrlen, sizeof(sockAddr)); + else { + if (sockAddr.sa_family != AF_INET) + xmlrpc_asprintf(errorP, + "Socket does not use the Inet (IP) address " + "family. Instead it uses family %d", + sockAddr.sa_family); + else { + *inAddrP = *(struct sockaddr_in *)&sockAddr; + + *errorP = NULL; + } + } + } +} + + + +static ChannelFormatPeerInfoImpl channelFormatPeerInfo; + +static void +channelFormatPeerInfo(TChannel * const channelP, + const char ** const peerStringP) { + + struct socketWin * const socketWinP = channelP->implP; + + struct sockaddr sockaddr; + socklen_t sockaddrLen; + int rc; + + sockaddrLen = sizeof(sockaddr); + + rc = getpeername(socketWinP->winsock, &sockaddr, &sockaddrLen); + + if (rc != 0) { + int const lastError = WSAGetLastError(); + xmlrpc_asprintf(peerStringP, "?? getpeername() failed. " + "WSAERROR %d (%s)", + lastError, getWSAError(lastError)); + } else { + switch (sockaddr.sa_family) { + case AF_INET: { + struct sockaddr_in * const sockaddrInP = + (struct sockaddr_in *) &sockaddr; + if (sockaddrLen < sizeof(*sockaddrInP)) + xmlrpc_asprintf(peerStringP, "??? getpeername() returned " + "the wrong size"); + else { + unsigned char * const ipaddr = (unsigned char *) + &sockaddrInP->sin_addr.s_addr; + xmlrpc_asprintf(peerStringP, "%u.%u.%u.%u:%hu", + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + sockaddrInP->sin_port); + } + } break; + default: + xmlrpc_asprintf(peerStringP, "??? AF=%u", sockaddr.sa_family); + } + } +} + + + +static struct TChannelVtbl const channelVtbl = { + &channelDestroy, + &channelWrite, + &channelRead, + &channelWait, + &channelInterrupt, + &channelFormatPeerInfo, +}; + + + +static void +makeChannelFromWinsock(SOCKET const winsock, + TChannel ** const channelPP, + const char ** const errorP) { + + struct socketWin * socketWinP; + + MALLOCVAR(socketWinP); + + if (socketWinP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for Windows " + "socket descriptor"); + else { + TChannel * channelP; + + socketWinP->winsock = winsock; + socketWinP->userSuppliedWinsock = TRUE; + socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + ChannelCreate(&channelVtbl, socketWinP, &channelP); + + if (channelP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for " + "channel descriptor."); + else { + *channelPP = channelP; + *errorP = NULL; + } + if (*errorP) { + CloseHandle(socketWinP->interruptEvent); + free(socketWinP); + } + } +} + + + +static void +makeChannelInfo(struct abyss_win_chaninfo ** const channelInfoPP, + struct sockaddr const peerAddr, + socklen_t const peerAddrLen, + const char ** const errorP) { + + struct abyss_win_chaninfo * channelInfoP; + + MALLOCVAR(channelInfoP); + + if (channelInfoP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory"); + else { + channelInfoP->peerAddrLen = peerAddrLen; + channelInfoP->peerAddr = peerAddr; + + *channelInfoPP = channelInfoP; + + *errorP = NULL; + } +} + + + +void +ChannelWinCreateWinsock(SOCKET const fd, + TChannel ** const channelPP, + struct abyss_win_chaninfo ** const channelInfoPP, + const char ** const errorP) { + + struct sockaddr peerAddr; + socklen_t peerAddrLen; + int rc; + + peerAddrLen = sizeof(peerAddr); + + rc = getpeername(fd, &peerAddr, &peerAddrLen); + + if (rc != 0) { + int const lastError = WSAGetLastError(); + if (lastError == WSAENOTCONN) { + /* NOTE: This specific string 'not in connected' is + required by one of the rpctest suite items, in abyss.c + (line 186), hence the separation of the error messages + in this case ... + */ + xmlrpc_asprintf(errorP, "Socket on file descriptor %d " + "is not in connected state. WSAERROR = %d (%s)", + fd, lastError, getWSAError(lastError)); + } else + xmlrpc_asprintf(errorP, "getpeername() failed. WSAERROR = %d (%s)", + lastError, getWSAError(lastError)); + } else { + makeChannelInfo(channelInfoPP, peerAddr, peerAddrLen, errorP); + if (!*errorP) { + makeChannelFromWinsock(fd, channelPP, errorP); + + if (*errorP) + free(*channelInfoPP); + } + } +} + + +/*============================================================================= + TChanSwitch +=============================================================================*/ + +static SwitchDestroyImpl chanSwitchDestroy; + +void +chanSwitchDestroy(TChanSwitch * const chanSwitchP) { + + struct socketWin * const socketWinP = chanSwitchP->implP; + + if (!socketWinP->userSuppliedWinsock) + closesocket(socketWinP->winsock); + + CloseHandle(socketWinP->interruptEvent); + + free(socketWinP); +} + + + +static SwitchListenImpl chanSwitchListen; + +static void +chanSwitchListen(TChanSwitch * const chanSwitchP, + uint32_t const backlog, + const char ** const errorP) { + + struct socketWin * const socketWinP = chanSwitchP->implP; + + int32_t const minus1 = -1; + + int rc; + + /* Disable the Nagle algorithm to make persistant connections faster */ + + setsockopt(socketWinP->winsock, IPPROTO_TCP, TCP_NODELAY, + (const char *)&minus1, sizeof(minus1)); + + rc = listen(socketWinP->winsock, backlog); + + if (rc != 0) { + int const lastError = WSAGetLastError(); + xmlrpc_asprintf(errorP, "setsockopt() failed with WSAERROR %d (%s)", + lastError, getWSAError(lastError)); + } else + *errorP = NULL; +} + + + +static void +createChannelForAccept(int const acceptedWinsock, + struct sockaddr const peerAddr, + TChannel ** const channelPP, + void ** const channelInfoPP, + const char ** const errorP) { + + struct abyss_win_chaninfo * channelInfoP; + makeChannelInfo(&channelInfoP, peerAddr, sizeof(peerAddr), errorP); + if (!*errorP) { + struct socketWin * acceptedSocketP; + + MALLOCVAR(acceptedSocketP); + + if (!acceptedSocketP) + xmlrpc_asprintf(errorP, "Unable to allocate memory"); + else { + TChannel * channelP; + + acceptedSocketP->winsock = acceptedWinsock; + acceptedSocketP->userSuppliedWinsock = FALSE; + acceptedSocketP->interruptEvent = + CreateEvent(NULL, FALSE, FALSE, NULL); + + ChannelCreate(&channelVtbl, acceptedSocketP, &channelP); + if (!channelP) + xmlrpc_asprintf(errorP, + "Failed to create TChannel object."); + else { + *errorP = NULL; + *channelPP = channelP; + *channelInfoPP = channelInfoP; + } + if (*errorP) { + CloseHandle(acceptedSocketP->interruptEvent); + free(acceptedSocketP); + } + } + } +} + + + +static SwitchAcceptImpl chanSwitchAccept; + +static void +chanSwitchAccept(TChanSwitch * const chanSwitchP, + TChannel ** const channelPP, + void ** const channelInfoPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Accept a connection via the channel switch *chanSwitchP. Return as + *channelPP the channel for the accepted connection. + + If no connection is waiting at *chanSwitchP, wait until one is. + + If we receive a signal while waiting, return immediately with + *channelPP == NULL. +-----------------------------------------------------------------------------*/ + struct socketWin * const listenSocketP = chanSwitchP->implP; + HANDLE acceptEvent = WSACreateEvent(); + bool interrupted; + TChannel * channelP; + + interrupted = FALSE; /* Haven't been interrupted yet */ + channelP = NULL; /* No connection yet */ + *errorP = NULL; /* No error yet */ + + WSAEventSelect(listenSocketP->winsock, acceptEvent, + FD_ACCEPT | FD_CLOSE | FD_READ); + + while (!channelP && !*errorP && !interrupted) { + HANDLE interrupts[2] = {acceptEvent, listenSocketP->interruptEvent}; + int rc; + struct sockaddr peerAddr; + socklen_t size = sizeof(peerAddr); + + rc = WaitForMultipleObjects(2, interrupts, FALSE, INFINITE); + if (WAIT_OBJECT_0 + 1 == rc) { + interrupted = TRUE; + continue; + }; + + rc = accept(listenSocketP->winsock, &peerAddr, &size); + + if (rc >= 0) { + int const acceptedWinsock = rc; + + createChannelForAccept(acceptedWinsock, peerAddr, + &channelP, channelInfoPP, errorP); + + if (*errorP) + closesocket(acceptedWinsock); + } else { + int const lastError = WSAGetLastError(); + + if (lastError == WSAEINTR) + interrupted = TRUE; + else + xmlrpc_asprintf(errorP, + "accept() failed, WSA error = %d (%s)", + lastError, getWSAError(lastError)); + } + } + *channelPP = channelP; + CloseHandle(acceptEvent); +} + + + +static SwitchInterruptImpl chanSwitchInterrupt; + +static void +chanSwitchInterrupt(TChanSwitch * const chanSwitchP) { +/*---------------------------------------------------------------------------- + Interrupt any waiting that a thread might be doing in chanSwitchAccept() + now or in the future. +-----------------------------------------------------------------------------*/ + struct socketWin * const listenSocketP = chanSwitchP->implP; + + SetEvent(listenSocketP->interruptEvent); +} + + + +static struct TChanSwitchVtbl const chanSwitchVtbl = { + &chanSwitchDestroy, + &chanSwitchListen, + &chanSwitchAccept, + &chanSwitchInterrupt, +}; + + + +static void +setSocketOptions(SOCKET const fd, + const char ** const errorP) { + + int32_t const n = 1; + + int rc; + + rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof(n)); + + if (rc != 0) { + int const lastError = WSAGetLastError(); + xmlrpc_asprintf(errorP, "Failed to set socket options. " + "setsockopt() failed with WSAERROR %d (%s)", + lastError, getWSAError(lastError)); + } else + *errorP = NULL; +} + + + +void +bindSocketToPort(SOCKET const winsock, + struct in_addr * const addrP, + uint16_t const portNumber, + const char ** const errorP) { + + struct sockaddr_in name; + int rc; + + ZeroMemory(&name, sizeof(name)); + name.sin_family = AF_INET; + name.sin_port = htons(portNumber); + if (addrP) + name.sin_addr = *addrP; + + rc = bind(winsock, (struct sockaddr *)&name, sizeof(name)); + + if (rc != 0) { + int const lastError = WSAGetLastError(); + xmlrpc_asprintf(errorP, "Unable to bind socket to port number %u. " + "bind() failed with WSAERROR %i (%s)", + portNumber, lastError, getWSAError(lastError)); + } else + *errorP = NULL; +} + + + +void +ChanSwitchWinCreate(uint16_t const portNumber, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Create a Winsock-based channel switch. + + Set the socket's local address so that a subsequent "listen" will listen + on all IP addresses, port number 'portNumber'. +-----------------------------------------------------------------------------*/ + struct socketWin * socketWinP; + + MALLOCVAR(socketWinP); + + if (!socketWinP) + xmlrpc_asprintf(errorP, "Unable to allocate memory for Windows socket " + "descriptor structure."); + else { + SOCKET winsock; + + winsock = socket(AF_INET, SOCK_STREAM, 0); + + if (winsock == 0 || winsock == INVALID_SOCKET) { + int const lastError = WSAGetLastError(); + xmlrpc_asprintf(errorP, "socket() failed with WSAERROR %d (%s)", + lastError, getWSAError(lastError)); + } else { + socketWinP->winsock = winsock; + socketWinP->userSuppliedWinsock = FALSE; + socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + setSocketOptions(socketWinP->winsock, errorP); + if (!*errorP) { + bindSocketToPort(socketWinP->winsock, NULL, portNumber, + errorP); + if (!*errorP) + ChanSwitchCreate(&chanSwitchVtbl, socketWinP, + chanSwitchPP); + } + + if (*errorP) { + CloseHandle(socketWinP->interruptEvent); + closesocket(winsock); + } + } + if (*errorP) + free(socketWinP); + } +} + + + +void +ChanSwitchWinCreateWinsock(SOCKET const winsock, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + struct socketWin * socketWinP; + + if (connected(winsock)) + xmlrpc_asprintf(errorP, "Socket is in connected state."); + else { + MALLOCVAR(socketWinP); + + if (socketWinP == NULL) + xmlrpc_asprintf(errorP, "unable to allocate memory for Windows " + "socket descriptor."); + else { + TChanSwitch * chanSwitchP; + + socketWinP->winsock = winsock; + socketWinP->userSuppliedWinsock = TRUE; + socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + ChanSwitchCreate(&chanSwitchVtbl, socketWinP, &chanSwitchP); + + if (chanSwitchP == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate memory for " + "channel switch descriptor"); + else { + *chanSwitchPP = chanSwitchP; + *errorP = NULL; + } + if (*errorP) { + CloseHandle(socketWinP->interruptEvent); + free(socketWinP); + } + } + } +} + +static void +bindSocketToAddr(SOCKET const winsock, + const struct sockaddr * const addrP, + socklen_t const sockAddrLen, + const char ** const errorP) { + + int rc; + + rc = bind(winsock, (struct sockaddr *)addrP, sockAddrLen); + + if (rc != 0) { + int const lastError = WSAGetLastError(); + xmlrpc_asprintf(errorP, "Unable to bind socket to the socket address. " + "bind() failed with WSAERROR %i (%s)", + lastError, getWSAError(lastError)); + } else + *errorP = NULL; +} + +void +ChanSwitchWinCreate2(int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + + struct socketWin * socketWinP; + + MALLOCVAR(socketWinP); + + if (!socketWinP) + xmlrpc_asprintf(errorP, "Unable to allocate memory for Windows socket " + "descriptor structure."); + else { + SOCKET winsock; + + winsock = socket(protocolFamily, SOCK_STREAM, 0); + + if (winsock == 0 || winsock == INVALID_SOCKET) { + int const lastError = WSAGetLastError(); + xmlrpc_asprintf(errorP, "socket() failed with WSAERROR %d (%s)", + lastError, getWSAError(lastError)); + } else { + socketWinP->winsock = winsock; + socketWinP->userSuppliedWinsock = FALSE; + socketWinP->interruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + setSocketOptions(socketWinP->winsock, errorP); + if (!*errorP) { + bindSocketToAddr(socketWinP->winsock, sockAddrP, sockAddrLen, + errorP); + if (!*errorP) + ChanSwitchCreate(&chanSwitchVtbl, socketWinP, + chanSwitchPP); + } + + if (*errorP) { + CloseHandle(socketWinP->interruptEvent); + closesocket(winsock); + } + } + if (*errorP) + free(socketWinP); + } +} + + + +void +ChanSwitchWinGetListenName(TChanSwitch * const chanSwitchP, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP) { + + struct socketWin * const socketWinP = chanSwitchP->implP; + + // Anyone who knows how to do this with Winsock, please submit a patch. + + xmlrpc_asprintf(errorP, "Code has not been written " + "(ChanSwitchWinGetListenName in " + "lib/abyss/src/socket_win.c) to determine the name of the " + "socket on which the channel switch is listening for " + "connections"); +} + + + diff --git a/trunk/lib/abyss/src/socket_win.h b/trunk/lib/abyss/src/socket_win.h new file mode 100644 index 000000000..b52305fea --- /dev/null +++ b/trunk/lib/abyss/src/socket_win.h @@ -0,0 +1,10 @@ +#ifndef SOCKET_WIN_H_INCLUDED +#define SOCKET_WIN_H_INCLUDED + +void +SocketWinInit(const char ** const errorP); + +void +SocketWinTerm(void); + +#endif diff --git a/trunk/lib/abyss/src/sockutil.c b/trunk/lib/abyss/src/sockutil.c new file mode 100644 index 000000000..bd991998b --- /dev/null +++ b/trunk/lib/abyss/src/sockutil.c @@ -0,0 +1,490 @@ +/*============================================================================= + sockutil.c +=============================================================================== + This is utility functions for use in channel and channel switches + that use Unix sockets. +=============================================================================*/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_SYS_FILIO_H + #include +#endif + +#include "c_util.h" +#include "int.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" +#include "mallocvar.h" +#include "trace.h" +#include "chanswitch.h" +#include "channel.h" +#include "socket.h" +#include "netinet/in.h" +#include "xmlrpc-c/abyss.h" + +#include "sockutil.h" + + +void +sockutil_interruptPipeInit(sockutil_InterruptPipe * const pipeP, + const char ** const errorP) { + + int pipeFd[2]; + int rc; + + rc = pipe(pipeFd); + + if (rc != 0) + xmlrpc_asprintf(errorP, "Unable to create a pipe to use to interrupt " + "waits. pipe() failed with errno %d (%s)", + errno, strerror(errno)); + else { + *errorP = NULL; + pipeP->interruptorFd = pipeFd[1]; + pipeP->interrupteeFd = pipeFd[0]; + } +} + + + +void +sockutil_interruptPipeTerm(sockutil_InterruptPipe const pipe) { + + close(pipe.interruptorFd); + close(pipe.interrupteeFd); +} + + + +void +sockutil_interruptPipeInterrupt(sockutil_InterruptPipe const interruptPipe) { + + unsigned char const zero[1] = {0u}; + + write(interruptPipe.interruptorFd, &zero, sizeof(zero)); +} + + + +bool +sockutil_connected(int const fd) { +/*---------------------------------------------------------------------------- + Return TRUE iff the socket on file descriptor 'fd' is in the connected + state. + + If 'fd' does not identify a stream socket or we are unable to determine + the state of the stream socket, the answer is "false". +-----------------------------------------------------------------------------*/ + bool connected; + struct sockaddr sockaddr; + socklen_t nameLen; + int rc; + + nameLen = sizeof(sockaddr); + + rc = getpeername(fd, &sockaddr, &nameLen); + + if (rc == 0) + connected = true; + else + connected = false; + + return connected; +} + + + +void +sockutil_getSockName(int const sockFd, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP) { + + unsigned char * sockName; + socklen_t nameSize; + + nameSize = sizeof(struct sockaddr) + 1; + + sockName = malloc(nameSize); + + if (sockName == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate space for socket name"); + else { + int rc; + socklen_t nameLen; + nameLen = nameSize; /* initial value */ + rc = getsockname(sockFd, (struct sockaddr *)sockName, &nameLen); + + if (rc < 0) + xmlrpc_asprintf(errorP, "getsockname() failed. errno=%d (%s)", + errno, strerror(errno)); + else { + if (nameLen > nameSize-1) + xmlrpc_asprintf(errorP, + "getsockname() says the socket name is " + "larger than %u bytes, which means it is " + "not in the expected format.", + nameSize-1); + else { + *sockaddrPP = (struct sockaddr *)sockName; + *sockaddrLenP = nameLen; + *errorP = NULL; + } + } + if (*errorP) + free(sockName); + } +} + + + +void +sockutil_getPeerName(int const sockFd, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP) { + + unsigned char * peerName; + socklen_t nameSize; + + nameSize = sizeof(struct sockaddr) + 1; + + peerName = malloc(nameSize); + + if (peerName == NULL) + xmlrpc_asprintf(errorP, "Unable to allocate space for peer name"); + else { + int rc; + socklen_t nameLen; + nameLen = nameSize; /* initial value */ + rc = getpeername(sockFd, (struct sockaddr *)peerName, &nameLen); + + if (rc < 0) + xmlrpc_asprintf(errorP, "getpeername() failed. errno=%d (%s)", + errno, strerror(errno)); + else { + if (nameLen > nameSize-1) + xmlrpc_asprintf(errorP, + "getpeername() says the socket name is " + "larger than %u bytes, which means it is " + "not in the expected format.", + nameSize-1); + else { + *sockaddrPP = (struct sockaddr *)peerName; + *sockaddrLenP = nameLen; + *errorP = NULL; + } + } + if (*errorP) + free(peerName); + } +} + + + +static void +formatPeerInfoInet(const struct sockaddr_in * const sockaddrInP, + socklen_t const sockaddrLen, + const char ** const peerStringP) { + + if (sockaddrLen < sizeof(*sockaddrInP)) + xmlrpc_asprintf(peerStringP, "??? getpeername() returned " + "the wrong size"); + else { + unsigned char * const ipaddr = (unsigned char *) + &sockaddrInP->sin_addr.s_addr; + xmlrpc_asprintf(peerStringP, "%u.%u.%u.%u:%hu", + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ntohs(sockaddrInP->sin_port)); + } +} + + + +static void +formatPeerInfoInet6(const struct sockaddr_in6 * const sockaddrIn6P, + socklen_t const sockaddrLen, + const char ** const peerStringP) { + + if (sockaddrLen < sizeof(*sockaddrIn6P)) + xmlrpc_asprintf(peerStringP, "??? getpeername() returned " + "the wrong size"); + else { + /* Gcc on Debian 6 gives a bewildering error message about aliasing + if we try to dereference sockaddrIn6P in various ways, regardless + of casts to void * or anything else. So we copy the data structure + as raw memory contents and then access the copy. 12.02.05. + */ + struct sockaddr_in6 sockaddr; + + MEMSCPY(&sockaddr, sockaddrIn6P); + + { + char buffer[256]; + const char * rc; + + rc = inet_ntop(AF_INET6, &sockaddr.sin6_addr, + buffer, sizeof(buffer)); + + /* Punt the supposedly impossible error */ + if (rc == NULL) + STRSCPY(buffer, "???"); + + xmlrpc_asprintf(peerStringP, "[%s]:%hu", + buffer, sockaddr.sin6_port); + } + } +} + + + +void +sockutil_formatPeerInfo(int const sockFd, + const char ** const peerStringP) { + + struct sockaddr sockaddr; + socklen_t sockaddrLen; + int rc; + + sockaddrLen = sizeof(sockaddr); + + rc = getpeername(sockFd, &sockaddr, &sockaddrLen); + + if (rc < 0) + xmlrpc_asprintf(peerStringP, "?? getpeername() failed. errno=%d (%s)", + errno, strerror(errno)); + else { + switch (sockaddr.sa_family) { + case AF_INET: + formatPeerInfoInet((const struct sockaddr_in *) &sockaddr, + sockaddrLen, + peerStringP); + break; + case AF_INET6: + formatPeerInfoInet6((const struct sockaddr_in6 *) &sockaddr, + sockaddrLen, + peerStringP); + break; + default: + xmlrpc_asprintf(peerStringP, "??? AF=%u", sockaddr.sa_family); + } + } +} + + + +void +sockutil_listen(int const sockFd, + uint32_t const backlog, + const char ** const errorP) { + + int32_t const minus1 = -1; + + int rc; + + /* Disable the Nagle algorithm to make persistant connections faster */ + + setsockopt(sockFd, IPPROTO_TCP, TCP_NODELAY, &minus1, sizeof(minus1)); + + rc = listen(sockFd, backlog); + + if (rc == -1) + xmlrpc_asprintf(errorP, "listen() failed with errno %d (%s)", + errno, strerror(errno)); + else + *errorP = NULL; +} + + + +void +sockutil_waitForConnection(int const listenSockFd, + sockutil_InterruptPipe const interruptPipe, + bool * const interruptedP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Wait for the listening socket to have a connection ready to accept. + + We return before the requested condition holds if the process receives + (and catches) a signal, but only if it receives that signal a certain + time after we start running. (That means this behavior isn't useful + for most purposes). + + We furthermore return before the requested condition holds if someone sends + a byte through the listening socket's interrupt pipe (or has sent one + previously since the most recent time the pipe was drained). + + Return *interruptedP == true if we return before there is a connection + ready to accept. +-----------------------------------------------------------------------------*/ + struct pollfd pollfds[2]; + int rc; + + pollfds[0].fd = listenSockFd; + pollfds[0].events = POLLIN; + + pollfds[1].fd = interruptPipe.interrupteeFd; + pollfds[1].events = POLLIN; + + rc = poll(pollfds, ARRAY_SIZE(pollfds), -1); + + if (rc < 0) { + if (errno == EINTR) { + *errorP = NULL; + *interruptedP = true; + } else { + xmlrpc_asprintf(errorP, "poll() failed, errno = %d (%s)", + errno, strerror(errno)); + *interruptedP = false; /* quiet compiler warning */ + } + } else if (pollfds[0].revents & POLLHUP) { + xmlrpc_asprintf(errorP, "INTERNAL ERROR: listening socket " + "is not listening"); + } else if (pollfds[1].revents & POLLHUP) { + xmlrpc_asprintf(errorP, "INTERNAL ERROR: interrupt socket hung up"); + } else if (pollfds[0].revents & POLLERR) { + xmlrpc_asprintf(errorP, "listening socket is in POLLERR status"); + } else if (pollfds[1].revents & POLLHUP) { + xmlrpc_asprintf(errorP, "interrupt socket is in POLLERR status"); + } else { + *errorP = NULL; + *interruptedP = !(pollfds[0].revents & POLLIN); + } +} + + + +void +sockutil_setSocketOptions(int const fd, + const char ** const errorP) { + + int32_t n = 1; + int rc; + + rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof(n)); + + if (rc < 0) + xmlrpc_asprintf(errorP, "Failed to set socket options. " + "setsockopt() failed with errno %d (%s)", + errno, strerror(errno)); + else + *errorP = NULL; +} + + + +static void +traceSocketBound(const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen) { + + if (sockAddrP->sa_family == AF_INET && + sockAddrLen >= sizeof(struct sockaddr_in)) { + const struct sockaddr_in * const sockAddrInP = + (const struct sockaddr_in *)sockAddrP; + + unsigned char * const ipaddr = (unsigned char *) + &sockAddrInP->sin_addr.s_addr; + + fprintf(stderr, "Bound socket for channel switch to " + "AF_INET port %u.%u.%u.%u:%hu\n", + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ntohs(sockAddrInP->sin_port)); + } else { + fprintf(stderr, "Bound socket for channel switch to address of " + "family %d\n", sockAddrP->sa_family); + } +} + + + +void +sockutil_bindSocketToPort(int const fd, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + const char ** const errorP) { + + int rc; + + rc = bind(fd, sockAddrP, sockAddrLen); + + if (rc == -1) + xmlrpc_asprintf(errorP, "Unable to bind socket " + "to the socket address. " + "bind() failed with errno %d (%s)", + errno, strerror(errno)); + else { + *errorP = NULL; + + if (SwitchTraceIsActive) + traceSocketBound(sockAddrP, sockAddrLen); + } +} + + + +void +sockutil_bindSocketToPortInet(int const fd, + uint16_t const portNumber, + const char ** const errorP) { + + struct sockaddr_in name; + int rc; + + name.sin_family = AF_INET; + name.sin_port = htons(portNumber); + name.sin_addr.s_addr = INADDR_ANY; + + rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); + + if (rc == -1) + xmlrpc_asprintf(errorP, "Unable to bind IPv4 socket " + "to port number %hu. " + "bind() failed with errno %d (%s)", + portNumber, errno, strerror(errno)); + else + *errorP = NULL; +} + + + +void +sockutil_bindSocketToPortInet6(int const fd, + uint16_t const portNumber, + const char ** const errorP) { + + struct sockaddr_in6 name; + int rc; + + name.sin6_family = AF_INET6; + name.sin6_port = htons(portNumber); + name.sin6_addr = in6addr_any; + + rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); + + if (rc == -1) + xmlrpc_asprintf(errorP, "Unable to bind IPv6 socket " + "to port number %hu. " + "bind() failed with errno %d (%s)", + portNumber, errno, strerror(errno)); + else + *errorP = NULL; +} + + + diff --git a/trunk/lib/abyss/src/sockutil.h b/trunk/lib/abyss/src/sockutil.h new file mode 100644 index 000000000..8d2b94e13 --- /dev/null +++ b/trunk/lib/abyss/src/sockutil.h @@ -0,0 +1,72 @@ +#ifndef SOCKUTIL_H_INCLUDED +#define SOCKUTIL_H_INCLUDED + +#include +#include + +typedef struct { + int interruptorFd; + int interrupteeFd; +} sockutil_InterruptPipe; + +void +sockutil_interruptPipeInit(sockutil_InterruptPipe * const pipeP, + const char ** const errorP); + +void +sockutil_interruptPipeTerm(sockutil_InterruptPipe const pipe); + +void +sockutil_interruptPipeInterrupt(sockutil_InterruptPipe const interruptPipe); + +bool +sockutil_connected(int const fd); + +void +sockutil_getSockName(int const sockFd, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP); + +void +sockutil_getPeerName(int const sockFd, + struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP, + const char ** const errorP); + +void +sockutil_formatPeerInfo(int const sockFd, + const char ** const peerStringP); + +void +sockutil_listen(int const sockFd, + uint32_t const backlog, + const char ** const errorP); + +void +sockutil_waitForConnection(int const listenSockFd, + sockutil_InterruptPipe const interruptPipe, + bool * const interruptedP, + const char ** const errorP); + +void +sockutil_setSocketOptions(int const fd, + const char ** const errorP); + +void +sockutil_bindSocketToPort(int const fd, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + const char ** const errorP); + +void +sockutil_bindSocketToPortInet(int const fd, + uint16_t const portNumber, + const char ** const errorP); + +void +sockutil_bindSocketToPortInet6(int const fd, + uint16_t const portNumber, + const char ** const errorP); + +#endif diff --git a/trunk/lib/abyss/src/thread.h b/trunk/lib/abyss/src/thread.h new file mode 100644 index 000000000..980200d4b --- /dev/null +++ b/trunk/lib/abyss/src/thread.h @@ -0,0 +1,57 @@ +#ifndef THREAD_H_INCLUDED +#define THREAD_H_INCLUDED + +/********************************************************************* +** Thread +*********************************************************************/ + +#include "bool.h" + +typedef struct abyss_thread TThread; + +void +ThreadPoolInit(void); + +typedef void TThreadProc(void * const userHandleP); +typedef void TThreadDoneFn(void * const userHandleP); + +void +ThreadCreate(TThread ** const threadPP, + void * const userHandle, + TThreadProc * const func, + TThreadDoneFn * const threadDone, + bool const useSigchld, + size_t const stackSize, + const char ** const errorP); + +bool +ThreadRun(TThread * const threadP); + +bool +ThreadStop(TThread * const threadP); + +bool +ThreadKill(TThread * const threadP); + +void +ThreadWaitAndRelease(TThread * const threadP); + +void +ThreadExit(TThread * const threadP, + int const retValue); + +void +ThreadRelease(TThread * const threadP); + +bool +ThreadForks(void); + +void +ThreadUpdateStatus(TThread * const threadP); + +#if !MSVCRT +void +ThreadHandleSigchld(pid_t const pid); +#endif + +#endif diff --git a/trunk/lib/abyss/src/thread_fork.c b/trunk/lib/abyss/src/thread_fork.c new file mode 100644 index 000000000..26d28341a --- /dev/null +++ b/trunk/lib/abyss/src/thread_fork.c @@ -0,0 +1,293 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/abyss.h" + +#include "mallocvar.h" +#include "thread.h" + + +static void +blockSignalClass(int const signalClass, + sigset_t * const oldBlockedSetP) { + + sigset_t newBlockedSet; + + sigemptyset(&newBlockedSet); + sigaddset(&newBlockedSet, signalClass); + + sigprocmask(SIG_BLOCK, &newBlockedSet, oldBlockedSetP); +} + + + +struct abyss_thread { + struct abyss_thread * nextInPoolP; + TThreadDoneFn * threadDone; + void * userHandle; + pid_t pid; + bool useSigchld; + /* This means that user is going to call ThreadHandleSigchld() + when it gets a death of a child signal for this process. If + false, he's going to leave us in the dark, so we'll have to + poll to know if the process is dead or not. + */ +}; + + +/* Because signals are global, we need this global variable in order for + the signal handler to figure out to what thread the signal belongs. +*/ + +/* We use a singly linked list. Every time we access it, we have to run + the whole chain. To make this scale up, we should replace it with + a doubly linked list and some kind of index by PID. + + But large scale systems probably aren't using fork threads anyway. +*/ + +static struct { + struct abyss_thread * firstP; +} ThreadPool; + + + +void +ThreadPoolInit(void) { + + ThreadPool.firstP = NULL; +} + + + +static struct abyss_thread * +findThread(pid_t const pid) { + + struct abyss_thread * p; + + for (p = ThreadPool.firstP; p && p->pid != pid; p = p->nextInPoolP); + + return p; +} + + + +static void +addToPool(struct abyss_thread * const threadP) { + + if (ThreadPool.firstP == NULL) + ThreadPool.firstP = threadP; + else { + struct abyss_thread * p; + + for (p = ThreadPool.firstP; p->nextInPoolP; p = p->nextInPoolP); + + /* p points to the last thread in the list */ + + p->nextInPoolP = threadP; + } +} + + + +static void +removeFromPool(struct abyss_thread * const threadP) { + + if (threadP == ThreadPool.firstP) + ThreadPool.firstP = threadP->nextInPoolP; + else { + struct abyss_thread * p; + + for (p = ThreadPool.firstP; + p && p->nextInPoolP != threadP; + p = p->nextInPoolP); + + if (p) + /* p points to thread right before the one we want to remove */ + p->nextInPoolP = threadP->nextInPoolP; + } +} + + + +void +ThreadHandleSigchld(pid_t const pid) { +/*---------------------------------------------------------------------------- + Handle a death of a child signal for process 'pid', which may be one + of our threads. +-----------------------------------------------------------------------------*/ + struct abyss_thread * const threadP = findThread(pid); + + if (threadP) { + if (threadP->threadDone) + threadP->threadDone(threadP->userHandle); + threadP->pid = 0; + } + /* Note that threadDone might free *threadP */ +} + + + +void +ThreadUpdateStatus(TThread * const threadP) { + + if (!threadP->useSigchld) { + if (threadP->pid) { + if (kill(threadP->pid, 0) != 0) { + if (threadP->threadDone) + threadP->threadDone(threadP->userHandle); + threadP->pid = 0; + } + } + } +} + + + +void +ThreadCreate(TThread ** const threadPP, + void * const userHandle, + TThreadProc * const func, + TThreadDoneFn * const threadDone, + bool const useSigchld, + size_t const stackSize ATTR_UNUSED, + const char ** const errorP) { + + TThread * threadP; + + MALLOCVAR(threadP); + if (threadP == NULL) + xmlrpc_asprintf(errorP, + "Can't allocate memory for thread descriptor."); + else { + sigset_t oldBlockedSet; + pid_t rc; + + threadP->nextInPoolP = NULL; + threadP->threadDone = threadDone; + threadP->userHandle = userHandle; + threadP->useSigchld = useSigchld; + threadP->pid = 0; + + /* We have to be sure we don't get the SIGCHLD for this child's + death until the child is properly registered in the thread pool + so that the handler will know who he is. + */ + blockSignalClass(SIGCHLD, &oldBlockedSet); + + rc = fork(); + + if (rc < 0) + xmlrpc_asprintf(errorP, "fork() failed, errno=%d (%s)", + errno, strerror(errno)); + else if (rc == 0) { + /* This is the child */ + free(threadP); + (*func)(userHandle); + /* Note that thread cleanup (threadDone) is done by the _parent_, + upon seeing our exit. + */ + exit(0); + } else { + /* This is the parent */ + threadP->pid = rc; + + addToPool(threadP); + + sigprocmask(SIG_SETMASK, &oldBlockedSet, NULL); /* restore */ + + *errorP = NULL; + *threadPP = threadP; + } + if (*errorP) { + removeFromPool(threadP); + free(threadP); + } + } +} + + + +bool +ThreadRun(TThread * const threadP ATTR_UNUSED) { + return true; +} + + + +bool +ThreadStop(TThread * const threadP ATTR_UNUSED) { + return true; +} + + + +bool +ThreadKill(TThread * const threadP ATTR_UNUSED) { + return true; +} + + + +void +ThreadWaitAndRelease(TThread * const threadP) { + + if (threadP->pid) { + int exitStatus; + + waitpid(threadP->pid, &exitStatus, 0); + + threadP->threadDone(threadP->userHandle); + + threadP->pid = 0; + } + ThreadRelease(threadP); +} + + + +void +ThreadExit(TThread * const threadP ATTR_UNUSED, + int const retValue) { + + /* Note that the OS will automatically send a SIGCHLD signal to + the parent process after we exit. The handler for that signal + will run threadDone in parent's context. Alternatively, if + the parent isn't set up for signals, the parent will eventually + poll for the existence of our PID and call threadDone when he + sees we've gone. + */ + + /* Note that thread cleanup (threadDone) is done by the _parent_, + upon seeing our exit. + */ + + exit(retValue); +} + + + +void +ThreadRelease(TThread * const threadP) { + + removeFromPool(threadP); + free(threadP); +} + + + +bool +ThreadForks(void) { + + return true; +} + + + diff --git a/trunk/lib/abyss/src/thread_pthread.c b/trunk/lib/abyss/src/thread_pthread.c new file mode 100644 index 000000000..dd0df72cb --- /dev/null +++ b/trunk/lib/abyss/src/thread_pthread.c @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" + +#include "bool.h" +#include "mallocvar.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" + +#include "xmlrpc-c/abyss.h" + +#include "thread.h" + + + +struct abyss_thread { + pthread_t thread; + void * userHandle; + TThreadProc * func; + TThreadDoneFn * threadDone; +}; + +/* We used to have MIN_STACK_SIZE = 16K, which was said to be the + minimum stack size on Win32. Scott Kolodzeski found in November + 2005 that this was insufficient for 64 bit Solaris -- we fail + when creating the first thread. So we changed to 128K. +*/ +#define MIN_STACK_SIZE (128*1024L) + + +typedef void * (pthreadStartRoutine)(void *); + + + +static pthreadStartRoutine execute; + +static void * +execute(void * const arg) { + + /* We make sure the user's "thread done" function runs as the thread + exits, whether it exits by directly calling ThreadExit() or by + returning to caller. + + In the direct exit case, the OS calls the "thread done" function by + virtual of a cleanup that we set up. In the return to caller case, we + get control back and our call to pthread_cleanup_pop() calls the + "thread done" function. + */ + + struct abyss_thread * const threadP = arg; + bool const executeTrue = true; + + pthread_cleanup_push(threadP->threadDone, threadP->userHandle); + + threadP->func(threadP->userHandle); + + pthread_cleanup_pop(executeTrue); + + return NULL; +} + + + + +void +ThreadCreate(TThread ** const threadPP, + void * const userHandle, + TThreadProc * const func, + TThreadDoneFn * const threadDone, + bool const useSigchld ATTR_UNUSED, + size_t const stackSize, + const char ** const errorP) { + + if ((size_t)(int)stackSize != stackSize) + xmlrpc_asprintf(errorP, "Stack size %lu is too big", + (unsigned long)stackSize); + else { + TThread * threadP; + + MALLOCVAR(threadP); + if (threadP == NULL) + xmlrpc_asprintf(errorP, + "Can't allocate memory for thread descriptor."); + else { + pthread_attr_t attr; + int rc; + + pthread_attr_init(&attr); + + pthread_attr_setstacksize(&attr, MAX(MIN_STACK_SIZE, stackSize)); + + threadP->userHandle = userHandle; + threadP->func = func; + threadP->threadDone = threadDone; + + rc = pthread_create(&threadP->thread, &attr, + execute, threadP); + if (rc == 0) { + *errorP = NULL; + *threadPP = threadP; + } else + xmlrpc_asprintf( + errorP, "pthread_create() failed, errno = %d (%s)", + errno, strerror(errno)); + + pthread_attr_destroy(&attr); + + if (*errorP) + free(threadP); + } + } +} + + + +bool +ThreadRun(TThread * const threadP ATTR_UNUSED) { + return true; +} + + + +bool +ThreadStop(TThread * const threadP ATTR_UNUSED) { + return true; +} + + + +bool +ThreadKill(TThread * const threadP ATTR_UNUSED) { + + return (pthread_kill(threadP->thread, SIGTERM) == 0); +} + + + +void +ThreadWaitAndRelease(TThread * const threadP) { + + void * threadReturn; + + pthread_join(threadP->thread, &threadReturn); + + free(threadP); +} + + + +void +ThreadExit(TThread * const threadP ATTR_UNUSED, + int const retValue) { + + pthread_exit((void*)&retValue); + + /* Note that the above runs our cleanup routine (which we registered + with pthread_cleanup_push() before exiting. + */ +} + + + +void +ThreadRelease(TThread * const threadP) { + + pthread_detach(threadP->thread); + + free(threadP); +} + + + +bool +ThreadForks(void) { + + return false; +} + + + +void +ThreadUpdateStatus(TThread * const threadP ATTR_UNUSED) { + + /* Threads keep their own statuses up to date, so there's nothing + to do here. + */ +} + + + +void +ThreadHandleSigchld(pid_t const pid ATTR_UNUSED) { + + /* Death of a child signals have nothing to do with pthreads */ +} + + + diff --git a/trunk/lib/abyss/src/thread_windows.c b/trunk/lib/abyss/src/thread_windows.c new file mode 100644 index 000000000..a0b240a07 --- /dev/null +++ b/trunk/lib/abyss/src/thread_windows.c @@ -0,0 +1,171 @@ +/* This code is just a first draft by someone who doesn't know anything + about Windows. It has never been compiled. It is just a framework + for someone who knows Windows to pick up and finish. + + Bryan Henderson redesigned the threading structure for Abyss in + April 2006 and wrote this file then. He used the former + threading code, which did work on Windows, as a basis. +*/ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include "xmlrpc_config.h" + +#include "bool.h" +#include "int.h" +#include "xmlrpc-c/util_int.h" +#include "mallocvar.h" +#include "xmlrpc-c/string_int.h" + +#include "xmlrpc-c/abyss.h" +#include "trace.h" + +#include "thread.h" + + +struct abyss_thread { + HANDLE handle; + void * userHandle; + TThreadProc * func; + TThreadDoneFn * threadDone; +}; + +#define MIN_THREAD_STACK_SIZE (16*1024L) + + +typedef uint32_t (WINAPI WinThreadProc)(void *); + + +static WinThreadProc threadRun; + +static uint32_t WINAPI +threadRun(void * const arg) { + + struct abyss_thread * const threadP = arg; + + threadP->func(threadP->userHandle); + + threadP->threadDone(threadP->userHandle); + + return 0; +} + + + +void +ThreadCreate(TThread ** const threadPP, + void * const userHandle, + TThreadProc * const func, + TThreadDoneFn * const threadDone, + bool const useSigchld, + size_t const stackSize, + const char ** const errorP) { + + TThread * threadP; + + MALLOCVAR(threadP); + + if (threadP == NULL) + xmlrpc_asprintf(errorP, + "Can't allocate memory for thread descriptor."); + else { + DWORD z; + + threadP->userHandle = userHandle; + threadP->func = func; + threadP->threadDone = threadDone; + + threadP->handle = (HANDLE) + _beginthreadex(NULL, + MAX(stackSize, MIN_THREAD_STACK_SIZE), + threadRun, + threadP, + CREATE_SUSPENDED, + &z); + + if (threadP->handle == NULL) + xmlrpc_asprintf(errorP, "_beginthreadex() failed."); + else { + *errorP = NULL; + *threadPP = threadP; + } + if (*errorP) + free(threadP); + } +} + + + +bool +ThreadRun(TThread * const threadP) { + return (ResumeThread(threadP->handle) != 0xFFFFFFFF); +} + + + +bool +ThreadStop(TThread * const threadP) { + + return (SuspendThread(threadP->handle) != 0xFFFFFFFF); +} + + + +bool +ThreadKill(TThread * const threadP) { + return (TerminateThread(threadP->handle, 0) != 0); +} + + + +void +ThreadWaitAndRelease(TThread * const threadP) { + + WaitForSingleObject(threadP->handle, INFINITE); + ThreadRelease(threadP); +} + + + +void +ThreadExit(TThread * const threadP, + int const retValue) { + + threadP->threadDone(threadP->userHandle); + + _endthreadex(retValue); +} + + + +void +ThreadRelease(TThread * const threadP) { + + CloseHandle(threadP->handle); + + free(threadP); +} + + + +bool +ThreadForks(void) { + + return FALSE; +} + + + +void +ThreadUpdateStatus(TThread * const threadP ATTR_UNUSED) { + + /* Threads keep their own statuses up to date, so there's nothing + to do here. + */ +} + + + diff --git a/trunk/lib/abyss/src/token.c b/trunk/lib/abyss/src/token.c new file mode 100644 index 000000000..084ee04e2 --- /dev/null +++ b/trunk/lib/abyss/src/token.c @@ -0,0 +1,65 @@ +#include + +#include "bool.h" + +#include "token.h" + + +void +NextToken(const char ** const pP) { + + bool gotToken; + + gotToken = false; + + while (!gotToken) { + switch (**pP) { + case '\t': + case ' ': + ++(*pP); + break; + default: + gotToken = true; + }; + } +} + + + +char * +GetToken(char ** const pP) { + + char * p0; + + p0 = *pP; + + while (1) { + switch (**pP) { + case '\t': + case ' ': + case '\r': + case '\n': + case '\0': + if (p0 == *pP) + return NULL; + + if (**pP) { + **pP = '\0'; + ++(*pP); + }; + return p0; + + default: + ++(*pP); + }; + } +} + + + +void +GetTokenConst(char ** const pP, + const char ** const tokenP) { + + *tokenP = GetToken(pP); +} diff --git a/trunk/lib/abyss/src/token.h b/trunk/lib/abyss/src/token.h new file mode 100644 index 000000000..d26e35154 --- /dev/null +++ b/trunk/lib/abyss/src/token.h @@ -0,0 +1,14 @@ +#ifndef ABYSS_TOKEN_H_INCLUDED +#define ABYSS_TOKEN_H_INCLUDED + +void +NextToken(const char ** const pP); + +char * +GetToken(char ** const pP); + +void +GetTokenConst(char ** const pP, + const char ** const tokenP); + +#endif diff --git a/trunk/lib/abyss/src/trace.c b/trunk/lib/abyss/src/trace.c new file mode 100644 index 000000000..807938898 --- /dev/null +++ b/trunk/lib/abyss/src/trace.c @@ -0,0 +1,78 @@ +/****************************************************************************** +** +** trace.c +** +** This file is part of the ABYSS Web server project. +** +** Copyright (C) 2000 by Moez Mahfoudh . +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +******************************************************************************/ + +#include +#include +#include + +#include "trace.h" + +/********************************************************************* +** Tracing functions +*********************************************************************/ + +static void +TraceVMsg(const char * const fmt, + va_list argptr) { + + vprintf(fmt,argptr); + + printf("\n"); +} + + + +void +TraceMsg(const char * const fmt, ...) { + + va_list argptr; + + va_start(argptr,fmt); + TraceVMsg(fmt,argptr); + va_end(argptr); +} + + + +void +TraceExit(const char * const fmt, ...) { + + va_list argptr; + + va_start(argptr,fmt); + TraceVMsg(fmt,argptr); + va_end(argptr); + + exit(1); +} diff --git a/trunk/lib/abyss/src/trace.h b/trunk/lib/abyss/src/trace.h new file mode 100644 index 000000000..849c0b3f7 --- /dev/null +++ b/trunk/lib/abyss/src/trace.h @@ -0,0 +1,11 @@ +#ifndef TRACE_H_INCLUDED +#define TRACE_H_INCLUDED + +void +TraceMsg(const char * const fmt, ...); + +void +TraceExit(const char * const fmt, ...); + +#endif + diff --git a/trunk/lib/curl_transport/Makefile b/trunk/lib/curl_transport/Makefile new file mode 100644 index 000000000..03a1973c0 --- /dev/null +++ b/trunk/lib/curl_transport/Makefile @@ -0,0 +1,83 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + LIBDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/curl_transport + +include $(BLDDIR)/config.mk + +default: all + +MODS := xmlrpc_curl_transport curltransaction curlmulti + +.PHONY: all +all: $(MODS:%=%.o) $(MODS:%=%.osh) + +# Rules for the above dependencies are in common.mk, +# courtesy of TARGET_MODS. + +TARGET_MODS = $(MODS) + +OMIT_CURL_TRANSPORT_RULE=Y + +include $(SRCDIR)/common.mk + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +CURL_VERSION := $(shell $(CURL_CONFIG) --vernum) + +# Some time at or before Curl 7.12, became an empty file +# (no-op). Some time after Curl 7.18, ceased to exist. +# curl-config --vernum yields a string of 6 digits; the first two are the +# major version in hexadecimal; the second two are the minor version number +# and so on. So "071000" means 7.16.0. + +NEED_CURL_TYPES_H := $(shell if test $(CURL_VERSION) '<' 071000; then echo Y; fi) + +ifeq ($(NEED_CURL_TYPES_H),Y) + CFLAGS_LOCAL += -DNEED_CURL_TYPES_H +endif + +CURL_INCLUDES := $(shell $(CURL_CONFIG) --cflags) +# We expect that curl-config --cflags just gives us -I options, because +# we need just the -I options for 'make dep'. Plus, it's scary to think +# of what any other compiler flag would do to our compile. + +INCLUDES = \ + -I$(BLDDIR) \ + -I$(BLDDIR)/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include \ + $(CURL_INCLUDES) + +.PHONY: clean +clean: clean-common + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: tags +tags: TAGS + +.PHONY: distdir +distdir: + +.PHONY: install +install: + +.PHONY: uninstall +uninstall: + +.PHONY: dep +dep: dep-common + +include depend.mk + +# Need this dependency for those who don't use depend.mk. +# Without it, version.h doesn't get created. +xmlrpc_curl_transport.o xmlrpc_curl_transport.osh: version.h diff --git a/trunk/lib/curl_transport/curlmulti.c b/trunk/lib/curl_transport/curlmulti.c new file mode 100644 index 000000000..47cbb128d --- /dev/null +++ b/trunk/lib/curl_transport/curlmulti.c @@ -0,0 +1,320 @@ +/*============================================================================= + curlMulti +=============================================================================== + This is an extension to Curl's CURLM object. The extensions are: + + 1) It has a lock so multiple threads can use it simultaneously. + + 2) Its "select" file descriptor vectors are self-contained. CURLM + requires the user to maintain them separately. +=============================================================================*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include "xmlrpc_config.h" + +#include +#if HAVE_SYS_SELECT_H +#include +#endif + +#include +#ifdef NEED_CURL_TYPES_H +#include +#endif +#include +#include + +#include "mallocvar.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/lock.h" +#include "xmlrpc-c/lock_platform.h" + +#include "curlversion.h" + +#include "curlmulti.h" + + + +static void +interpretCurlMultiError(const char ** const descriptionP, + CURLMcode const code) { + +#if HAVE_CURL_STRERROR + *descriptionP = strdup(curl_multi_strerror(code)); +#else + xmlrpc_asprintf(descriptionP, "Curl error code (CURLMcode) %d", code); +#endif +} + + + +struct curlMulti { + CURLM * curlMultiP; + struct lock * lockP; + /* Hold this lock while accessing or using *curlMultiP. You're + using the multi manager whenever you're calling a Curl + library multi manager function. + */ + /* The following file descriptor sets are an integral part of the + CURLM object; Our curlMulti_fdset() routine binds them to the + CURLM object, and said object expects us to use them in a very + specific way, including doing a select() on them. It is very, + very messy. + */ + fd_set readFdSet; + fd_set writeFdSet; + fd_set exceptFdSet; +}; + + + +curlMulti * +curlMulti_create(void) { + + curlMulti * retval; + curlMulti * curlMultiP; + + MALLOCVAR(curlMultiP); + + if (curlMultiP == NULL) + retval = NULL; + else { + curlMultiP->lockP = xmlrpc_lock_create(); + + if (curlMultiP->lockP == NULL) + retval = NULL; + else { + curlMultiP->curlMultiP = curl_multi_init(); + if (curlMultiP->curlMultiP == NULL) + retval = NULL; + else + retval = curlMultiP; + + if (retval == NULL) + curlMultiP->lockP->destroy(curlMultiP->lockP); + } + if (retval == NULL) + free(curlMultiP); + } + return retval; +} + + + +void +curlMulti_destroy(curlMulti * const curlMultiP) { + + curl_multi_cleanup(curlMultiP->curlMultiP); + + curlMultiP->lockP->destroy(curlMultiP->lockP); + + free(curlMultiP); +} + + + +void +curlMulti_perform(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + bool * const immediateWorkToDoP, + int * const runningHandleCtP) { +/*---------------------------------------------------------------------------- + Do whatever work is ready to be done under the control of multi + manager 'curlMultiP'. E.g. if HTTP response data has recently arrived + from the network, process it as an HTTP response. + + Iff this results in some work being finished from our point of view, + return *immediateWorkToDoP true. (Caller can query the multi manager for + messages and find out what it is). + + Return as *runningHandleCtP the number of Curl easy handles under the + multi manager's control that are still running -- yet to finish. +-----------------------------------------------------------------------------*/ + CURLMcode rc; + + curlMultiP->lockP->acquire(curlMultiP->lockP); + + rc = curl_multi_perform(curlMultiP->curlMultiP, runningHandleCtP); + + curlMultiP->lockP->release(curlMultiP->lockP); + + if (rc == CURLM_CALL_MULTI_PERFORM) { + *immediateWorkToDoP = true; + } else { + *immediateWorkToDoP = false; + + if (rc != CURLM_OK) { + const char * reason; + interpretCurlMultiError(&reason, rc); + xmlrpc_faultf(envP, "Impossible failure of curl_multi_perform(): " + "%s", reason); + xmlrpc_strfree(reason); + } + } +} + + + +void +curlMulti_addHandle(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + CURL * const curlSessionP) { + + CURLMcode rc; + + curlMultiP->lockP->acquire(curlMultiP->lockP); + + rc = curl_multi_add_handle(curlMultiP->curlMultiP, curlSessionP); + + curlMultiP->lockP->release(curlMultiP->lockP); + + /* Old libcurl (e.g. 7.12) actually returns CURLM_CALL_MULTI_PERFORM + (by design) when it succeeds. Current libcurl returns CURLM_OK. + */ + + if (rc != CURLM_OK && rc != CURLM_CALL_MULTI_PERFORM) { + const char * reason; + interpretCurlMultiError(&reason, rc); + xmlrpc_faultf(envP, "Could not add Curl session to the " + "curl multi manager. curl_multi_add_handle() " + "failed: %s", reason); + xmlrpc_strfree(reason); + } +} + + + +void +curlMulti_removeHandle(curlMulti * const curlMultiP, + CURL * const curlSessionP) { + + curlMultiP->lockP->acquire(curlMultiP->lockP); + + curl_multi_remove_handle(curlMultiP->curlMultiP, curlSessionP); + + curlMultiP->lockP->release(curlMultiP->lockP); +} + + + +void +curlMulti_getMessage(curlMulti * const curlMultiP, + bool * const endOfMessagesP, + CURLMsg * const curlMsgP) { +/*---------------------------------------------------------------------------- + Get the next message from the queue of things the Curl multi manager + wants to say to us. + + Return the message as *curlMsgP. + + Iff there are no messages in the queue, return *endOfMessagesP == true. +-----------------------------------------------------------------------------*/ + int remainingMsgCount; + CURLMsg * privateCurlMsgP; + /* Note that this is a pointer into the multi manager's memory, + so we have to use it under lock. + */ + + curlMultiP->lockP->acquire(curlMultiP->lockP); + + privateCurlMsgP = curl_multi_info_read(curlMultiP->curlMultiP, + &remainingMsgCount); + + if (privateCurlMsgP == NULL) + *endOfMessagesP = true; + else { + *endOfMessagesP = false; + *curlMsgP = *privateCurlMsgP; + } + curlMultiP->lockP->release(curlMultiP->lockP); +} + + + +void +curlMulti_fdset(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + fd_set * const readFdSetP, + fd_set * const writeFdSetP, + fd_set * const exceptFdSetP, + int * const maxFdP) { +/*---------------------------------------------------------------------------- + Set the CURLM object's file descriptor sets to those in the + curlMulti object, update those file descriptor sets with the + current needs of the multi manager, and return the resulting values + of the file descriptor sets. + + This is a bizarre operation, but is necessary because of the nonmodular + way in which the Curl multi interface works with respect to waiting + for work with select(). +-----------------------------------------------------------------------------*/ + CURLMcode rc; + + curlMultiP->lockP->acquire(curlMultiP->lockP); + + /* curl_multi_fdset() doesn't _set_ the fdsets. It adds to existing + ones (so you can easily do a select() on other fds and Curl + fds at the same time). So we have to clear first: + */ + FD_ZERO(&curlMultiP->readFdSet); + FD_ZERO(&curlMultiP->writeFdSet); + FD_ZERO(&curlMultiP->exceptFdSet); + + /* WARNING: curl_multi_fdset() doesn't just update the fdsets pointed + to by its arguments. It makes the CURLM object remember those + pointers and refer back to them later! In fact, curl_multi_perform + expects its caller to have done a select() on those masks. No, + really. The man page even admits it. + + Inspection of the Libcurl code in March 2007 indicates that + this isn't actually true -- curl_multi_fdset() updates your + fdset and doesn't remember the pointer at all. I.e. it's just + what you would expect. The man pages still says it's as + described above. My guess is that Libcurl was fixed at some + time and the man page not updated. In any case, we have to + work with old Libcurl if at all possible, so we still maintain + these fdsets as if they belong to the CURLM object. + */ + + rc = curl_multi_fdset(curlMultiP->curlMultiP, + &curlMultiP->readFdSet, + &curlMultiP->writeFdSet, + &curlMultiP->exceptFdSet, + maxFdP); + + *readFdSetP = curlMultiP->readFdSet; + *writeFdSetP = curlMultiP->writeFdSet; + *exceptFdSetP = curlMultiP->exceptFdSet; + + curlMultiP->lockP->release(curlMultiP->lockP); + + if (rc != CURLM_OK) { + const char * reason; + interpretCurlMultiError(&reason, rc); + xmlrpc_faultf(envP, "Impossible failure of curl_multi_fdset(): %s", + reason); + xmlrpc_strfree(reason); + } +} + + + +void +curlMulti_updateFdSet(curlMulti * const curlMultiP, + fd_set const readFdSet, + fd_set const writeFdSet, + fd_set const exceptFdSet) { +/*---------------------------------------------------------------------------- + curl_multi_perform() expects the file descriptor sets, which were bound + to the CURLM object via a prior curlMulti_fdset(), to contain the results + of a recent select(). This subroutine provides you a way to supply those. +-----------------------------------------------------------------------------*/ + curlMultiP->readFdSet = readFdSet; + curlMultiP->writeFdSet = writeFdSet; + curlMultiP->exceptFdSet = exceptFdSet; +} + + + diff --git a/trunk/lib/curl_transport/curlmulti.h b/trunk/lib/curl_transport/curlmulti.h new file mode 100644 index 000000000..265ed0c17 --- /dev/null +++ b/trunk/lib/curl_transport/curlmulti.h @@ -0,0 +1,51 @@ +#ifndef CURLMULTI_H_INCLUDED +#define CURLMULTI_H_INCLUDED + +#include "bool.h" +#include "xmlrpc-c/util.h" + +#include "curltransaction.h" + +typedef struct curlMulti curlMulti; + +curlMulti * +curlMulti_create(void); + +void +curlMulti_destroy(curlMulti * const curlMultiP); + +void +curlMulti_perform(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + bool * const immediateWorkToDoP, + int * const runningHandlesP); + +void +curlMulti_addHandle(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + CURL * const curlSessionP); + +void +curlMulti_removeHandle(curlMulti * const curlMultiP, + CURL * const curlSessionP); + +void +curlMulti_getMessage(curlMulti * const curlMultiP, + bool * const endOfMessagesP, + CURLMsg * const curlMsgP); + +void +curlMulti_fdset(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + fd_set * const readFdSetP, + fd_set * const writeFdSetP, + fd_set * const exceptFdSetP, + int * const maxFdP); + +void +curlMulti_updateFdSet(curlMulti * const curlMultiP, + fd_set const readFdSet, + fd_set const writeFdSet, + fd_set const exceptFdSet); + +#endif diff --git a/trunk/lib/curl_transport/curltransaction.c b/trunk/lib/curl_transport/curltransaction.c new file mode 100644 index 000000000..f0aafae8c --- /dev/null +++ b/trunk/lib/curl_transport/curltransaction.c @@ -0,0 +1,1031 @@ +/*============================================================================= + curlTransaction +=============================================================================*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include + +#include "mallocvar.h" + +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/client_int.h" +#include "version.h" + +#include +#ifdef NEED_CURL_TYPES_H +#include +#endif +#include + +#include "curlversion.h" + +#include "curltransaction.h" + + +/* ABOUT LIBCURL AND SIGNALS: + + The Curl library has two timeout functions: one on original connection + (including DNS lookup) and another on the individual transactions. In the + original implementation, both use SIGALRM. But it is a terrible idea for a + library to mess with signals, because they are process-global. In fact, if + the program is multithreaded, this can be disastrous as a different thread + can receive the signal from the thread that is waiting. Programs even + crash. + + It is easy enough for Curl to time out the transaction without using + SIGALRM, and in current implementations it does. But for the DNS lookup, + using the traditional DNS lookup library, SIGALRM is the only way. + Therefore, the user must make a choice: have a timeout or have multiple + threads. To reflect that choice, Curl has the CURLOPT_NOSIGNAL setting. + When you set that, Curl does the right thing as keeps its hands off the + signals, but DNS lookups are indefinite. If you don't, then the connect + timeout (which defaults to 5 minutes and is user-settable) is effective + against the DNS lookup, but you had better not have multiple threads. + + For backward compatibilty, the default is to use SIGALRM. That means + single-threaded programs continue to enjoy DNS lookup timeouts even when + using new Curl. + + There is an optional way of building the Curl library -- with the ARES + library -- that allows the connect timeout to work on the DNS lookup without + SIGALRM + + In Xmlrpc-c, we always set CURLOPT_NOSIGNAL, to avoid undefined behavior in + multithreaded programs. This means that if the Curl library was not built + for ARES, the DNS lookup will not time out. For consistency, we also set + CURLOPT_CONNECTTIMEOUT to infinite. That way, users see the same behavior + with ARES. + + It wasn't always this way, Before Xmlrpc-c 1.41, we set CURLOPT_NOSIGNAL + only when the user specified the 'timeout' curl transport option, and we + never set CURLOPT_CONNECTTIMEOUT. This means programs that have a nice 5 + minute (Curl default) DNS lookup timeout with old Xmlrpc-c, (and happen not + to have the SIGALRM-related crash problem) have an indefinite wait with + current Xmlrpc-c. This was an unfortunate break to provide a more usable + interface to future users. + + For the old Curl that does not have CURLOPT_NOSIGNAL, we fail any attempt + to set a timeout (and we provide the user a way to know whether such + failure would occur). +*/ + +struct curlTransaction { + /* This is all stuff that really ought to be in a Curl object, but + the Curl library is a little too simple for that. So we build + a layer on top of Curl, and define this "transaction," as an + object subordinate to a Curl "session." A Curl session has + zero or one transactions in progress. The Curl session + "private data" is a pointer to the CurlTransaction object for + the current transaction. + */ + CURL * curlSessionP; + /* Handle for the Curl session that hosts this transaction. + Note that only one transaction at a time can use a particular + Curl session, so this had better not be a session that some other + transaction is using simultaneously. + */ + curlt_finishFn * finish; + curlt_progressFn * progress; + void * userContextP; + /* Meaningful to our client; opaque to us */ + CURLcode result; + /* Result of the transaction (succeeded, TCP connect failed, etc.). + A properly executed HTTP transaction (request & response) counts + as a successful transaction. When 'result' show success, + curl_easy_get_info() tells you whether the transaction succeeded + at the HTTP level. + */ + char curlError[CURL_ERROR_SIZE]; + /* Error message from Curl */ + struct curl_slist * headerList; + /* The HTTP headers for the transaction */ + const char * serverUrl; /* malloc'ed - belongs to this object */ + xmlrpc_mem_block * postDataP; + /* The data to send for the POST method */ + xmlrpc_mem_block * responseDataP; + /* This is normally where to put the body of the HTTP response. But + because of a quirk of Curl, if the response is not valid HTTP, + rather than this just being irrelevant, it is the place that Curl + puts the server's non-HTTP response. That can be useful for error + reporting. + */ +}; + + + +static void +addHeader(xmlrpc_env * const envP, + struct curl_slist ** const headerListP, + const char * const headerText) { + + struct curl_slist * newHeaderList; + newHeaderList = curl_slist_append(*headerListP, headerText); + if (newHeaderList == NULL) + xmlrpc_faultf(envP, + "Could not add header '%s'. " + "curl_slist_append() failed.", headerText); + else + *headerListP = newHeaderList; +} + + + +static void +addContentTypeHeader(xmlrpc_env * const envP, + struct curl_slist ** const headerListP) { + + addHeader(envP, headerListP, "Content-Type: text/xml"); +} + + + +static const char * +xmlrpcUserAgentPart(bool const reportIt) { + + const char * retval; + + if (reportIt) { + curl_version_info_data * const curlInfoP = + curl_version_info(CURLVERSION_NOW); + char curlVersion[32]; + + XMLRPC_SNPRINTF(curlVersion, sizeof(curlVersion), "%u.%u.%u", + (curlInfoP->version_num >> 16) & 0xff, + (curlInfoP->version_num >> 8) & 0xff, + (curlInfoP->version_num >> 0) & 0xff + ); + + xmlrpc_asprintf(&retval, + "Xmlrpc-c/%s Curl/%s", + XMLRPC_C_VERSION, curlVersion); + } else + xmlrpc_asprintf(&retval, "%s", ""); + + return retval; +} + + + +static void +addUserAgentHeader(xmlrpc_env * const envP, + struct curl_slist ** const headerListP, + bool const reportXmlrpc, + const char * const userAgent) { +/*---------------------------------------------------------------------------- + Add a User-Agent HTTP header to the Curl header list *headerListP, + if appropriate. + + 'reportXmlrpc' means we want to tell the client what XML-RPC agent + is being used -- Xmlrpc-c and layers below. + + 'userAgent' is a string describing the layers above Xmlrpc-c. We + assume it is in the proper format to be included in a User-Agent + header. (We should probably fix that some day -- take ownership + of that format). +-----------------------------------------------------------------------------*/ + if (reportXmlrpc || userAgent) { + /* Add the header */ + + /* Note: Curl has a CURLOPT_USERAGENT option that does some of this + work. We prefer to be totally in control, though, so we build + the header explicitly. + */ + + const char * const xmlrpcPart = xmlrpcUserAgentPart(reportXmlrpc); + + if (xmlrpc_strnomem(xmlrpcPart)) + xmlrpc_faultf(envP, "Couldn't allocate memory for " + "User-Agent header"); + else { + const char * const userPart = userAgent ? userAgent : ""; + const char * const space = userAgent && reportXmlrpc ? " " : ""; + + const char * userAgentHeader; + + xmlrpc_asprintf(&userAgentHeader, + "User-Agent: %s%s%s", + userPart, space, xmlrpcPart); + + if (xmlrpc_strnomem(userAgentHeader)) + xmlrpc_faultf(envP, "Couldn't allocate memory for " + "User-Agent header"); + else { + addHeader(envP, headerListP, userAgentHeader); + + xmlrpc_strfree(userAgentHeader); + } + xmlrpc_strfree(xmlrpcPart); + } + } +} + + + +static void +addAuthorizationHeader(xmlrpc_env * const envP, + struct curl_slist ** const headerListP, + const char * const hdrValue) { + + const char * authorizationHeader; + + xmlrpc_asprintf(&authorizationHeader, "Authorization: %s", hdrValue); + + if (xmlrpc_strnomem(authorizationHeader)) + xmlrpc_faultf(envP, "Couldn't allocate memory for " + "Authorization header"); + else { + addHeader(envP, headerListP, authorizationHeader); + + xmlrpc_strfree(authorizationHeader); + } +} + + + +/* + In HTTP 1.1, the client can send the header "Expect: 100-continue", which + tells the server that the client isn't going to send the body until the + server tells it to by sending a "continue" response (HTTP response code 100). + The server is obligated to send that response. + + However, many servers are broken and don't send the Continue response. + + Early libcurl did not send the Expect: header, thus worked fine with such + broken servers. But as of ca. 2007, libcurl sends the Expect:, and waits + for the response, when the body is large. It gives up after 3 seconds and + sends the body anyway. + + To accomodate the broken servers and for backward compatibility, we always + force libcurl not to send the Expect and consequently not to wait for the + response, using the hackish (but according to libcurl design) method of + including an entry in our explicit header list that is an Expect: header + with an empty argument. This causes libcurl not to send any Expect: header. + This is since 1.19; we may find there are also servers and/or libcurl levels + that can't work with that. + + We may find a case where the Expect/Continue protocol is desirable. If we + do, we should add a transport option to request the function and let libcurl + do its thing when the user requests it. + + The purpose of Expect/Continue is to save the client the trouble of + generating and/or sending the body when the server is just going to reject + the transaction based on the headers -- like maybe because the body is + too big. +*/ + + +static void +addExpectHeader(xmlrpc_env * const envP, + struct curl_slist ** const headerListP) { + + addHeader(envP, headerListP, "Expect:"); + /* Don't send Expect header. See explanation above. */ +} + + + +static void +createCurlHeaderList(xmlrpc_env * const envP, + const char * const authHdrValue, + bool const dontAdvertise, + const char * const userAgent, + struct curl_slist ** const headerListP) { + + struct curl_slist * headerList; + + headerList = NULL; /* initial value - empty list */ + + addContentTypeHeader(envP, &headerList); + if (!envP->fault_occurred) { + addUserAgentHeader(envP, &headerList, !dontAdvertise, userAgent); + if (!envP->fault_occurred) { + if (authHdrValue) + addAuthorizationHeader(envP, &headerList, authHdrValue); + } + if (!envP->fault_occurred) + addExpectHeader(envP, &headerList); + } + if (envP->fault_occurred) + curl_slist_free_all(headerList); + + *headerListP = headerList; +} + + + +static size_t +collect(void * const ptr, + size_t const size, + size_t const nmemb, + void * const streamP) { +/*---------------------------------------------------------------------------- + This is a Curl write function. Curl calls this to deliver the + HTTP response body to the Curl client. + + But as a design quirk, Curl also calls this when there is no HTTP body + because the response from the server is not valid HTTP. In that case, + Curl calls this to deliver the raw contents of the response. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * const responseXmlP = streamP; + char * const buffer = ptr; + size_t const length = nmemb * size; + + size_t retval; + xmlrpc_env env; + + xmlrpc_env_init(&env); + xmlrpc_mem_block_append(&env, responseXmlP, buffer, length); + if (env.fault_occurred) + retval = (size_t)-1; + else { + retval = length; + /* Really. Analogy to fread() would require this to be 'nmemb', + but Curl does expect the byte count. + */ + } + + return retval; +} + + + +static int +curlProgress(void * const contextP, + double const dltotal, + double const dlnow, + double const ultotal, + double const ulnow) { +/*---------------------------------------------------------------------------- + This is a Curl "progress function." It's something various Curl functions + call every so often, including whenever something gets interrupted by the + process receiving, and catching, a signal. There are two purposes of a + Curl progress function: 1) lets us log the progress of a long-running + transaction such as a big download, e.g. by displaying a progress bar + somewhere. 2) allows us to tell the Curl function, via our return code, + that calls it that we don't want to wait anymore for the operation to + complete. + + In Curl versions before March 2007, we get called once per second and + signals have no effect. In current Curl, we usually get called immediately + after a signal gets caught while Curl is waiting to receive a response from + the server. But Curl doesn't properly synchronize with signals, so it may + miss one and then we don't get called until the next scheduled + one-per-second call. + + All we do is pass the call through to the curlTransaction's progress + function (the one that the creator of the curlTransaction registered). + + This function is not as important as it once was for interrupting purposes. + This module used to use curl_easy_perform(), which can be interrupted only + via this progress function. But because of the above-mentioned failure of + Curl to properly synchronize signals (and Bryan's failure to get Curl + developers to accept code to fix it), we now use the Curl "multi" facility + instead and do our own pselect(). But this function still normally gets + called by curl_multi_perform(), which the transport tries to call even when + the user has requested interruption, because we don't trust our ability to + abort a running Curl transaction. curl_multi_perform() reliably winds up a + Curl transaction when this function tells it to. +-----------------------------------------------------------------------------*/ + curlTransaction * const curlTransactionP = contextP; + + bool abort; + + /* We require anyone setting us up as the Curl progress function to + supply a progress function: + */ + assert(curlTransactionP); + assert(curlTransactionP->progress); + + curlTransactionP->progress(curlTransactionP->userContextP, + dltotal, dlnow, ultotal, ulnow, + &abort); + + return abort; +} + + + +static void +setupAuth(xmlrpc_env * const envP ATTR_UNUSED, + CURL * const curlSessionP, + const xmlrpc_server_info * const serverInfoP, + const char ** const authHdrValueP) { +/*---------------------------------------------------------------------------- + Set the options in the Curl session 'curlSessionP' to set up the HTTP + authentication described by *serverInfoP. + + But we have an odd special function for backward compatibility, because + this code dates to a time when libcurl did not have the ability to + handle authentication, but we provided such function nonetheless by + building our own Authorization: header. But we did this only for + HTTP basic authentication. + + So the special function is this: if libcurl is too old to have + authorization options and *serverInfoP allows basic authentication, return + as *authHdrValueP an appropriate parameter for the Authorization: Basic: + HTTP header. Otherwise, return *authHdrValueP == NULL. +-----------------------------------------------------------------------------*/ + CURLcode rc; + + /* We don't worry if libcurl is too old for specific kinds of + authentication; they're defined only as _allowed_ authentication + methods, for when client and server are capable of using it, and unlike + with basic authentication, we have no historical commitment to consider + an old libcurl as capable of doing these. + + Note that curl_easy_setopt(CURLOPT_HTTPAUTH) succeeds even if there are + flags in it argument that weren't defined when it was written. + */ + + if (serverInfoP->userNamePw) + curl_easy_setopt(curlSessionP, CURLOPT_USERPWD, + serverInfoP->userNamePw); + + rc = curl_easy_setopt( + curlSessionP, CURLOPT_HTTPAUTH, + (serverInfoP->allowedAuth.basic ? CURLAUTH_BASIC : 0) | + (serverInfoP->allowedAuth.digest ? CURLAUTH_DIGEST : 0) | + (serverInfoP->allowedAuth.gssnegotiate ? CURLAUTH_GSSNEGOTIATE : 0) | + (serverInfoP->allowedAuth.ntlm ? CURLAUTH_NTLM : 0)); + + if (rc != CURLE_OK) { + /* Curl is too old to do authentication, so we do it ourselves + with an explicit header if we have to. + */ + if (serverInfoP->allowedAuth.basic) { + *authHdrValueP = strdup(serverInfoP->basicAuthHdrValue); + if (*authHdrValueP == NULL) + xmlrpc_faultf(envP, "Unable to allocate memory for basic " + "authentication header"); + } else + *authHdrValueP = NULL; + } else + *authHdrValueP = NULL; +} + + + +static void +setCurlTimeout(CURL * const curlSessionP ATTR_UNUSED, + unsigned int const timeoutMs ATTR_UNUSED) { + +#if HAVE_CURL_NOSIGNAL + unsigned int const timeoutSec = (timeoutMs + 999)/1000; + + assert((long)timeoutSec == (int)timeoutSec); + /* Calling requirement */ + curl_easy_setopt(curlSessionP, CURLOPT_TIMEOUT, (long)timeoutSec); +#else + /* Caller should not have called us */ + abort(); +#endif +} + + + +static void +setCurlConnectTimeout(CURL * const curlSessionP ATTR_UNUSED, + unsigned int const timeoutMs ATTR_UNUSED) { + +#if HAVE_CURL_NOSIGNAL + unsigned int const timeoutSec = (timeoutMs + 999)/1000; + + assert((long)timeoutSec == (int)timeoutSec); + /* Calling requirement */ + curl_easy_setopt(curlSessionP, CURLOPT_CONNECTTIMEOUT, (long)timeoutSec); +#else + /* Caller should not have called us */ + abort(); +#endif +} + + + +static void +assertConstantsMatch(void) { +/*---------------------------------------------------------------------------- + There are some constants that we define as part of the Xmlrpc-c + interface that are identical to constants in the Curl interface to + make curl option setting work. This function asserts such + formally. +-----------------------------------------------------------------------------*/ +#define assertMatch(xmlrpc_name, curl_name) \ + assert((unsigned)xmlrpc_name == (unsigned)curl_name) + + assertMatch(XMLRPC_SSLVERSION_DEFAULT , CURL_SSLVERSION_DEFAULT); + assertMatch(XMLRPC_SSLVERSION_TLSv1 , CURL_SSLVERSION_TLSv1 ); + assertMatch(XMLRPC_SSLVERSION_SSLv2 , CURL_SSLVERSION_SSLv2 ); + assertMatch(XMLRPC_SSLVERSION_SSLv3 , CURL_SSLVERSION_SSLv3 ); + + assertMatch(XMLRPC_HTTPAUTH_BASIC , CURLAUTH_BASIC ); + assertMatch(XMLRPC_HTTPAUTH_DIGEST , CURLAUTH_DIGEST ); + assertMatch(XMLRPC_HTTPAUTH_GSSNEGOTIATE , CURLAUTH_GSSNEGOTIATE); + assertMatch(XMLRPC_HTTPAUTH_NTLM , CURLAUTH_NTLM ); + + assertMatch(XMLRPC_HTTPPROXY_HTTP , CURLPROXY_HTTP ); + assertMatch(XMLRPC_HTTPPROXY_SOCKS5 , CURLPROXY_SOCKS5 ); + +#undef assertMatch +} + + + +/* About Curl and GSSAPI credential delegation: + + Up through Curl 7.21.6, libcurl always delegates GSSAPI credentials, which + means it gives the client's secrets to the server so the server can operate + on the client's behalf. In mid-2011, this was noticed to be a major + security exposure, because the server is not necessarily trustworthy. + One is supposed to delegate one's credentials only to a server one trusts. + So in 7.21.7, Curl never delegates GSSAPI credentials. + + But that causes problems for clients that _do_ trust their server, which + had always relied upon Curl's delegation. + + So starting in 7.22.0, Curl gives the user the choice. The default is no + delegation, but the Curl user can set the CURLOPT_GSSAPI_DELEGATION flag to + order delegation. + + Complicating matters is that some people made local variations of Curl + during the transition phase, so the version number alone isn't + determinative, so we rely on it only where we have to. + + So Xmlrpc-c gives the same choice to its own user, via its + 'gssapi_delegation' Curl transport option. + + Current Xmlrpc-c can be linked with, and compiled with, any version of + Curl, so it has to carefully consider all the possibilities. +*/ + + + +static bool +curlAlwaysDelegatesGssapi(void) { +/*---------------------------------------------------------------------------- + The Curl library we're using always delegates GSSAPI credentials + (we don't have a choice). + + This works with Curl as distributed by the Curl project, but there are + other versions of Curl for which it doesn't -- those versions report + older version numbers but in fact don't always delegate. Some never + delegate, and some give the user the option. +-----------------------------------------------------------------------------*/ + curl_version_info_data * const curlInfoP = + curl_version_info(CURLVERSION_NOW); + + return (curlInfoP->version_num <= 0x071506); /* 7.21.6 */ +} + + + +static void +requestGssapiDelegation(CURL * const curlSessionP ATTR_UNUSED, + bool * const gotItP) { +/*---------------------------------------------------------------------------- + Set up the Curl session *curlSessionP to delegate its GSSAPI credentials to + the server. + + Return *gotitP is true iff we succeed. We fail when the version of libcurl + for which we are compiled or to which we are linked is not capable of such + delegation. +-----------------------------------------------------------------------------*/ +#if HAVE_CURL_GSSAPI_DELEGATION + int rc; + + rc = curl_easy_setopt(curlSessionP, CURLOPT_GSSAPI_DELEGATION, + CURLGSSAPI_DELEGATION_FLAG); + + if (rc == CURLE_OK) + *gotItP = true; + else { + /* The only way curl_easy_setopt() could have failed is that we + are running with an old libcurl from before + CURLOPT_GSSAPI_DELEGATION was invented. + */ + if (curlAlwaysDelegatesGssapi()) { + /* No need to request delegation; we got it anyway */ + *gotItP = true; + } else + *gotItP = false; + } +#else + if (curlAlwaysDelegatesGssapi()) + *gotItP = true; + else { + /* The library may be able to do credential delegation on request, but + we have no way to request it; the Curl for which we are compiled is + too old. + */ + *gotItP = false; + } +#endif +} + + + +static void +setupCurlSession(xmlrpc_env * const envP, + curlTransaction * const transP, + const xmlrpc_server_info * const serverInfoP, + bool const dontAdvertise, + const char * const userAgent, + const struct curlSetup * const curlSetupP) { +/*---------------------------------------------------------------------------- + Set up the Curl session for the transaction *transP so that + a subsequent curl_easy_perform() would perform said transaction. + + *serverInfoP tells what sort of authentication to set up. This is + an embarassment, as the xmlrpc_server_info type is part of the + Xmlrpc-c interface. Some day, we need to replace this with a type + (probably identical) not tied to Xmlrpc-c. +-----------------------------------------------------------------------------*/ + CURL * const curlSessionP = transP->curlSessionP; + + assertConstantsMatch(); + + /* A Curl session is serial -- it processes zero or one transaction + at a time. We use the "private" attribute of the Curl session to + indicate which transaction it is presently processing. This is + important when the transaction finishes, because libcurl will just + tell us that something finished on a particular session, not that + a particular transaction finished. + */ + + /* It is our policy to do a libcurl call only where necessary, I.e. not + to set what is the default anyhow. The reduction in calls may save + some time, but mostly, it will save us encountering rare bugs or + suffering from backward incompatibilities in future libcurl. I.e. we + don't exercise any more of libcurl than we have to. + */ + + curl_easy_setopt(curlSessionP, CURLOPT_NOSIGNAL, 1); + /* See discussion of CURLOPT_NOSIGNAL above */ + + curl_easy_setopt(curlSessionP, CURLOPT_PRIVATE, transP); + + curl_easy_setopt(curlSessionP, CURLOPT_POST, 1); + curl_easy_setopt(curlSessionP, CURLOPT_URL, transP->serverUrl); + + XMLRPC_MEMBLOCK_APPEND(char, envP, transP->postDataP, "\0", 1); + if (!envP->fault_occurred) { + curl_easy_setopt(curlSessionP, CURLOPT_POSTFIELDS, + XMLRPC_MEMBLOCK_CONTENTS(char, transP->postDataP)); + curl_easy_setopt(curlSessionP, CURLOPT_WRITEFUNCTION, collect); + curl_easy_setopt(curlSessionP, CURLOPT_FILE, transP->responseDataP); + /* CURLOPT_FILE is the older name for CURLOPT_WRITEDATA */ + curl_easy_setopt(curlSessionP, CURLOPT_HEADER, 0); + curl_easy_setopt(curlSessionP, CURLOPT_ERRORBUFFER, transP->curlError); + if (transP->progress) { + curl_easy_setopt(curlSessionP, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(curlSessionP, CURLOPT_PROGRESSFUNCTION, + curlProgress); + curl_easy_setopt(curlSessionP, CURLOPT_PROGRESSDATA, transP); + } else + curl_easy_setopt(curlSessionP, CURLOPT_NOPROGRESS, 1); + + curl_easy_setopt(curlSessionP, CURLOPT_SSL_VERIFYPEER, + curlSetupP->sslVerifyPeer); + curl_easy_setopt(curlSessionP, CURLOPT_SSL_VERIFYHOST, + curlSetupP->sslVerifyHost ? 2 : 0); + + if (curlSetupP->networkInterface) + curl_easy_setopt(curlSessionP, CURLOPT_INTERFACE, + curlSetupP->networkInterface); + if (curlSetupP->referer) + curl_easy_setopt(curlSessionP, CURLOPT_REFERER, + curlSetupP->referer); + if (curlSetupP->sslCert) + curl_easy_setopt(curlSessionP, CURLOPT_SSLCERT, + curlSetupP->sslCert); + if (curlSetupP->sslCertType) + curl_easy_setopt(curlSessionP, CURLOPT_SSLCERTTYPE, + curlSetupP->sslCertType); + if (curlSetupP->sslCertPasswd) + curl_easy_setopt(curlSessionP, CURLOPT_SSLCERTPASSWD, + curlSetupP->sslCertPasswd); + if (curlSetupP->sslKey) + curl_easy_setopt(curlSessionP, CURLOPT_SSLKEY, + curlSetupP->sslKey); + if (curlSetupP->sslKeyType) + curl_easy_setopt(curlSessionP, CURLOPT_SSLKEYTYPE, + curlSetupP->sslKeyType); + if (curlSetupP->sslKeyPasswd) + curl_easy_setopt(curlSessionP, CURLOPT_SSLKEYPASSWD, + curlSetupP->sslKeyPasswd); + if (curlSetupP->sslEngine) + curl_easy_setopt(curlSessionP, CURLOPT_SSLENGINE, + curlSetupP->sslEngine); + if (curlSetupP->sslEngineDefault) + /* 3rd argument seems to be required by some Curl */ + curl_easy_setopt(curlSessionP, CURLOPT_SSLENGINE_DEFAULT, 1l); + if (curlSetupP->sslVersion != XMLRPC_SSLVERSION_DEFAULT) + curl_easy_setopt(curlSessionP, CURLOPT_SSLVERSION, + curlSetupP->sslVersion); + if (curlSetupP->caInfo) + curl_easy_setopt(curlSessionP, CURLOPT_CAINFO, + curlSetupP->caInfo); + if (curlSetupP->caPath) + curl_easy_setopt(curlSessionP, CURLOPT_CAPATH, + curlSetupP->caPath); + if (curlSetupP->randomFile) + curl_easy_setopt(curlSessionP, CURLOPT_RANDOM_FILE, + curlSetupP->randomFile); + if (curlSetupP->egdSocket) + curl_easy_setopt(curlSessionP, CURLOPT_EGDSOCKET, + curlSetupP->egdSocket); + if (curlSetupP->sslCipherList) + curl_easy_setopt(curlSessionP, CURLOPT_SSL_CIPHER_LIST, + curlSetupP->sslCipherList); + + if (curlSetupP->proxy) + curl_easy_setopt(curlSessionP, CURLOPT_PROXY, curlSetupP->proxy); + if (curlSetupP->proxyAuth != CURLAUTH_BASIC) + /* Note that the Xmlrpc-c default and the Curl default are + different. Xmlrpc-c is none, while Curl is basic. One reason + for this is that it makes our extensible parameter list scheme, + wherein zero always means default, easier. + */ + curl_easy_setopt(curlSessionP, CURLOPT_PROXYAUTH, + curlSetupP->proxyAuth); + if (curlSetupP->proxyPort) + curl_easy_setopt(curlSessionP, CURLOPT_PROXYPORT, + curlSetupP->proxyPort); + if (curlSetupP->proxyUserPwd) + curl_easy_setopt(curlSessionP, CURLOPT_PROXYUSERPWD, + curlSetupP->proxyUserPwd); + if (curlSetupP->proxyType) + curl_easy_setopt(curlSessionP, CURLOPT_PROXYTYPE, + curlSetupP->proxyType); + + if (curlSetupP->verbose) + curl_easy_setopt(curlSessionP, CURLOPT_VERBOSE, 1l); + + if (curlSetupP->timeout) + setCurlTimeout(curlSessionP, curlSetupP->timeout); + + if (curlSetupP->connectTimeout) + setCurlConnectTimeout(curlSessionP, curlSetupP->connectTimeout); + else + curl_easy_setopt(curlSessionP, CURLOPT_CONNECTTIMEOUT, + LONG_MAX/1000); + /* Some documentation says 0 means indefinite and other says 0 + means 5 minutes. The latter appears to be true. Some + libcurl (e.g. 7.12.2, but not 7.21.0) has an apparent bug + in which anything larger than LONG_MAX/1000 results in an + instantaneous timeout. + */ + + if (curlSetupP->gssapiDelegation) { + bool gotIt; + requestGssapiDelegation(curlSessionP, &gotIt); + + if (!gotIt) + xmlrpc_faultf(envP, "Cannot honor 'gssapi_delegation' " + "Curl transport option. " + "This version of libcurl is not " + "capable of delegating GSSAPI credentials"); + } + + if (!envP->fault_occurred) { + const char * authHdrValue; + /* NULL means we don't have to construct an explicit + Authorization: header. non-null means we have to + construct one with this as its value. + */ + + setupAuth(envP, curlSessionP, serverInfoP, &authHdrValue); + if (!envP->fault_occurred) { + struct curl_slist * headerList; + createCurlHeaderList(envP, authHdrValue, + dontAdvertise, userAgent, + &headerList); + if (!envP->fault_occurred) { + curl_easy_setopt( + curlSessionP, CURLOPT_HTTPHEADER, headerList); + transP->headerList = headerList; + } + if (authHdrValue) + xmlrpc_strfree(authHdrValue); + } + } + } +} + + + +void +curlTransaction_create(xmlrpc_env * const envP, + CURL * const curlSessionP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block * const responseXmlP, + bool const dontAdvertise, + const char * const userAgent, + const struct curlSetup * const curlSetupStuffP, + void * const userContextP, + curlt_finishFn * const finish, + curlt_progressFn * const progress, + curlTransaction ** const curlTransactionPP) { + + curlTransaction * curlTransactionP; + + MALLOCVAR(curlTransactionP); + if (curlTransactionP == NULL) + xmlrpc_faultf(envP, "No memory to create Curl transaction."); + else { + curlTransactionP->finish = finish; + curlTransactionP->curlSessionP = curlSessionP; + curlTransactionP->userContextP = userContextP; + curlTransactionP->progress = progress; + + /* Curl sometimes neglects to set 'curlError', so we set it here to + a value that means no explanation available. + */ + curlTransactionP->curlError[0] = '\0'; + + curlTransactionP->serverUrl = strdup(serverP->serverUrl); + if (curlTransactionP->serverUrl == NULL) + xmlrpc_faultf(envP, "Out of memory to store server URL."); + else { + curlTransactionP->postDataP = callXmlP; + curlTransactionP->responseDataP = responseXmlP; + + setupCurlSession(envP, curlTransactionP, + serverP, dontAdvertise, userAgent, + curlSetupStuffP); + + if (envP->fault_occurred) + xmlrpc_strfree(curlTransactionP->serverUrl); + } + if (envP->fault_occurred) + free(curlTransactionP); + } + *curlTransactionPP = curlTransactionP; +} + + + +void +curlTransaction_destroy(curlTransaction * const curlTransactionP) { + + curl_slist_free_all(curlTransactionP->headerList); + xmlrpc_strfree(curlTransactionP->serverUrl); + + free(curlTransactionP); +} + + + +static void +interpretCurlEasyError(const char ** const descriptionP, + CURLcode const code) { + +#if HAVE_CURL_STRERROR + *descriptionP = strdup(curl_easy_strerror(code)); +#else + xmlrpc_asprintf(descriptionP, "Curl error code (CURLcode) %d", code); +#endif +} + + + +/* CURL quirks: + + We have seen Curl report that the transaction completed OK (CURLE_OK) when + the server sent back garbage instead of an HTTP response (because it wasn't + an HTTP server). In that case Curl reports zero in place of the response + code. It's strange that Curl doesn't report that protocol violation at a + higher level (perhaps with more detail), but apparently it does not, so we + go by the HTTP_CODE value. Note that if the server closes the connection + without responding at all, Curl calls the transaction failed with an "empty + reply from server" error code. + + It appears to be the case that when the server sends non-HTTP garbage, Curl + reports it as the HTTP response body. E.g. we had an inetd server respond + with a "library not found" error message because the server connected + Standard Error to the socket. The 'curl' program typed out the error + message, naked, and exited with exit status zero. We exploit this + discovery to give better error reporting to our user. + + We saw this with Curl 7.16.1. +*/ + + + +static const char * +formatDataReceived(curlTransaction * const curlTransactionP) { + + const char * retval; + + if (XMLRPC_MEMBLOCK_SIZE(char, curlTransactionP->responseDataP) == 0) + retval = xmlrpc_strdupsol(""); + else { + xmlrpc_asprintf( + &retval, + "Raw data from server: '%s'\n", + XMLRPC_MEMBLOCK_CONTENTS(char, curlTransactionP->responseDataP)); + } + return retval; +} + + + +void +curlTransaction_getError(curlTransaction * const curlTransactionP, + xmlrpc_env * const envP) { +/*---------------------------------------------------------------------------- + Determine whether the transaction *curlTransactionP was successful in HTTP + terms. Assume the transaction did complete. Return as *envP an indication + of whether the transaction failed and if so, how. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + + xmlrpc_env_init(&env); + + if (curlTransactionP->result != CURLE_OK) { + /* We've seen Curl just return a null string for an explanation + (e.g. when TCP connect() fails because IP address doesn't exist). + */ + const char * explanation; + + if (strlen(curlTransactionP->curlError) == 0) + interpretCurlEasyError(&explanation, curlTransactionP->result); + else + xmlrpc_asprintf(&explanation, "%s", curlTransactionP->curlError); + + xmlrpc_env_set_fault_formatted( + &env, XMLRPC_NETWORK_ERROR, "libcurl failed even to execute the " + "HTTP transaction, explaining: %s", explanation); + + xmlrpc_strfree(explanation); + } else { + CURLcode res; + long http_result; + + res = curl_easy_getinfo(curlTransactionP->curlSessionP, + CURLINFO_HTTP_CODE, &http_result); + /* CURLINFO_HTTP_CODE is the old name for CURLINFO_RESPONSE_CODE */ + + if (res != CURLE_OK) + xmlrpc_env_set_fault_formatted( + &env, XMLRPC_INTERNAL_ERROR, + "Curl performed the HTTP transaction, but was " + "unable to say what the HTTP result code was. " + "curl_easy_getinfo(CURLINFO_HTTP_CODE) says: %s", + curlTransactionP->curlError); + else { + if (http_result == 0) { + /* See above for what this case means */ + const char * const dataReceived = + formatDataReceived(curlTransactionP); + + xmlrpc_env_set_fault_formatted( + &env, XMLRPC_NETWORK_ERROR, + "Server is not an XML-RPC server. Its response to our " + "call is not valid HTTP. Or it's valid HTTP with a " + "response code of zero. %s", dataReceived); + xmlrpc_strfree(dataReceived); + } else if (http_result != 200) + xmlrpc_env_set_fault_formatted( + &env, XMLRPC_NETWORK_ERROR, + "HTTP response code is %ld, not 200", + http_result); + } + } + + if (env.fault_occurred) { + xmlrpc_env_set_fault_formatted( + envP, + env.fault_code, + "HTTP POST to URL '%s' failed. %s", + curlTransactionP->serverUrl, env.fault_string); + } + xmlrpc_env_clean(&env); +} + + + +void +curlTransaction_finish(xmlrpc_env * const envP, + curlTransaction * const curlTransactionP, + CURLcode const result) { + + curlTransactionP->result = result; + + if (curlTransactionP->finish) + curlTransactionP->finish(envP, curlTransactionP->userContextP); +} + + + +CURL * +curlTransaction_curlSession(curlTransaction * const curlTransactionP) { + + return curlTransactionP->curlSessionP; + +} diff --git a/trunk/lib/curl_transport/curltransaction.h b/trunk/lib/curl_transport/curltransaction.h new file mode 100644 index 000000000..fd81090e4 --- /dev/null +++ b/trunk/lib/curl_transport/curltransaction.h @@ -0,0 +1,127 @@ +#ifndef CURLTRANSACTION_H_INCLUDED +#define CURLTRANSACTION_H_INCLUDED + +#include "bool.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/client.h" +#include + +typedef struct curlTransaction curlTransaction; + +typedef void curlt_finishFn(xmlrpc_env * const, void * const); +typedef void curlt_progressFn( + void * const, double const, double const, double const, double const, + bool * const); + +struct curlSetup { + + /* This is all client transport properties that are implemented as + simple Curl session properties (i.e. the transport basically just + passes them through to Curl without looking at them). + + People occasionally want to replace all this with something where + the Xmlrpc-c user simply does the curl_easy_setopt() call and this + code need not know about all these options. Unfortunately, that's + a significant modularity violation. Either the Xmlrpc-c user + controls the Curl object or he doesn't. If he does, then he + shouldn't use libxmlrpc_client -- he should just copy some of this + code into his own program. If he doesn't, then he should never see + the Curl library. + + Speaking of modularity: the only reason this is a separate struct + is to make the code easier to manage. Ideally, the fact that these + particular properties of the transport are implemented by simple + Curl session setup would be known only at the lowest level code + that does that setup. + */ + + const char * networkInterface; + /* This identifies the network interface on the local side to + use for the session. It is an ASCIIZ string in the form + that the Curl recognizes for setting its CURLOPT_INTERFACE + option (also the --interface option of the Curl program). + E.g. "9.1.72.189" or "giraffe-data.com" or "eth0". + + It isn't necessarily valid, but it does have a terminating NUL. + + NULL means we have no preference. + */ + const char * referer; + bool sslVerifyPeer; + /* In an SSL connection, we should authenticate the server's SSL + certificate -- refuse to talk to him if it isn't authentic. + This is equivalent to Curl's CURLOPT_SSL_VERIFY_PEER option. + */ + bool sslVerifyHost; + /* In an SSL connection, we should verify that the server's + certificate (independently of whether the certificate is + authentic) indicates the host name that is in the URL we + are using for the server. + */ + + const char * sslCert; + const char * sslCertType; + const char * sslCertPasswd; + const char * sslKey; + const char * sslKeyType; + const char * sslKeyPasswd; + const char * sslEngine; + bool sslEngineDefault; + unsigned int sslVersion; + const char * caInfo; + const char * caPath; + const char * randomFile; + const char * egdSocket; + const char * sslCipherList; + + const char * proxy; + unsigned int proxyPort; + unsigned int proxyAuth; + /* e.g. CURLAUTH_BASIC, CURLAUTH_NTLM, ... */ + const char * proxyUserPwd; + unsigned int proxyType; + /* see enum curl_proxytype: CURLPROXY_HTTP, CURLPROXY_SOCKS4, ... */ + + bool gssapiDelegation; + /* allow GSSAPI credential delegation */ + + unsigned int timeout; + /* 0 = no Curl timeout after connect. This is in milliseconds. */ + + unsigned int connectTimeout; + /* 0 = no Curl timeout on connect. This is in milliseconds. */ + + bool verbose; +}; + + +void +curlTransaction_create(xmlrpc_env * const envP, + CURL * const curlSessionP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block * const responseXmlP, + bool const dontAdvertise, + const char * const userAgent, + const struct curlSetup * const curlSetupStuffP, + void * const userContextP, + curlt_finishFn * const finish, + curlt_progressFn * const progress, + curlTransaction ** const curlTransactionPP); + +void +curlTransaction_destroy(curlTransaction * const curlTransactionP); + +void +curlTransaction_finish(xmlrpc_env * const envP, + curlTransaction * const curlTransactionP, + CURLcode const result); + +void +curlTransaction_getError(curlTransaction * const curlTransactionP, + xmlrpc_env * const envP); + +CURL * +curlTransaction_curlSession(curlTransaction * const curlTransactionP); + +#endif diff --git a/trunk/lib/curl_transport/curlversion.h b/trunk/lib/curl_transport/curlversion.h new file mode 100644 index 000000000..4ad445a09 --- /dev/null +++ b/trunk/lib/curl_transport/curlversion.h @@ -0,0 +1,26 @@ +#ifndef CURLVERSION_H_INCLUDED +#define CURLVERSION_H_INCLUDED + +#define CMAJOR LIBCURL_VERSION_MAJOR +#define CMINOR LIBCURL_VERSION_MINOR +#if CMAJOR > 7 || (CMAJOR == 7 && CMINOR >= 10) + #define HAVE_CURL_NOSIGNAL 1 +#else + #define HAVE_CURL_NOSIGNAL 0 +#endif +#if CMAJOR > 7 || (CMAJOR == 7 && CMINOR >= 12) + #define HAVE_CURL_STRERROR 1 +#else + #define HAVE_CURL_STRERROR 0 +#endif + +#ifdef CURLGSSAPI_DELEGATION_FLAG +#define HAVE_CURL_GSSAPI_DELEGATION 1 +#else +#define HAVE_CURL_GSSAPI_DELEGATION 0 +#endif + +#undef CMAJOR +#undef CMINOR + +#endif diff --git a/trunk/lib/curl_transport/xmlrpc_curl_transport.c b/trunk/lib/curl_transport/xmlrpc_curl_transport.c new file mode 100644 index 000000000..70ebc6765 --- /dev/null +++ b/trunk/lib/curl_transport/xmlrpc_curl_transport.c @@ -0,0 +1,1652 @@ +/*============================================================================= + xmlrpc_curl_transport +=============================================================================== + Curl-based client transport for Xmlrpc-c + + By Bryan Henderson 04.12.10. + + Contributed to the public domain by its author. +=============================================================================*/ + +/*---------------------------------------------------------------------------- + Curl global variables: + + Curl maintains some minor information in process-global variables. + One must call curl_global_init() to initialize them before calling + any other Curl library function. This is not state information -- + it is constants. They just aren't the kind of constants that the + library loader knows how to set, so there has to be this explicit + call to set them up. The matching function curl_global_cleanup() + returns resources these use (to wit, the constants live in + malloc'ed storage and curl_global_cleanup() frees the storage). + + So our setup_global_const transport operation calls + curl_global_init() and our teardown_global_const calls + curl_global_cleanup(). + + The Curl library is supposed to maintain a reference count for the + global constants so that multiple modules using the library and + independently calling curl_global_init() and curl_global_cleanup() + are not a problem. But today, it just keeps a flag "I have been + initialized" and the first call to curl_global_cleanup() destroys + the constants for everybody. Therefore, the user of the Xmlrpc-c + Curl client XML transport must make sure not to call + teardownGlobalConstants until everything else in his program is + done using the Curl library. + + Note that curl_global_init() is not threadsafe (with or without the + reference count), therefore our setup_global_const is not, and must + be called when no other thread in the process is running. + Typically, one calls it right at the beginning of the program. + + There are actually two other classes of global variables in the + Curl library, which we are ignoring: debug options and custom + memory allocator function identities. Our code never changes these + global variables from default. If something else in the user's + program does, User is responsible for making sure it doesn't + interfere with our use of the library. + + Note that when we say what the Curl library does, we're also + talking about various other libraries Curl uses internally, and in + fact much of what we're saying about global variables springs from + such subordinate libraries as OpenSSL and Winsock. +-----------------------------------------------------------------------------*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include +#if HAVE_SYS_SELECT_H +#include +#endif +#include +#include + +#include "bool.h" +#include "girmath.h" +#include "mallocvar.h" +#include "linklist.h" +#include "girstring.h" + +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/select_int.h" +#include "xmlrpc-c/client_int.h" +#include "xmlrpc-c/transport.h" +#include "xmlrpc-c/time_int.h" +#include "xmlrpc-c/lock.h" +#include "xmlrpc-c/lock_platform.h" + +#include +#ifdef NEED_CURL_TYPES_H +#include +#endif +#include +#include + +#include "curltransaction.h" +#include "curlmulti.h" +#include "curlversion.h" + +#if MSVCRT +#if defined(_DEBUG) +# include +# define new DEBUG_NEW +# define malloc(size) _malloc_dbg( size, _NORMAL_BLOCK, __FILE__, __LINE__) +# undef THIS_FILE + static char THIS_FILE[] = __FILE__; +#endif +#endif + + +typedef struct rpc rpc; + + + +static void +tracev(const char * const fmt, + va_list args) { + + vfprintf(stderr, fmt, args); + + fprintf(stderr, "\n"); +} + + + +static void +trace(const char * const fmt, ...) { + + if (xmlrpc_trace_transport) { + va_list args; + + va_start(args, fmt); + tracev(fmt, args); + va_end(args); + } +} + + + +static int +timeDiffMillisec(xmlrpc_timespec const minuend, + xmlrpc_timespec const subtractor) { + + unsigned int const million = 1000000; + + return (minuend.tv_sec - subtractor.tv_sec) * 1000 + + (minuend.tv_nsec - subtractor.tv_nsec + million/2) / million; +} + + + +static bool +timeIsAfter(xmlrpc_timespec const comparator, + xmlrpc_timespec const comparand) { + + if (comparator.tv_sec > comparand.tv_sec) + return true; + else if (comparator.tv_sec < comparand.tv_sec) + return false; + else { + /* Seconds are equal */ + if (comparator.tv_nsec > comparand.tv_nsec) + return true; + else + return false; + } +} + + + +static void +addMilliseconds(xmlrpc_timespec const addend, + unsigned int const adder, + xmlrpc_timespec * const sumP) { + + unsigned int const million = 1000000; + unsigned int const billion = 1000000000; + + xmlrpc_timespec sum; + + sum.tv_sec = addend.tv_sec + adder / 1000; + sum.tv_nsec = addend.tv_nsec + (adder % 1000) * million; + + if ((uint32_t)sum.tv_nsec >= billion) { + sum.tv_sec += 1; + sum.tv_nsec -= billion; + } + *sumP = sum; +} + + + +struct xmlrpc_client_transport { + CURL * syncCurlSessionP; + /* Handle for a Curl library session object that we use for + all synchronous RPCs. An async RPC has one of its own, + and consequently does not share things such as persistent + connections and cookies with any other RPC. + */ + struct lock * syncCurlSessionLockP; + /* Hold this lock while accessing or using *syncCurlSessionP. + You're using the session from the time you set any + attributes in it or start a transaction with it until any + transaction has finished and you've lost interest in any + attributes of the session. + */ + curlMulti * syncCurlMultiP; + /* The Curl multi manager that this transport uses to execute + Curl transactions for RPCs requested via the synchronous + interface. The fact that there is never more than one such + transaction going at a time might make you wonder why a + "multi" manager is needed. The reason is that it is the only + interface in libcurl that gives us the flexibility to execute + the transaction with proper interruptibility. The only Curl + transaction ever attached to this multi manager is + 'syncCurlSessionP'. + + This is constant (the handle, not the object). + */ + curlMulti * asyncCurlMultiP; + /* The Curl multi manager that this transport uses to execute + Curl transactions for RPCs requested via the asynchronous + interface. Note that there may be multiple such Curl transactions + simultaneously and one can't wait for a particular one to finish; + the collection of asynchronous RPCs are an indivisible mass. + + This is constant (the handle, not the object). + */ + bool dontAdvertise; + /* Don't identify to the server the XML-RPC engine we are using. If + false, include a User-Agent HTTP header in all requests that + identifies the Xmlrpc-c and Curl libraries. + + See also 'userAgent'. + + This is constant. + */ + const char * userAgent; + /* Information to include in a User-Agent HTTP header, reflecting + facilities outside of Xmlrpc-c. + + Null means none. + + The full User-Agent header value is this information (if + 'userAgent' is non-null) followed by identification of Xmlrpc-c + and Curl (if 'dontAdvertise' is false). If 'userAgent' is null + and 'dontAdvertise' is true, we put no User-Agent header at all + in the request. + + This is constant. + */ + struct curlSetup curlSetupStuff; + /* This is constant */ + int * interruptP; + /* Pointer to a value that user sets to nonzero to indicate he wants + the transport to give up on whatever it is doing and return ASAP. + + NULL means none -- transport never gives up. + + This is constant. + */ +}; + + + +struct rpc { + struct xmlrpc_client_transport * transportP; + /* The client XML transport that transports this RPC */ + curlTransaction * curlTransactionP; + /* The object which does the HTTP transaction, with no knowledge + of XML-RPC or Xmlrpc-c. + */ + CURL * curlSessionP; + /* The Curl session to use for the Curl transaction to perform + the RPC. + */ + xmlrpc_mem_block * responseXmlP; + /* Where the response XML for this RPC should go or has gone. */ + xmlrpc_transport_asynch_complete complete; + /* Routine to call to complete the RPC after it is complete HTTP-wise. + NULL if none. + */ + xmlrpc_transport_progress progress; + /* Routine to call periodically to report the progress of transporting + the call and response. NULL if none. + */ + struct xmlrpc_call_info * callInfoP; + /* User's identifier for this RPC */ +}; + + +static void +lockSyncCurlSession(struct xmlrpc_client_transport * const transportP) { + transportP->syncCurlSessionLockP->acquire( + transportP->syncCurlSessionLockP); +} + + + +static void +unlockSyncCurlSession(struct xmlrpc_client_transport * const transportP) { + transportP->syncCurlSessionLockP->release( + transportP->syncCurlSessionLockP); +} + + + +static void +initWindowsStuff(xmlrpc_env * const envP ATTR_UNUSED) { + +#if MSVCRT + /* This is CRITICAL so that cURL-Win32 works properly! */ + + /* So this commenter says, but I wonder why. libcurl should do the + required WSAStartup() itself, and it looks to me like it does. + -Bryan 06.01.01 + */ + WORD wVersionRequested; + WSADATA wsaData; + int err; + wVersionRequested = MAKEWORD(1, 1); + + err = WSAStartup(wVersionRequested, &wsaData); + if (err) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INTERNAL_ERROR, + "Winsock startup failed. WSAStartup returned rc %d", err); + else { + if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { + /* Tell the user that we couldn't find a useable */ + /* winsock.dll. */ + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INTERNAL_ERROR, "Winsock reported that " + "it does not implement the requested version 1.1."); + } + if (envP->fault_occurred) + WSACleanup(); + } +#endif +} + + + +static void +termWindowsStuff(void) { + +#if MSVCRT + WSACleanup(); +#endif +} + + + +static bool +curlHasNosignal(void) { + + bool retval; + +#if HAVE_CURL_NOSIGNAL + curl_version_info_data * const curlInfoP = + curl_version_info(CURLVERSION_NOW); + + retval = (curlInfoP->version_num >= 0x070A00); /* 7.10.0 */ +#else + retval = false; +#endif + return retval; +} + + + +static xmlrpc_timespec +pselectTimeout(xmlrpc_timeoutType const timeoutType, + xmlrpc_timespec const timeoutDt) { +/*---------------------------------------------------------------------------- + Return the value that should be used in the select() call to wait for + there to be work for the Curl multi manager to do, given that the user + wants to timeout according to 'timeoutType' and 'timeoutDt'. +-----------------------------------------------------------------------------*/ + unsigned int const million = 1000000; + unsigned int selectTimeoutMillisec; + xmlrpc_timespec retval; + + /* We assume there is work to do at least every 3 seconds, because + the Curl multi manager often has retries and other scheduled work + that doesn't involve file handles on which we can select(). + One thing that might cause work to do without any file handle becoming + ready is Curl timing out a request. + */ + switch (timeoutType) { + case timeout_no: + selectTimeoutMillisec = 3000; + break; + case timeout_yes: { + xmlrpc_timespec nowTime; + int timeLeft; + + xmlrpc_gettimeofday(&nowTime); + timeLeft = timeDiffMillisec(timeoutDt, nowTime); + + selectTimeoutMillisec = MIN(3000, MAX(0, timeLeft)); + } break; + } + retval.tv_sec = selectTimeoutMillisec / 1000; + retval.tv_nsec = (uint32_t)((selectTimeoutMillisec % 1000) * million); + + return retval; +} + + + +static void +processCurlMessages(xmlrpc_env * const envP, + curlMulti * const curlMultiP) { + + bool endOfMessages; + + endOfMessages = false; /* initial assumption */ + + while (!endOfMessages && !envP->fault_occurred) { + CURLMsg curlMsg; + + curlMulti_getMessage(curlMultiP, &endOfMessages, &curlMsg); + + if (!endOfMessages) { + if (curlMsg.msg == CURLMSG_DONE) { + curlTransaction * curlTransactionP; + + curl_easy_getinfo(curlMsg.easy_handle, CURLINFO_PRIVATE, + (void *)&curlTransactionP); + + curlTransaction_finish(envP, + curlTransactionP, curlMsg.data.result); + } + } + } +} + + + +static void +waitForWork(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + xmlrpc_timeoutType const timeoutType, + xmlrpc_timespec const deadline, + sigset_t * const sigmaskP) { +/*---------------------------------------------------------------------------- + Wait for the Curl multi manager to have work to do, time to run out, + or a signal to be received (and caught), whichever comes first. + + Update the Curl multi manager's file descriptor sets to indicate what + work we found for it to do. + + Wait under signal mask *sigmaskP. The point of this is that Caller can + make sure that arrival of a signal of a certain class interrupts our wait, + even if the signal arrives shortly before we begin waiting. Caller blocks + that signal class, then checks whether a signal of that class has already + been received. If not, he calls us with *sigmaskP indicating that class + NOT blocked. Thus, if a signal of that class arrived any time after Caller + checked, we will return immediately and if it arrives while we're waiting, + we will return then. Note that we can provide this service only because + pselect() has the same atomic unblock/wait feature. + + If sigmaskP is NULL, wait under whatever the current signal mask is. +-----------------------------------------------------------------------------*/ + fd_set readFdSet; + fd_set writeFdSet; + fd_set exceptFdSet; + int maxFd; + + trace("Waiting for work"); + + curlMulti_fdset(envP, curlMultiP, + &readFdSet, &writeFdSet, &exceptFdSet, &maxFd); + if (!envP->fault_occurred) { + if (maxFd == -1) { + /* There are no Curl file descriptors on which to wait. + So either there's work to do right now or all transactions + are already complete. + */ + } else { + xmlrpc_timespec const pselectTimeoutArg = + pselectTimeout(timeoutType, deadline); + + int rc; + + trace("No work available; waiting for a Curl file descriptor to " + "be ready or %u.%03u sec", + pselectTimeoutArg.tv_sec, pselectTimeoutArg.tv_nsec/1000000); + + rc = xmlrpc_pselect(maxFd+1, &readFdSet, &writeFdSet, &exceptFdSet, + &pselectTimeoutArg, sigmaskP); + + if (rc < 0 && errno != EINTR) + xmlrpc_faultf(envP, "Impossible failure of pselect() " + "with errno %d (%s)", + errno, strerror(errno)); + else { + /* Believe it or not, the Curl multi manager needs the + results of our pselect(). So hand them over: + */ + curlMulti_updateFdSet(curlMultiP, + readFdSet, writeFdSet, exceptFdSet); + } + } + trace("Wait is over"); + } +} + + + +static void +waitForWorkInt(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + xmlrpc_timeoutType const timeoutType, + xmlrpc_timespec const deadline, + int * const interruptP) { +/*---------------------------------------------------------------------------- + Same as waitForWork(), except we guarantee to return if a signal handler + sets or has set *interruptP, whereas waitForWork() can miss a signal + that happens before or just after it starts. + + We mess with global state -- the signal mask -- so we might mess up + a multithreaded program. Therefore, don't call this if + waitForWork() will suffice. +-----------------------------------------------------------------------------*/ + sigset_t callerBlockSet; +#if MSVCRT + waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); +#else + sigset_t allSignals; + + assert(interruptP != NULL); + + sigfillset(&allSignals); + + sigprocmask(SIG_BLOCK, &allSignals, &callerBlockSet); + + if (*interruptP == 0) + waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); + else + trace("Not waiting because interrupt flag is set\n"); + + sigprocmask(SIG_SETMASK, &callerBlockSet, NULL); +#endif +} + + + +static void +doCurlWork(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + bool * const transStillRunningP) { +/*---------------------------------------------------------------------------- + Do whatever work is ready to be done by the Curl multi manager + identified by 'curlMultiP'. This typically is transferring data on + an HTTP connection because the server is ready. + + For each transaction for which the multi manager finishes all the + required work, complete the transaction by calling its + "finish" routine. + + Return *transStillRunningP false if this work completes all of the + manager's transactions so that there is no reason to call us ever + again. +-----------------------------------------------------------------------------*/ + bool immediateWorkToDo; + int runningHandleCt; + + trace("Calling libcurl to perform all immediate work"); + + immediateWorkToDo = true; /* initial assumption */ + + while (immediateWorkToDo && !envP->fault_occurred) { + curlMulti_perform(envP, curlMultiP, + &immediateWorkToDo, &runningHandleCt); + } + + /* We either did all the work that's ready to do or hit an error. */ + + if (!envP->fault_occurred) { + trace("libcurl has performed all immediate work; %d tasks " + "(file handles) still running", runningHandleCt); + + /* The work we did may have resulted in asynchronous messages + (asynchronous to the thing they refer to, not to us, of course). + In particular the message "Curl transaction has completed". + So we process those now. + */ + processCurlMessages(envP, curlMultiP); + + *transStillRunningP = runningHandleCt > 0; + } +} + + + +static void +finishCurlMulti(xmlrpc_env * const envP, + curlMulti * const curlMultiP, + xmlrpc_timeoutType const timeoutType, + xmlrpc_timespec const deadline, + int * const interruptP) { +/*---------------------------------------------------------------------------- + Prosecute all the Curl transactions under the control of + *curlMultiP. E.g. send data if server is ready to take it, get + data if server has sent some, wind up the transaction if it is + done. + + Don't return until all the Curl transactions are done or we time out. + + if 'interruptP' is non-null, it points to a value which is normally zero, + but is nonzero when Caller wants us to abort all the transactions and + return ASAP. + + The *interruptP flag alone will not interrupt us. We will wait in + spite of it for all Curl transactions to complete. *interruptP + just gives us a hint that the Curl transactions are being + interrupted, so we know there is work to do for them. (The way it + works is Caller sets up a "progress" function that checks the same + interrupt flag and reports "kill me." When we see the interrupt + flag, we tell libcurl to do whatever work there is to do, and as part of + that, libcurl calls the progress function, gets the "kill me" message, + and passes that on to us). +-----------------------------------------------------------------------------*/ + /* For integrity, we make sure we don't let *interruptP interrupt our + wait for work more than once. That way, if for any reason libcurl + fails to call the progress function, or the progress function fails + to notice the interrupt flag and tell libcurl to abort, or libcurl + does abort as told, we don't have a busy loop of calls to + doCurlWork(). + + 'curlCalledSinceInterrupt' is part of this logic. + */ + + bool rpcStillRunning; + bool timedOut; + bool curlCalledSinceInterrupt; + + rpcStillRunning = true; /* initial assumption */ + timedOut = false; + curlCalledSinceInterrupt = false; + + while (rpcStillRunning && !timedOut && !envP->fault_occurred) { + + if (interruptP && !curlCalledSinceInterrupt) { + waitForWorkInt(envP, curlMultiP, timeoutType, deadline, + interruptP); + } else + waitForWork(envP, curlMultiP, timeoutType, deadline, NULL); + + if (!envP->fault_occurred) { + xmlrpc_timespec nowTime; + + /* doCurlWork() (among other things) finds Curl transactions that + user wants to abort and finishes them. (This is by virtue + of libcurl calling its progress function when we tell it to do + all available work). + */ + if (interruptP && *interruptP) + curlCalledSinceInterrupt = true; + + doCurlWork(envP, curlMultiP, &rpcStillRunning); + + xmlrpc_gettimeofday(&nowTime); + + timedOut = (timeoutType == timeout_yes && + timeIsAfter(nowTime, deadline)); + } + } +} + + + +static void +getTimeoutParm(xmlrpc_env * const envP, + const struct xmlrpc_curl_xportparms * const curlXportParmsP, + size_t const parmSize, + unsigned int * const timeoutP) { + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(timeout)) + *timeoutP = 0; + else { + if (curlHasNosignal()) { + /* libcurl takes a 'long' in milliseconds for the timeout value */ + if ((unsigned)(long)(curlXportParmsP->timeout) != + curlXportParmsP->timeout) + xmlrpc_faultf(envP, "Timeout value %u is too large.", + curlXportParmsP->timeout); + else + *timeoutP = curlXportParmsP->timeout; + } else + xmlrpc_faultf(envP, "You cannot specify a 'timeout' parameter " + "because the Curl library is too old and is not " + "capable of doing timeouts except by using " + "signals. You need at least Curl 7.10"); + } +} + + + +static void +getConnectTimeoutParm( + xmlrpc_env * const envP, + const struct xmlrpc_curl_xportparms * const curlXportParmsP, + size_t const parmSize, + unsigned int * const timeoutP) { + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(connect_timeout)) + *timeoutP = 0; + else { + if (curlHasNosignal()) { + /* libcurl represents the timeout in milliseconds with a 'long', + giving wrong results if it doesn't fit. + */ + if ((unsigned)(long)(curlXportParmsP->connect_timeout) != + curlXportParmsP->connect_timeout) + xmlrpc_faultf(envP, "Timeout value %u is too large.", + curlXportParmsP->connect_timeout); + else + *timeoutP = curlXportParmsP->connect_timeout; + } else + xmlrpc_faultf(envP, "You cannot specify a " + "'connect_timeout' parameter " + "because the Curl library is too old and is not " + "capable of doing timeouts except by using " + "signals. You need at least Curl 7.10"); + } +} + + + +static void +setVerbose(bool * const verboseP) { + + const char * const xmlrpcTraceCurl = getenv("XMLRPC_TRACE_CURL"); + + if (xmlrpcTraceCurl) + *verboseP = true; + else + *verboseP = false; +} + + + +static void +getXportParms(xmlrpc_env * const envP, + const struct xmlrpc_curl_xportparms * const curlXportParmsP, + size_t const parmSize, + struct xmlrpc_client_transport * const transportP) { +/*---------------------------------------------------------------------------- + Get the parameters out of *curlXportParmsP and update *transportP + to reflect them. + + *curlXportParmsP is a 'parmSize' bytes long prefix of + struct xmlrpc_curl_xportparms. + + curlXportParmsP is something the user created. It's designed to be + friendly to the user, not to this program, and is encumbered by + lots of backward compatibility constraints. In particular, the + user may have coded and/or compiled it at a time that struct + xmlrpc_curl_xportparms was smaller than it is now! + + Also, the user might have specified something invalid. + + So that's why we don't simply attach a copy of *curlXportParmsP to + *transportP. + + To the extent that *curlXportParmsP is too small to contain a parameter, + we return the default value for that parameter. + + Special case: curlXportParmsP == NULL means there is no input at all. + In that case, we return default values for everything. +-----------------------------------------------------------------------------*/ + struct curlSetup * const curlSetupP = &transportP->curlSetupStuff; + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(user_agent)) + transportP->userAgent = NULL; + else if (curlXportParmsP->user_agent == NULL) + transportP->userAgent = NULL; + else + transportP->userAgent = strdup(curlXportParmsP->user_agent); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(dont_advertise)) + transportP->dontAdvertise = false; + else + transportP->dontAdvertise = curlXportParmsP->dont_advertise; + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(network_interface)) + curlSetupP->networkInterface = NULL; + else if (curlXportParmsP->network_interface == NULL) + curlSetupP->networkInterface = NULL; + else + curlSetupP->networkInterface = + strdup(curlXportParmsP->network_interface); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(no_ssl_verifypeer)) + curlSetupP->sslVerifyPeer = true; + else + curlSetupP->sslVerifyPeer = !curlXportParmsP->no_ssl_verifypeer; + + if (!curlXportParmsP || + parmSize < XMLRPC_CXPSIZE(no_ssl_verifyhost)) + curlSetupP->sslVerifyHost = true; + else + curlSetupP->sslVerifyHost = !curlXportParmsP->no_ssl_verifyhost; + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(ssl_cert)) + curlSetupP->sslCert = NULL; + else if (curlXportParmsP->ssl_cert == NULL) + curlSetupP->sslCert = NULL; + else + curlSetupP->sslCert = strdup(curlXportParmsP->ssl_cert); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcerttype)) + curlSetupP->sslCertType = NULL; + else if (curlXportParmsP->sslcerttype == NULL) + curlSetupP->sslCertType = NULL; + else + curlSetupP->sslCertType = strdup(curlXportParmsP->sslcerttype); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslcertpasswd)) + curlSetupP->sslCertPasswd = NULL; + else if (curlXportParmsP->sslcertpasswd == NULL) + curlSetupP->sslCertPasswd = NULL; + else + curlSetupP->sslCertPasswd = strdup(curlXportParmsP->sslcertpasswd); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkey)) + curlSetupP->sslKey = NULL; + else if (curlXportParmsP->sslkey == NULL) + curlSetupP->sslKey = NULL; + else + curlSetupP->sslKey = strdup(curlXportParmsP->sslkey); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeytype)) + curlSetupP->sslKeyType = NULL; + else if (curlXportParmsP->sslkeytype == NULL) + curlSetupP->sslKeyType = NULL; + else + curlSetupP->sslKeyType = strdup(curlXportParmsP->sslkeytype); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslkeypasswd)) + curlSetupP->sslKeyPasswd = NULL; + else if (curlXportParmsP->sslkeypasswd == NULL) + curlSetupP->sslKeyPasswd = NULL; + else + curlSetupP->sslKeyPasswd = strdup(curlXportParmsP->sslkeypasswd); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine)) + curlSetupP->sslEngine = NULL; + else if (curlXportParmsP->sslengine == NULL) + curlSetupP->sslEngine = NULL; + else + curlSetupP->sslEngine = strdup(curlXportParmsP->sslengine); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslengine_default)) + curlSetupP->sslEngineDefault = false; + else + curlSetupP->sslEngineDefault = !!curlXportParmsP->sslengine_default; + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(sslversion)) + curlSetupP->sslVersion = XMLRPC_SSLVERSION_DEFAULT; + else + curlSetupP->sslVersion = curlXportParmsP->sslversion; + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(cainfo)) + curlSetupP->caInfo = NULL; + else if (curlXportParmsP->cainfo == NULL) + curlSetupP->caInfo = NULL; + else + curlSetupP->caInfo = strdup(curlXportParmsP->cainfo); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(capath)) + curlSetupP->caPath = NULL; + else if (curlXportParmsP->capath == NULL) + curlSetupP->caPath = NULL; + else + curlSetupP->caPath = strdup(curlXportParmsP->capath); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(randomfile)) + curlSetupP->randomFile = NULL; + else if (curlXportParmsP->randomfile == NULL) + curlSetupP->randomFile = NULL; + else + curlSetupP->randomFile = strdup(curlXportParmsP->randomfile); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(egdsocket)) + curlSetupP->egdSocket = NULL; + else if (curlXportParmsP->egdsocket == NULL) + curlSetupP->egdSocket = NULL; + else + curlSetupP->egdSocket = strdup(curlXportParmsP->egdsocket); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(ssl_cipher_list)) + curlSetupP->sslCipherList = NULL; + else if (curlXportParmsP->ssl_cipher_list == NULL) + curlSetupP->sslCipherList = NULL; + else + curlSetupP->sslCipherList = strdup(curlXportParmsP->ssl_cipher_list); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy)) + curlSetupP->proxy = NULL; + else if (curlXportParmsP->proxy == NULL) + curlSetupP->proxy = NULL; + else + curlSetupP->proxy = strdup(curlXportParmsP->proxy); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy_port)) + curlSetupP->proxyPort = 8080; + else + curlSetupP->proxyPort = curlXportParmsP->proxy_port; + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy_auth)) + curlSetupP->proxyAuth = CURLAUTH_BASIC; + else + curlSetupP->proxyAuth = curlXportParmsP->proxy_auth; + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy_userpwd)) + curlSetupP->proxyUserPwd = NULL; + else if (curlXportParmsP->proxy_userpwd == NULL) + curlSetupP->proxyUserPwd = NULL; + else + curlSetupP->proxyUserPwd = strdup(curlXportParmsP->proxy_userpwd); + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(proxy_type)) + curlSetupP->proxyType = CURLPROXY_HTTP; + else + curlSetupP->proxyType = curlXportParmsP->proxy_type; + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(gssapi_delegation)) + curlSetupP->gssapiDelegation = false; + else + curlSetupP->gssapiDelegation = !!curlXportParmsP->gssapi_delegation; + + if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(referer)) + curlSetupP->referer = NULL; + else if (curlXportParmsP->referer == NULL) + curlSetupP->referer = NULL; + else + curlSetupP->referer = strdup(curlXportParmsP->referer); + + getTimeoutParm(envP, curlXportParmsP, parmSize, &curlSetupP->timeout); + + getConnectTimeoutParm(envP, curlXportParmsP, parmSize, + &curlSetupP->connectTimeout); +} + + + +static void +freeXportParms(const struct xmlrpc_client_transport * const transportP) { + + const struct curlSetup * const curlSetupP = &transportP->curlSetupStuff; + + if (curlSetupP->sslCipherList) + xmlrpc_strfree(curlSetupP->sslCipherList); + if (curlSetupP->egdSocket) + xmlrpc_strfree(curlSetupP->egdSocket); + if (curlSetupP->randomFile) + xmlrpc_strfree(curlSetupP->randomFile); + if (curlSetupP->caPath) + xmlrpc_strfree(curlSetupP->caPath); + if (curlSetupP->caInfo) + xmlrpc_strfree(curlSetupP->caInfo); + if (curlSetupP->sslEngine) + xmlrpc_strfree(curlSetupP->sslEngine); + if (curlSetupP->sslKeyPasswd) + xmlrpc_strfree(curlSetupP->sslKeyPasswd); + if (curlSetupP->sslKeyType) + xmlrpc_strfree(curlSetupP->sslKeyType); + if (curlSetupP->sslKey) + xmlrpc_strfree(curlSetupP->sslKey); + if (curlSetupP->sslCertPasswd) + xmlrpc_strfree(curlSetupP->sslCertPasswd); + if (curlSetupP->sslCertType) + xmlrpc_strfree(curlSetupP->sslCertType); + if (curlSetupP->sslCert) + xmlrpc_strfree(curlSetupP->sslCert); + if (curlSetupP->networkInterface) + xmlrpc_strfree(curlSetupP->networkInterface); + if (transportP->userAgent) + xmlrpc_strfree(transportP->userAgent); + if (curlSetupP->proxy) + xmlrpc_strfree(curlSetupP->proxy); + if (curlSetupP->proxyUserPwd) + xmlrpc_strfree(curlSetupP->proxyUserPwd); + if (curlSetupP->referer) + xmlrpc_strfree(curlSetupP->referer); +} + + + +static void +createSyncCurlSession(xmlrpc_env * const envP, + CURL ** const curlSessionPP) { +/*---------------------------------------------------------------------------- + Create a Curl session to be used for multiple serial transactions. + The Curl session we create is not complete -- it still has to be + further set up for each particular transaction. + + We can't set up anything here that changes from one transaction to the + next. + + We don't bother setting up anything that has to be set up for an + asynchronous transaction because code that is common between synchronous + and asynchronous transactions takes care of that anyway. + + That leaves things, such as cookies, that don't exist for + asynchronous transactions, and are common to multiple serial + synchronous transactions. +-----------------------------------------------------------------------------*/ + CURL * const curlSessionP = curl_easy_init(); + + if (curlSessionP == NULL) + xmlrpc_faultf(envP, "Could not create Curl session. " + "curl_easy_init() failed."); + else { + /* The following is a trick. CURLOPT_COOKIEFILE is the name + of the file containing the initial cookies for the Curl + session. But setting it is also what turns on the cookie + function itself, whereby the Curl library accepts and + stores cookies from the server and sends them back on + future requests. We don't have a file of initial cookies, but + we want to turn on cookie function, so we set the option to + something we know does not validly name a file. Curl will + ignore the error and just start up cookie function with no + initial cookies. + */ + curl_easy_setopt(curlSessionP, CURLOPT_COOKIEFILE, ""); + + *curlSessionPP = curlSessionP; + } +} + + + +static void +destroySyncCurlSession(CURL * const curlSessionP) { + + curl_easy_cleanup(curlSessionP); +} + + + +static void +makeSyncCurlSession(xmlrpc_env * const envP, + struct xmlrpc_client_transport * const transportP) { + + transportP->syncCurlSessionLockP = xmlrpc_lock_create(); + if (transportP->syncCurlSessionLockP == NULL) + xmlrpc_faultf(envP, "Unable to create lock for " + "synchronous Curl session."); + else { + createSyncCurlSession(envP, &transportP->syncCurlSessionP); + + if (!envP->fault_occurred) { + /* We'll need a multi manager to actually execute this session: */ + transportP->syncCurlMultiP = curlMulti_create(); + + if (transportP->syncCurlMultiP == NULL) + xmlrpc_faultf(envP, "Unable to create Curl multi manager for " + "synchronous RPCs"); + + if (envP->fault_occurred) + destroySyncCurlSession(transportP->syncCurlSessionP); + } + if (envP->fault_occurred) + transportP->syncCurlSessionLockP->destroy( + transportP->syncCurlSessionLockP); + } +} + + + +static void +unmakeSyncCurlSession(struct xmlrpc_client_transport * const transportP) { + + curlMulti_destroy(transportP->syncCurlMultiP); + + destroySyncCurlSession(transportP->syncCurlSessionP); + + transportP->syncCurlSessionLockP->destroy( + transportP->syncCurlSessionLockP); +} + + + +static void +create(xmlrpc_env * const envP, + int const flags ATTR_UNUSED, + const char * const appname ATTR_UNUSED, + const char * const appversion ATTR_UNUSED, + const void * const transportparmsP, + size_t const parm_size, + struct xmlrpc_client_transport ** const handlePP) { +/*---------------------------------------------------------------------------- + This does the 'create' operation for a Curl client transport. +-----------------------------------------------------------------------------*/ + const struct xmlrpc_curl_xportparms * const curlXportParmsP = + transportparmsP; + + struct xmlrpc_client_transport * transportP; + + MALLOCVAR(transportP); + if (transportP == NULL) + xmlrpc_faultf(envP, "Unable to allocate transport descriptor."); + else { + setVerbose(&transportP->curlSetupStuff.verbose); + + transportP->interruptP = NULL; + + transportP->asyncCurlMultiP = curlMulti_create(); + + if (transportP->asyncCurlMultiP == NULL) + xmlrpc_faultf(envP, "Unable to create Curl multi manager for " + "asynchronous RPCs"); + else { + getXportParms(envP, curlXportParmsP, parm_size, transportP); + + if (!envP->fault_occurred) { + makeSyncCurlSession(envP, transportP); + + if (envP->fault_occurred) + freeXportParms(transportP); + } + if (envP->fault_occurred) + curlMulti_destroy(transportP->asyncCurlMultiP); + } + if (envP->fault_occurred) + free(transportP); + } + *handlePP = transportP; +} + + + +static void +setInterrupt(struct xmlrpc_client_transport * const clientTransportP, + int * const interruptP) { + + clientTransportP->interruptP = interruptP; +} + + + +static void +assertNoOutstandingCurlWork(curlMulti * const curlMultiP) { + + xmlrpc_env env; + bool immediateWorkToDo; + int runningHandles; + + xmlrpc_env_init(&env); + + curlMulti_perform(&env, curlMultiP, &immediateWorkToDo, &runningHandles); + + /* We know the above was a no-op, since we're asserting that there + is no outstanding work. + */ + XMLRPC_ASSERT(!env.fault_occurred); + XMLRPC_ASSERT(!immediateWorkToDo); + XMLRPC_ASSERT(runningHandles == 0); + xmlrpc_env_clean(&env); +} + + + +static void +destroy(struct xmlrpc_client_transport * const clientTransportP) { +/*---------------------------------------------------------------------------- + This does the 'destroy' operation for a Curl client transport. + + An RPC is a reference to a client XML transport, so you may not + destroy a transport while RPCs are running. To ensure no + asynchronous RPCs are running, you must successfully execute the + transport 'finishAsync' method, with no interruptions or timeouts + allowed. To speed that up, you can set the transport's interrupt + flag to 1 first, which will make all outstanding RPCs fail + immediately. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(clientTransportP != NULL); + + assertNoOutstandingCurlWork(clientTransportP->asyncCurlMultiP); + /* We know this is true because a condition of destroying the + transport is that there be no outstanding asynchronous RPCs. + */ + assertNoOutstandingCurlWork(clientTransportP->syncCurlMultiP); + /* This is because a condition of destroying the transport is + that no transport method be running. The only way a + synchronous RPC can be in progress is for the 'perform' method + to be running. + */ + + unmakeSyncCurlSession(clientTransportP); + + curlMulti_destroy(clientTransportP->asyncCurlMultiP); + + freeXportParms(clientTransportP); + + free(clientTransportP); +} + + + +static void +performCurlTransaction(xmlrpc_env * const envP, + curlTransaction * const curlTransactionP, + curlMulti * const curlMultiP, + int * const interruptP) { + + curlMulti_addHandle(envP, curlMultiP, + curlTransaction_curlSession(curlTransactionP)); + + /* Failure here just means something screwy in the multi manager; + Above does not even begin to perform the HTTP transaction + */ + + if (!envP->fault_occurred) { + xmlrpc_timespec const dummy = {0,0}; + + finishCurlMulti(envP, curlMultiP, timeout_no, dummy, interruptP); + + /* Failure here just means something screwy in the multi + manager; any failure of the HTTP transaction would have been + recorded in *curlTransactionP. + */ + + if (!envP->fault_occurred) { + /* Curl session completed OK. But did HTTP transaction + it prosecuted work? + */ + curlTransaction_getError(curlTransactionP, envP); + } + /* If the CURL transaction is still going, removing the handle + here aborts it. At least it's supposed to. From what I've + seen in the Curl code in 2007, I don't think it does. I + couldn't get Curl maintainers interested in the problem, + except to say, "If you're right, there's a bug." + */ + curlMulti_removeHandle(curlMultiP, + curlTransaction_curlSession(curlTransactionP)); + } +} + + + +static void +startRpc(xmlrpc_env * const envP, + rpc * const rpcP) { + + curlMulti_addHandle(envP, + rpcP->transportP->asyncCurlMultiP, + curlTransaction_curlSession(rpcP->curlTransactionP)); +} + + + +static curlt_finishFn finishRpcCurlTransaction; +static curlt_progressFn curlTransactionProgress; + + + +static void +createRpc(xmlrpc_env * const envP, + struct xmlrpc_client_transport * const clientTransportP, + CURL * const curlSessionP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block * const responseXmlP, + xmlrpc_transport_asynch_complete complete, + xmlrpc_transport_progress progress, + struct xmlrpc_call_info * const callInfoP, + rpc ** const rpcPP) { + + rpc * rpcP; + + MALLOCVAR(rpcP); + if (rpcP == NULL) + xmlrpc_faultf(envP, "Couldn't allocate memory for rpc object"); + else { + curlt_progressFn * curlProgressFn; + + if (progress || clientTransportP->interruptP) + curlProgressFn = &curlTransactionProgress; + else { + /* There's nothing for curlTransactionProgress() to do, so save + the time and complexity of calling it. + */ + curlProgressFn = NULL; + } + rpcP->transportP = clientTransportP; + rpcP->curlSessionP = curlSessionP; + rpcP->callInfoP = callInfoP; + rpcP->complete = complete; + rpcP->progress = progress; + rpcP->responseXmlP = responseXmlP; + + curlTransaction_create(envP, + curlSessionP, + serverP, + callXmlP, responseXmlP, + clientTransportP->dontAdvertise, + clientTransportP->userAgent, + &clientTransportP->curlSetupStuff, + rpcP, + complete ? &finishRpcCurlTransaction : NULL, + curlProgressFn, + &rpcP->curlTransactionP); + if (!envP->fault_occurred) { + if (envP->fault_occurred) + curlTransaction_destroy(rpcP->curlTransactionP); + } + if (envP->fault_occurred) + free(rpcP); + } + *rpcPP = rpcP; +} + + + +static void +destroyRpc(rpc * const rpcP) { + + XMLRPC_ASSERT_PTR_OK(rpcP); + + curlTransaction_destroy(rpcP->curlTransactionP); + + free(rpcP); +} + + + +static void +performRpc(xmlrpc_env * const envP, + rpc * const rpcP, + curlMulti * const curlMultiP, + int * const interruptP) { + + performCurlTransaction(envP, rpcP->curlTransactionP, curlMultiP, + interruptP); +} + + + +static curlt_finishFn finishRpcCurlTransaction; + +static void +finishRpcCurlTransaction(xmlrpc_env * const envP ATTR_UNUSED, + void * const userContextP) { +/*---------------------------------------------------------------------------- + Handle the event that a Curl transaction for an asynchronous RPC has + completed on the Curl session identified by 'curlSessionP'. + + Tell the requester of the RPC the results. + + Remove the Curl session from its Curl multi manager and destroy the + Curl session, the XML response buffer, the Curl transaction, and the RPC. +-----------------------------------------------------------------------------*/ + rpc * const rpcP = userContextP; + curlTransaction * const curlTransactionP = rpcP->curlTransactionP; + struct xmlrpc_client_transport * const transportP = rpcP->transportP; + + curlMulti_removeHandle(transportP->asyncCurlMultiP, + curlTransaction_curlSession(curlTransactionP)); + + { + xmlrpc_env env; + + xmlrpc_env_init(&env); + + curlTransaction_getError(curlTransactionP, &env); + + rpcP->complete(rpcP->callInfoP, rpcP->responseXmlP, env); + + xmlrpc_env_clean(&env); + } + + curl_easy_cleanup(rpcP->curlSessionP); + + XMLRPC_MEMBLOCK_FREE(char, rpcP->responseXmlP); + + destroyRpc(rpcP); +} + + + +static curlt_progressFn curlTransactionProgress; + +static void +curlTransactionProgress(void * const context, + double const dlTotal, + double const dlNow, + double const ulTotal, + double const ulNow, + bool * const abortP) { +/*---------------------------------------------------------------------------- + This is equivalent to a Curl "progress function" (the curlTransaction + object just passes through the call from libcurl). + + The curlTransaction calls this once a second telling us how much + data has transferred. If the transport user has set up a progress + function, we call that with this progress information. That + function might e.g. display a progress bar. + + Additionally, the curlTransaction gives us the opportunity to tell it + to abort the transaction, which we do if the user has set his + "interrupt" flag (which he registered with the transport when he + created it). +-----------------------------------------------------------------------------*/ + rpc * const rpcP = context; + struct xmlrpc_client_transport * const transportP = rpcP->transportP; + + assert(rpcP); + assert(transportP); + + trace("Progress function called back by libcurl"); + + if (rpcP->progress) { + struct xmlrpc_progress_data progressData; + + trace("Calling transport client's progress function with %u %u %u %u", + dlTotal, dlNow, ulTotal, ulNow); + + progressData.response.total = dlTotal; + progressData.response.now = dlNow; + progressData.call.total = ulTotal; + progressData.call.now = ulNow; + + rpcP->progress(rpcP->callInfoP, progressData); + } + if (transportP->interruptP) { + trace("Interrupt flag is set; " + "directing libcurl to abort the transaction"); + *abortP = *transportP->interruptP; + } else + *abortP = false; +} + + + +static void +sendRequest(xmlrpc_env * const envP, + struct xmlrpc_client_transport * const clientTransportP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_transport_asynch_complete complete, + xmlrpc_transport_progress progress, + struct xmlrpc_call_info * const callInfoP) { +/*---------------------------------------------------------------------------- + Initiate an XML-RPC rpc asynchronously. Don't wait for it to go to + the server. + + Unless we return failure, we arrange to have complete() called when + the rpc completes. + + This does the 'send_request' operation for a Curl client transport. +-----------------------------------------------------------------------------*/ + rpc * rpcP; + xmlrpc_mem_block * responseXmlP; + + responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + if (!envP->fault_occurred) { + CURL * const curlSessionP = curl_easy_init(); + + if (curlSessionP == NULL) + xmlrpc_faultf(envP, "Could not create Curl session. " + "curl_easy_init() failed."); + else { + createRpc(envP, clientTransportP, curlSessionP, serverP, + callXmlP, responseXmlP, complete, progress, callInfoP, + &rpcP); + + if (!envP->fault_occurred) { + startRpc(envP, rpcP); + + if (envP->fault_occurred) + destroyRpc(rpcP); + } + if (envP->fault_occurred) + curl_easy_cleanup(curlSessionP); + } + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, responseXmlP); + } + /* If we're returning success, the user's eventual finish_asynch + call will destroy this RPC, Curl session, and response buffer + and remove the Curl session from the Curl multi manager. + (If we're returning failure, we didn't create any of those). + */ +} + + + +static void +finishAsynch( + struct xmlrpc_client_transport * const clientTransportP, + xmlrpc_timeoutType const timeoutType, + xmlrpc_timeout const timeout) { +/*---------------------------------------------------------------------------- + Wait for the Curl multi manager to finish the Curl transactions for + all outstanding RPCs and destroy those RPCs. + + But give up if a) too much time passes as defined by 'timeoutType' + and 'timeout'; or b) the transport client requests interruption + (i.e. the transport's interrupt flag becomes nonzero). Normally, a + signal must get our attention for us to notice the interrupt flag. + + This does the 'finish_asynch' operation for a Curl client transport. + + It would be cool to replace this with something analogous to the + Curl asynchronous interface: Have something like curl_multi_fdset() + that returns a bunch of file descriptors on which the user can wait + (along with possibly other file descriptors of his own) and + something like curl_multi_perform() to finish whatever RPCs are + ready to finish at that moment. The implementation would be little + more than wrapping curl_multi_fdset() and curl_multi_perform(). + + Note that the user can call this multiple times, because of timeouts, + but must eventually call it once with no timeout so he + knows that all the RPCs are finished. Either that or terminate the + process so it doesn't matter if RPCs are still going. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + + xmlrpc_timespec waitTimeoutTime; + /* The datetime after which we should quit waiting */ + + xmlrpc_env_init(&env); + + if (timeoutType == timeout_yes) { + xmlrpc_timespec waitStartTime; + xmlrpc_gettimeofday(&waitStartTime); + addMilliseconds(waitStartTime, timeout, &waitTimeoutTime); + } + + finishCurlMulti(&env, clientTransportP->asyncCurlMultiP, + timeoutType, waitTimeoutTime, + clientTransportP->interruptP); + + /* If the above fails, it is catastrophic, because it means there is + no way to complete outstanding Curl transactions and RPCs, and + no way to release their resources. + + We should at least expand this interface some day to push the + problem back up to the user, but for now we just do this Hail Mary + response. + + Note that a failure of finish_curlMulti() does not mean that + a session completed with an error or an RPC completed with an + error. Those things are reported up through the user's + xmlrpc_transport_asynch_complete routine. A failure here is + something that stopped us from calling that. + + Note that a timeout causes a successful completion, + but without finishing all the RPCs! + */ + + if (env.fault_occurred) + fprintf(stderr, "finishAsync() failed. Xmlrpc-c Curl transport " + "is now in an unknown state and may not be able to " + "continue functioning. Specifics of the failure: %s\n", + env.fault_string); + + xmlrpc_env_clean(&env); +} + + + +static void +call(xmlrpc_env * const envP, + struct xmlrpc_client_transport * const clientTransportP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block ** const responseXmlPP) { + + xmlrpc_mem_block * responseXmlP; + rpc * rpcP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(serverP); + XMLRPC_ASSERT_PTR_OK(callXmlP); + XMLRPC_ASSERT_PTR_OK(responseXmlPP); + + responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + if (!envP->fault_occurred) { + /* Only one RPC at a time can use a Curl session, so we have to + hold the lock as long as our RPC exists. + */ + lockSyncCurlSession(clientTransportP); + createRpc(envP, clientTransportP, clientTransportP->syncCurlSessionP, + serverP, + callXmlP, responseXmlP, + NULL, NULL, NULL, + &rpcP); + + if (!envP->fault_occurred) { + performRpc(envP, rpcP, clientTransportP->syncCurlMultiP, + clientTransportP->interruptP); + + *responseXmlPP = responseXmlP; + + destroyRpc(rpcP); + } + unlockSyncCurlSession(clientTransportP); + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, responseXmlP); + } +} + + + +static void +setupGlobalConstants(xmlrpc_env * const envP) { +/*---------------------------------------------------------------------------- + See longwinded discussion of the global constant issue at the top of + this file. +-----------------------------------------------------------------------------*/ + initWindowsStuff(envP); + + if (!envP->fault_occurred) { + CURLcode rc; + + rc = curl_global_init(CURL_GLOBAL_ALL); + + if (rc != CURLE_OK) + xmlrpc_faultf(envP, "curl_global_init() failed with code %d", rc); + } +} + + + +static void +teardownGlobalConstants(void) { +/*---------------------------------------------------------------------------- + See longwinded discussion of the global constant issue at the top of + this file. +-----------------------------------------------------------------------------*/ + curl_global_cleanup(); + + termWindowsStuff(); +} + + + +struct xmlrpc_client_transport_ops xmlrpc_curl_transport_ops = { + &setupGlobalConstants, + &teardownGlobalConstants, + &create, + &destroy, + &sendRequest, + &call, + &finishAsynch, + &setInterrupt, +}; diff --git a/trunk/lib/expat/Makefile b/trunk/lib/expat/Makefile new file mode 100644 index 000000000..d8828ff2a --- /dev/null +++ b/trunk/lib/expat/Makefile @@ -0,0 +1,70 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + LIBDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/expat + +include $(BLDDIR)/config.mk + +default: all + +SUBDIRS = gennmtab xmlparse xmltok + +PKGCONFIG_FILES_TO_INSTALL := xmlrpc_expat.pc + +include $(SRCDIR)/common.mk + +.PHONY: all +all: $(SUBDIRS:%=%/all) $(PKGCONFIG_FILES_TO_INSTALL) + +# Extra dependencies to make parallel make work in spite of all the submakes +# (See top level make file for details) +xmlparse/all: gennmtab/all xmltok/all +xmltok/all: gennmtab/all + +#----------------------------------------------------------------------------- +# RULES TO MAKE PKGCONFIG FILES +# +# (These are files used by the 'pkg-config' program to get information about +# using the libraries we build) +#----------------------------------------------------------------------------- + +xmlrpc_expat.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_expat" >>$@ + @echo "Description: Xmlrpc-c XML parsing library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_xmlparse -lxmlrpc_xmltok" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +.PHONY: clean +clean: $(SUBDIRS:%=%/clean) clean-common + +.PHONY: distclean +distclean: $(SUBDIRS:%=%/distclean) clean-common distclean-common + +.PHONY: tags +tags: $(SUBDIRS:%=%/tags) TAGS + +DISTFILES = + +.PHONY: distdir +distdir: distdir-common + +.PHONY: install +install: install-common $(SUBDIRS:%=%/install) + +.PHONY: uninstall +uninstall: uninstall-common $(SUBDIRS:%=%/uninstall) + +.PHONY: check +check: + +.PHONY: dep +dep: $(SUBDIRS:%=%/dep) + diff --git a/trunk/lib/expat/expat.html b/trunk/lib/expat/expat.html new file mode 100644 index 000000000..c555659b0 --- /dev/null +++ b/trunk/lib/expat/expat.html @@ -0,0 +1,93 @@ + + + + +expat + + + +

expat - XML Parser Toolkit

+ +

This is outdated stuff from the independently developed Expat which +was forked in 2001 to make the Xmlrpc-c embedded version. + +

Version 1.2

+ +

Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center +Ltd. Expat is freely available with source under a very liberal license (the MIT license).

+ +

This is a production version of expat. Relative to expat 1.1, it +adds support for parsing external DTDs and parameter entities. +Compiling with -DXML_DTD enables this support. There's a new +-p option for xmlwf which will cause it to process +external DTDs and parameter entities; this implies the -x +option. See the comment above XML_SetParamEntityParsing +in xmlparse.h for the API addition that enables this.

+ +

For Xmlrpc-c, we find no reason to exclude this function from the +library, and ifdefs make code harder to maintain, so we include the +function unconditionally. (i.e. -DXML_DTD does nothing). + +

Expat is an XML 1.0 parser +written in C. It aims to be fully conforming. It is currently not a +validating XML processor. The current production version of expat 1.X +can be downloaded from ftp://ftp.jclark.com/pub/xml/expat.zip.

+ +

Development of expat 2.0 is being handled by a team led by Clark +Cooper, hosted by sourceforge.net. See http://expat.sourceforge.net for +the latest on expat 2.0.

+ +

The directory xmltok contains a low-level library for +tokenizing XML. The interface is documented in +xmltok/xmltok.h.

+ +

The directory xmlparse contains an XML parser library +which is built on top of the xmltok library. The +interface is documented in xmlparse/xmlparse.h. The +directory sample contains a simple example program using +this interface; sample/build.bat is a batch file to build +the example using Visual C++.

+ +

The directory xmlwf contains the xmlwf +application, which uses the xmlparse library. The +arguments to xmlwf are one or more files which are each +to be checked for well-formedness. An option -d +dir can be specified; for each well-formed input +file the corresponding canonical XML will +be written to dir/f, where +f is the filename (without any path) of the +input file. A -x option will cause references to +external general entities to be processed. A -s option +will make documents that are not standalone cause an error (a document +is considered standalone if either it is intrinsically standalone +because it has no external subset and no references to parameter +entities in the internal subset or it is declared as standalone in the +XML declaration).

+ +

The bin directory contains Win32 executables. The +lib directory contains Win32 import libraries.

+ +

Answers to some frequently asked questions about expat can be found +in the expat +FAQ.

+ +

+ +
+ +James Clark + +
+ + + + diff --git a/trunk/lib/expat/gennmtab/Makefile b/trunk/lib/expat/gennmtab/Makefile new file mode 100644 index 000000000..93d4787f6 --- /dev/null +++ b/trunk/lib/expat/gennmtab/Makefile @@ -0,0 +1,49 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + EXPATDIR := $(call updir,$(CURDIR)) + LIBDIR := $(call updir,$(EXPATDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/expat/gennmtab + +include $(BLDDIR)/config.mk + +INCLUDES = -I$(BLDDIR) -Isrcdir/lib/util/include + +default: all + +include $(SRCDIR)/common.mk + +.PHONY: all +all: gennmtab + +.PHONY: clean +clean: clean-common + rm -f gennmtab + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: tags +tags: TAGS + +.PHONY: distdir +distdir: + +.PHONY: install +install: + +.PHONY: uninstall +uninstall: + +.PHONY: dep +dep: dep-common + +gennmtab.o:%.o:%.c + $(CC_FOR_BUILD) -c $< -o $@ $(CFLAGS_ALL_FOR_BUILD) + +gennmtab:%:%.o + $(CC_FOR_BUILD) -o $@ $(LDFLAGS_ALL_FOR_BUILD) $^ + +include depend.mk diff --git a/trunk/lib/expat/gennmtab/gennmtab.c b/trunk/lib/expat/gennmtab/gennmtab.c new file mode 100644 index 000000000..c6bdb7df1 --- /dev/null +++ b/trunk/lib/expat/gennmtab/gennmtab.c @@ -0,0 +1,433 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#include +#include +#include + +#include "xmlrpc_config.h" + +struct range { + int start; + int end; +}; + +struct range nmstrt[] = { + { '_', 0 }, + { ':', 0 }, + /* BaseChar */ + { 0x0041, 0x005a }, + { 0x0061, 0x007a }, + { 0x00c0, 0x00d6 }, + { 0x00d8, 0x00f6 }, + { 0x00f8, 0x00ff }, + { 0x0100, 0x0131 }, + { 0x0134, 0x013e }, + { 0x0141, 0x0148 }, + { 0x014a, 0x017e }, + { 0x0180, 0x01c3 }, + { 0x01cd, 0x01f0 }, + { 0x01f4, 0x01f5 }, + { 0x01fa, 0x0217 }, + { 0x0250, 0x02a8 }, + { 0x02bb, 0x02c1 }, + { 0x0386, 0 }, + { 0x0388, 0x038a }, + { 0x038c, 0 }, + { 0x038e, 0x03a1 }, + { 0x03a3, 0x03ce }, + { 0x03d0, 0x03d6 }, + { 0x03da, 0 }, + { 0x03dc, 0 }, + { 0x03de, 0 }, + { 0x03e0, 0 }, + { 0x03e2, 0x03f3 }, + { 0x0401, 0x040c }, + { 0x040e, 0x044f }, + { 0x0451, 0x045c }, + { 0x045e, 0x0481 }, + { 0x0490, 0x04c4 }, + { 0x04c7, 0x04c8 }, + { 0x04cb, 0x04cc }, + { 0x04d0, 0x04eb }, + { 0x04ee, 0x04f5 }, + { 0x04f8, 0x04f9 }, + { 0x0531, 0x0556 }, + { 0x0559, 0 }, + { 0x0561, 0x0586 }, + { 0x05d0, 0x05ea }, + { 0x05f0, 0x05f2 }, + { 0x0621, 0x063a }, + { 0x0641, 0x064a }, + { 0x0671, 0x06b7 }, + { 0x06ba, 0x06be }, + { 0x06c0, 0x06ce }, + { 0x06d0, 0x06d3 }, + { 0x06d5, 0 }, + { 0x06e5, 0x06e6 }, + { 0x0905, 0x0939 }, + { 0x093d, 0 }, + { 0x0958, 0x0961 }, + { 0x0985, 0x098c }, + { 0x098f, 0x0990 }, + { 0x0993, 0x09a8 }, + { 0x09aa, 0x09b0 }, + { 0x09b2, 0 }, + { 0x09b6, 0x09b9 }, + { 0x09dc, 0x09dd }, + { 0x09df, 0x09e1 }, + { 0x09f0, 0x09f1 }, + { 0x0a05, 0x0a0a }, + { 0x0a0f, 0x0a10 }, + { 0x0a13, 0x0a28 }, + { 0x0a2a, 0x0a30 }, + { 0x0a32, 0x0a33 }, + { 0x0a35, 0x0a36 }, + { 0x0a38, 0x0a39 }, + { 0x0a59, 0x0a5c }, + { 0x0a5e, 0 }, + { 0x0a72, 0x0a74 }, + { 0x0a85, 0x0a8b }, + { 0x0a8d, 0 }, + { 0x0a8f, 0x0a91 }, + { 0x0a93, 0x0aa8 }, + { 0x0aaa, 0x0ab0 }, + { 0x0ab2, 0x0ab3 }, + { 0x0ab5, 0x0ab9 }, + { 0x0abd, 0 }, + { 0x0ae0, 0 }, + { 0x0b05, 0x0b0c }, + { 0x0b0f, 0x0b10 }, + { 0x0b13, 0x0b28 }, + { 0x0b2a, 0x0b30 }, + { 0x0b32, 0x0b33 }, + { 0x0b36, 0x0b39 }, + { 0x0b3d, 0 }, + { 0x0b5c, 0x0b5d }, + { 0x0b5f, 0x0b61 }, + { 0x0b85, 0x0b8a }, + { 0x0b8e, 0x0b90 }, + { 0x0b92, 0x0b95 }, + { 0x0b99, 0x0b9a }, + { 0x0b9c, 0 }, + { 0x0b9e, 0x0b9f }, + { 0x0ba3, 0x0ba4 }, + { 0x0ba8, 0x0baa }, + { 0x0bae, 0x0bb5 }, + { 0x0bb7, 0x0bb9 }, + { 0x0c05, 0x0c0c }, + { 0x0c0e, 0x0c10 }, + { 0x0c12, 0x0c28 }, + { 0x0c2a, 0x0c33 }, + { 0x0c35, 0x0c39 }, + { 0x0c60, 0x0c61 }, + { 0x0c85, 0x0c8c }, + { 0x0c8e, 0x0c90 }, + { 0x0c92, 0x0ca8 }, + { 0x0caa, 0x0cb3 }, + { 0x0cb5, 0x0cb9 }, + { 0x0cde, 0 }, + { 0x0ce0, 0x0ce1 }, + { 0x0d05, 0x0d0c }, + { 0x0d0e, 0x0d10 }, + { 0x0d12, 0x0d28 }, + { 0x0d2a, 0x0d39 }, + { 0x0d60, 0x0d61 }, + { 0x0e01, 0x0e2e }, + { 0x0e30, 0 }, + { 0x0e32, 0x0e33 }, + { 0x0e40, 0x0e45 }, + { 0x0e81, 0x0e82 }, + { 0x0e84, 0 }, + { 0x0e87, 0x0e88 }, + { 0x0e8a, 0 }, + { 0x0e8d, 0 }, + { 0x0e94, 0x0e97 }, + { 0x0e99, 0x0e9f }, + { 0x0ea1, 0x0ea3 }, + { 0x0ea5, 0 }, + { 0x0ea7, 0 }, + { 0x0eaa, 0x0eab }, + { 0x0ead, 0x0eae }, + { 0x0eb0, 0 }, + { 0x0eb2, 0x0eb3 }, + { 0x0ebd, 0 }, + { 0x0ec0, 0x0ec4 }, + { 0x0f40, 0x0f47 }, + { 0x0f49, 0x0f69 }, + { 0x10a0, 0x10c5 }, + { 0x10d0, 0x10f6 }, + { 0x1100, 0 }, + { 0x1102, 0x1103 }, + { 0x1105, 0x1107 }, + { 0x1109, 0 }, + { 0x110b, 0x110c }, + { 0x110e, 0x1112 }, + { 0x113c, 0 }, + { 0x113e, 0 }, + { 0x1140, 0 }, + { 0x114c, 0 }, + { 0x114e, 0 }, + { 0x1150, 0 }, + { 0x1154, 0x1155 }, + { 0x1159, 0 }, + { 0x115f, 0x1161 }, + { 0x1163, 0 }, + { 0x1165, 0 }, + { 0x1167, 0 }, + { 0x1169, 0 }, + { 0x116d, 0x116e }, + { 0x1172, 0x1173 }, + { 0x1175, 0 }, + { 0x119e, 0 }, + { 0x11a8, 0 }, + { 0x11ab, 0 }, + { 0x11ae, 0x11af }, + { 0x11b7, 0x11b8 }, + { 0x11ba, 0 }, + { 0x11bc, 0x11c2 }, + { 0x11eb, 0 }, + { 0x11f0, 0 }, + { 0x11f9, 0 }, + { 0x1e00, 0x1e9b }, + { 0x1ea0, 0x1ef9 }, + { 0x1f00, 0x1f15 }, + { 0x1f18, 0x1f1d }, + { 0x1f20, 0x1f45 }, + { 0x1f48, 0x1f4d }, + { 0x1f50, 0x1f57 }, + { 0x1f59, 0 }, + { 0x1f5b, 0 }, + { 0x1f5d, 0 }, + { 0x1f5f, 0x1f7d }, + { 0x1f80, 0x1fb4 }, + { 0x1fb6, 0x1fbc }, + { 0x1fbe, 0 }, + { 0x1fc2, 0x1fc4 }, + { 0x1fc6, 0x1fcc }, + { 0x1fd0, 0x1fd3 }, + { 0x1fd6, 0x1fdb }, + { 0x1fe0, 0x1fec }, + { 0x1ff2, 0x1ff4 }, + { 0x1ff6, 0x1ffc }, + { 0x2126, 0 }, + { 0x212a, 0x212b }, + { 0x212e, 0 }, + { 0x2180, 0x2182 }, + { 0x3041, 0x3094 }, + { 0x30a1, 0x30fa }, + { 0x3105, 0x312c }, + { 0xac00, 0xd7a3 }, + /* Ideographic */ + { 0x4e00, 0x9fa5 }, + { 0x3007, 0 }, + { 0x3021, 0x3029 }, +}; + +/* name chars that are not name start chars */ +struct range name[] = { + { '.', 0 }, + { '-', 0 }, + /* CombiningChar */ + { 0x0300, 0x0345 }, + { 0x0360, 0x0361 }, + { 0x0483, 0x0486 }, + { 0x0591, 0x05a1 }, + { 0x05a3, 0x05b9 }, + { 0x05bb, 0x05bd }, + { 0x05bf, 0 }, + { 0x05c1, 0x05c2 }, + { 0x05c4, 0 }, + { 0x064b, 0x0652 }, + { 0x0670, 0 }, + { 0x06d6, 0x06dc }, + { 0x06dd, 0x06df }, + { 0x06e0, 0x06e4 }, + { 0x06e7, 0x06e8 }, + { 0x06ea, 0x06ed }, + { 0x0901, 0x0903 }, + { 0x093c, 0 }, + { 0x093e, 0x094c }, + { 0x094d, 0 }, + { 0x0951, 0x0954 }, + { 0x0962, 0x0963 }, + { 0x0981, 0x0983 }, + { 0x09bc, 0 }, + { 0x09be, 0 }, + { 0x09bf, 0 }, + { 0x09c0, 0x09c4 }, + { 0x09c7, 0x09c8 }, + { 0x09cb, 0x09cd }, + { 0x09d7, 0 }, + { 0x09e2, 0x09e3 }, + { 0x0a02, 0 }, + { 0x0a3c, 0 }, + { 0x0a3e, 0 }, + { 0x0a3f, 0 }, + { 0x0a40, 0x0a42 }, + { 0x0a47, 0x0a48 }, + { 0x0a4b, 0x0a4d }, + { 0x0a70, 0x0a71 }, + { 0x0a81, 0x0a83 }, + { 0x0abc, 0 }, + { 0x0abe, 0x0ac5 }, + { 0x0ac7, 0x0ac9 }, + { 0x0acb, 0x0acd }, + { 0x0b01, 0x0b03 }, + { 0x0b3c, 0 }, + { 0x0b3e, 0x0b43 }, + { 0x0b47, 0x0b48 }, + { 0x0b4b, 0x0b4d }, + { 0x0b56, 0x0b57 }, + { 0x0b82, 0x0b83 }, + { 0x0bbe, 0x0bc2 }, + { 0x0bc6, 0x0bc8 }, + { 0x0bca, 0x0bcd }, + { 0x0bd7, 0 }, + { 0x0c01, 0x0c03 }, + { 0x0c3e, 0x0c44 }, + { 0x0c46, 0x0c48 }, + { 0x0c4a, 0x0c4d }, + { 0x0c55, 0x0c56 }, + { 0x0c82, 0x0c83 }, + { 0x0cbe, 0x0cc4 }, + { 0x0cc6, 0x0cc8 }, + { 0x0cca, 0x0ccd }, + { 0x0cd5, 0x0cd6 }, + { 0x0d02, 0x0d03 }, + { 0x0d3e, 0x0d43 }, + { 0x0d46, 0x0d48 }, + { 0x0d4a, 0x0d4d }, + { 0x0d57, 0 }, + { 0x0e31, 0 }, + { 0x0e34, 0x0e3a }, + { 0x0e47, 0x0e4e }, + { 0x0eb1, 0 }, + { 0x0eb4, 0x0eb9 }, + { 0x0ebb, 0x0ebc }, + { 0x0ec8, 0x0ecd }, + { 0x0f18, 0x0f19 }, + { 0x0f35, 0 }, + { 0x0f37, 0 }, + { 0x0f39, 0 }, + { 0x0f3e, 0 }, + { 0x0f3f, 0 }, + { 0x0f71, 0x0f84 }, + { 0x0f86, 0x0f8b }, + { 0x0f90, 0x0f95 }, + { 0x0f97, 0 }, + { 0x0f99, 0x0fad }, + { 0x0fb1, 0x0fb7 }, + { 0x0fb9, 0 }, + { 0x20d0, 0x20dc }, + { 0x20e1, 0 }, + { 0x302a, 0x302f }, + { 0x3099, 0 }, + { 0x309a, 0 }, + /* Digit */ + { 0x0030, 0x0039 }, + { 0x0660, 0x0669 }, + { 0x06f0, 0x06f9 }, + { 0x0966, 0x096f }, + { 0x09e6, 0x09ef }, + { 0x0a66, 0x0a6f }, + { 0x0ae6, 0x0aef }, + { 0x0b66, 0x0b6f }, + { 0x0be7, 0x0bef }, + { 0x0c66, 0x0c6f }, + { 0x0ce6, 0x0cef }, + { 0x0d66, 0x0d6f }, + { 0x0e50, 0x0e59 }, + { 0x0ed0, 0x0ed9 }, + { 0x0f20, 0x0f29 }, + /* Extender */ + { 0xb7 , 0 }, + { 0x02d0, 0 }, + { 0x02d1, 0 }, + { 0x0387, 0 }, + { 0x0640, 0 }, + { 0x0e46, 0 }, + { 0x0ec6, 0 }, + { 0x3005, 0 }, + { 0x3031, 0x3035 }, + { 0x309d, 0x309e }, + { 0x30fc, 0x30fe }, +}; + +static void +setTab(char *tab, struct range *ranges, size_t nRanges) +{ + size_t i; + int j; + for (i = 0; i < nRanges; i++) { + if (ranges[i].end) { + for (j = ranges[i].start; j <= ranges[i].end; j++) + tab[j] = 1; + } + else + tab[ranges[i].start] = 1; + } +} + +static void +printTabs(char *tab) +{ + int nBitmaps = 2; + int i, j, k; + unsigned char pageIndex[512]; + + printf( +"static const unsigned namingBitmap[] = {\n\ +0x00000000, 0x00000000, 0x00000000, 0x00000000,\n\ +0x00000000, 0x00000000, 0x00000000, 0x00000000,\n\ +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n\ +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,\n"); + for (i = 0; i < 512; i++) { + int kind = tab[i*256]; + for (j = 1; j < 256; j++) + if (tab[i*256 +j] != kind) { + kind = -1; + break; + } + if (i >= 256 && memcmp(tab + (i - 256)*256, tab + i*256, 256) == 0) + pageIndex[i] = pageIndex[i - 256]; + else if (kind == -1) { + pageIndex[i] = nBitmaps++; + for (j = 0; j < 8; j++) { + unsigned val = 0; + for (k = 0; k < 32; k++) { + if (tab[i*256 + j*32 +k]) + val |= (1 << k); + } + printf("0x%08X,", val); + putchar((((j + 1) & 3) == 0) ? '\n' : ' '); + } + } + else + pageIndex[i] = kind; + } + printf("};\n"); + printf("static const unsigned char nmstrtPages[] = {\n"); + for (i = 0; i < 512; i++) { + if (i == 256) + printf("};\nstatic const unsigned char namePages[] = {\n"); + printf("0x%02X,", pageIndex[i]); + putchar((((i + 1) & 7) == 0) ? '\n' : ' '); + } + printf("};\n"); +} + +int +main(int const argc ATTR_UNUSED, + char ** const argv ATTR_UNUSED) { + + char tab[2*65536]; + memset(tab, 0, 65536); + setTab(tab, nmstrt, sizeof(nmstrt)/sizeof(nmstrt[0])); + memcpy(tab + 65536, tab, 65536); + setTab(tab + 65536, name, sizeof(name)/sizeof(name[0])); + printTabs(tab); + return 0; +} diff --git a/trunk/lib/expat/xmlparse/Makefile b/trunk/lib/expat/xmlparse/Makefile new file mode 100644 index 000000000..9df0d893f --- /dev/null +++ b/trunk/lib/expat/xmlparse/Makefile @@ -0,0 +1,96 @@ +############################################################################### +# This directory builds libxmlrpc_xmlparse, an XML parser. This is +# essentially the separately distributed Expat library from 2001, but +# with slight changes. The main reason it is bundled with Xmlrpc-c is +# to make the latter easier to build and use. +# +# The library is about XML in general. There is nothing specific to +# XML-RPC here. +############################################################################### + +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + EXPATDIR := $(call updir,$(CURDIR)) + LIBDIR := $(call updir,$(EXPATDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/expat/xmlparse + +XMLTOKDIR = srcdir/lib/expat/xmltok +UTILDIR = srcdir/lib/util + +default: all + +include $(BLDDIR)/config.mk + +TARGET_LIBRARY_NAMES := libxmlrpc_xmlparse + +STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_xmlparse.a + +SHARED_LIBS_TO_BUILD := libxmlrpc_xmlparse +SHARED_LIBS_TO_INSTALL := libxmlrpc_xmlparse + +TARGET_MODS = xmlparse + +OMIT_XMLPARSE_LIB_RULE=Y +MAJ=3 + # Major number of shared libraries in this directory + +include $(SRCDIR)/common.mk + +INCLUDES = \ + -I$(BLDDIR) \ + -I$(XMLTOKDIR) \ + -I$(UTILDIR)/include \ + -Isrcdir/include \ + +# LIBDEP is the shared libraries on which libxmlrpc_abyss depends. +# The runtime loader should load these libraries when it loads libxmlrpc_abyss. + +LIBDEP = $(LIBXMLRPC_XMLTOK) $(LIBXMLRPC_UTIL) + +XMLPARSE_SHLIB = $(call shlibfn,libxmlrpc_xmlparse) +#XMLPARSE_SHLIB is e.g. libxmlrpc_xmlparse.so.3.1 +XMLPARSE_SHLIBLE = $(call shliblefn,libxmlrpc_xmlparse) +#XMLPARSE_SHLIBLE is e.g. libxmlrpc_xmlparse.so + +.PHONY: all +all: libxmlrpc_xmlparse.a $(TARGET_SHARED_LIBRARIES) $(TARGET_SHARED_LE_LIBS) + +# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES: +$(XMLPARSE_SHLIB): $(TARGET_MODS:%=%.osh) $(LIBDEP) +$(XMLPARSE_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) $(LIBDEP) + +# Rule for this is in common.mk, courtesy of TARGET_STATIC_LIBRARIES: + +libxmlrpc_xmlparse.a: $(TARGET_MODS:%=%.o) +libxmlrpc_xmlparse.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) + +#----------------------------------------------------------------------------- +# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES +#----------------------------------------------------------------------------- + +# Rules to compile object modules from which to build the static and shared +# library are in common.mk, courtesy of TARGET_MODS. + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean distclean +clean: clean-common + +distclean: clean distclean-common + +.PHONY: dep +dep: dep-common + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir + +include depend.mk diff --git a/trunk/lib/expat/xmlparse/xmlparse.c b/trunk/lib/expat/xmlparse/xmlparse.c new file mode 100644 index 000000000..48adfb33c --- /dev/null +++ b/trunk/lib/expat/xmlparse/xmlparse.c @@ -0,0 +1,5029 @@ +/* +Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +/* In 2001, this was part of the Expat package. We copied it into + Xmlrpc-c because it's easier on the user than making him get and + link Expat separately, and we don't expect to benefit from separate + maintenance of Expat. + + But we changed all the external symbols that in Expat are named + "XML_xxxx" to "xmlrpc_XML_xxxx" because people do link Xmlrpc-c + libraries into programs that also link Expat (a good example is + where an Apache module uses Xmlrpc-c). We don't want our names to + collide with Expat's. +*/ + +#include +#include +#include /* UINT_MAX */ +#include /* time() */ + +#include "xmlrpc_config.h" +#include "c_util.h" +#include "girmath.h" +#include "mallocvar.h" +#include "xmlrpc-c/string_int.h" +#include "xmldef.h" +#include "xmlparse.h" + +static const char * +extractXmlSample(const char * const start, + const char * const end, + size_t const maximumLen) { + + size_t const len = MIN(maximumLen, (size_t)(end - start)); + + return xmlrpc_makePrintable_lp(start, len); +} + + + +#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX +#define XmlConvert XmlUtf8Convert +#define XmlGetInternalEncoding xmlrpc_XmlGetUtf8InternalEncoding +#define XmlGetInternalEncodingNS xmlrpc_XmlGetUtf8InternalEncodingNS +#define XmlEncode xmlrpc_XmlUtf8Encode +#define MUST_CONVERT(enc, s) (!(enc)->isUtf8) +typedef char ICHAR; + + +#ifndef XML_NS + +#define XmlInitEncodingNS XmlInitEncoding +#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding +#undef XmlGetInternalEncodingNS +#define XmlGetInternalEncodingNS XmlGetInternalEncoding +#define XmlParseXmlDeclNS XmlParseXmlDecl + +#endif + +/* XML_T is a vestige of conditionally compiled code that was never used in + Xmlrpc-c that made characters 16 bits. In that case, XML_T was defined + differently. +*/ + +#define XML_T(x) x + +/* Round up n to be a multiple of sz, where sz is a power of 2. */ +#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) + +#include "xmltok.h" +#include "xmlrole.h" + +typedef const XML_Char *KEY; + +typedef struct { + KEY name; +} NAMED; + +typedef struct { + NAMED **v; + size_t size; + size_t used; + size_t usedLim; +} HASH_TABLE; + +typedef struct { + NAMED **p; + NAMED **end; +} HASH_TABLE_ITER; + +#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ +#define INIT_DATA_BUF_SIZE 1024 +#define INIT_ATTS_SIZE 16 +#define INIT_BLOCK_SIZE 1024 +#define INIT_BUFFER_SIZE 1024 + +#define EXPAND_SPARE 24 + +typedef struct binding { + struct prefix *prefix; + struct binding *nextTagBinding; + struct binding *prevPrefixBinding; + const struct attribute_id *attId; + XML_Char *uri; + int uriLen; + int uriAlloc; +} BINDING; + +typedef struct prefix { + const XML_Char *name; + BINDING *binding; +} PREFIX; + +typedef struct { + const XML_Char *str; + const XML_Char *localPart; + int uriLen; +} TAG_NAME; + +typedef struct tag { + struct tag *parent; + const char *rawName; + int rawNameLength; + TAG_NAME name; + char *buf; + char *bufEnd; + BINDING *bindings; +} TAG; + +typedef struct { + const XML_Char *name; + const XML_Char *textPtr; + size_t textLen; + const XML_Char *systemId; + const XML_Char *base; + const XML_Char *publicId; + const XML_Char *notation; + char open; +} ENTITY; + +typedef struct block { + struct block *next; + int size; + XML_Char s[1]; +} BLOCK; + +typedef struct { + BLOCK *blocks; + BLOCK *freeBlocks; + const XML_Char *end; + XML_Char *ptr; + XML_Char *start; +} STRING_POOL; + +/* The XML_Char before the name is used to determine whether +an attribute has been specified. */ +typedef struct attribute_id { + XML_Char *name; + PREFIX *prefix; + char maybeTokenized; + char xmlns; +} ATTRIBUTE_ID; + +typedef struct { + const ATTRIBUTE_ID *id; + char isCdata; + const XML_Char *value; +} DEFAULT_ATTRIBUTE; + +typedef struct { + const XML_Char *name; + PREFIX *prefix; + const ATTRIBUTE_ID *idAtt; + int nDefaultAtts; + int allocDefaultAtts; + DEFAULT_ATTRIBUTE *defaultAtts; +} ELEMENT_TYPE; + +typedef struct { + HASH_TABLE generalEntities; + HASH_TABLE elementTypes; + HASH_TABLE attributeIds; + HASH_TABLE prefixes; + STRING_POOL pool; + int complete; + int standalone; + HASH_TABLE paramEntities; + PREFIX defaultPrefix; +} DTD; + +typedef struct open_internal_entity { + const char *internalEventPtr; + const char *internalEventEndPtr; + struct open_internal_entity *next; + ENTITY *entity; +} OPEN_INTERNAL_ENTITY; + +typedef void Processor(XML_Parser parser, + const char * const start, + const char * const end, + const char ** const endPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP); + +static +int setContext(XML_Parser parser, const XML_Char *context); + +#define poolStart(pool) ((pool)->start) +#define poolEnd(pool) ((pool)->ptr) +#define poolLength(pool) ((pool)->ptr - (pool)->start) +#define poolChop(pool) ((void)--(pool->ptr)) +#define poolLastChar(pool) (((pool)->ptr)[-1]) +#define poolDiscard(pool) ((pool)->ptr = (pool)->start) +#define poolFinish(pool) ((pool)->start = (pool)->ptr) + + +typedef struct { + /* The first member must be userData so that the XML_GetUserData macro works. */ + void *m_userData; + void *m_handlerArg; + char *m_buffer; + /* first character to be parsed */ + const char *m_bufferPtr; + /* past last character to be parsed */ + char *m_bufferEnd; + /* allocated end of buffer */ + const char *m_bufferLim; + long m_parseEndByteIndex; + const char *m_parseEndPtr; + XML_Char *m_dataBuf; + XML_Char *m_dataBufEnd; + XML_StartElementHandler m_startElementHandler; + XML_EndElementHandler m_endElementHandler; + XML_CharacterDataHandler m_characterDataHandler; + XML_ProcessingInstructionHandler m_processingInstructionHandler; + XML_CommentHandler m_commentHandler; + XML_StartCdataSectionHandler m_startCdataSectionHandler; + XML_EndCdataSectionHandler m_endCdataSectionHandler; + XML_DefaultHandler m_defaultHandler; + XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; + XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; + XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; + XML_NotationDeclHandler m_notationDeclHandler; + XML_ExternalParsedEntityDeclHandler m_externalParsedEntityDeclHandler; + XML_InternalParsedEntityDeclHandler m_internalParsedEntityDeclHandler; + XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; + XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; + XML_NotStandaloneHandler m_notStandaloneHandler; + XML_ExternalEntityRefHandler m_externalEntityRefHandler; + void *m_externalEntityRefHandlerArg; + XML_UnknownEncodingHandler m_unknownEncodingHandler; + const ENCODING *m_encoding; + INIT_ENCODING m_initEncoding; + const ENCODING *m_internalEncoding; + const XML_Char *m_protocolEncodingName; + /* NULL if no encoding assigned */ + int m_ns; + void *m_unknownEncodingMem; + void *m_unknownEncodingData; + void *m_unknownEncodingHandlerData; + void (*m_unknownEncodingRelease)(void *); + PROLOG_STATE m_prologState; + Processor *m_processor; + /* The next processor to run */ + enum XML_Error m_errorCode; + /* Explanation of the failure of the most recent call to Expat. + XML_ERROR_NONE means it didn't fail. This is redundant with + m_errorString if the latter is non-null. + The latter is newer and better. + */ + const char * m_errorString; + /* malloc'ed string describing the failure of the most recent call + to Expat. NULL means m_errorCode is the only error information + available. + */ + const char *m_eventPtr; + const char *m_eventEndPtr; + const char *m_positionPtr; + OPEN_INTERNAL_ENTITY *m_openInternalEntities; + int m_defaultExpandInternalEntities; + int m_tagLevel; + ENTITY *m_declEntity; + const XML_Char *m_declNotationName; + const XML_Char *m_declNotationPublicId; + ELEMENT_TYPE *m_declElementType; + ATTRIBUTE_ID *m_declAttributeId; + char m_declAttributeIsCdata; + char m_declAttributeIsId; + DTD m_dtd; + const XML_Char *m_curBase; + TAG *m_tagStack; + TAG *m_freeTagList; + BINDING *m_inheritedBindings; + BINDING *m_freeBindingList; + int m_attsSize; + int m_nSpecifiedAtts; + int m_idAttIndex; + ATTRIBUTE *m_atts; + POSITION m_position; + STRING_POOL m_tempPool; + STRING_POOL m_temp2Pool; + char *m_groupConnector; + unsigned m_groupSize; + int m_hadExternalDoctype; + XML_Char m_namespaceSeparator; + enum XML_ParamEntityParsing m_paramEntityParsing; + XML_Parser m_parentParser; + unsigned long m_hash_secret_salt; +} Parser; + +#define userData (((Parser *)parser)->m_userData) +#define handlerArg (((Parser *)parser)->m_handlerArg) +#define startElementHandler (((Parser *)parser)->m_startElementHandler) +#define endElementHandler (((Parser *)parser)->m_endElementHandler) +#define characterDataHandler (((Parser *)parser)->m_characterDataHandler) +#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler) +#define commentHandler (((Parser *)parser)->m_commentHandler) +#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler) +#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler) +#define defaultHandler (((Parser *)parser)->m_defaultHandler) +#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler) +#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler) +#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler) +#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler) +#define externalParsedEntityDeclHandler (((Parser *)parser)->m_externalParsedEntityDeclHandler) +#define internalParsedEntityDeclHandler (((Parser *)parser)->m_internalParsedEntityDeclHandler) +#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler) +#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler) +#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler) +#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler) +#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg) +#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler) +#define initEncoding (((Parser *)parser)->m_initEncoding) +#define internalEncoding (((Parser *)parser)->m_internalEncoding) +#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem) +#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData) +#define unknownEncodingHandlerData \ + (((Parser *)parser)->m_unknownEncodingHandlerData) +#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease) +#define ns (((Parser *)parser)->m_ns) +#define prologState (((Parser *)parser)->m_prologState) +#define processor (((Parser *)parser)->m_processor) +#define errorCode (((Parser *)parser)->m_errorCode) +#define errorString (((Parser *)parser)->m_errorString) +#define eventPtr (((Parser *)parser)->m_eventPtr) +#define eventEndPtr (((Parser *)parser)->m_eventEndPtr) +#define positionPtr (((Parser *)parser)->m_positionPtr) +#define position (((Parser *)parser)->m_position) +#define openInternalEntities (((Parser *)parser)->m_openInternalEntities) +#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities) +#define tagLevel (((Parser *)parser)->m_tagLevel) +#define buffer (((Parser *)parser)->m_buffer) +#define bufferPtr (((Parser *)parser)->m_bufferPtr) +#define bufferEnd (((Parser *)parser)->m_bufferEnd) +#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex) +#define parseEndPtr (((Parser *)parser)->m_parseEndPtr) +#define bufferLim (((Parser *)parser)->m_bufferLim) +#define dataBuf (((Parser *)parser)->m_dataBuf) +#define dataBufEnd (((Parser *)parser)->m_dataBufEnd) +#define dtd (((Parser *)parser)->m_dtd) +#define curBase (((Parser *)parser)->m_curBase) +#define declEntity (((Parser *)parser)->m_declEntity) +#define declNotationName (((Parser *)parser)->m_declNotationName) +#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId) +#define declElementType (((Parser *)parser)->m_declElementType) +#define declAttributeId (((Parser *)parser)->m_declAttributeId) +#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata) +#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId) +#define freeTagList (((Parser *)parser)->m_freeTagList) +#define freeBindingList (((Parser *)parser)->m_freeBindingList) +#define inheritedBindings (((Parser *)parser)->m_inheritedBindings) +#define tagStack (((Parser *)parser)->m_tagStack) +#define atts (((Parser *)parser)->m_atts) +#define attsSize (((Parser *)parser)->m_attsSize) +#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts) +#define idAttIndex (((Parser *)parser)->m_idAttIndex) +#define tempPool (((Parser *)parser)->m_tempPool) +#define temp2Pool (((Parser *)parser)->m_temp2Pool) +#define groupConnector (((Parser *)parser)->m_groupConnector) +#define groupSize (((Parser *)parser)->m_groupSize) +#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype) +#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator) +#define parentParser (((Parser *)parser)->m_parentParser) +#define hash_secret_salt (((Parser *)parser)->m_hash_secret_salt) + + + +static +void poolInit(STRING_POOL *pool) +{ + pool->blocks = 0; + pool->freeBlocks = 0; + pool->start = 0; + pool->ptr = 0; + pool->end = 0; +} + +static +void poolClear(STRING_POOL *pool) +{ + if (!pool->freeBlocks) + pool->freeBlocks = pool->blocks; + else { + BLOCK *p = pool->blocks; + while (p) { + BLOCK *tem = p->next; + p->next = pool->freeBlocks; + pool->freeBlocks = p; + p = tem; + } + } + pool->blocks = 0; + pool->start = 0; + pool->ptr = 0; + pool->end = 0; +} + +static +void poolDestroy(STRING_POOL *pool) +{ + BLOCK *p = pool->blocks; + while (p) { + BLOCK *tem = p->next; + free(p); + p = tem; + } + pool->blocks = 0; + p = pool->freeBlocks; + while (p) { + BLOCK *tem = p->next; + free(p); + p = tem; + } + pool->freeBlocks = 0; + pool->ptr = 0; + pool->start = 0; + pool->end = 0; +} + + + +static void +poolGrowFromFreeBlocks(STRING_POOL * const poolP, + bool * const wasGrownFromFreeBlocksP) { + + if (poolP->freeBlocks) { + if (poolP->start == 0) { + poolP->blocks = poolP->freeBlocks; + poolP->freeBlocks = poolP->freeBlocks->next; + poolP->blocks->next = 0; + poolP->start = poolP->blocks->s; + poolP->end = poolP->start + poolP->blocks->size; + poolP->ptr = poolP->start; + + *wasGrownFromFreeBlocksP = true; + } else if (poolP->end - poolP->start < poolP->freeBlocks->size) { + BLOCK * const newFreeBlocks = poolP->freeBlocks->next; + + poolP->freeBlocks->next = poolP->blocks; + poolP->blocks = poolP->freeBlocks; + poolP->freeBlocks = newFreeBlocks; + memcpy(poolP->blocks->s, poolP->start, + (poolP->end - poolP->start) * sizeof(XML_Char)); + poolP->ptr = poolP->blocks->s + (poolP->ptr - poolP->start); + poolP->start = poolP->blocks->s; + poolP->end = poolP->start + poolP->blocks->size; + + *wasGrownFromFreeBlocksP = true; + } + } else + *wasGrownFromFreeBlocksP = false; +} + + + +static void +poolGrow(STRING_POOL * const poolP, + const char ** const errorP) { + + bool wasGrownFromFreeBlocks; + + poolGrowFromFreeBlocks(poolP, &wasGrownFromFreeBlocks); + + if (wasGrownFromFreeBlocks) + *errorP = NULL; + else { + if (poolP->blocks && poolP->start == poolP->blocks->s) { + size_t const blockSize = (poolP->end - poolP->start)*2; + size_t const newSize = + offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); + + BLOCK * const newBlocks = realloc(poolP->blocks, newSize); + + if (newBlocks) { + poolP->blocks = newBlocks; + poolP->blocks->size = blockSize; + poolP->ptr = poolP->blocks->s + (poolP->ptr - poolP->start); + poolP->start = poolP->blocks->s; + poolP->end = poolP->start + blockSize; + *errorP = NULL; + } else + xmlrpc_asprintf(errorP, + "Failed to allocate %u bytes of memory", + (unsigned)newSize); + } else { + size_t const poolLen = poolP->end - poolP->start; + size_t const blockSize = + poolLen < INIT_BLOCK_SIZE ? INIT_BLOCK_SIZE : poolLen * 2; + size_t const newSize = + offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); + + BLOCK * const newBlocksP = malloc(newSize); + + if (newBlocksP) { + newBlocksP->size = blockSize; + newBlocksP->next = poolP->blocks; + poolP->blocks = newBlocksP; + if (poolP->ptr != poolP->start) + memcpy(newBlocksP->s, poolP->start, + (poolP->ptr - poolP->start) * sizeof(XML_Char)); + poolP->ptr = newBlocksP->s + (poolP->ptr - poolP->start); + poolP->start = newBlocksP->s; + poolP->end = newBlocksP->s + blockSize; + *errorP = NULL; + } else + xmlrpc_asprintf(errorP, + "Failed to allocate %u bytes of memory", + (unsigned)newSize); + } + } +} + + + +static +XML_Char * +poolAppend(STRING_POOL * const poolP, + const ENCODING * const encodingP, + const char * const initialPtr, + const char * const end) { + + const char * ptr; + + ptr = initialPtr; /* initial value */ + + if (!poolP->ptr) { + const char * error; + + poolGrow(poolP, &error); + + if (error) { + xmlrpc_strfree(error); + return NULL; + } + } + + for (;;) { + const char * error; + + XmlConvert(encodingP, &ptr, end, (ICHAR **)&(poolP->ptr), + (ICHAR *)poolP->end); + + if (ptr == end) + break; + + poolGrow(poolP, &error); + + if (error) { + xmlrpc_strfree(error); + return NULL; + } + } + return poolP->start; +} + + + +static bool +poolAppendChar(STRING_POOL * const poolP, + XML_Char const c) { + + bool retval; + const char * error; + + if (poolP->ptr == poolP->end) + poolGrow(poolP, &error); + else + error = NULL; + + if (error) { + xmlrpc_strfree(error); + retval = false; + } else { + *poolP->ptr++ = c; + + retval = true; + } + return retval; +} + + + +static const XML_Char * +poolCopyString(STRING_POOL * const poolP, + const XML_Char * const source) { + + const XML_Char * retval; + const XML_Char * s; + + s = &source[0]; /* initial value */ + + do { + if (!poolAppendChar(poolP, *s)) + return 0; + } while (*s++); + + retval = poolP->start; + + poolFinish(poolP); + + return retval; +} + + + +static const XML_Char * +poolCopyStringN(STRING_POOL * const poolP, + const XML_Char * const source, + int const size) { + + const XML_Char * retval; + const XML_Char * s; + int n; + + s = source; /* initial value */ + n = size; /* initial value */ + + if (!poolP->ptr) { + const char * error; + poolGrow(poolP, &error); + if (error) { + xmlrpc_strfree(error); + return NULL; + } + } + + for (; n > 0; --n, ++s) { + if (!poolAppendChar(poolP, *s)) + return NULL; + } + retval = poolP->start; + + poolFinish(poolP); + + return retval; +} + + + +static XML_Char * +poolStoreString(STRING_POOL * const poolP, + const ENCODING * const encodingP, + const char * const ptr, + const char * const end) { + + if (!poolAppend(poolP, encodingP, ptr, end)) + return NULL; + + if (poolP->ptr == poolP->end) { + const char * error; + poolGrow(poolP, &error); + if (error) { + xmlrpc_strfree(error); + return NULL; + } + } + + *(poolP->ptr)++ = 0; + + return poolP->start; +} + + + +static unsigned long +generate_hash_secret_salt(void) +{ + unsigned int seed = time(NULL) % UINT_MAX; + srand(seed); + return rand(); +} + +static int /* only valid for root parser */ +startParsing(XML_Parser parser) +{ + static + const XML_Char implicitContext[] = { + XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='), + XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'), + XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'), + XML_T('.'), XML_T('w'), XML_T('3'), + XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'), + XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'), + XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'), + XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'), + XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'), + XML_T('\0') + }; + + /* hash functions must be initialized before setContext() is called */ + if (hash_secret_salt == 0) + hash_secret_salt = generate_hash_secret_salt(); + if (parser) + return setContext(parser, implicitContext); + return 0; +} + +#define INIT_SIZE 64 + +static +int keyeq(KEY s1, KEY s2) +{ + for (; *s1 == *s2; s1++, s2++) + if (*s1 == 0) + return 1; + return 0; +} + +static +unsigned long hash(XML_Parser parser, KEY s) +{ + unsigned long h = hash_secret_salt; + while (*s) + h = (h << 5) + h + (unsigned char)*s++; + return h; +} + +static +NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) +{ + size_t i; + if (table->size == 0) { + if (!createSize) + return 0; + table->v = calloc(INIT_SIZE, sizeof(NAMED *)); + if (!table->v) + return 0; + table->size = INIT_SIZE; + table->usedLim = INIT_SIZE / 2; + i = hash(parser, name) & (table->size - 1); + } + else { + unsigned long h = hash(parser, name); + for (i = h & (table->size - 1); + table->v[i]; + i == 0 ? i = table->size - 1 : --i) { + if (keyeq(name, table->v[i]->name)) + return table->v[i]; + } + if (!createSize) + return 0; + if (table->used == table->usedLim) { + /* check for overflow */ + size_t newSize = table->size * 2; + NAMED **newV = calloc(newSize, sizeof(NAMED *)); + if (!newV) + return 0; + for (i = 0; i < table->size; i++) + if (table->v[i]) { + size_t j; + for (j = hash(parser, table->v[i]->name) & (newSize - 1); + newV[j]; + j == 0 ? j = newSize - 1 : --j) + ; + newV[j] = table->v[i]; + } + free(table->v); + table->v = newV; + table->size = newSize; + table->usedLim = newSize/2; + for (i = h & (table->size - 1); + table->v[i]; + i == 0 ? i = table->size - 1 : --i) + ; + } + } + table->v[i] = calloc(1, createSize); + if (!table->v[i]) + return 0; + table->v[i]->name = name; + (table->used)++; + return table->v[i]; +} + +static +void hashTableDestroy(HASH_TABLE *table) +{ + size_t i; + for (i = 0; i < table->size; i++) { + NAMED *p = table->v[i]; + if (p) + free(p); + } + if (table->v) + free(table->v); +} + +static +void hashTableInit(HASH_TABLE *p) +{ + p->size = 0; + p->usedLim = 0; + p->used = 0; + p->v = 0; +} + +static +void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) +{ + iter->p = table->v; + iter->end = iter->p + table->size; +} + +static +NAMED *hashTableIterNext(HASH_TABLE_ITER *iter) +{ + while (iter->p != iter->end) { + NAMED *tem = *(iter->p)++; + if (tem) + return tem; + } + return 0; +} + + + +static int dtdInit(DTD *p) +{ + poolInit(&(p->pool)); + hashTableInit(&(p->generalEntities)); + hashTableInit(&(p->elementTypes)); + hashTableInit(&(p->attributeIds)); + hashTableInit(&(p->prefixes)); + p->complete = 1; + p->standalone = 0; + hashTableInit(&(p->paramEntities)); + p->defaultPrefix.name = 0; + p->defaultPrefix.binding = 0; + return 1; +} + + + +static void dtdSwap(DTD *p1, DTD *p2) +{ + DTD tem; + memcpy(&tem, p1, sizeof(DTD)); + memcpy(p1, p2, sizeof(DTD)); + memcpy(p2, &tem, sizeof(DTD)); +} + + + + +static void dtdDestroy(DTD *p) +{ + HASH_TABLE_ITER iter; + hashTableIterInit(&iter, &(p->elementTypes)); + for (;;) { + ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (!e) + break; + if (e->allocDefaultAtts != 0) + free(e->defaultAtts); + } + hashTableDestroy(&(p->generalEntities)); + hashTableDestroy(&(p->paramEntities)); + hashTableDestroy(&(p->elementTypes)); + hashTableDestroy(&(p->attributeIds)); + hashTableDestroy(&(p->prefixes)); + poolDestroy(&(p->pool)); +} + +static int copyEntityTable(XML_Parser oldParser, + HASH_TABLE *newTable, + STRING_POOL *newPool, + const HASH_TABLE *oldTable) +{ + HASH_TABLE_ITER iter; + const XML_Char *cachedOldBase = 0; + const XML_Char *cachedNewBase = 0; + + hashTableIterInit(&iter, oldTable); + + for (;;) { + ENTITY *newE; + const XML_Char *name; + const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); + if (!oldE) + break; + name = poolCopyString(newPool, oldE->name); + if (!name) + return 0; + newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); + if (!newE) + return 0; + if (oldE->systemId) { + const XML_Char *tem = poolCopyString(newPool, oldE->systemId); + if (!tem) + return 0; + newE->systemId = tem; + if (oldE->base) { + if (oldE->base == cachedOldBase) + newE->base = cachedNewBase; + else { + cachedOldBase = oldE->base; + tem = poolCopyString(newPool, cachedOldBase); + if (!tem) + return 0; + cachedNewBase = newE->base = tem; + } + } + } + else { + const XML_Char *tem = + poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); + if (!tem) + return 0; + newE->textPtr = tem; + newE->textLen = oldE->textLen; + } + if (oldE->notation) { + const XML_Char *tem = poolCopyString(newPool, oldE->notation); + if (!tem) + return 0; + newE->notation = tem; + } + } + return 1; +} + + + +/* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise. +The new DTD has already been initialized. */ + +static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd) +{ + HASH_TABLE_ITER iter; + + /* Copy the prefix table. */ + + hashTableIterInit(&iter, &(oldDtd->prefixes)); + for (;;) { + const XML_Char *name; + const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); + if (!oldP) + break; + name = poolCopyString(&(newDtd->pool), oldP->name); + if (!name) + return 0; + if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) + return 0; + } + + hashTableIterInit(&iter, &(oldDtd->attributeIds)); + + /* Copy the attribute id table. */ + + for (;;) { + ATTRIBUTE_ID *newA; + const XML_Char *name; + const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); + + if (!oldA) + break; + /* Remember to allocate the scratch byte before the name. */ + if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) + return 0; + name = poolCopyString(&(newDtd->pool), oldA->name); + if (!name) + return 0; + ++name; + newA = (ATTRIBUTE_ID *) + lookup(oldParser, &(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID)); + if (!newA) + return 0; + newA->maybeTokenized = oldA->maybeTokenized; + if (oldA->prefix) { + newA->xmlns = oldA->xmlns; + if (oldA->prefix == &oldDtd->defaultPrefix) + newA->prefix = &newDtd->defaultPrefix; + else + newA->prefix = (PREFIX *) + lookup(oldParser, &(newDtd->prefixes), oldA->prefix->name, 0); + } + } + + /* Copy the element type table. */ + + hashTableIterInit(&iter, &(oldDtd->elementTypes)); + + for (;;) { + int i; + ELEMENT_TYPE *newE; + const XML_Char *name; + const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (!oldE) + break; + name = poolCopyString(&(newDtd->pool), oldE->name); + if (!name) + return 0; + newE = (ELEMENT_TYPE *) + lookup(oldParser, &(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE)); + if (!newE) + return 0; + if (oldE->nDefaultAtts) { + newE->defaultAtts = (DEFAULT_ATTRIBUTE *) + malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); + if (!newE->defaultAtts) + return 0; + } + if (oldE->idAtt) + newE->idAtt = (ATTRIBUTE_ID *) + lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0); + newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; + if (oldE->prefix) + newE->prefix = (PREFIX *) + lookup(oldParser, &(newDtd->prefixes), oldE->prefix->name, 0); + for (i = 0; i < newE->nDefaultAtts; i++) { + newE->defaultAtts[i].id = (ATTRIBUTE_ID *) + lookup(oldParser, &(newDtd->attributeIds), + oldE->defaultAtts[i].id->name, 0); + newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; + if (oldE->defaultAtts[i].value) { + newE->defaultAtts[i].value = + poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); + if (!newE->defaultAtts[i].value) + return 0; + } + else + newE->defaultAtts[i].value = 0; + } + } + + /* Copy the entity tables. */ + if (!copyEntityTable(oldParser, &(newDtd->generalEntities), + &(newDtd->pool), + &(oldDtd->generalEntities))) + return 0; + + if (!copyEntityTable(oldParser, &(newDtd->paramEntities), + &(newDtd->pool), + &(oldDtd->paramEntities))) + return 0; + + newDtd->complete = oldDtd->complete; + newDtd->standalone = oldDtd->standalone; + return 1; +} + + + +static +int addBinding(XML_Parser parser, + PREFIX *prefix, + const ATTRIBUTE_ID *attId, + const XML_Char *uri, + BINDING **bindingsPtr) +{ + BINDING *b; + int len; + for (len = 0; uri[len]; len++) + ; + if (namespaceSeparator) + len++; + if (freeBindingList) { + b = freeBindingList; + if (len > b->uriAlloc) { + XML_Char *temp = realloc(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); + if (!temp) + return 0; + b->uri = temp; + b->uriAlloc = len + EXPAND_SPARE; + } + freeBindingList = b->nextTagBinding; + } + else { + b = malloc(sizeof(BINDING)); + if (!b) + return 0; + b->uri = malloc(sizeof(XML_Char) * (len + EXPAND_SPARE)); + if (!b->uri) { + free(b); + return 0; + } + b->uriAlloc = len + EXPAND_SPARE; + } + b->uriLen = len; + memcpy(b->uri, uri, len * sizeof(XML_Char)); + if (namespaceSeparator) + b->uri[len - 1] = namespaceSeparator; + b->prefix = prefix; + b->attId = attId; + b->prevPrefixBinding = prefix->binding; + if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix) + prefix->binding = 0; + else + prefix->binding = b; + b->nextTagBinding = *bindingsPtr; + *bindingsPtr = b; + if (startNamespaceDeclHandler) + startNamespaceDeclHandler(handlerArg, prefix->name, + prefix->binding ? uri : 0); + return 1; +} + + + +#define CONTEXT_SEP XML_T('\f') + +static +const XML_Char *getContext(XML_Parser parser) +{ + HASH_TABLE_ITER iter; + int needSep = 0; + + if (dtd.defaultPrefix.binding) { + int i; + int len; + if (!poolAppendChar(&tempPool, XML_T('='))) + return 0; + len = dtd.defaultPrefix.binding->uriLen; + if (namespaceSeparator != XML_T('\0')) + len--; + for (i = 0; i < len; i++) + if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i])) + return 0; + needSep = 1; + } + + hashTableIterInit(&iter, &(dtd.prefixes)); + for (;;) { + int i; + int len; + const XML_Char *s; + PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); + if (!prefix) + break; + if (!prefix->binding) + continue; + if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) + return 0; + for (s = prefix->name; *s; s++) + if (!poolAppendChar(&tempPool, *s)) + return 0; + if (!poolAppendChar(&tempPool, XML_T('='))) + return 0; + len = prefix->binding->uriLen; + if (namespaceSeparator != XML_T('\0')) + len--; + for (i = 0; i < len; i++) + if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) + return 0; + needSep = 1; + } + + + hashTableIterInit(&iter, &(dtd.generalEntities)); + for (;;) { + const XML_Char *s; + ENTITY *e = (ENTITY *)hashTableIterNext(&iter); + if (!e) + break; + if (!e->open) + continue; + if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) + return 0; + for (s = e->name; *s; s++) + if (!poolAppendChar(&tempPool, *s)) + return 0; + needSep = 1; + } + + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return 0; + return tempPool.start; +} + +static +int setContext(XML_Parser parser, const XML_Char *context) +{ + const XML_Char *s = context; + + while (*context != XML_T('\0')) { + if (*s == CONTEXT_SEP || *s == XML_T('\0')) { + ENTITY *e; + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return 0; + e = (ENTITY *)lookup(parser, &dtd.generalEntities, poolStart(&tempPool), + 0); + if (e) + e->open = 1; + if (*s != XML_T('\0')) + s++; + context = s; + poolDiscard(&tempPool); + } + else if (*s == '=') { + PREFIX *prefix; + if (poolLength(&tempPool) == 0) + prefix = &dtd.defaultPrefix; + else { + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return 0; + prefix = (PREFIX *) + lookup(parser, &dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX)); + if (!prefix) + return 0; + if (prefix->name == poolStart(&tempPool)) { + prefix->name = poolCopyString(&dtd.pool, prefix->name); + if (!prefix->name) + return 0; + } + poolDiscard(&tempPool); + } + for (context = s + 1; + *context != CONTEXT_SEP && *context != XML_T('\0'); + ++context) + if (!poolAppendChar(&tempPool, *context)) + return 0; + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return 0; + if (!addBinding(parser, prefix, 0, poolStart(&tempPool), + &inheritedBindings)) + return 0; + poolDiscard(&tempPool); + if (*context != XML_T('\0')) + ++context; + s = context; + } + else { + if (!poolAppendChar(&tempPool, *s)) + return 0; + s++; + } + } + return 1; +} + + + +static void +normalizeLines(XML_Char *s) +{ + XML_Char *p; + for (;; s++) { + if (*s == XML_T('\0')) + return; + if (*s == 0xD) + break; + } + p = s; + do { + if (*s == 0xD) { + *p++ = 0xA; + if (*++s == 0xA) + s++; + } + else + *p++ = *s++; + } while (*s); + *p = XML_T('\0'); +} + + + +struct EventPtr { + const char ** startP; + const char ** endP; +}; + + + +static struct EventPtr +getEventPtr(XML_Parser const xmlParserP, + const ENCODING * const encoderP) { + + Parser * const parserP = xmlParserP; + + struct EventPtr retval; + + if (encoderP == parserP->m_encoding) { + retval.startP = &parserP->m_eventPtr; + retval.endP = &parserP->m_eventEndPtr; + } else { + retval.startP = &parserP->m_openInternalEntities->internalEventPtr; + retval.endP = &parserP->m_openInternalEntities->internalEventEndPtr; + } + + return retval; +} + + + +static void +reportDefault(XML_Parser const xmlParserP, + const ENCODING * const encoderP, + const char * const start, + const char * const end) { + + Parser * const parser = (Parser *)xmlParserP; + + if (MUST_CONVERT(encoderP, start)) { + struct EventPtr const evPtr = getEventPtr(xmlParserP, encoderP); + + const char * inCursor; + + inCursor = start; + do { + ICHAR * dataPtr; + + dataPtr = (ICHAR *)parser->m_dataBuf; /* initial value */ + + XmlConvert(encoderP, &inCursor, end, + &dataPtr, (ICHAR *)parser->m_dataBufEnd); + *evPtr.endP = inCursor; + { + size_t const len = dataPtr - (ICHAR *)parser->m_dataBuf; + assert((size_t)(int)len == len); /* parser requirement */ + defaultHandler(parser->m_handlerArg, + parser->m_dataBuf, (int)len); + } + *evPtr.startP = inCursor; + } while (inCursor != end); + } else { + size_t const len = (XML_Char *)end - (XML_Char *)start; + assert((size_t)(int)len == len); /* parser requirement */ + defaultHandler(parser->m_handlerArg, (XML_Char *)start, len); + } +} + + + +static void +processDataCharsToken(XML_Parser * const xmlParserP, + const ENCODING * const encoderP, + const char * const tokenStart, + const char * const tokenEnd) { + + Parser * const parser = (Parser *)xmlParserP; + /* For use by macros */ + + if (characterDataHandler) { + if (MUST_CONVERT(encoderP, tokenStart)) { + struct EventPtr const evPtr = getEventPtr(xmlParserP, encoderP); + + const char * inCursor; + for (inCursor = tokenStart; inCursor < tokenEnd;) { + + ICHAR * outCursor; + + outCursor = (ICHAR *)dataBuf; + *evPtr.startP = inCursor; + assert((ICHAR *)dataBufEnd - (ICHAR *)dataBuf >= 4); + + XmlConvert(encoderP, &inCursor, tokenEnd, &outCursor, + (ICHAR *)dataBufEnd); + + *evPtr.endP = inCursor; + { + size_t const len = outCursor - (ICHAR *)dataBuf; + assert((size_t)(int)len == len); /* parser reqt */ + characterDataHandler(handlerArg, dataBuf, (int)len); + } + } + } else { + size_t const len = (XML_Char *)tokenEnd - (XML_Char *)tokenStart; + assert((size_t)(int)len == len); /* parser reqt */ + characterDataHandler(handlerArg, (XML_Char *)tokenStart, len); + } + } else if (defaultHandler) + reportDefault(xmlParserP, encoderP, tokenStart, tokenEnd); +} + + + +static int +reportProcessingInstruction(XML_Parser parser, + const ENCODING *enc, + const char *start, + const char *end) +{ + const XML_Char *target; + XML_Char *data; + const char *tem; + if (!processingInstructionHandler) { + if (defaultHandler) + reportDefault(parser, enc, start, end); + return 1; + } + start += enc->minBytesPerChar * 2; + tem = start + XmlNameLength(enc, start); + target = poolStoreString(&tempPool, enc, start, tem); + if (!target) + return 0; + poolFinish(&tempPool); + data = poolStoreString(&tempPool, enc, + XmlSkipS(enc, tem), + end - enc->minBytesPerChar*2); + if (!data) + return 0; + normalizeLines(data); + processingInstructionHandler(handlerArg, target, data); + poolClear(&tempPool); + return 1; +} + +static int +reportComment(XML_Parser parser, + const ENCODING *enc, + const char *start, + const char *end) +{ + XML_Char *data; + if (!commentHandler) { + if (defaultHandler) + reportDefault(parser, enc, start, end); + return 1; + } + data = poolStoreString(&tempPool, + enc, + start + enc->minBytesPerChar * 4, + end - enc->minBytesPerChar * 3); + if (!data) + return 0; + normalizeLines(data); + commentHandler(handlerArg, data); + poolClear(&tempPool); + return 1; +} + + + +static void +initXmlEncoding(XML_Encoding * const xmlEncP) { + + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(xmlEncP->map); ++i) + xmlEncP->map[i] = -1; + + xmlEncP->convert = 0; + xmlEncP->data = 0; + xmlEncP->release = 0; +} + + + +static enum XML_Error +handleUnknownEncoding(XML_Parser const xmlParserP, + const XML_Char * const encodingName) { + + Parser * const parser = (Parser *) xmlParserP; + + if (unknownEncodingHandler) { + XML_Encoding info; + + initXmlEncoding(&info); + + if (unknownEncodingHandler(unknownEncodingHandlerData, + encodingName, &info)) { + ENCODING * enc; + unknownEncodingMem = malloc(xmlrpc_XmlSizeOfUnknownEncoding()); + if (!unknownEncodingMem) { + if (info.release) + info.release(info.data); + return XML_ERROR_NO_MEMORY; + } + enc = (ns + ? xmlrpc_XmlInitUnknownEncodingNS + : xmlrpc_XmlInitUnknownEncoding)(unknownEncodingMem, + info.map, + info.convert, + info.data); + if (enc) { + unknownEncodingData = info.data; + unknownEncodingRelease = info.release; + parser->m_encoding = enc; + return XML_ERROR_NONE; + } + } + if (info.release) + info.release(info.data); + } + return XML_ERROR_UNKNOWN_ENCODING; +} + + + +static enum XML_Error +initializeEncoding(XML_Parser const xmlParserP) { + + Parser * const parser = (Parser *) xmlParserP; + + enum XML_Error retval; + int rc; + + rc = (ns ? xmlrpc_XmlInitEncodingNS : xmlrpc_XmlInitEncoding)( + &parser->m_initEncoding, &parser->m_encoding, + parser->m_protocolEncodingName); + + if (rc == 0) { + /* 'parser->m_protocolEncodingName' is not a recognized name */ + retval = handleUnknownEncoding(xmlParserP, + parser->m_protocolEncodingName); + } else + retval = XML_ERROR_NONE; + + return retval; +} + + + +static void +handleUnknownEncoding0(XML_Parser const xmlParserP, + const char * const encodingName, + const ENCODING * const encoding, + STRING_POOL * const tempPoolP, + enum XML_Error * const resultP) { + + const XML_Char * const s = + poolStoreString(tempPoolP, encoding, encodingName, + encodingName + XmlNameLength(encoding, + encodingName)); + if (s) { + *resultP = handleUnknownEncoding(xmlParserP, s); + poolDiscard(tempPoolP); + } else + *resultP = XML_ERROR_NO_MEMORY; +} + + + +static void +processXmlDecl(XML_Parser const xmlParserP, + int const isGeneralTextEntity, + const char * const s, + const char * const next, + enum XML_Error * const resultP) { +/*---------------------------------------------------------------------------- + Process an XML declaration processing instruction (PI), i.e. + + + If *xmlParserP does not already have an encoding assigned and the + declaration names an encoding, set that up as the encoding for the parser + if possible. + + If *xmlParserP already has an encoding assigned, ignore any encoding + specification in the declaration, even errors in it. +-----------------------------------------------------------------------------*/ + Parser * const parserP = (Parser *) xmlParserP; + + const char *encodingName = 0; + const ENCODING *newEncodingP = 0; + const char *version; + int standalone = -1; + bool validSyntax; + + validSyntax = (parserP->m_ns + ? xmlrpc_XmlParseXmlDeclNS + : xmlrpc_XmlParseXmlDecl)(isGeneralTextEntity, + parserP->m_encoding, + s, + next, + &parserP->m_eventPtr, + &version, + &encodingName, + &newEncodingP, + &standalone); + if (!validSyntax) { + *resultP = XML_ERROR_SYNTAX; + /* parserP->m_eventPtr points to the invalid part */ + } else { + if (!isGeneralTextEntity && standalone == 1) { + parserP->m_dtd.standalone = 1; + if (parserP->m_paramEntityParsing == + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) + parserP->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; + } + if (parserP->m_defaultHandler) + reportDefault(xmlParserP, parserP->m_encoding, s, next); + if (parserP->m_protocolEncodingName) + *resultP = XML_ERROR_NONE; + else { + if (newEncodingP) { + /* The declaration names an encoding and the parser recognized + the name as referring to 'newEncodingP'. + */ + if (newEncodingP->minBytesPerChar != + parserP->m_encoding->minBytesPerChar) { + parserP->m_eventPtr = encodingName; + *resultP = XML_ERROR_INCORRECT_ENCODING; + } else { + parserP->m_encoding = newEncodingP; + *resultP = XML_ERROR_NONE; + } + } else { + if (encodingName) { + /* The declaration names an encoding, but the parser + didn't recognize the name. + */ + enum XML_Error result; + handleUnknownEncoding0(xmlParserP, encodingName, + parserP->m_encoding, + &parserP->m_tempPool, &result); + + if (result == XML_ERROR_UNKNOWN_ENCODING) + parserP->m_eventPtr = encodingName; + + *resultP = result; + } else + /* The declaration doesn't name an encoding */ + *resultP = XML_ERROR_NONE; + } + } + } +} + + + +static ATTRIBUTE_ID * +getAttributeId(XML_Parser parser, + const ENCODING *enc, + const char *start, + const char *end) +{ + ATTRIBUTE_ID *id; + const XML_Char *name; + if (!poolAppendChar(&dtd.pool, XML_T('\0'))) + return 0; + name = poolStoreString(&dtd.pool, enc, start, end); + if (!name) + return 0; + ++name; + id = (ATTRIBUTE_ID *)lookup(parser, &dtd.attributeIds, name, + sizeof(ATTRIBUTE_ID)); + if (!id) + return 0; + if (id->name != name) + poolDiscard(&dtd.pool); + else { + poolFinish(&dtd.pool); + if (!ns) + ; + else if (name[0] == 'x' + && name[1] == 'm' + && name[2] == 'l' + && name[3] == 'n' + && name[4] == 's' + && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) { + if (name[5] == '\0') + id->prefix = &dtd.defaultPrefix; + else + id->prefix = (PREFIX *)lookup(parser, &dtd.prefixes, name + 6, + sizeof(PREFIX)); + id->xmlns = 1; + } + else { + int i; + for (i = 0; name[i]; i++) { + if (name[i] == XML_T(':')) { + int j; + for (j = 0; j < i; j++) { + if (!poolAppendChar(&dtd.pool, name[j])) + return 0; + } + if (!poolAppendChar(&dtd.pool, XML_T('\0'))) + return 0; + id->prefix = (PREFIX *) + lookup(parser, &dtd.prefixes, poolStart(&dtd.pool), + sizeof(PREFIX)); + if (id->prefix->name == poolStart(&dtd.pool)) + poolFinish(&dtd.pool); + else + poolDiscard(&dtd.pool); + break; + } + } + } + } + return id; +} + +static +void normalizePublicId(XML_Char *publicId) +{ + XML_Char *p = publicId; + XML_Char *s; + for (s = publicId; *s; s++) { + switch (*s) { + case 0x20: + case 0xD: + case 0xA: + if (p != publicId && p[-1] != 0x20) + *p++ = 0x20; + break; + default: + *p++ = *s; + } + } + if (p != publicId && p[-1] == 0x20) + --p; + *p = XML_T('\0'); +} + + + +static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) +{ + const XML_Char *name; + for (name = elementType->name; *name; name++) { + if (*name == XML_T(':')) { + PREFIX *prefix; + const XML_Char *s; + for (s = elementType->name; s != name; s++) { + if (!poolAppendChar(&dtd.pool, *s)) + return 0; + } + if (!poolAppendChar(&dtd.pool, XML_T('\0'))) + return 0; + prefix = (PREFIX *) + lookup(parser, &dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX)); + if (!prefix) + return 0; + if (prefix->name == poolStart(&dtd.pool)) + poolFinish(&dtd.pool); + else + poolDiscard(&dtd.pool); + elementType->prefix = prefix; + + } + } + return 1; +} + + + +static enum XML_Error +appendAttributeValue(XML_Parser const xmlParserP, + const ENCODING * const enc, + int const isCdata, + const char * const ptrArg, + const char * const end, + STRING_POOL * const pool) { + + Parser * const parser = (Parser *) xmlParserP; + + const char * ptr; + + ptr = ptrArg; + + for (;;) { + const char *next; + int tok = XmlAttributeValueTok(enc, ptr, end, &next); + switch (tok) { + case XML_TOK_NONE: + return XML_ERROR_NONE; + case XML_TOK_INVALID: + if (enc == parser->m_encoding) + eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (enc == parser->m_encoding) + eventPtr = ptr; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_CHAR_REF: + { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(enc, ptr); + if (n < 0) { + if (enc == parser->m_encoding) + eventPtr = ptr; + return XML_ERROR_BAD_CHAR_REF; + } + if (!isCdata + && n == 0x20 /* space */ + && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) + break; + n = XmlEncode(n, (ICHAR *)buf); + if (!n) { + if (enc == parser->m_encoding) + eventPtr = ptr; + return XML_ERROR_BAD_CHAR_REF; + } + for (i = 0; i < n; i++) { + if (!poolAppendChar(pool, buf[i])) + return XML_ERROR_NO_MEMORY; + } + } + break; + case XML_TOK_DATA_CHARS: + if (!poolAppend(pool, enc, ptr, next)) + return XML_ERROR_NO_MEMORY; + break; + break; + case XML_TOK_TRAILING_CR: + next = ptr + enc->minBytesPerChar; + /* fall through */ + case XML_TOK_ATTRIBUTE_VALUE_S: + case XML_TOK_DATA_NEWLINE: + if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) + break; + if (!poolAppendChar(pool, 0x20)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_ENTITY_REF: + { + const XML_Char *name; + ENTITY *entity; + XML_Char ch = XmlPredefinedEntityName(enc, + ptr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (ch) { + if (!poolAppendChar(pool, ch)) + return XML_ERROR_NO_MEMORY; + break; + } + name = poolStoreString(&temp2Pool, enc, + ptr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(parser, &dtd.generalEntities, name, 0); + poolDiscard(&temp2Pool); + if (!entity) { + if (dtd.complete) { + if (enc == parser->m_encoding) + eventPtr = ptr; + return XML_ERROR_UNDEFINED_ENTITY; + } + } + else if (entity->open) { + if (enc == parser->m_encoding) + eventPtr = ptr; + return XML_ERROR_RECURSIVE_ENTITY_REF; + } + else if (entity->notation) { + if (enc == parser->m_encoding) + eventPtr = ptr; + return XML_ERROR_BINARY_ENTITY_REF; + } + else if (!entity->textPtr) { + if (enc == parser->m_encoding) + eventPtr = ptr; + return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; + } + else { + enum XML_Error result; + const XML_Char *textEnd = entity->textPtr + entity->textLen; + entity->open = 1; + result = appendAttributeValue(xmlParserP, internalEncoding, + isCdata, (char *)entity->textPtr, + (char *)textEnd, pool); + entity->open = 0; + if (result) + return result; + } + } + break; + default: + abort(); + } + ptr = next; + } + /* not reached */ +} + + + +static enum XML_Error +storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, + const char *ptr, const char *end, + STRING_POOL *pool) +{ + enum XML_Error result = + appendAttributeValue(parser, enc, isCdata, ptr, end, pool); + if (result) + return result; + if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) + poolChop(pool); + if (!poolAppendChar(pool, XML_T('\0'))) + return XML_ERROR_NO_MEMORY; + return XML_ERROR_NONE; +} + + + +static enum XML_Error +storeEntityValue(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const entityTextPtrArg, + const char * const entityTextEnd) { + + Parser * const parser = (Parser *) xmlParserP; + + STRING_POOL * const pool = &(dtd.pool); + const char * entityTextPtr; + + entityTextPtr = entityTextPtrArg; + + for (;;) { + const char * next; + int tok; + + tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); + switch (tok) { + case XML_TOK_PARAM_ENTITY_REF: + if (parentParser || enc != parser->m_encoding) { + enum XML_Error result; + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&tempPool, enc, + entityTextPtr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(parser, &dtd.paramEntities, name, 0); + poolDiscard(&tempPool); + if (!entity) { + if (enc == parser->m_encoding) + eventPtr = entityTextPtr; + return XML_ERROR_UNDEFINED_ENTITY; + } + if (entity->open) { + if (enc == parser->m_encoding) + eventPtr = entityTextPtr; + return XML_ERROR_RECURSIVE_ENTITY_REF; + } + if (entity->systemId) { + if (enc == parser->m_encoding) + eventPtr = entityTextPtr; + return XML_ERROR_PARAM_ENTITY_REF; + } + entity->open = 1; + result = storeEntityValue(parser, + internalEncoding, + (char *)entity->textPtr, + (char *)(entity->textPtr + entity->textLen)); + entity->open = 0; + if (result) + return result; + break; + } + eventPtr = entityTextPtr; + return XML_ERROR_SYNTAX; + case XML_TOK_NONE: + return XML_ERROR_NONE; + case XML_TOK_ENTITY_REF: + case XML_TOK_DATA_CHARS: + if (!poolAppend(pool, enc, entityTextPtr, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_TRAILING_CR: + next = entityTextPtr + enc->minBytesPerChar; + /* fall through */ + case XML_TOK_DATA_NEWLINE: { + if (pool->end == pool->ptr) { + const char * error; + poolGrow(pool, &error); + if (error) { + xmlrpc_strfree(error); + return XML_ERROR_NO_MEMORY; + } + } + *(pool->ptr)++ = 0xA; + } break; + case XML_TOK_CHAR_REF: + { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(enc, entityTextPtr); + if (n < 0) { + if (enc == parser->m_encoding) + eventPtr = entityTextPtr; + return XML_ERROR_BAD_CHAR_REF; + } + n = XmlEncode(n, (ICHAR *)buf); + if (!n) { + if (enc == parser->m_encoding) + eventPtr = entityTextPtr; + return XML_ERROR_BAD_CHAR_REF; + } + for (i = 0; i < n; i++) { + if (pool->end == pool->ptr) { + const char * error; + poolGrow(pool, &error); + if (error) { + xmlrpc_strfree(error); + return XML_ERROR_NO_MEMORY; + } + } + *(pool->ptr)++ = buf[i]; + } + } + break; + case XML_TOK_PARTIAL: + if (enc == parser->m_encoding) + eventPtr = entityTextPtr; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_INVALID: + if (enc == parser->m_encoding) + eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + default: + abort(); + } + entityTextPtr = next; + } + /* not reached */ +} + + + +static int +defineAttribute(ELEMENT_TYPE *type, + ATTRIBUTE_ID *attId, + int isCdata, + int isId, + const XML_Char *value) +{ + DEFAULT_ATTRIBUTE *att; + if (value || isId) { + /* The handling of default attributes gets messed up if we have + a default which duplicates a non-default. */ + int i; + for (i = 0; i < type->nDefaultAtts; i++) + if (attId == type->defaultAtts[i].id) + return 1; + if (isId && !type->idAtt && !attId->xmlns) + type->idAtt = attId; + } + if (type->nDefaultAtts == type->allocDefaultAtts) { + if (type->allocDefaultAtts == 0) { + type->allocDefaultAtts = 8; + type->defaultAtts = + malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); + if (!type->defaultAtts) + return 0; + } + else { + DEFAULT_ATTRIBUTE *temp; + type->allocDefaultAtts *= 2; + temp = realloc(type->defaultAtts, + type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); + if (!temp) + return 0; + type->defaultAtts = temp; + } + } + att = type->defaultAtts + type->nDefaultAtts; + att->id = attId; + att->value = value; + att->isCdata = isCdata; + if (!isCdata) + attId->maybeTokenized = 1; + type->nDefaultAtts += 1; + return 1; +} + + + +/* If tagNamePtr is non-null, build a real list of attributes, +otherwise just check the attributes for well-formedness. */ + +static enum XML_Error +storeAtts(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const attStr, + TAG_NAME * const tagNamePtr, + BINDING ** const bindingsPtr) { + + Parser * const parser = (Parser *)xmlParserP; + + ELEMENT_TYPE *elementType = 0; + int nDefaultAtts = 0; + const XML_Char ** appAtts; + /* the attribute list to pass to the application */ + int attIndex = 0; + int i; + int n; + int nPrefixes = 0; + BINDING *binding; + const XML_Char *localPart; + + /* lookup the element type name */ + if (tagNamePtr) { + elementType = (ELEMENT_TYPE *) + lookup(parser, &dtd.elementTypes, tagNamePtr->str, 0); + if (!elementType) { + tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str); + if (!tagNamePtr->str) + return XML_ERROR_NO_MEMORY; + elementType = (ELEMENT_TYPE *) + lookup(parser, &dtd.elementTypes, tagNamePtr->str, + sizeof(ELEMENT_TYPE)); + if (!elementType) + return XML_ERROR_NO_MEMORY; + if (ns && !setElementTypePrefix(xmlParserP, elementType)) + return XML_ERROR_NO_MEMORY; + } + nDefaultAtts = elementType->nDefaultAtts; + } + /* get the attributes from the tokenizer */ + n = XmlGetAttributes(enc, attStr, attsSize, atts); + if (n + nDefaultAtts > attsSize) { + int oldAttsSize = attsSize; + ATTRIBUTE *temp; + attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; + temp = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE)); + if (!temp) + return XML_ERROR_NO_MEMORY; + atts = temp; + if (n > oldAttsSize) + XmlGetAttributes(enc, attStr, n, atts); + } + appAtts = (const XML_Char **)atts; + for (i = 0; i < n; i++) { + /* add the name and value to the attribute list */ + ATTRIBUTE_ID *attId = getAttributeId(xmlParserP, enc, atts[i].name, + atts[i].name + + XmlNameLength(enc, atts[i].name)); + if (!attId) + return XML_ERROR_NO_MEMORY; + /* detect duplicate attributes */ + if ((attId->name)[-1]) { + if (enc == parser->m_encoding) + eventPtr = atts[i].name; + return XML_ERROR_DUPLICATE_ATTRIBUTE; + } + (attId->name)[-1] = 1; + appAtts[attIndex++] = attId->name; + if (!atts[i].normalized) { + enum XML_Error result; + int isCdata = 1; + + /* figure out whether declared as other than CDATA */ + if (attId->maybeTokenized) { + int j; + for (j = 0; j < nDefaultAtts; j++) { + if (attId == elementType->defaultAtts[j].id) { + isCdata = elementType->defaultAtts[j].isCdata; + break; + } + } + } + + /* normalize the attribute value */ + result = storeAttributeValue(xmlParserP, enc, isCdata, + atts[i].valuePtr, atts[i].valueEnd, + &tempPool); + if (result) + return result; + if (tagNamePtr) { + appAtts[attIndex] = poolStart(&tempPool); + poolFinish(&tempPool); + } + else + poolDiscard(&tempPool); + } + else if (tagNamePtr) { + /* the value did not need normalizing */ + appAtts[attIndex] = + poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd); + if (appAtts[attIndex] == 0) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + } + /* handle prefixed attribute names */ + if (attId->prefix && tagNamePtr) { + if (attId->xmlns) { + /* deal with namespace declarations here */ + if (!addBinding(xmlParserP, attId->prefix, attId, appAtts[attIndex], + bindingsPtr)) + return XML_ERROR_NO_MEMORY; + --attIndex; + } + else { + /* deal with other prefixed names later */ + attIndex++; + nPrefixes++; + (attId->name)[-1] = 2; + } + } + else + attIndex++; + } + if (tagNamePtr) { + int j; + nSpecifiedAtts = attIndex; + if (elementType->idAtt && (elementType->idAtt->name)[-1]) { + for (i = 0; i < attIndex; i += 2) + if (appAtts[i] == elementType->idAtt->name) { + idAttIndex = i; + break; + } + } + else + idAttIndex = -1; + /* do attribute defaulting */ + for (j = 0; j < nDefaultAtts; j++) { + const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j; + if (!(da->id->name)[-1] && da->value) { + if (da->id->prefix) { + if (da->id->xmlns) { + if (!addBinding(xmlParserP, da->id->prefix, da->id, da->value, + bindingsPtr)) + return XML_ERROR_NO_MEMORY; + } + else { + (da->id->name)[-1] = 2; + nPrefixes++; + appAtts[attIndex++] = da->id->name; + appAtts[attIndex++] = da->value; + } + } + else { + (da->id->name)[-1] = 1; + appAtts[attIndex++] = da->id->name; + appAtts[attIndex++] = da->value; + } + } + } + appAtts[attIndex] = 0; + } + i = 0; + if (nPrefixes) { + /* expand prefixed attribute names */ + for (; i < attIndex; i += 2) { + if (appAtts[i][-1] == 2) { + ATTRIBUTE_ID *id; + ((XML_Char *)(appAtts[i]))[-1] = 0; + id = (ATTRIBUTE_ID *)lookup(parser, &dtd.attributeIds, appAtts[i], 0); + if (id->prefix->binding) { + int j; + const BINDING *b = id->prefix->binding; + const XML_Char *s = appAtts[i]; + for (j = 0; j < b->uriLen; j++) { + if (!poolAppendChar(&tempPool, b->uri[j])) + return XML_ERROR_NO_MEMORY; + } + while (*s++ != ':') + ; + do { + if (!poolAppendChar(&tempPool, *s)) + return XML_ERROR_NO_MEMORY; + } while (*s++); + appAtts[i] = poolStart(&tempPool); + poolFinish(&tempPool); + } + if (!--nPrefixes) + break; + } + else + ((XML_Char *)(appAtts[i]))[-1] = 0; + } + } + /* clear the flags that say whether attributes were specified */ + for (; i < attIndex; i += 2) + ((XML_Char *)(appAtts[i]))[-1] = 0; + if (!tagNamePtr) + return XML_ERROR_NONE; + for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) + binding->attId->name[-1] = 0; + /* expand the element type name */ + if (elementType->prefix) { + binding = elementType->prefix->binding; + if (!binding) + return XML_ERROR_NONE; + localPart = tagNamePtr->str; + while (*localPart++ != XML_T(':')) + ; + } + else if (dtd.defaultPrefix.binding) { + binding = dtd.defaultPrefix.binding; + localPart = tagNamePtr->str; + } + else + return XML_ERROR_NONE; + tagNamePtr->localPart = localPart; + tagNamePtr->uriLen = binding->uriLen; + for (i = 0; localPart[i++];) + ; + n = i + binding->uriLen; + if (n > binding->uriAlloc) { + TAG *p; + XML_Char *uri = malloc((n + EXPAND_SPARE) * sizeof(XML_Char)); + if (!uri) + return XML_ERROR_NO_MEMORY; + binding->uriAlloc = n + EXPAND_SPARE; + memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); + for (p = tagStack; p; p = p->parent) + if (p->name.str == binding->uri) + p->name.str = uri; + free(binding->uri); + binding->uri = uri; + } + memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char)); + tagNamePtr->str = binding->uri; + return XML_ERROR_NONE; +} + + + +static Processor epilogProcessor; + +static void +epilogProcessor(XML_Parser const xmlParserP, + const char * const startArg, + const char * const end, + const char ** const nextPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + const char * s; + + *errorP = NULL; + + s = startArg; + + processor = epilogProcessor; + eventPtr = s; + for (;;) { + const char *next; + int tok = XmlPrologTok(parser->m_encoding, s, end, &next); + eventEndPtr = next; + switch (tok) { + case -XML_TOK_PROLOG_S: + if (defaultHandler) { + eventEndPtr = end; + reportDefault(xmlParserP, parser->m_encoding, s, end); + } + /* fall through */ + case XML_TOK_NONE: + if (nextPtr) + *nextPtr = end; + *errorCodeP = XML_ERROR_NONE; + return; + case XML_TOK_PROLOG_S: + if (defaultHandler) + reportDefault(xmlParserP, parser->m_encoding, s, next); + break; + case XML_TOK_PI: + if (!reportProcessingInstruction(xmlParserP, parser->m_encoding, + s, next)) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + break; + case XML_TOK_COMMENT: + if (!reportComment(xmlParserP, parser->m_encoding, s, next)) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + break; + case XML_TOK_INVALID: + eventPtr = next; + *errorCodeP = XML_ERROR_INVALID_TOKEN; + return; + case XML_TOK_PARTIAL: + if (nextPtr) { + *nextPtr = s; + *errorCodeP = XML_ERROR_NONE; + } else + *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; + return; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + *errorCodeP = XML_ERROR_NONE; + } else + *errorCodeP = XML_ERROR_PARTIAL_CHAR; + return; + default: + *errorCodeP = XML_ERROR_JUNK_AFTER_DOC_ELEMENT; + return; + } + eventPtr = s = next; + } +} + + + +static enum XML_Error +doCdataSection(XML_Parser const xmlParserP, + const ENCODING * const encoderP, + const char ** const startPtr, + const char * const end, + const char ** const nextPtr) { + + Parser * const parser = (Parser *) xmlParserP; + struct EventPtr const evPtr = getEventPtr(xmlParserP, encoderP); + + const char * s; + + s = *startPtr; /* initial value */ + *evPtr.startP = s; + *startPtr = 0; + for (;;) { + const char *next; + int tok = XmlCdataSectionTok(encoderP, s, end, &next); + *evPtr.endP = next; + switch (tok) { + case XML_TOK_CDATA_SECT_CLOSE: + if (endCdataSectionHandler) + endCdataSectionHandler(handlerArg); + else if (defaultHandler) + reportDefault(xmlParserP, encoderP, s, next); + *startPtr = next; + return XML_ERROR_NONE; + case XML_TOK_DATA_NEWLINE: + if (characterDataHandler) { + XML_Char c = 0xA; + characterDataHandler(handlerArg, &c, 1); + } + else if (defaultHandler) + reportDefault(xmlParserP, encoderP, s, next); + break; + case XML_TOK_DATA_CHARS: + processDataCharsToken(xmlParserP, encoderP, s, next); + break; + case XML_TOK_INVALID: + *evPtr.startP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_PARTIAL: + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_CDATA_SECTION; + default: + abort(); + } + *evPtr.startP = s = next; + } + /* not reached */ +} + + + +/* Forward declaration for recursive reference: */ +static void +doContent(XML_Parser const xmlParserP, + int const startTagLevel, + const ENCODING * const enc, + const char * const startArg, + const char * const end, + const char ** const nextPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP); + + +static Processor contentProcessor; + +static void +contentProcessor(XML_Parser const xmlParserP, + const char * const start, + const char * const end, + const char ** const endPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + const char * error; + + parser->m_errorString = NULL; + + doContent(xmlParserP, 0, parser->m_encoding, start, end, endPtr, + errorCodeP, &error); + + if (*errorCodeP != XML_ERROR_NONE) { + if (error) { + xmlrpc_asprintf(errorP, "Invalid XML \"content\". %s", error); + + xmlrpc_strfree(error); + } else { + const char * const sampleXml = extractXmlSample(start, end, 40); + + xmlrpc_asprintf(errorP, "Invalid XML \"content\" starting " + "with '%s'. %s", + sampleXml, + xmlrpc_XML_ErrorString(*errorCodeP)); + + xmlrpc_strfree(sampleXml); + } + } else + *errorP = NULL; +} + + + +/* The idea here is to avoid using stack for each CDATA section when +the whole file is parsed with one call. */ + + + +static Processor cdataSectionProcessor; + +static void +cdataSectionProcessor(XML_Parser const xmlParserP, + const char * const startArg, + const char * const end, + const char ** const endPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + enum XML_Error result; + const char * start; + + start = startArg; + + result = + doCdataSection(xmlParserP, parser->m_encoding, &start, end, endPtr); + + if (start) { + processor = contentProcessor; + contentProcessor(xmlParserP, start, end, endPtr, errorCodeP, errorP); + } else { + *errorCodeP = result; + *errorP = NULL; + } +} + + + +static void +doCharacterEntityRef(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const next, + XML_Char const ch, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parserP = (Parser *) xmlParserP; + + if (parserP->m_characterDataHandler) + parserP->m_characterDataHandler(parserP->m_handlerArg, &ch, 1); + else if (parserP->m_defaultHandler) + reportDefault(xmlParserP, enc, s, next); + + *errorCodeP = XML_ERROR_NONE; + *errorP = NULL; +} + + + +static void +doInternalEntityRef(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const next, + ENTITY * const entityP, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parserP = (Parser *) xmlParserP; + + if (parserP->m_defaultHandler && + !parserP->m_defaultExpandInternalEntities) { + reportDefault(xmlParserP, enc, s, next); + *errorCodeP = XML_ERROR_NONE; + *errorP = NULL; + } else { + OPEN_INTERNAL_ENTITY openEntity; + + entityP->open = 1; /* recursion control */ + + openEntity.next = parserP->m_openInternalEntities; + + parserP->m_openInternalEntities = &openEntity; + openEntity.entity = entityP; + openEntity.internalEventPtr = 0; + openEntity.internalEventEndPtr = 0; + + doContent(xmlParserP, + parserP->m_tagLevel, + parserP->m_internalEncoding, + (char *)entityP->textPtr, + (char *)(entityP->textPtr + entityP->textLen), + 0, errorCodeP, errorP); + + entityP->open = 0; /* recursion control */ + parserP->m_openInternalEntities = openEntity.next; + } +} + + + +static void +doExternalEntityRef(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const next, + ENTITY * const entityP, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parserP = (Parser *) xmlParserP; + + *errorP = NULL; + + if (parserP->m_externalEntityRefHandler) { + const XML_Char * contextP; + + entityP->open = 1; + contextP = getContext(xmlParserP); + entityP->open = 0; + + if (!contextP) + *errorCodeP = XML_ERROR_NO_MEMORY; + else { + int rc; + + rc = parserP->m_externalEntityRefHandler( + parserP->m_externalEntityRefHandlerArg, + contextP, + entityP->base, + entityP->systemId, + entityP->publicId); + if (rc != 0) + *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING; + else { + poolDiscard(&parserP->m_tempPool); + *errorCodeP = XML_ERROR_NONE; + } + } + } else if (parserP->m_defaultHandler) { + reportDefault(xmlParserP, enc, s, next); + + *errorCodeP = XML_ERROR_NONE; + } else + *errorCodeP = XML_ERROR_NONE; +} + + + +static void +doEntityRef(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const next, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + XML_Char const ch = XmlPredefinedEntityName(enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + + if (ch) + doCharacterEntityRef(xmlParserP, enc, s, next, ch, errorCodeP, errorP); + else { + Parser * const parserP = (Parser *) xmlParserP; + + const XML_Char * name; + ENTITY * entityP; + + *errorP = NULL; + + name = poolStoreString(&parserP->m_dtd.pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) { + *errorCodeP = XML_ERROR_NO_MEMORY; + } else { + entityP = (ENTITY *) + lookup(parserP, &parserP->m_dtd.generalEntities, name, 0); + poolDiscard(&parserP->m_dtd.pool); + if (!entityP) { + if (parserP->m_dtd.complete || parserP->m_dtd.standalone) + *errorCodeP = XML_ERROR_UNDEFINED_ENTITY; + else { + if (parserP->m_defaultHandler) + reportDefault(xmlParserP, enc, s, next); + *errorCodeP = XML_ERROR_NONE; + } + } else { + if (entityP->open) + *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF; + else if (entityP->notation) + *errorCodeP = XML_ERROR_BINARY_ENTITY_REF; + else { + if (entityP->textPtr) + doInternalEntityRef(xmlParserP, enc, s, next, entityP, + errorCodeP, errorP); + else + doExternalEntityRef(xmlParserP, enc, s, next, entityP, + errorCodeP, errorP); + } + } + } + } +} + + + +static void +doStartTagNoAtts(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const next, + const char ** const nextPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + TAG *tag; + + *errorP = NULL; + + if (freeTagList) { + tag = freeTagList; + freeTagList = freeTagList->parent; + } else { + tag = malloc(sizeof(TAG)); + if (!tag) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + tag->buf = malloc(INIT_TAG_BUF_SIZE); + if (!tag->buf) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; + } + tag->bindings = NULL; + tag->parent = tagStack; + tagStack = tag; + tag->name.localPart = 0; + tag->rawName = s + enc->minBytesPerChar; + tag->rawNameLength = XmlNameLength(enc, tag->rawName); + if (nextPtr) { + /* Need to guarantee that: tag->buf + + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= + tag->bufEnd - sizeof(XML_Char) + */ + + if (tag->rawNameLength + + (int)(sizeof(XML_Char) - 1) + + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) { + char *temp; + int bufSize = tag->rawNameLength * 4; + bufSize = ROUND_UP(bufSize, sizeof(XML_Char)); + temp = realloc(tag->buf, bufSize); + if (!temp) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + tag->buf = temp; + tag->bufEnd = tag->buf + bufSize; + } + memcpy(tag->buf, tag->rawName, tag->rawNameLength); + tag->rawName = tag->buf; + } + ++tagLevel; + if (startElementHandler) { + enum XML_Error result; + XML_Char *toPtr; + for (;;) { + const char *rawNameEnd = tag->rawName + tag->rawNameLength; + const char *fromPtr = tag->rawName; + if (nextPtr) + toPtr = (XML_Char *) + (tag->buf + ROUND_UP(tag->rawNameLength, + sizeof(XML_Char))); + else + toPtr = (XML_Char *)tag->buf; + tag->name.str = toPtr; + XmlConvert(enc, + &fromPtr, rawNameEnd, + (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); + if (fromPtr == rawNameEnd) + break; + else { + size_t const bufSize = (tag->bufEnd - tag->buf) << 1; + char *temp = realloc(tag->buf, bufSize); + if (!temp) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + tag->buf = temp; + tag->bufEnd = tag->buf + bufSize; + if (nextPtr) + tag->rawName = tag->buf; + } + } + *toPtr = XML_T('\0'); + result = storeAtts(xmlParserP, enc, s, + &(tag->name), &(tag->bindings)); + if (result) { + *errorCodeP = result; + return; + } + startElementHandler(handlerArg, tag->name.str, + (const XML_Char **)atts); + poolClear(&tempPool); + } else { + tag->name.str = 0; + if (defaultHandler) + reportDefault(xmlParserP, enc, s, next); + } +} + + + +static void +doEmptyElementNoAtts(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const end, + const char * const next, + const char ** const nextPtr, + const char ** const eventPP, + const char ** const eventEndPP, + bool * const doneP, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + if (startElementHandler || endElementHandler) { + const char * const rawName = s + enc->minBytesPerChar; + + enum XML_Error result; + BINDING * bindings; + TAG_NAME name; + + bindings = NULL; /* initial value */ + name.str = poolStoreString(&tempPool, enc, rawName, + rawName + XmlNameLength(enc, rawName)); + if (!name.str) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + poolFinish(&tempPool); + result = storeAtts(xmlParserP, enc, s, &name, &bindings); + if (result) { + *errorCodeP = result; + return; + } + poolFinish(&tempPool); + if (startElementHandler) + startElementHandler(handlerArg, name.str, (const XML_Char **)atts); + if (endElementHandler) { + if (startElementHandler) + *eventPP = *eventEndPP; + endElementHandler(handlerArg, name.str); + } + poolClear(&tempPool); + while (bindings) { + BINDING * const b = bindings; + if (endNamespaceDeclHandler) + endNamespaceDeclHandler(handlerArg, b->prefix->name); + bindings = bindings->nextTagBinding; + b->nextTagBinding = freeBindingList; + freeBindingList = b; + b->prefix->binding = b->prevPrefixBinding; + } + } else if (defaultHandler) + reportDefault(xmlParserP, enc, s, next); + + if (tagLevel == 0) { + epilogProcessor(xmlParserP, next, end, nextPtr, errorCodeP, errorP); + *doneP = true; + } else + *doneP = false; +} + + + +static void +doEndTag(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char * const s, + const char * const end, + const char * const next, + const char ** const nextPtr, + int const startTagLevel, + const char ** const eventPP, + bool * const doneP, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + if (tagLevel == startTagLevel) + *errorCodeP = XML_ERROR_ASYNC_ENTITY; + else { + TAG * const tag = tagStack; + + int len; + const char * rawName; + + tagStack = tag->parent; + tag->parent = freeTagList; + freeTagList = tag; + rawName = s + enc->minBytesPerChar*2; + len = XmlNameLength(enc, rawName); + if (len != tag->rawNameLength + || memcmp(tag->rawName, rawName, len) != 0) { + *eventPP = rawName; + *errorCodeP = XML_ERROR_TAG_MISMATCH; + } else { + --tagLevel; + if (endElementHandler && tag->name.str) { + if (tag->name.localPart) { + XML_Char * to; + const XML_Char * from; + to = (XML_Char *)tag->name.str + tag->name.uriLen; + from = tag->name.localPart; + while ((*to++ = *from++) != 0) + ; + } + endElementHandler(handlerArg, tag->name.str); + } else if (defaultHandler) + reportDefault(xmlParserP, enc, s, next); + + while (tag->bindings) { + BINDING * const b = tag->bindings; + if (endNamespaceDeclHandler) + endNamespaceDeclHandler(handlerArg, b->prefix->name); + tag->bindings = tag->bindings->nextTagBinding; + b->nextTagBinding = freeBindingList; + freeBindingList = b; + b->prefix->binding = b->prevPrefixBinding; + } + if (tagLevel == 0) { + epilogProcessor(xmlParserP, next, end, nextPtr, + errorCodeP, errorP); + *doneP = true; + } else { + *errorCodeP = XML_ERROR_NONE; + *doneP = false; + } + } + } +} + + + +static void +processContentToken(XML_Parser const xmlParserP, + int const tok, + const ENCODING * const enc, + const char * const s, + const char * const end, + const char ** const nextP, + const char ** const nextPtr, + int const startTagLevel, + bool * const doneP, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + struct EventPtr const evPtr = getEventPtr(xmlParserP, enc); + + *errorP = NULL; + *errorCodeP = XML_ERROR_NONE; + + switch (tok) { + case XML_TOK_TRAILING_CR: + if (nextPtr) { + *nextPtr = s; + *doneP = true; + } else { + *evPtr.endP = end; + + if (characterDataHandler) { + XML_Char c = 0xA; + characterDataHandler(handlerArg, &c, 1); + } else if (defaultHandler) + reportDefault(xmlParserP, enc, s, end); + + if (startTagLevel == 0) + *errorCodeP = XML_ERROR_NO_ELEMENTS; + else if (tagLevel != startTagLevel) { + *errorCodeP = XML_ERROR_ASYNC_ENTITY; + } else + *doneP = true; + } + break; + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + *doneP = true; + } else if (startTagLevel > 0) { + if (tagLevel != startTagLevel) + *errorCodeP = XML_ERROR_ASYNC_ENTITY; + else + *doneP = true; + } else + *errorCodeP = XML_ERROR_NO_ELEMENTS; + break; + case XML_TOK_INVALID: + *evPtr.startP = *nextP; + *errorCodeP = XML_ERROR_INVALID_TOKEN; + xmlrpc_asprintf(errorP, "Invalid token, starting %ld bytes in", + (long)(*nextP - s)); + break; + case XML_TOK_PARTIAL: + if (nextPtr) { + *nextPtr = s; + *doneP = true; + } else + *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; + break; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + *doneP = true; + } else + *errorCodeP = XML_ERROR_PARTIAL_CHAR; + break; + case XML_TOK_ENTITY_REF: + doEntityRef(xmlParserP, enc, s, *nextP, errorCodeP, errorP); + break; + case XML_TOK_START_TAG_WITH_ATTS: + if (!startElementHandler) + *errorCodeP = storeAtts(xmlParserP, enc, s, 0, 0); + if (*errorCodeP == XML_ERROR_NONE) + doStartTagNoAtts(xmlParserP, enc, s, *nextP, nextPtr, + errorCodeP, errorP); + break; + case XML_TOK_START_TAG_NO_ATTS: + doStartTagNoAtts(xmlParserP, enc, s, *nextP, nextPtr, + errorCodeP, errorP); + break; + case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: + if (!startElementHandler) + *errorCodeP = storeAtts(xmlParserP, enc, s, 0, 0); + + if (*errorCodeP == XML_ERROR_NONE) + doEmptyElementNoAtts(xmlParserP, enc, s, end, *nextP, nextPtr, + evPtr.startP, evPtr.endP, + doneP, errorCodeP, errorP); + break; + case XML_TOK_EMPTY_ELEMENT_NO_ATTS: + doEmptyElementNoAtts(xmlParserP, enc, s, end, *nextP, nextPtr, + evPtr.startP, evPtr.endP, + doneP, errorCodeP, errorP); + break; + case XML_TOK_END_TAG: + doEndTag(xmlParserP, enc, s, end, *nextP, nextPtr, startTagLevel, + evPtr.startP, doneP, errorCodeP, errorP); + break; + case XML_TOK_CHAR_REF: { + int const n = XmlCharRefNumber(enc, s); + if (n < 0) + *errorCodeP = XML_ERROR_BAD_CHAR_REF; + else { + if (characterDataHandler) { + XML_Char buf[XML_ENCODE_MAX]; + characterDataHandler(handlerArg, buf, + XmlEncode(n, (ICHAR *)buf)); + } else if (defaultHandler) + reportDefault(xmlParserP, enc, s, *nextP); + } + } break; + case XML_TOK_XML_DECL: + *errorCodeP = XML_ERROR_MISPLACED_XML_PI; + break; + case XML_TOK_DATA_NEWLINE: + if (characterDataHandler) { + XML_Char c = 0xA; + characterDataHandler(handlerArg, &c, 1); + } else if (defaultHandler) + reportDefault(xmlParserP, enc, s, *nextP); + break; + case XML_TOK_CDATA_SECT_OPEN: { + enum XML_Error result; + if (startCdataSectionHandler) + startCdataSectionHandler(handlerArg); + else if (defaultHandler) + reportDefault(xmlParserP, enc, s, *nextP); + result = doCdataSection(xmlParserP, enc, nextP, end, nextPtr); + if (!*nextP) { + processor = cdataSectionProcessor; + *errorCodeP = result; + } + } break; + case XML_TOK_TRAILING_RSQB: + if (nextPtr) { + *nextPtr = s; + *errorCodeP = XML_ERROR_NONE; + } else { + if (characterDataHandler) { + if (MUST_CONVERT(enc, s)) { + const char * from; + ICHAR * dataPtr; + from = s; + dataPtr = (ICHAR *)dataBuf; + XmlConvert(enc, &from, end, &dataPtr, (ICHAR *)dataBufEnd); + { + size_t const len = dataPtr - (ICHAR *)dataBuf; + assert((size_t)(int)len == len); /* parser reqt */ + characterDataHandler(handlerArg, dataBuf, (int)len); + } + } else { + size_t const len = (XML_Char *)end - (XML_Char *)s; + assert((size_t)(int)len == len); /* parser reqt */ + characterDataHandler(handlerArg, (XML_Char *)s, (int)len); + } + } else if (defaultHandler) + reportDefault(xmlParserP, enc, s, end); + + if (startTagLevel == 0) { + *evPtr.startP = end; + *errorCodeP = XML_ERROR_NO_ELEMENTS; + } else if (tagLevel != startTagLevel) { + *evPtr.startP = end; + *errorCodeP = XML_ERROR_ASYNC_ENTITY; + } else + *doneP = true; + } + break; + case XML_TOK_DATA_CHARS: + processDataCharsToken(xmlParserP, enc, s, *nextP); + break; + case XML_TOK_PI: + if (!reportProcessingInstruction(xmlParserP, enc, s, *nextP)) + *errorCodeP = XML_ERROR_NO_MEMORY; + break; + case XML_TOK_COMMENT: + if (!reportComment(xmlParserP, enc, s, *nextP)) + *errorCodeP = XML_ERROR_NO_MEMORY; + break; + default: + if (defaultHandler) + reportDefault(xmlParserP, enc, s, *nextP); + break; + } +} + + + +static void +doContent(XML_Parser const xmlParserP, + int const startTagLevel, + const ENCODING * const enc, + const char * const startArg, + const char * const end, + const char ** const nextPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + struct EventPtr const evPtr = getEventPtr(xmlParserP, enc); + + const char * s; + bool done; + + s = startArg; + *evPtr.startP = s; + done = false; + *errorCodeP = XML_ERROR_NONE; + *errorP = NULL; + + while (*errorCodeP == XML_ERROR_NONE && !done) { + int tok; + const char * next; + const char * error; + + next = s; /* XmlContentTok doesn't always set the last arg */ + /* XmlContentTok() is normally normal_contentTok(), aka + PREFIX(contentTok)() in xmltok/xmltok_impl.c + */ + tok = XmlContentTok(enc, s, end, &next); + *evPtr.endP = next; + + processContentToken(xmlParserP, tok, enc, s, end, &next, nextPtr, + startTagLevel, &done, + errorCodeP, &error); + + if (*errorCodeP != XML_ERROR_NONE) { + const char * const xmlSample = extractXmlSample(s, end, 40); + + if (error) { + xmlrpc_asprintf(errorP, "Problem with token at '%s...': %s", + xmlSample, error); + xmlrpc_strfree(error); + } else + xmlrpc_asprintf(errorP, "Problem with token at '%s...': %s", + xmlSample, + xmlrpc_XML_ErrorString(*errorCodeP)); + + xmlrpc_strfree(xmlSample); + } + *evPtr.startP = s = next; + } +} + + + +static Processor externalEntityContentProcessor; + +static void +externalEntityContentProcessor(XML_Parser const xmlParserP, + const char * const start, + const char * const end, + const char ** const endPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + *errorP = NULL; + + doContent(xmlParserP, 1, parser->m_encoding, start, end, endPtr, + errorCodeP, errorP); +} + + + +static Processor externalEntityInitProcessor3; + +static void +externalEntityInitProcessor3(XML_Parser const xmlParserP, + const char * const startArg, + const char * const end, + const char ** const endPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + const char * start; + const char *next; + int tok; + + tok = XmlContentTok(parser->m_encoding, startArg, end, &next); + + *errorP = NULL; + + start = startArg; + + switch (tok) { + case XML_TOK_XML_DECL: + { + enum XML_Error result; + processXmlDecl(xmlParserP, 1, start, next, &result); + if (result != XML_ERROR_NONE) { + *errorCodeP = result; + return; + } + start = next; + } + break; + case XML_TOK_PARTIAL: + if (endPtr) { + *endPtr = start; + *errorCodeP = XML_ERROR_NONE; + return; + } + eventPtr = start; + *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; + return; + case XML_TOK_PARTIAL_CHAR: + if (endPtr) { + *endPtr = start; + *errorCodeP = XML_ERROR_NONE; + return; + } + eventPtr = start; + *errorCodeP = XML_ERROR_PARTIAL_CHAR; + return; + } + processor = externalEntityContentProcessor; + tagLevel = 1; + doContent(xmlParserP, 1, parser->m_encoding, start, end, endPtr, + errorCodeP, errorP); +} + + + +static Processor externalEntityInitProcessor2; + +static void +externalEntityInitProcessor2(XML_Parser const xmlParserP, + const char * const startArg, + const char * const end, + const char ** const endPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *)xmlParserP; + + const char * start; + const char * next; + int tok; + + tok = XmlContentTok(parser->m_encoding, startArg, end, &next); + + start = startArg; + + switch (tok) { + case XML_TOK_BOM: + start = next; + break; + case XML_TOK_PARTIAL: + if (endPtr) { + *endPtr = start; + *errorCodeP = XML_ERROR_NONE; + *errorP = NULL; + } else { + eventPtr = start; + *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; + *errorP = NULL; + } + return; + case XML_TOK_PARTIAL_CHAR: + if (endPtr) { + *endPtr = start; + *errorCodeP = XML_ERROR_NONE; + *errorP = NULL; + } else { + eventPtr = start; + *errorCodeP = XML_ERROR_PARTIAL_CHAR; + *errorP = NULL; + } + return; + } + processor = externalEntityInitProcessor3; + externalEntityInitProcessor3(xmlParserP, start, end, endPtr, + errorCodeP, errorP); +} + + + +static Processor externalEntityInitProcessor; + +static void +externalEntityInitProcessor(XML_Parser const parser, + const char * const start, + const char * const end, + const char ** const endPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + enum XML_Error result; + + result = initializeEncoding(parser); + + if (result != XML_ERROR_NONE) { + *errorCodeP = result; + *errorP = NULL; + } else { + processor = externalEntityInitProcessor2; + + externalEntityInitProcessor2(parser, start, end, endPtr, + errorCodeP, errorP); + } +} + + + +static enum XML_Error +doIgnoreSection(XML_Parser const xmlParserP, + const ENCODING * const enc, + const char ** const startPtr, + const char * const end, + const char ** const nextPtr) { +/*---------------------------------------------------------------------------- + + We set *startPtr to non-null is the section is closed, and to null if + the section is not yet closed. +-----------------------------------------------------------------------------*/ + Parser * const parser = xmlParserP; + struct EventPtr const evPtr = getEventPtr(xmlParserP, enc); + const char * const s = *startPtr; + + enum XML_Error retval; + const char * next; + int tok; + + *evPtr.startP = s; + *startPtr = '\0'; + tok = XmlIgnoreSectionTok(enc, s, end, &next); + *evPtr.endP = next; + + switch (tok) { + case XML_TOK_IGNORE_SECT: + if (defaultHandler) + reportDefault(xmlParserP, enc, s, next); + *startPtr = next; + retval = XML_ERROR_NONE; + break; + case XML_TOK_INVALID: + *evPtr.startP = next; + retval = XML_ERROR_INVALID_TOKEN; + break; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + retval = XML_ERROR_NONE; + } else + retval = XML_ERROR_PARTIAL_CHAR; + break; + case XML_TOK_PARTIAL: + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + retval = XML_ERROR_NONE; + } else + retval = XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ + break; + default: + assert(false); /* All possibilities are handled above */ + retval = 99; /* quiet compiler warning */ + } + + return retval; +} + + + +static Processor prologProcessor; + + +/* The idea here is to avoid using stack for each IGNORE section when +the whole file is parsed with one call. */ + +static Processor ignoreSectionProcessor; + +static void +ignoreSectionProcessor(XML_Parser const xmlParserP, + const char * const startArg, + const char * const end, + const char ** const endPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + enum XML_Error result; + const char * start; + + start = startArg; /* initial value */ + + result = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr); + + if (start) { + processor = prologProcessor; + prologProcessor(xmlParserP, start, end, endPtr, errorCodeP, errorP); + } else { + *errorCodeP = result; + *errorP = NULL; + } +} + + + +/* Forward declaration for recursive reference: */ +static void +processInternalParamEntity(XML_Parser const parser, + ENTITY * const entity, + enum XML_Error * const errorCodeP, + const char ** const errorP); + +static void +doProlog(XML_Parser const xmlParserP, + const ENCODING * const encArg, + const char * const startArg, + const char * const end, + int const tokArg, + const char * const nextArg, + const char ** const nextPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = xmlParserP; + struct EventPtr const evPtr = getEventPtr(xmlParserP, encArg); + + int tok; + const char * next; + const ENCODING * enc; + const char * s; + + static const XML_Char externalSubsetName[] = { '#' , '\0' }; + + *errorP = NULL; + + tok = tokArg; + next = nextArg; + enc = encArg; + s = startArg; + + for (;;) { + int role; + *evPtr.startP = s; + *evPtr.endP = next; + if (tok <= 0) { + if (nextPtr != 0 && tok != XML_TOK_INVALID) { + *nextPtr = s; + *errorCodeP = XML_ERROR_NONE; + return; + } + switch (tok) { + case XML_TOK_INVALID: + *evPtr.startP = next; + *errorCodeP = XML_ERROR_INVALID_TOKEN; + return; + case XML_TOK_PARTIAL: + *errorCodeP = XML_ERROR_UNCLOSED_TOKEN; + return; + case XML_TOK_PARTIAL_CHAR: + *errorCodeP = XML_ERROR_PARTIAL_CHAR; + return; + case XML_TOK_NONE: + if (enc != parser->m_encoding) + *errorCodeP = XML_ERROR_NONE; + else { + if (parentParser) { + if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) + == XML_ROLE_ERROR) { + *errorCodeP = XML_ERROR_SYNTAX; + } else { + *errorCodeP = XML_ERROR_NONE; + hadExternalDoctype = 0; + } + } else + *errorCodeP = XML_ERROR_NO_ELEMENTS; + } + return; + default: + tok = -tok; + next = end; + break; + } + } + role = XmlTokenRole(&prologState, tok, s, next, enc); + switch (role) { + case XML_ROLE_XML_DECL: { + enum XML_Error result; + processXmlDecl(xmlParserP, 0, s, next, &result); + if (result != XML_ERROR_NONE) { + *errorCodeP = result; + return; + } + enc = parser->m_encoding; + } + break; + case XML_ROLE_DOCTYPE_NAME: + if (startDoctypeDeclHandler) { + const XML_Char *name = poolStoreString(&tempPool, enc, s, next); + if (!name) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + startDoctypeDeclHandler(handlerArg, name); + poolClear(&tempPool); + } + break; + case XML_ROLE_TEXT_DECL: { + enum XML_Error result; + processXmlDecl(xmlParserP, 1, s, next, &result); + if (result != XML_ERROR_NONE) { + *errorCodeP = result; + return; + } + enc = parser->m_encoding; + } + break; + case XML_ROLE_DOCTYPE_PUBLIC_ID: + declEntity = (ENTITY *)lookup(parser, &dtd.paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!declEntity) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + /* fall through */ + case XML_ROLE_ENTITY_PUBLIC_ID: + if (!XmlIsPublicId(enc, s, next, evPtr.startP)) { + *errorCodeP = XML_ERROR_SYNTAX; + return; + } + if (declEntity) { + XML_Char *tem = poolStoreString(&dtd.pool, + enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!tem) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + normalizePublicId(tem); + declEntity->publicId = tem; + poolFinish(&dtd.pool); + } + break; + case XML_ROLE_DOCTYPE_CLOSE: + if (dtd.complete && hadExternalDoctype) { + dtd.complete = 0; + if (parser->m_paramEntityParsing != XML_PARAM_ENTITY_PARSING_NEVER + && externalEntityRefHandler) { + ENTITY *entity = (ENTITY *)lookup(parser, &dtd.paramEntities, + externalSubsetName, + 0); + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) { + *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING; + return; + } + } + if (!dtd.complete + && !dtd.standalone + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) { + *errorCodeP = XML_ERROR_NOT_STANDALONE; + return; + } + } + if (endDoctypeDeclHandler) + endDoctypeDeclHandler(handlerArg); + break; + case XML_ROLE_INSTANCE_START: { + processor = contentProcessor; + contentProcessor(xmlParserP, s, end, nextPtr, errorCodeP, errorP); + return; + } + case XML_ROLE_ATTLIST_ELEMENT_NAME: + { + const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); + if (!name) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + declElementType = (ELEMENT_TYPE *) + lookup(parser, &dtd.elementTypes, name, sizeof(ELEMENT_TYPE)); + if (!declElementType) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + if (declElementType->name != name) + poolDiscard(&dtd.pool); + else { + poolFinish(&dtd.pool); + if (!setElementTypePrefix(xmlParserP, declElementType)) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + } + break; + } + case XML_ROLE_ATTRIBUTE_NAME: + declAttributeId = getAttributeId(xmlParserP, enc, s, next); + if (!declAttributeId) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + declAttributeIsCdata = 0; + declAttributeIsId = 0; + break; + case XML_ROLE_ATTRIBUTE_TYPE_CDATA: + declAttributeIsCdata = 1; + break; + case XML_ROLE_ATTRIBUTE_TYPE_ID: + declAttributeIsId = 1; + break; + case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: + case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: + if (dtd.complete + && !defineAttribute(declElementType, declAttributeId, + declAttributeIsCdata, + declAttributeIsId, 0)) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + break; + case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: + case XML_ROLE_FIXED_ATTRIBUTE_VALUE: + { + const XML_Char *attVal; + enum XML_Error result + = storeAttributeValue(xmlParserP, enc, declAttributeIsCdata, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar, + &dtd.pool); + if (result) { + *errorCodeP = result; + return; + } + attVal = poolStart(&dtd.pool); + poolFinish(&dtd.pool); + if (dtd.complete + /* ID attributes aren't allowed to have a default */ + && !defineAttribute(declElementType, declAttributeId, + declAttributeIsCdata, 0, attVal)) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + break; + } + case XML_ROLE_ENTITY_VALUE: + { + enum XML_Error result = storeEntityValue(xmlParserP, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (declEntity) { + declEntity->textPtr = poolStart(&dtd.pool); + declEntity->textLen = poolLength(&dtd.pool); + poolFinish(&dtd.pool); + if (internalParsedEntityDeclHandler + /* Check it's not a parameter entity */ + && ((ENTITY *)lookup(parser, &dtd.generalEntities, + declEntity->name, 0) + == declEntity)) { + *evPtr.endP = s; + internalParsedEntityDeclHandler(handlerArg, + declEntity->name, + declEntity->textPtr, + declEntity->textLen); + } + } + else + poolDiscard(&dtd.pool); + if (result != XML_ERROR_NONE) { + *errorCodeP = result; + return; + } + } + break; + case XML_ROLE_DOCTYPE_SYSTEM_ID: + if (!dtd.standalone + && parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_NEVER + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) { + *errorCodeP = XML_ERROR_NOT_STANDALONE; + return; + } + hadExternalDoctype = 1; + if (!declEntity) { + declEntity = (ENTITY *)lookup(parser, &dtd.paramEntities, + externalSubsetName, + sizeof(ENTITY)); + if (!declEntity) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + } + /* fall through */ + case XML_ROLE_ENTITY_SYSTEM_ID: + if (declEntity) { + declEntity->systemId = poolStoreString(&dtd.pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!declEntity->systemId) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + declEntity->base = curBase; + poolFinish(&dtd.pool); + } + break; + case XML_ROLE_ENTITY_NOTATION_NAME: + if (declEntity) { + declEntity->notation = poolStoreString(&dtd.pool, enc, s, next); + if (!declEntity->notation) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + poolFinish(&dtd.pool); + if (unparsedEntityDeclHandler) { + *evPtr.endP = s; + unparsedEntityDeclHandler(handlerArg, + declEntity->name, + declEntity->base, + declEntity->systemId, + declEntity->publicId, + declEntity->notation); + } + + } + break; + case XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION: + if (declEntity && externalParsedEntityDeclHandler) { + *evPtr.endP = s; + externalParsedEntityDeclHandler(handlerArg, + declEntity->name, + declEntity->base, + declEntity->systemId, + declEntity->publicId); + } + break; + case XML_ROLE_GENERAL_ENTITY_NAME: + { + const XML_Char *name; + if (XmlPredefinedEntityName(enc, s, next)) { + declEntity = 0; + break; + } + name = poolStoreString(&dtd.pool, enc, s, next); + if (!name) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + if (dtd.complete) { + declEntity = (ENTITY *) + lookup(parser, &dtd.generalEntities, name, sizeof(ENTITY)); + if (!declEntity) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + if (declEntity->name != name) { + poolDiscard(&dtd.pool); + declEntity = 0; + } + else + poolFinish(&dtd.pool); + } + else { + poolDiscard(&dtd.pool); + declEntity = 0; + } + } + break; + case XML_ROLE_PARAM_ENTITY_NAME: + if (dtd.complete) { + const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); + if (!name) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + declEntity = (ENTITY *) + lookup(parser, &dtd.paramEntities, name, sizeof(ENTITY)); + if (!declEntity) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + if (declEntity->name != name) { + poolDiscard(&dtd.pool); + declEntity = 0; + } + else + poolFinish(&dtd.pool); + } + break; + case XML_ROLE_NOTATION_NAME: + declNotationPublicId = 0; + declNotationName = 0; + if (notationDeclHandler) { + declNotationName = poolStoreString(&tempPool, enc, s, next); + if (!declNotationName) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + poolFinish(&tempPool); + } + break; + case XML_ROLE_NOTATION_PUBLIC_ID: + if (!XmlIsPublicId(enc, s, next, evPtr.startP)) { + *errorCodeP = XML_ERROR_SYNTAX; + return; + } + if (declNotationName) { + XML_Char *tem = poolStoreString(&tempPool, + enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!tem) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + normalizePublicId(tem); + declNotationPublicId = tem; + poolFinish(&tempPool); + } + break; + case XML_ROLE_NOTATION_SYSTEM_ID: + if (declNotationName && notationDeclHandler) { + const XML_Char *systemId + = poolStoreString(&tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!systemId) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + *evPtr.endP = s; + notationDeclHandler(handlerArg, + declNotationName, + curBase, + systemId, + declNotationPublicId); + } + poolClear(&tempPool); + break; + case XML_ROLE_NOTATION_NO_SYSTEM_ID: + if (declNotationPublicId && notationDeclHandler) { + *evPtr.endP = s; + notationDeclHandler(handlerArg, + declNotationName, + curBase, + 0, + declNotationPublicId); + } + poolClear(&tempPool); + break; + case XML_ROLE_ERROR: + switch (tok) { + case XML_TOK_PARAM_ENTITY_REF: + *errorCodeP = XML_ERROR_PARAM_ENTITY_REF; + case XML_TOK_XML_DECL: + *errorCodeP = XML_ERROR_MISPLACED_XML_PI; + default: + *errorCodeP = XML_ERROR_SYNTAX; + } + return; + case XML_ROLE_IGNORE_SECT: + { + enum XML_Error result; + if (defaultHandler) + reportDefault(xmlParserP, enc, s, next); + result = doIgnoreSection(xmlParserP, enc, &next, end, nextPtr); + if (!next) { + processor = ignoreSectionProcessor; + *errorCodeP = result; + return; + } + } + break; + case XML_ROLE_GROUP_OPEN: + if (prologState.level >= groupSize) { + if (groupSize) { + char *temp = realloc(groupConnector, groupSize *= 2); + if (!temp) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + groupConnector = temp; + } else { + groupConnector = malloc(groupSize = 32); + if (!groupConnector) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + } + } + groupConnector[prologState.level] = 0; + break; + case XML_ROLE_GROUP_SEQUENCE: + if (groupConnector[prologState.level] == '|') { + *errorCodeP = XML_ERROR_SYNTAX; + return; + } + groupConnector[prologState.level] = ','; + break; + case XML_ROLE_GROUP_CHOICE: + if (groupConnector[prologState.level] == ',') { + *errorCodeP = XML_ERROR_SYNTAX; + return; + } + groupConnector[prologState.level] = '|'; + break; + case XML_ROLE_PARAM_ENTITY_REF: + case XML_ROLE_INNER_PARAM_ENTITY_REF: + if (parser->m_paramEntityParsing != XML_PARAM_ENTITY_PARSING_NEVER + && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) { + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&dtd.pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + entity = (ENTITY *)lookup(parser, &dtd.paramEntities, name, 0); + poolDiscard(&dtd.pool); + if (!entity) { + /* FIXME what to do if !dtd.complete? */ + *errorCodeP = XML_ERROR_UNDEFINED_ENTITY; + return; + } + if (entity->open) { + *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF; + return; + } + if (entity->textPtr) { + processInternalParamEntity(xmlParserP, entity, errorCodeP, errorP); + if (*errorCodeP != XML_ERROR_NONE) + return; + break; + } + if (role == XML_ROLE_INNER_PARAM_ENTITY_REF) { + *errorCodeP = XML_ERROR_PARAM_ENTITY_REF; + return; + } + if (externalEntityRefHandler) { + dtd.complete = 0; + entity->open = 1; + if (!externalEntityRefHandler(externalEntityRefHandlerArg, + 0, + entity->base, + entity->systemId, + entity->publicId)) { + entity->open = 0; + *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING; + return; + } + entity->open = 0; + if (dtd.complete) + break; + } + } + if (!dtd.standalone + && notStandaloneHandler + && !notStandaloneHandler(handlerArg)) { + *errorCodeP = XML_ERROR_NOT_STANDALONE; + return; + } + dtd.complete = 0; + if (defaultHandler) + reportDefault(xmlParserP, enc, s, next); + break; + case XML_ROLE_NONE: + switch (tok) { + case XML_TOK_PI: + if (!reportProcessingInstruction(xmlParserP, enc, s, next)) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + break; + case XML_TOK_COMMENT: + if (!reportComment(xmlParserP, enc, s, next)) { + *errorCodeP = XML_ERROR_NO_MEMORY; + return; + } + break; + } + break; + } + if (defaultHandler) { + switch (tok) { + case XML_TOK_PI: + case XML_TOK_COMMENT: + case XML_TOK_BOM: + case XML_TOK_XML_DECL: + case XML_TOK_IGNORE_SECT: + case XML_TOK_PARAM_ENTITY_REF: + break; + default: + if (role != XML_ROLE_IGNORE_SECT) + reportDefault(xmlParserP, enc, s, next); + } + } + s = next; + tok = XmlPrologTok(enc, s, end, &next); + } + /* not reached */ +} + + + +static Processor prologProcessor; + +static void +prologProcessor(XML_Parser const xmlParserP, + const char * const s, + const char * const end, + const char ** const nextPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + Parser * const parser = (Parser *) xmlParserP; + + const char * next; + int tok; + + *errorP = NULL; + + tok = XmlPrologTok(parser->m_encoding, s, end, &next); + + doProlog(xmlParserP, parser->m_encoding, s, end, tok, next, nextPtr, + errorCodeP, errorP); +} + + + +static Processor prologInitProcessor; + +static void +prologInitProcessor(XML_Parser const parser, + const char * const s, + const char * const end, + const char ** const nextPtr, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + enum XML_Error result; + + *errorP = NULL; + + result = initializeEncoding(parser); + + if (result != XML_ERROR_NONE) + *errorCodeP = result; + else { + processor = prologProcessor; + prologProcessor(parser, s, end, nextPtr, errorCodeP, errorP); + } +} + + + +static void +processInternalParamEntity(XML_Parser const parser, + ENTITY * const entity, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + const char *s, *end, *next; + int tok; + OPEN_INTERNAL_ENTITY openEntity; + + entity->open = 1; + openEntity.next = openInternalEntities; + openInternalEntities = &openEntity; + openEntity.entity = entity; + openEntity.internalEventPtr = 0; + openEntity.internalEventEndPtr = 0; + s = (char *)entity->textPtr; + end = (char *)(entity->textPtr + entity->textLen); + tok = XmlPrologTok(internalEncoding, s, end, &next); + + doProlog(parser, internalEncoding, s, end, tok, next, 0, + errorCodeP, errorP); + + entity->open = 0; + openInternalEntities = openEntity.next; +} + + + +XML_Parser +xmlrpc_XML_ParserCreate(const XML_Char * const encodingName) { + + XML_Parser const xmlParserP = malloc(sizeof(Parser)); + + bool error; + + if (xmlParserP) { + Parser * const parser = (Parser *)xmlParserP; + + parser->m_processor = prologInitProcessor; + xmlrpc_XmlPrologStateInit(&parser->m_prologState); + parser->m_userData = 0; + parser->m_handlerArg = 0; + parser->m_startElementHandler = 0; + parser->m_endElementHandler = 0; + parser->m_characterDataHandler = 0; + parser->m_processingInstructionHandler = 0; + parser->m_commentHandler = 0; + parser->m_startCdataSectionHandler = 0; + parser->m_endCdataSectionHandler = 0; + parser->m_defaultHandler = 0; + parser->m_startDoctypeDeclHandler = 0; + parser->m_endDoctypeDeclHandler = 0; + parser->m_unparsedEntityDeclHandler = 0; + parser->m_notationDeclHandler = 0; + parser->m_externalParsedEntityDeclHandler = 0; + parser->m_internalParsedEntityDeclHandler = 0; + parser->m_startNamespaceDeclHandler = 0; + parser->m_endNamespaceDeclHandler = 0; + parser->m_notStandaloneHandler = 0; + parser->m_externalEntityRefHandler = 0; + parser->m_externalEntityRefHandlerArg = parser; + parser->m_unknownEncodingHandler = 0; + parser->m_buffer = 0; + parser->m_bufferPtr = 0; + parser->m_bufferEnd = 0; + parser->m_parseEndByteIndex = 0; + parser->m_parseEndPtr = 0; + parser->m_bufferLim = 0; + parser->m_declElementType = 0; + parser->m_declAttributeId = 0; + parser->m_declEntity = 0; + parser->m_declNotationName = 0; + parser->m_declNotationPublicId = 0; + memset(&parser->m_position, 0, sizeof(POSITION)); + parser->m_errorCode = XML_ERROR_NONE; + parser->m_errorString = NULL; + parser->m_eventPtr = 0; + parser->m_eventEndPtr = 0; + parser->m_positionPtr = 0; + parser->m_openInternalEntities = 0; + parser->m_tagLevel = 0; + parser->m_tagStack = 0; + parser->m_freeTagList = 0; + parser->m_freeBindingList = 0; + parser->m_inheritedBindings = 0; + parser->m_attsSize = INIT_ATTS_SIZE; + parser->m_atts = malloc(attsSize * sizeof(ATTRIBUTE)); + parser->m_nSpecifiedAtts = 0; + parser->m_dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); + parser->m_groupSize = 0; + parser->m_groupConnector = 0; + parser->m_hadExternalDoctype = 0; + parser->m_unknownEncodingMem = 0; + parser->m_unknownEncodingRelease = 0; + parser->m_unknownEncodingData = 0; + parser->m_unknownEncodingHandlerData = 0; + parser->m_namespaceSeparator = '!'; + parser->m_parentParser = 0; + parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; + parser->m_hash_secret_salt = 0; + parser->m_ns = 0; + poolInit(&parser->m_tempPool); + poolInit(&parser->m_temp2Pool); + parser->m_protocolEncodingName = + encodingName ? + poolCopyString(&parser->m_tempPool, encodingName) : NULL; + parser->m_curBase = 0; + if (!dtdInit(&parser->m_dtd) || !parser->m_atts || !parser->m_dataBuf + || (encodingName && !parser->m_protocolEncodingName)) + error = true; + else { + parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; + xmlrpc_XmlInitEncoding(&parser->m_initEncoding, + &parser->m_encoding, + 0); + parser->m_internalEncoding = XmlGetInternalEncoding(); + error = false; + } + if (error) + xmlrpc_XML_ParserFree(xmlParserP); + } else + error =true; + + return error ? NULL : xmlParserP; +} + +XML_Parser +xmlrpc_XML_ParserCreateNS(const XML_Char * const encodingName, + XML_Char const nsSep) { + + XML_Parser const xmlParserP = xmlrpc_XML_ParserCreate(encodingName); + Parser * const parser = (Parser *)xmlParserP; + + if (xmlParserP) { + xmlrpc_XmlInitEncodingNS(&initEncoding, &parser->m_encoding, 0); + ns = 1; + internalEncoding = XmlGetInternalEncodingNS(); + namespaceSeparator = nsSep; + } + + return xmlParserP; +} + + + +static void +resetErrorString(Parser * const parserP) { + + if (parserP->m_errorString) { + xmlrpc_strfree(parserP->m_errorString); + parserP->m_errorString = NULL; + } +} + + + +int +xmlrpc_XML_SetEncoding(XML_Parser const xmlParserP, + const XML_Char * const encodingName) { + + Parser * const parser = (Parser *) xmlParserP; + + int retval; + + if (!encodingName) { + parser->m_protocolEncodingName = NULL; + retval = 1; + } else { + parser->m_protocolEncodingName = + poolCopyString(&tempPool, encodingName); + if (parser->m_protocolEncodingName) + retval = 1; + else + retval = 0; + } + return retval; +} + + + +XML_Parser +xmlrpc_XML_ExternalEntityParserCreate(XML_Parser oldParser, + const XML_Char *context, + const XML_Char *encodingName) +{ + XML_Parser xmlParserP = oldParser; + Parser * parser = xmlParserP; + DTD *oldDtd = &dtd; + XML_StartElementHandler oldStartElementHandler = startElementHandler; + XML_EndElementHandler oldEndElementHandler = endElementHandler; + XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; + XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler; + XML_CommentHandler oldCommentHandler = commentHandler; + XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler; + XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler; + XML_DefaultHandler oldDefaultHandler = defaultHandler; + XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler; + XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; + XML_ExternalParsedEntityDeclHandler oldExternalParsedEntityDeclHandler = externalParsedEntityDeclHandler; + XML_InternalParsedEntityDeclHandler oldInternalParsedEntityDeclHandler = internalParsedEntityDeclHandler; + XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler; + XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler; + XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; + XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler; + XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler; + void *oldUserData = userData; + void *oldHandlerArg = handlerArg; + int oldDefaultExpandInternalEntities = defaultExpandInternalEntities; + void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; + int oldParamEntityParsing = parser->m_paramEntityParsing; + /* Note that the new parser shares the same hash secret as the old + parser, so that dtdCopy and copyEntityTable can lookup values + from hash tables associated with either parser without us having + to worry which hash secrets each table has. + */ + unsigned long oldhash_secret_salt = hash_secret_salt; + parser = (ns + ? xmlrpc_XML_ParserCreateNS(encodingName, namespaceSeparator) + : xmlrpc_XML_ParserCreate(encodingName)); + if (!parser) + return 0; + startElementHandler = oldStartElementHandler; + endElementHandler = oldEndElementHandler; + characterDataHandler = oldCharacterDataHandler; + processingInstructionHandler = oldProcessingInstructionHandler; + commentHandler = oldCommentHandler; + startCdataSectionHandler = oldStartCdataSectionHandler; + endCdataSectionHandler = oldEndCdataSectionHandler; + defaultHandler = oldDefaultHandler; + unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; + notationDeclHandler = oldNotationDeclHandler; + externalParsedEntityDeclHandler = oldExternalParsedEntityDeclHandler; + internalParsedEntityDeclHandler = oldInternalParsedEntityDeclHandler; + startNamespaceDeclHandler = oldStartNamespaceDeclHandler; + endNamespaceDeclHandler = oldEndNamespaceDeclHandler; + notStandaloneHandler = oldNotStandaloneHandler; + externalEntityRefHandler = oldExternalEntityRefHandler; + unknownEncodingHandler = oldUnknownEncodingHandler; + userData = oldUserData; + if (oldUserData == oldHandlerArg) + handlerArg = userData; + else + handlerArg = parser; + if (oldExternalEntityRefHandlerArg != oldParser) + externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; + defaultExpandInternalEntities = oldDefaultExpandInternalEntities; + hash_secret_salt = oldhash_secret_salt; + parser->m_paramEntityParsing = oldParamEntityParsing; + if (context) { + if (!dtdCopy(oldParser, &dtd, oldDtd) || !setContext(parser, context)) { + xmlrpc_XML_ParserFree(parser); + return 0; + } + processor = externalEntityInitProcessor; + } + else { + dtdSwap(&dtd, oldDtd); + parentParser = oldParser; + xmlrpc_XmlPrologStateInitExternalEntity(&prologState); + dtd.complete = 1; + hadExternalDoctype = 1; + } + return parser; +} + +static +void destroyBindings(BINDING *bindings) +{ + for (;;) { + BINDING *b = bindings; + if (!b) + break; + bindings = b->nextTagBinding; + free(b->uri); + free(b); + } +} + +void +xmlrpc_XML_ParserFree(XML_Parser parser) +{ + for (;;) { + TAG *p; + if (tagStack == 0) { + if (freeTagList == 0) + break; + tagStack = freeTagList; + freeTagList = 0; + } + p = tagStack; + tagStack = tagStack->parent; + free(p->buf); + destroyBindings(p->bindings); + free(p); + } + destroyBindings(freeBindingList); + destroyBindings(inheritedBindings); + poolDestroy(&tempPool); + poolDestroy(&temp2Pool); + if (parentParser) { + if (hadExternalDoctype) + dtd.complete = 0; + dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd); + } + dtdDestroy(&dtd); + free((void *)atts); + free(groupConnector); + free(buffer); + free(dataBuf); + free(unknownEncodingMem); + if (unknownEncodingRelease) + unknownEncodingRelease(unknownEncodingData); + resetErrorString(parser); + free(parser); +} + +void +xmlrpc_XML_UseParserAsHandlerArg(XML_Parser parser) +{ + handlerArg = parser; +} + +void +xmlrpc_XML_SetUserData(XML_Parser parser, void *p) +{ + if (handlerArg == userData) + handlerArg = userData = p; + else + userData = p; +} + +int +xmlrpc_XML_SetBase(XML_Parser parser, const XML_Char *p) +{ + if (p) { + p = poolCopyString(&dtd.pool, p); + if (!p) + return 0; + curBase = p; + } + else + curBase = 0; + return 1; +} + +const XML_Char * +xmlrpc_XML_GetBase(XML_Parser parser) +{ + return curBase; +} + +int +xmlrpc_XML_GetSpecifiedAttributeCount(XML_Parser parser) +{ + return nSpecifiedAtts; +} + +int +xmlrpc_XML_GetIdAttributeIndex(XML_Parser parser) +{ + return idAttIndex; +} + +void +xmlrpc_XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end) +{ + startElementHandler = start; + endElementHandler = end; +} + +void +xmlrpc_XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler) +{ + characterDataHandler = handler; +} + +void +xmlrpc_XML_SetProcessingInstructionHandler( + XML_Parser parser, + XML_ProcessingInstructionHandler handler) +{ + processingInstructionHandler = handler; +} + +void +xmlrpc_XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler) +{ + commentHandler = handler; +} + +void +xmlrpc_XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end) +{ + startCdataSectionHandler = start; + endCdataSectionHandler = end; +} + +void +xmlrpc_XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler) +{ + defaultHandler = handler; + defaultExpandInternalEntities = 0; +} + +void +xmlrpc_XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler) +{ + defaultHandler = handler; + defaultExpandInternalEntities = 1; +} + +void +xmlrpc_XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end) +{ + startDoctypeDeclHandler = start; + endDoctypeDeclHandler = end; +} + +void +xmlrpc_XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler) +{ + unparsedEntityDeclHandler = handler; +} + +void +xmlrpc_XML_SetExternalParsedEntityDeclHandler( + XML_Parser parser, + XML_ExternalParsedEntityDeclHandler handler) +{ + externalParsedEntityDeclHandler = handler; +} + +void +xmlrpc_XML_SetInternalParsedEntityDeclHandler( + XML_Parser parser, + XML_InternalParsedEntityDeclHandler handler) +{ + internalParsedEntityDeclHandler = handler; +} + +void +xmlrpc_XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler) +{ + notationDeclHandler = handler; +} + +void +xmlrpc_XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end) +{ + startNamespaceDeclHandler = start; + endNamespaceDeclHandler = end; +} + +void +xmlrpc_XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler) +{ + notStandaloneHandler = handler; +} + +void +xmlrpc_XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler) +{ + externalEntityRefHandler = handler; +} + +void +xmlrpc_XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) +{ + if (arg) + externalEntityRefHandlerArg = arg; + else + externalEntityRefHandlerArg = parser; +} + +void +xmlrpc_XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *data) +{ + unknownEncodingHandler = handler; + unknownEncodingHandlerData = data; +} + + + +int +xmlrpc_XML_SetParamEntityParsing( + XML_Parser const xmlParserP, + enum XML_ParamEntityParsing const parsing) { + + Parser * const parserP = (Parser *) xmlParserP; + + int retval; + + parserP->m_paramEntityParsing = parsing; + + retval = 1; + + return retval; +} + + + +static Processor errorProcessor; + +static void +errorProcessor(XML_Parser const parser ATTR_UNUSED, + const char * const s ATTR_UNUSED, + const char * const end ATTR_UNUSED, + const char ** const nextPtr ATTR_UNUSED, + enum XML_Error * const errorCodeP, + const char ** const errorP) { + + *errorP = errorString; + *errorCodeP = errorCode; +} + + + +static void +parseFinalLen0(Parser * const parser, + int * const retvalP) { + + positionPtr = bufferPtr; + parseEndPtr = bufferEnd; + + processor(parser, bufferPtr, bufferEnd, 0, &errorCode, &errorString); + + if (errorCode == XML_ERROR_NONE) + *retvalP = 1; + else { + eventEndPtr = eventPtr; + processor = errorProcessor; + *retvalP = 0; + } +} + + + +static void +parseNoBuffer(Parser * const parser, + const char * const s, + size_t const len, + bool const isFinal, + int * const succeededP) { + + parser->m_parseEndByteIndex += len; + parser->m_positionPtr = s; + + if (isFinal) { + parser->m_parseEndPtr = s + len; + parser->m_processor(parser, s, parser->m_parseEndPtr, 0, + &parser->m_errorCode, &parser->m_errorString); + if (parser->m_errorCode == XML_ERROR_NONE) + *succeededP = true; + else { + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; + *succeededP = false; + } + } else { + const char * end; + + parser->m_parseEndPtr = s + len; + parser->m_processor(parser, s, s + len, + &end, + &parser->m_errorCode, &parser->m_errorString); + if (parser->m_errorCode != XML_ERROR_NONE) { + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; + *succeededP = false; + } else { + int const nLeftOver = s + len - end; + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, + &parser->m_position); + if (nLeftOver > 0) { + if (buffer == 0 || + nLeftOver > parser->m_bufferLim - parser->m_buffer) { + REALLOCARRAY(parser->m_buffer, len * 2); + if (parser->m_buffer) + parser->m_bufferLim = parser->m_buffer + len * 2; + } + + if (parser->m_buffer) { + memcpy(parser->m_buffer, end, nLeftOver); + parser->m_bufferPtr = parser->m_buffer; + parser->m_bufferEnd = parser->m_buffer + nLeftOver; + *succeededP = true; + } else { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + parser->m_eventPtr = 0; + parser->m_eventEndPtr = 0; + parser->m_processor = errorProcessor; + *succeededP = false; + } + } else + *succeededP = true; + } + } +} + + +int +XML_SetHashSalt(XML_Parser parser, + unsigned long hash_salt) +{ + hash_secret_salt = hash_salt; + return 1; +} + +int +xmlrpc_XML_Parse(XML_Parser const xmlParserP, + const char * const s, + size_t const len, + int const isFinal) { + + Parser * const parser = (Parser *) xmlParserP; + + int retval; + + resetErrorString(parser); + + if (parser->m_parentParser == NULL && !startParsing(parser)) { + errorCode = XML_ERROR_NO_MEMORY; + return 0; + } + + if (len == 0) { + if (!isFinal) + retval = 1; + else + parseFinalLen0(parser, &retval); + } else if (parser->m_bufferPtr == parser->m_bufferEnd) + parseNoBuffer(parser, s, len, isFinal, &retval); + else { + memcpy(xmlrpc_XML_GetBuffer(parser, len), s, len); + retval = xmlrpc_XML_ParseBuffer(parser, len, isFinal); + } + return retval; +} + + + +int +xmlrpc_XML_ParseBuffer(XML_Parser const xmlParserP, + int const len, + int const isFinal) { + + Parser * const parser = (Parser *)xmlParserP; + + const char * const start = bufferPtr; + + resetErrorString(parser); + + if (parser->m_parentParser == NULL && !startParsing(parser)) { + errorCode = XML_ERROR_NO_MEMORY; + return 0; + } + + parser->m_positionPtr = start; + parser->m_bufferEnd += len; + parser->m_parseEndByteIndex += len; + parser->m_parseEndPtr = parser->m_bufferEnd; + parser->m_processor(xmlParserP, start, parser->m_parseEndPtr, + isFinal ? NULL : &parser->m_bufferPtr, + &parser->m_errorCode, &parser->m_errorString); + if (parser->m_errorCode == XML_ERROR_NONE) { + if (!isFinal) + XmlUpdatePosition(parser->m_encoding, + parser->m_positionPtr, parser->m_bufferPtr, + &parser->m_position); + return 1; + } else { + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; + return 0; + } +} + + + +void * +xmlrpc_XML_GetBuffer(XML_Parser const xmlParserP, + size_t const len) { + + Parser * const parser = (Parser *)xmlParserP; + + assert(bufferLim >= bufferEnd); + + if (len > (size_t)(bufferLim - bufferEnd)) { + /* FIXME avoid integer overflow */ + size_t neededSize = len + (bufferEnd - bufferPtr); + assert(bufferLim >= buffer); + if (neededSize <= (size_t)(bufferLim - buffer)) { + memmove(buffer, bufferPtr, bufferEnd - bufferPtr); + bufferEnd = buffer + (bufferEnd - bufferPtr); + bufferPtr = buffer; + } else { + size_t bufferSize; + char * newBuf; + + bufferSize = bufferLim > bufferPtr ? + bufferLim - bufferPtr : INIT_BUFFER_SIZE; + + do { + bufferSize *= 2; + } while (bufferSize < neededSize); + newBuf = malloc(bufferSize); + if (newBuf == 0) { + errorCode = XML_ERROR_NO_MEMORY; + return 0; + } + bufferLim = newBuf + bufferSize; + if (bufferPtr) { + memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); + free(buffer); + } + bufferEnd = newBuf + (bufferEnd - bufferPtr); + bufferPtr = buffer = newBuf; + } + } + return bufferEnd; +} + + + +enum XML_Error +xmlrpc_XML_GetErrorCode(XML_Parser const parser) { + + return errorCode; +} + + + +const char * +xmlrpc_XML_GetErrorString(XML_Parser const parser) { + + if (errorString) + return errorString; + else if (errorCode == XML_ERROR_NONE) + return NULL; + else + return xmlrpc_XML_ErrorString(errorCode); +} + + + +long +xmlrpc_XML_GetCurrentByteIndex(XML_Parser const parser) { + + long retval; + + if (eventPtr) { + size_t const bytesLeft = parseEndPtr - eventPtr; + + if ((size_t)(long)(bytesLeft) != bytesLeft) + retval = -1; + else + retval = parseEndByteIndex - (long)bytesLeft; + } else + retval = -1; + + return retval; +} + + + +int +xmlrpc_XML_GetCurrentByteCount(XML_Parser const parser) { + + int retval; + + if (eventEndPtr && eventPtr) { + size_t const byteCount = eventEndPtr - eventPtr; + + assert((size_t)(int)byteCount == byteCount); + + retval = (int)byteCount; + } else + retval = 0; + + return retval; +} + + + +int +xmlrpc_XML_GetCurrentLineNumber(XML_Parser const xmlParserP) { + + Parser * const parser = (Parser *) xmlParserP; + + if (eventPtr) { + XmlUpdatePosition(parser->m_encoding, positionPtr, eventPtr, + &position); + positionPtr = eventPtr; + } + return position.lineNumber + 1; +} + + + +int +xmlrpc_XML_GetCurrentColumnNumber(XML_Parser const xmlParserP) { + + Parser * const parser = (Parser *) xmlParserP; + + if (eventPtr) { + XmlUpdatePosition(parser->m_encoding, positionPtr, eventPtr, + &position); + positionPtr = eventPtr; + } + return position.columnNumber; +} + + + +void +xmlrpc_XML_DefaultCurrent(XML_Parser const xmlParserP) { + + Parser * const parser = (Parser *) xmlParserP; + + if (defaultHandler) { + if (openInternalEntities) + reportDefault(xmlParserP, + internalEncoding, + openInternalEntities->internalEventPtr, + openInternalEntities->internalEventEndPtr); + else + reportDefault(xmlParserP, parser->m_encoding, + eventPtr, eventEndPtr); + } +} + +const XML_LChar * +xmlrpc_XML_ErrorString(int const code) { + + static const XML_LChar * const message[] = { + /* NONE */ NULL, + /* NO_MEMORY */ XML_T("out of memory"), + /* SYNTAX */ XML_T("syntax error"), + /* NO_ELEMENTS */ XML_T("no element found"), + /* INVALID_TOKEN */ XML_T("not well-formed"), + /* UNCLOSED_TOKEN */ XML_T("unclosed token"), + /* PARTIAL_CHAR */ XML_T("unclosed token"), + /* TAG_MISMATCH */ XML_T("mismatched tag"), + /* DUPLICATE_ATTRIBUTE */ XML_T("duplicate attribute"), + /* JUNK_AFTER_DOC_ELEMENT */ XML_T("junk after document element"), + /* PARAM_ENTITY_REF */ + XML_T("illegal parameter entity reference"), + /* UNDEFINED_ENTITY */ XML_T("undefined entity"), + /* RECURSIVE_ENTITY_REF */ XML_T("recursive entity reference"), + /* ASYNC_ENTITY */ XML_T("asynchronous entity"), + /* BAD_CHAR_REF */ + XML_T("reference to invalid character number"), + /* BINARY_ENTITY_REF */ XML_T("reference to binary entity"), + /* ATTRIBUTE_EXTERNAL_ENTITY_REF */ + XML_T("reference to external entity in attribute"), + /* MISPLACED_XML_PI */ + XML_T("xml processing instruction not at start " + "of external entity"), + /* UNKNOWN_ENCODING */ XML_T("unknown encoding"), + /* INCORRECT_ENCODING */ + XML_T("encoding specified in XML declaration is incorrect"), + /* UNCLOSED_CDATA_SECTION */ XML_T("unclosed CDATA section"), + /* EXTERNAL_ENTITY_HANDLING */ + XML_T("error in processing external entity reference"), + /* NOT_STANDALONE */ XML_T("document is not standalone") + }; + + const XML_LChar * retval; + + if (code > 0 && (unsigned)code < ARRAY_SIZE(message)) + retval = message[code]; + else + retval = NULL; + + return retval; +} diff --git a/trunk/lib/expat/xmlparse/xmlparse.h b/trunk/lib/expat/xmlparse/xmlparse.h new file mode 100644 index 000000000..76cf0db43 --- /dev/null +++ b/trunk/lib/expat/xmlparse/xmlparse.h @@ -0,0 +1,584 @@ +/* + Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file copying.txt for copying permission. +*/ + +#ifndef XMLPARSE_H_INCLUDED +#define XMLPARSE_H_INCLUDED + +#include "xmlrpc-c/c_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *XML_Parser; + +/* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; + +/* Constructs a new parser; encoding is the encoding specified by the external +protocol or null if there is none specified. */ + +XMLRPC_DLLEXPORT +XML_Parser +xmlrpc_XML_ParserCreate(const XML_Char * const encoding); + +/* Constructs a new parser and namespace processor. Element type names +and attribute names that belong to a namespace will be expanded; +unprefixed attribute names are never expanded; unprefixed element type +names are expanded only if there is a default namespace. The expanded +name is the concatenation of the namespace URI, the namespace separator character, +and the local part of the name. If the namespace separator is '\0' then +the namespace URI and the local part will be concatenated without any +separator. When a namespace is not declared, the name and prefix will be +passed through without expansion. */ + +XMLRPC_DLLEXPORT +XML_Parser +xmlrpc_XML_ParserCreateNS(const XML_Char * const encoding, + XML_Char const namespaceSeparator); + + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. */ + +typedef void (*XML_StartElementHandler)(void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (*XML_EndElementHandler)(void *userData, + const XML_Char *name); + +/* s is not 0 terminated. */ +typedef void (*XML_CharacterDataHandler)(void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (*XML_ProcessingInstructionHandler)(void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data); + +typedef void (*XML_StartCdataSectionHandler)(void *userData); +typedef void (*XML_EndCdataSectionHandler)(void *userData); + +/* This is called for any characters in the XML document for +which there is no applicable handler. This includes both +characters that are part of markup which is of a kind that is +not reported (comments, markup declarations), or characters +that are part of a construct which could be reported but +for which no handler has been supplied. The characters are passed +exactly as they were in the XML document except that +they will be encoded in UTF-8. Line boundaries are not normalized. +Note that a byte order mark character is not passed to the default handler. +There are no guarantees about how characters are divided between calls +to the default handler: for example, a comment might be split between +multiple calls. */ + +typedef void (*XML_DefaultHandler)(void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration when the +name of the DOCTYPE is encountered. */ +typedef void (*XML_StartDoctypeDeclHandler)(void *userData, + const XML_Char *doctypeName); + +/* This is called for the start of the DOCTYPE declaration when the +closing > is encountered, but after processing any external subset. */ +typedef void (*XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for a declaration of an unparsed (NDATA) +entity. The base argument is whatever was set by XML_SetBase. +The entityName, systemId and notationName arguments will never be null. +The other arguments may be. */ + +typedef void (*XML_UnparsedEntityDeclHandler)(void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. +The base argument is whatever was set by XML_SetBase. +The notationName will never be null. The other arguments can be. */ + +typedef void (*XML_NotationDeclHandler)(void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +typedef void (*XML_ExternalParsedEntityDeclHandler)(void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +typedef void (*XML_InternalParsedEntityDeclHandler)(void *userData, + const XML_Char *entityName, + const XML_Char *replacementText, + int replacementTextLength); + +/* When namespace processing is enabled, these are called once for +each namespace declaration. The call to the start and end element +handlers occur between the calls to the start and end namespace +declaration handlers. For an xmlns attribute, prefix will be null. +For an xmlns="" attribute, uri will be null. */ + +typedef void (*XML_StartNamespaceDeclHandler)(void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (*XML_EndNamespaceDeclHandler)(void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone (it has an +external subset or a reference to a parameter entity, but does not +have standalone="yes"). If this handler returns 0, then processing +will not continue, and the parser will return a +XML_ERROR_NOT_STANDALONE error. */ + +typedef int (*XML_NotStandaloneHandler)(void *userData); + +/* This is called for a reference to an external parsed general entity. +The referenced entity is not automatically parsed. +The application can parse it immediately or later using +XML_ExternalEntityParserCreate. +The parser argument is the parser parsing the entity containing the reference; +it can be passed as the parser argument to XML_ExternalEntityParserCreate. +The systemId argument is the system identifier as specified in the entity declaration; +it will not be null. +The base argument is the system identifier that should be used as the base for +resolving systemId if systemId was relative; this is set by XML_SetBase; +it may be null. +The publicId argument is the public identifier as specified in the entity declaration, +or null if none was specified; the whitespace in the public identifier +will have been normalized as required by the XML spec. +The context argument specifies the parsing context in the format +expected by the context argument to +XML_ExternalEntityParserCreate; context is valid only until the handler +returns, so if the referenced entity is to be parsed later, it must be copied. +The handler should return 0 if processing should not continue because of +a fatal error in the handling of the external entity. +In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING +error. +Note that unlike other handlers the first argument is the parser, not userData. */ + +typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This structure is filled in by the XML_UnknownEncodingHandler +to provide information to the parser about encodings that are unknown +to the parser. +The map[b] member gives information about byte sequences +whose first byte is b. +If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c. +If map[b] is -1, then the byte sequence is malformed. +If map[b] is -n, where n >= 2, then b is the first byte of an n-byte +sequence that encodes a single Unicode scalar value. +The data member will be passed as the first argument to the convert function. +The convert function is used to convert multibyte sequences; +s will point to a n-byte sequence where map[(unsigned char)*s] == -n. +The convert function must return the Unicode scalar value +represented by this byte sequence or -1 if the byte sequence is malformed. +The convert function may be null if the encoding is a single-byte encoding, +that is if map[b] >= -1 for all bytes b. +When the parser is finished with the encoding, then if release is not null, +it will call release passing it the data member; +once release has been called, the convert function will not be called again. + +Expat places certain restrictions on the encodings that are supported +using this mechanism. + +1. Every ASCII character that can appear in a well-formed XML document, +other than the characters + + $@\^`{}~ + +must be represented by a single byte, and that byte must be the +same byte that represents that character in ASCII. + +2. No character may require more than 4 bytes to encode. + +3. All characters encoded must have Unicode scalar values <= 0xFFFF, +(ie characters that would be encoded by surrogates in UTF-16 +are not allowed). Note that this restriction doesn't apply to +the built-in support for UTF-8 and UTF-16. + +4. No Unicode character may be encoded by more than one distinct sequence +of bytes. */ + +typedef struct { + int map[256]; + void *data; + int (*convert)(void *data, const char *s); + void (*release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. +The encodingHandlerData argument is that which was passed as the +second argument to XML_SetUnknownEncodingHandler. +The name argument gives the name of the encoding as specified in +the encoding declaration. +If the callback can provide information about the encoding, +it must fill in the XML_Encoding structure, and return 1. +Otherwise it must return 0. +If info does not describe a suitable encoding, +then the parser will return an XML_UNKNOWN_ENCODING error. */ + +typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetProcessingInstructionHandler( + XML_Parser parser, + XML_ProcessingInstructionHandler handler); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. The entity reference will be passed to the default + handler. +*/ + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of internal + entities. The entity reference will not be passed to the default + handler. +*/ + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetExternalParsedEntityDeclHandler( + XML_Parser parser, + XML_ExternalParsedEntityDeclHandler handler); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetInternalParsedEntityDeclHandler( + XML_Parser parser, + XML_InternalParsedEntityDeclHandler handler); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-null value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg); + +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end element, + processing instruction or character data. It causes the corresponding + markup to be passed to the default handler. +*/ +XMLRPC_DLLEXPORT +void +xmlrpc_XML_DefaultCurrent(XML_Parser parser); + +/* This value is passed as the userData argument to callbacks. */ +XMLRPC_DLLEXPORT +void +xmlrpc_XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or null. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument +to XML_ParserCreate. It must not be called after XML_Parse +or XML_ParseBuffer. */ + +XMLRPC_DLLEXPORT +int +xmlrpc_XML_SetEncoding(XML_Parser const xmlParserP, + const XML_Char * const encodingName); + +/* If this function is called, then the parser will be passed + as the first argument to callbacks instead of userData. + The userData will still be accessible using XML_GetUserData. +*/ +XMLRPC_DLLEXPORT +void +xmlrpc_XML_UseParserAsHandlerArg(XML_Parser parser); + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is left + to the application: this value will be passed through as the base + argument to the XML_ExternalEntityRefHandler, XML_NotationDeclHandler + and XML_UnparsedEntityDeclHandler. The base argument will be copied. + Returns zero if out of memory, non-zero otherwise. +*/ +XMLRPC_DLLEXPORT +int +xmlrpc_XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLRPC_DLLEXPORT +const XML_Char * +xmlrpc_XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLRPC_DLLEXPORT +int +xmlrpc_XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an index + into the atts array passed to the XML_StartElementHandler. +*/ +XMLRPC_DLLEXPORT +int +xmlrpc_XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns 0 if a fatal error is detected. + The last call to XML_Parse must have isFinal true; + len may be zero for this call (or any other). +*/ +XMLRPC_DLLEXPORT +int +xmlrpc_XML_Parse(XML_Parser const xmlParserP, + const char * const s, + size_t const len, + int const isFinal); + +XMLRPC_DLLEXPORT +void * +xmlrpc_XML_GetBuffer(XML_Parser const xmlParserP, + size_t const len); + +XMLRPC_DLLEXPORT +int +xmlrpc_XML_ParseBuffer(XML_Parser const parser, + int const len, + int const isFinal); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of the + externally specified encoding, or null if there is no externally + specified encoding. The context string consists of a sequence of + tokens separated by formfeeds (\f); a token consisting of a name + specifies that the general entity of the name is open; a token of the + form prefix=uri specifies the namespace for a particular prefix; a + token of the form =uri specifies the default namespace. This can be + called at any point after the first call to an + ExternalEntityRefHandler so longer as the parser has not yet been + freed. The new parser is completely independent and may safely be + used in a separate thread. The handlers and userData are initialized + from the parser argument. Returns 0 if out of memory. Otherwise + returns a new XML_Parser object. +*/ +XMLRPC_DLLEXPORT +XML_Parser +xmlrpc_XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then references + to external parameter entities (including the external DTD subset) + will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + Unlike external general entities, external parameter entities can only + be parsed synchronously. If the external parameter entity is to be + parsed, it must be parsed during the call to the external entity ref + handler: the complete sequence of XML_ExternalEntityParserCreate, + XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during + this call. After XML_ExternalEntityParserCreate has been called to + create the parser for the external parameter entity (context must be 0 + for this call), it is illegal to make any calls on the old parser + until XML_ParserFree has been called on the newly created parser. If + the library has been compiled without support for parameter entity + parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. +*/ +XMLRPC_DLLEXPORT +int +xmlrpc_XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* Sets the hash salt to use for internal hash calculations. + Helps in preventing DoS attacks based on predicting hash + function behavior. This must be called before parsing is started. + Returns 1 if successful, 0 when called after parsing has started. +*/ +int +XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE +}; + +/* If xmlrpc_XML_Parse or xmlrpc_XML_ParseBuffer have returned 0, then + xmlrpc_XML_GetErrorString and xmlrpc_XML_GetErrorCode return + information about the error. +*/ + +XMLRPC_DLLEXPORT +enum XML_Error +xmlrpc_XML_GetErrorCode(XML_Parser const parser); + +XMLRPC_DLLEXPORT +const char * +xmlrpc_XML_GetErrorString(XML_Parser const parser); + +/* These functions return information about the current parse location. + They may be called when XML_Parse or XML_ParseBuffer return 0; + in this case the location is the location of the character at which + the error was detected. + They may also be called from any other callback called to report + some parse event; in this the location is the location of the first + of the sequence of characters that generated the event. +*/ + +XMLRPC_DLLEXPORT +int +xmlrpc_XML_GetCurrentLineNumber(XML_Parser parser); + +XMLRPC_DLLEXPORT +int +xmlrpc_XML_GetCurrentColumnNumber(XML_Parser parser); + +XMLRPC_DLLEXPORT +long +xmlrpc_XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. +Returns 0 if the event is in an internal entity. */ + +XMLRPC_DLLEXPORT +int +xmlrpc_XML_GetCurrentByteCount(XML_Parser parser); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees memory used by the parser. */ +XMLRPC_DLLEXPORT +void +xmlrpc_XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLRPC_DLLEXPORT +const XML_LChar * +xmlrpc_XML_ErrorString(int const code); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/trunk/lib/expat/xmltok/Makefile b/trunk/lib/expat/xmltok/Makefile new file mode 100644 index 000000000..66e706325 --- /dev/null +++ b/trunk/lib/expat/xmltok/Makefile @@ -0,0 +1,112 @@ +############################################################################### +# This directory builds libxmlrpc_xmltok, an XML token parser. This is +# essentially the separately distributed Expat library from 2001, but +# with slight changes. The main reason it is bundled with Xmlrpc-c is +# to make the latter easier to build and use. +# +# The library is about XML in general. There is nothing specific to +# XML-RPC here. +############################################################################### + +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + EXPATDIR := $(call updir,$(CURDIR)) + LIBDIR := $(call updir,$(EXPATDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/expat/xmltok + +include $(BLDDIR)/config.mk + +# I can't figure out what XML_BYTE_ORDER is, but it doesn't look like the +# code has ever defined it. That means it's treated like 0 in #if. Since +# we started using the Gcc -Wundef option, that generates a warning, so +# se set it explicitly to 0 here. + +CFLAGS_LOCAL = -DXML_BYTE_ORDER=0 + +# -I. is necessary when blddir != srcdir +INCLUDES = -I. -I$(BLDDIR) -Isrcdir/lib/util/include -Isrcdir/include + +default: all + +TARGET_LIBRARY_NAMES := libxmlrpc_xmltok + +STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_xmltok.a + +SHARED_LIBS_TO_BUILD := libxmlrpc_xmltok +SHARED_LIBS_TO_INSTALL := libxmlrpc_xmltok + +TARGET_MODS = xmltok xmlrole + +OMIT_XMLTOK_LIB_RULE = Y +MAJ=3 + # Major number of shared libraries in this directory + +include $(SRCDIR)/common.mk + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +XMLTOK_SHLIB = $(call shlibfn,libxmlrpc_xmltok) +#XMLTOK_SHLIB is e.g. libxmlrpc_xmltok.so.3.1 +XMLTOK_SHLIBLE = $(call shliblefn,libxmlrpc_xmltok) +#XMLTOK_SHLIBLE is e.g. libxmlrpc_xmltok.so + +.PHONY: all +all: libxmlrpc_xmltok.a $(TARGET_SHARED_LIBRARIES) $(TARGET_SHARED_LE_LIBS) + +# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES +$(XMLTOK_SHLIB): $(TARGET_MODS:%=%.osh) +$(XMLTOK_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) + +# Rule for this is in common.mk, courtesy of TARGET_STATIC_LIBRARIES: + +libxmlrpc_xmltok.a: $(TARGET_MODS:%=%.o) +libxmlrpc_xmltok.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) + +#----------------------------------------------------------------------------- +# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES +#----------------------------------------------------------------------------- + +# Rules to compile object modules from which to build the static and shared +# library are in common.mk, courtesy of TARGET_MODS. + + +.PHONY: clean +clean: clean-common + rm -f nametab.h + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: tags +tags: TAGS + +.PHONY: distdir +distdir: + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: dep +dep: dep-common + +GENNMTAB = ../gennmtab/gennmtab + +nametab.h: $(GENNMTAB) + rm -f $@ + $(GENNMTAB) >$@ + +$(GENNMTAB): + $(MAKE) -C $(dir $@) $(notdir $@) + +xmltok.o xmltok.osh: nametab.h xmltok_impl.c + +include depend.mk diff --git a/trunk/lib/expat/xmltok/ascii.h b/trunk/lib/expat/xmltok/ascii.h new file mode 100644 index 000000000..a8a621ce7 --- /dev/null +++ b/trunk/lib/expat/xmltok/ascii.h @@ -0,0 +1,86 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#define ASCII_A 0x41 +#define ASCII_B 0x42 +#define ASCII_C 0x43 +#define ASCII_D 0x44 +#define ASCII_E 0x45 +#define ASCII_F 0x46 +#define ASCII_G 0x47 +#define ASCII_H 0x48 +#define ASCII_I 0x49 +#define ASCII_J 0x4A +#define ASCII_K 0x4B +#define ASCII_L 0x4C +#define ASCII_M 0x4D +#define ASCII_N 0x4E +#define ASCII_O 0x4F +#define ASCII_P 0x50 +#define ASCII_Q 0x51 +#define ASCII_R 0x52 +#define ASCII_S 0x53 +#define ASCII_T 0x54 +#define ASCII_U 0x55 +#define ASCII_V 0x56 +#define ASCII_W 0x57 +#define ASCII_X 0x58 +#define ASCII_Y 0x59 +#define ASCII_Z 0x5A + +#define ASCII_a 0x61 +#define ASCII_b 0x62 +#define ASCII_c 0x63 +#define ASCII_d 0x64 +#define ASCII_e 0x65 +#define ASCII_f 0x66 +#define ASCII_g 0x67 +#define ASCII_h 0x68 +#define ASCII_i 0x69 +#define ASCII_j 0x6A +#define ASCII_k 0x6B +#define ASCII_l 0x6C +#define ASCII_m 0x6D +#define ASCII_n 0x6E +#define ASCII_o 0x6F +#define ASCII_p 0x70 +#define ASCII_q 0x71 +#define ASCII_r 0x72 +#define ASCII_s 0x73 +#define ASCII_t 0x74 +#define ASCII_u 0x75 +#define ASCII_v 0x76 +#define ASCII_w 0x77 +#define ASCII_x 0x78 +#define ASCII_y 0x79 +#define ASCII_z 0x7A + +#define ASCII_0 0x30 +#define ASCII_1 0x31 +#define ASCII_2 0x32 +#define ASCII_3 0x33 +#define ASCII_4 0x34 +#define ASCII_5 0x35 +#define ASCII_6 0x36 +#define ASCII_7 0x37 +#define ASCII_8 0x38 +#define ASCII_9 0x39 + +#define ASCII_TAB 0x09 +#define ASCII_SPACE 0x20 +#define ASCII_EXCL 0x21 +#define ASCII_QUOT 0x22 +#define ASCII_AMP 0x26 +#define ASCII_APOS 0x27 +#define ASCII_MINUS 0x2D +#define ASCII_PERIOD 0x2E +#define ASCII_COLON 0x3A +#define ASCII_SEMI 0x3B +#define ASCII_LT 0x3C +#define ASCII_EQUALS 0x3D +#define ASCII_GT 0x3E +#define ASCII_LSQB 0x5B +#define ASCII_RSQB 0x5D +#define ASCII_UNDERSCORE 0x5F diff --git a/trunk/lib/expat/xmltok/asciitab.h b/trunk/lib/expat/xmltok/asciitab.h new file mode 100644 index 000000000..e994576a7 --- /dev/null +++ b/trunk/lib/expat/xmltok/asciitab.h @@ -0,0 +1,37 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, +/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, +/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, +/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, +/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, +/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, +/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, +/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, +/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, +/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, +/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/trunk/lib/expat/xmltok/dllmain.c b/trunk/lib/expat/xmltok/dllmain.c new file mode 100644 index 000000000..2ab2b6d0e --- /dev/null +++ b/trunk/lib/expat/xmltok/dllmain.c @@ -0,0 +1,15 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#define STRICT 1 + +#define WIN32_LEAN_AND_MEAN +#include + +BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) +{ + return TRUE; +} + diff --git a/trunk/lib/expat/xmltok/iasciitab.h b/trunk/lib/expat/xmltok/iasciitab.h new file mode 100644 index 000000000..2694d9d64 --- /dev/null +++ b/trunk/lib/expat/xmltok/iasciitab.h @@ -0,0 +1,38 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, +/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, +/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, +/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, +/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, +/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, +/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, +/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, +/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, +/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, +/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/trunk/lib/expat/xmltok/latin1tab.h b/trunk/lib/expat/xmltok/latin1tab.h new file mode 100644 index 000000000..6e01d50e0 --- /dev/null +++ b/trunk/lib/expat/xmltok/latin1tab.h @@ -0,0 +1,37 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, +/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, +/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, +/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, diff --git a/trunk/lib/expat/xmltok/utf8tab.h b/trunk/lib/expat/xmltok/utf8tab.h new file mode 100644 index 000000000..28d9b5960 --- /dev/null +++ b/trunk/lib/expat/xmltok/utf8tab.h @@ -0,0 +1,38 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + + +/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, +/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, diff --git a/trunk/lib/expat/xmltok/xmldef.h b/trunk/lib/expat/xmltok/xmldef.h new file mode 100644 index 000000000..2ef9d494d --- /dev/null +++ b/trunk/lib/expat/xmltok/xmldef.h @@ -0,0 +1,49 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#include + +#ifdef XML_WINLIB + +#define WIN32_LEAN_AND_MEAN +#ifndef STRICT +#define STRICT 1 +#endif +#include + +#define malloc(x) HeapAlloc(GetProcessHeap(), 0, (x)) +#define calloc(x, y) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)*(y)) +#define free(x) HeapFree(GetProcessHeap(), 0, (x)) +#define realloc(x, y) HeapReAlloc(GetProcessHeap(), 0, x, y) +#define abort() /* as nothing */ + +#else /* not XML_WINLIB */ + +#include + +#endif /* not XML_WINLIB */ + +/* This file can be used for any definitions needed in +particular environments. */ + +/* Mozilla specific defines */ + +#ifdef MOZILLA_CLIENT + +#include "nspr.h" +#define malloc(x) PR_Malloc((size_t)(x)) +#define realloc(x, y) PR_Realloc((x), (size_t)(y)) +#define calloc(x, y) PR_Calloc((x),(y)) +#define free(x) PR_Free(x) +#if PR_BYTES_PER_INT != 4 +#define int int32 +#endif + +/* Enable Unicode string processing in expat. */ +#ifndef XML_UNICODE +#define XML_UNICODE +#endif + +#endif /* MOZILLA_CLIENT */ diff --git a/trunk/lib/expat/xmltok/xmlrole.c b/trunk/lib/expat/xmltok/xmlrole.c new file mode 100644 index 000000000..821971343 --- /dev/null +++ b/trunk/lib/expat/xmltok/xmlrole.c @@ -0,0 +1,1262 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ +#include "xmlrpc_config.h" + +#include "xmldef.h" +#include "xmlrole.h" +#include "ascii.h" + +/* Doesn't check: + + that ,| are not mixed in a model group + content of literals + +*/ + +static const char KW_ANY[] = { ASCII_A, ASCII_N, ASCII_Y, '\0' }; +static const char KW_ATTLIST[] = { ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' }; +static const char KW_CDATA[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +static const char KW_DOCTYPE[] = { ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' }; +static const char KW_ELEMENT[] = { ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' }; +static const char KW_EMPTY[] = { ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' }; +static const char KW_ENTITIES[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' }; +static const char KW_ENTITY[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; +static const char KW_FIXED[] = { ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' }; +static const char KW_ID[] = { ASCII_I, ASCII_D, '\0' }; +static const char KW_IDREF[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; +static const char KW_IDREFS[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; +static const char KW_IGNORE[] = { ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' }; +static const char KW_IMPLIED[] = { ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' }; +static const char KW_INCLUDE[] = { ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' }; +static const char KW_NDATA[] = { ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +static const char KW_NMTOKEN[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; +static const char KW_NMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' }; +static const char KW_NOTATION[] = { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, '\0' }; +static const char KW_PCDATA[] = { ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +static const char KW_PUBLIC[] = { ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' }; +static const char KW_REQUIRED[] = { ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, '\0' }; +static const char KW_SYSTEM[] = { ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' }; + +#ifndef MIN_BYTES_PER_CHAR +#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) +#endif + +#define setTopLevel(state) \ + ((state)->handler = ((state)->documentEntity \ + ? internalSubset \ + : externalSubset1)) + +typedef int PROLOG_HANDLER(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc); + +static PROLOG_HANDLER + prolog0, prolog1, prolog2, + doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, + internalSubset, + entity0, entity1, entity2, entity3, entity4, entity5, entity6, + entity7, entity8, entity9, + notation0, notation1, notation2, notation3, notation4, + attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, + attlist7, attlist8, attlist9, + element0, element1, element2, element3, element4, element5, element6, + element7, + externalSubset0, externalSubset1, + condSect0, condSect1, condSect2, + declClose, + error; + +static +int common(PROLOG_STATE *state, int tok); + +static +int prolog0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + state->handler = prolog1; + return XML_ROLE_NONE; + case XML_TOK_XML_DECL: + state->handler = prolog1; + return XML_ROLE_XML_DECL; + case XML_TOK_PI: + state->handler = prolog1; + return XML_ROLE_NONE; + case XML_TOK_COMMENT: + state->handler = prolog1; + case XML_TOK_BOM: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (!XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_DOCTYPE)) + break; + state->handler = doctype0; + return XML_ROLE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static +int prolog1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + case XML_TOK_COMMENT: + case XML_TOK_BOM: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (!XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_DOCTYPE)) + break; + state->handler = doctype0; + return XML_ROLE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static +int prolog2(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + case XML_TOK_COMMENT: + return XML_ROLE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static +int doctype0(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = doctype1; + return XML_ROLE_DOCTYPE_NAME; + } + return common(state, tok); +} + +static +int doctype1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = doctype3; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = doctype2; + return XML_ROLE_NONE; + } + break; + } + return common(state, tok); +} + +static +int doctype2(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype3; + return XML_ROLE_DOCTYPE_PUBLIC_ID; + } + return common(state, tok); +} + +static +int doctype3(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype4; + return XML_ROLE_DOCTYPE_SYSTEM_ID; + } + return common(state, tok); +} + +static +int doctype4(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return common(state, tok); +} + +static +int doctype5(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return common(state, tok); +} + +static +int internalSubset(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_ENTITY)) { + state->handler = entity0; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_ATTLIST)) { + state->handler = attlist0; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_ELEMENT)) { + state->handler = element0; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + end, + KW_NOTATION)) { + state->handler = notation0; + return XML_ROLE_NONE; + } + break; + case XML_TOK_PI: + case XML_TOK_COMMENT: + return XML_ROLE_NONE; + case XML_TOK_PARAM_ENTITY_REF: + return XML_ROLE_PARAM_ENTITY_REF; + case XML_TOK_CLOSE_BRACKET: + state->handler = doctype5; + return XML_ROLE_NONE; + } + return common(state, tok); +} + + + +static +int externalSubset0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + state->handler = externalSubset1; + if (tok == XML_TOK_XML_DECL) + return XML_ROLE_TEXT_DECL; + return externalSubset1(state, tok, ptr, end, enc); +} + +static +int externalSubset1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_COND_SECT_OPEN: + state->handler = condSect0; + return XML_ROLE_NONE; + case XML_TOK_COND_SECT_CLOSE: + if (state->includeLevel == 0) + break; + state->includeLevel -= 1; + return XML_ROLE_NONE; + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_BRACKET: + break; + case XML_TOK_NONE: + if (state->includeLevel) + break; + return XML_ROLE_NONE; + default: + return internalSubset(state, tok, ptr, end, enc); + } + return common(state, tok); +} + + + +static +int entity0(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PERCENT: + state->handler = entity1; + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = entity2; + return XML_ROLE_GENERAL_ENTITY_NAME; + } + return common(state, tok); +} + +static +int entity1(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = entity7; + return XML_ROLE_PARAM_ENTITY_NAME; + } + return common(state, tok); +} + +static +int entity2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = entity4; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = entity3; + return XML_ROLE_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_ENTITY_VALUE; + } + return common(state, tok); +} + +static +int entity3(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = entity4; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return common(state, tok); +} + + +static +int entity4(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = entity5; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return common(state, tok); +} + +static +int entity5(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { + state->handler = entity6; + return XML_ROLE_NONE; + } + break; + } + return common(state, tok); +} + +static +int entity6(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = declClose; + return XML_ROLE_ENTITY_NOTATION_NAME; + } + return common(state, tok); +} + +static +int entity7(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = entity9; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = entity8; + return XML_ROLE_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_ENTITY_VALUE; + } + return common(state, tok); +} + +static +int entity8(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = entity9; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return common(state, tok); +} + +static +int entity9(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return common(state, tok); +} + +static +int notation0(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = notation1; + return XML_ROLE_NOTATION_NAME; + } + return common(state, tok); +} + +static +int notation1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = notation3; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = notation2; + return XML_ROLE_NONE; + } + break; + } + return common(state, tok); +} + +static +int notation2(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = notation4; + return XML_ROLE_NOTATION_PUBLIC_ID; + } + return common(state, tok); +} + +static +int notation3(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_NOTATION_SYSTEM_ID; + } + return common(state, tok); +} + +static +int notation4(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_NOTATION_SYSTEM_ID; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_NOTATION_NO_SYSTEM_ID; + } + return common(state, tok); +} + +static +int attlist0(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist1; + return XML_ROLE_ATTLIST_ELEMENT_NAME; + } + return common(state, tok); +} + +static +int attlist1(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist2; + return XML_ROLE_ATTRIBUTE_NAME; + } + return common(state, tok); +} + +static +int attlist2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + { + static const char *types[] = { + KW_CDATA, + KW_ID, + KW_IDREF, + KW_IDREFS, + KW_ENTITY, + KW_ENTITIES, + KW_NMTOKEN, + KW_NMTOKENS, + }; + int i; + for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) + if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { + state->handler = attlist8; + return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; + } + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { + state->handler = attlist5; + return XML_ROLE_NONE; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = attlist3; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +static +int attlist3(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NMTOKEN: + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist4; + return XML_ROLE_ATTRIBUTE_ENUM_VALUE; + } + return common(state, tok); +} + +static +int attlist4(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_NONE; + case XML_TOK_OR: + state->handler = attlist3; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +static +int attlist5(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_PAREN: + state->handler = attlist6; + return XML_ROLE_NONE; + } + return common(state, tok); +} + + +static +int attlist6(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = attlist7; + return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; + } + return common(state, tok); +} + +static +int attlist7(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_NONE; + case XML_TOK_OR: + state->handler = attlist6; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +/* default value */ +static +int attlist8(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + end, + KW_IMPLIED)) { + state->handler = attlist1; + return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + end, + KW_REQUIRED)) { + state->handler = attlist1; + return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + end, + KW_FIXED)) { + state->handler = attlist9; + return XML_ROLE_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; + } + return common(state, tok); +} + +static +int attlist9(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_FIXED_ATTRIBUTE_VALUE; + } + return common(state, tok); +} + +static +int element0(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element1; + return XML_ROLE_ELEMENT_NAME; + } + return common(state, tok); +} + +static +int element1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { + state->handler = declClose; + return XML_ROLE_CONTENT_EMPTY; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { + state->handler = declClose; + return XML_ROLE_CONTENT_ANY; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = element2; + state->level = 1; + return XML_ROLE_GROUP_OPEN; + } + return common(state, tok); +} + +static +int element2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + end, + KW_PCDATA)) { + state->handler = element3; + return XML_ROLE_CONTENT_PCDATA; + } + break; + case XML_TOK_OPEN_PAREN: + state->level = 2; + state->handler = element6; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return common(state, tok); +} + +static +int element3(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN: + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +static +int element4(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element5; + return XML_ROLE_CONTENT_ELEMENT; + } + return common(state, tok); +} + +static +int element5(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +static +int element6(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_PAREN: + state->level += 1; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return common(state, tok); +} + +static +int element7(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN: + state->level -= 1; + if (state->level == 0) + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->level -= 1; + if (state->level == 0) + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_CLOSE_PAREN_QUESTION: + state->level -= 1; + if (state->level == 0) + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_OPT; + case XML_TOK_CLOSE_PAREN_PLUS: + state->level -= 1; + if (state->level == 0) + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_PLUS; + case XML_TOK_COMMA: + state->handler = element6; + return XML_ROLE_GROUP_SEQUENCE; + case XML_TOK_OR: + state->handler = element6; + return XML_ROLE_GROUP_CHOICE; + } + return common(state, tok); +} + + + +static +int condSect0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { + state->handler = condSect1; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { + state->handler = condSect2; + return XML_ROLE_NONE; + } + break; + } + return common(state, tok); +} + + + +static int +condSect1(PROLOG_STATE * state, + int tok, + const char * ptr ATTR_UNUSED, + const char * end ATTR_UNUSED, + const ENCODING * enc ATTR_UNUSED) { + + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + state->includeLevel += 1; + return XML_ROLE_NONE; + } + return common(state, tok); +} + + + +static int +condSect2(PROLOG_STATE * state, + int tok, + const char * ptr ATTR_UNUSED, + const char * end ATTR_UNUSED, + const ENCODING * enc ATTR_UNUSED) { + + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + return XML_ROLE_IGNORE_SECT; + } + return common(state, tok); +} + + + +static +int declClose(PROLOG_STATE *state, + int tok, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_NONE; + } + return common(state, tok); +} + +#if 0 + +static +int ignore(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_DECL_CLOSE: + state->handler = internalSubset; + return 0; + default: + return XML_ROLE_NONE; + } + return common(state, tok); +} +#endif + +static +int error(PROLOG_STATE *state ATTR_UNUSED, + int tok ATTR_UNUSED, + const char *ptr ATTR_UNUSED, + const char *end ATTR_UNUSED, + const ENCODING *enc ATTR_UNUSED) +{ + return XML_ROLE_NONE; +} + +static +int common(PROLOG_STATE *state, int tok ATTR_UNUSED) +{ + if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) + return XML_ROLE_INNER_PARAM_ENTITY_REF; + state->handler = error; + return XML_ROLE_ERROR; +} + + + +void +xmlrpc_XmlPrologStateInit(PROLOG_STATE * const state) { + + state->handler = prolog0; + state->documentEntity = 1; + state->includeLevel = 0; +} + + + +void +xmlrpc_XmlPrologStateInitExternalEntity(PROLOG_STATE * const state) { + + state->handler = externalSubset0; + state->documentEntity = 0; + state->includeLevel = 0; +} diff --git a/trunk/lib/expat/xmltok/xmlrole.h b/trunk/lib/expat/xmltok/xmlrole.h new file mode 100644 index 000000000..12695e37b --- /dev/null +++ b/trunk/lib/expat/xmltok/xmlrole.h @@ -0,0 +1,99 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#ifndef XMLROLE_H_INCLUDED +#define XMLROLE_H_INCLUDED + +#include "xmlrpc-c/c_util.h" +#include "xmltok.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + XML_ROLE_ERROR = -1, + XML_ROLE_NONE = 0, + XML_ROLE_XML_DECL, + XML_ROLE_INSTANCE_START, + XML_ROLE_DOCTYPE_NAME, + XML_ROLE_DOCTYPE_SYSTEM_ID, + XML_ROLE_DOCTYPE_PUBLIC_ID, + XML_ROLE_DOCTYPE_CLOSE, + XML_ROLE_GENERAL_ENTITY_NAME, + XML_ROLE_PARAM_ENTITY_NAME, + XML_ROLE_ENTITY_VALUE, + XML_ROLE_ENTITY_SYSTEM_ID, + XML_ROLE_ENTITY_PUBLIC_ID, + XML_ROLE_ENTITY_NOTATION_NAME, + XML_ROLE_NOTATION_NAME, + XML_ROLE_NOTATION_SYSTEM_ID, + XML_ROLE_NOTATION_NO_SYSTEM_ID, + XML_ROLE_NOTATION_PUBLIC_ID, + XML_ROLE_ATTRIBUTE_NAME, + XML_ROLE_ATTRIBUTE_TYPE_CDATA, + XML_ROLE_ATTRIBUTE_TYPE_ID, + XML_ROLE_ATTRIBUTE_TYPE_IDREF, + XML_ROLE_ATTRIBUTE_TYPE_IDREFS, + XML_ROLE_ATTRIBUTE_TYPE_ENTITY, + XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, + XML_ROLE_ATTRIBUTE_ENUM_VALUE, + XML_ROLE_ATTRIBUTE_NOTATION_VALUE, + XML_ROLE_ATTLIST_ELEMENT_NAME, + XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, + XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, + XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, + XML_ROLE_FIXED_ATTRIBUTE_VALUE, + XML_ROLE_ELEMENT_NAME, + XML_ROLE_CONTENT_ANY, + XML_ROLE_CONTENT_EMPTY, + XML_ROLE_CONTENT_PCDATA, + XML_ROLE_GROUP_OPEN, + XML_ROLE_GROUP_CLOSE, + XML_ROLE_GROUP_CLOSE_REP, + XML_ROLE_GROUP_CLOSE_OPT, + XML_ROLE_GROUP_CLOSE_PLUS, + XML_ROLE_GROUP_CHOICE, + XML_ROLE_GROUP_SEQUENCE, + XML_ROLE_CONTENT_ELEMENT, + XML_ROLE_CONTENT_ELEMENT_REP, + XML_ROLE_CONTENT_ELEMENT_OPT, + XML_ROLE_CONTENT_ELEMENT_PLUS, + XML_ROLE_TEXT_DECL, + XML_ROLE_IGNORE_SECT, + XML_ROLE_INNER_PARAM_ENTITY_REF, + XML_ROLE_PARAM_ENTITY_REF, + XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION +}; + +typedef struct prolog_state { + int (*handler)(struct prolog_state *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc); + unsigned level; + unsigned includeLevel; + int documentEntity; +} PROLOG_STATE; + +XMLRPC_DLLEXPORT +void +xmlrpc_XmlPrologStateInit(PROLOG_STATE * const state); + +XMLRPC_DLLEXPORT +void +xmlrpc_XmlPrologStateInitExternalEntity(PROLOG_STATE * const state); + +#define XmlTokenRole(state, tok, ptr, end, enc) \ + (((state)->handler)(state, tok, ptr, end, enc)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/trunk/lib/expat/xmltok/xmltok.c b/trunk/lib/expat/xmltok/xmltok.c new file mode 100644 index 000000000..7b31fbb4b --- /dev/null +++ b/trunk/lib/expat/xmltok/xmltok.c @@ -0,0 +1,1570 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#include +#include "xmlrpc_config.h" +#include "bool.h" +#include "c_util.h" +#include "xmldef.h" +#include "xmltok.h" +#include "nametab.h" + +#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) + +#define VTABLE1 \ + { PREFIX(prologTok), PREFIX(contentTok), \ + PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ + { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ + PREFIX(sameName), \ + PREFIX(nameMatchesAscii), \ + PREFIX(nameLength), \ + PREFIX(skipS), \ + PREFIX(getAtts), \ + PREFIX(charRefNumber), \ + PREFIX(predefinedEntityName), \ + PREFIX(updatePosition), \ + PREFIX(isPublicId) + +#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) + +#define UCS2_GET_NAMING(pages, hi, lo) \ + (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F))) + +/* A 2 byte UTF-8 representation splits the characters 11 bits +between the bottom 5 and 6 bits of the bytes. +We need 8 bits to index into pages, 3 bits to add to that index and +5 bits to generate the mask. */ +#define UTF8_GET_NAMING2(pages, byte) \ + (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + + ((((byte)[0]) & 3) << 1) \ + + ((((byte)[1]) >> 5) & 1)] \ + & (1 << (((byte)[1]) & 0x1F))) + +/* A 3 byte UTF-8 representation splits the characters 16 bits +between the bottom 4, 6 and 6 bits of the bytes. +We need 8 bits to index into pages, 3 bits to add to that index and +5 bits to generate the mask. */ +#define UTF8_GET_NAMING3(pages, byte) \ + (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ + + ((((byte)[1]) >> 2) & 0xF)] \ + << 3) \ + + ((((byte)[1]) & 3) << 1) \ + + ((((byte)[2]) >> 5) & 1)] \ + & (1 << (((byte)[2]) & 0x1F))) + +#define UTF8_GET_NAMING(pages, p, n) \ + ((n) == 2 \ + ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ + : ((n) == 3 \ + ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \ + : 0)) + +#define UTF8_INVALID3(p) \ + ((*p) == 0xED \ + ? (((p)[1] & 0x20) != 0) \ + : ((*p) == 0xEF \ + ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \ + : 0)) + +#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0) + +static +int isNever(const ENCODING *enc ATTR_UNUSED, const char *p ATTR_UNUSED) +{ + return 0; +} + +static +int utf8_isName2(const ENCODING *enc ATTR_UNUSED, const char *p) +{ + return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); +} + +static +int utf8_isName3(const ENCODING *enc ATTR_UNUSED, const char *p) +{ + return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); +} + +#define utf8_isName4 isNever + +static +int utf8_isNmstrt2(const ENCODING *enc ATTR_UNUSED, const char *p) +{ + return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); +} + +static +int utf8_isNmstrt3(const ENCODING *enc ATTR_UNUSED, const char *p) +{ + return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); +} + +#define utf8_isNmstrt4 isNever + +#define utf8_isInvalid2 isNever + +static +int utf8_isInvalid3(const ENCODING *enc ATTR_UNUSED, const char *p) +{ + return UTF8_INVALID3((const unsigned char *)p); +} + +static +int utf8_isInvalid4(const ENCODING *enc ATTR_UNUSED, const char *p) +{ + return UTF8_INVALID4((const unsigned char *)p); +} + +struct normal_encoding { + ENCODING enc; + unsigned char type[256]; +#ifdef XML_MIN_SIZE + int (*byteType)(const ENCODING *, const char *); + int (*isNameMin)(const ENCODING *, const char *); + int (*isNmstrtMin)(const ENCODING *, const char *); + int (*byteToAscii)(const ENCODING *, const char *); + int (*charMatches)(const ENCODING *, const char *, int); +#endif /* XML_MIN_SIZE */ + int (*isName2)(const ENCODING *, const char *); + int (*isName3)(const ENCODING *, const char *); + int (*isName4)(const ENCODING *, const char *); + int (*isNmstrt2)(const ENCODING *, const char *); + int (*isNmstrt3)(const ENCODING *, const char *); + int (*isNmstrt4)(const ENCODING *, const char *); + int (*isInvalid2)(const ENCODING *, const char *); + int (*isInvalid3)(const ENCODING *, const char *); + int (*isInvalid4)(const ENCODING *, const char *); +}; + +#ifdef XML_MIN_SIZE + +#define STANDARD_VTABLE(E) \ + E ## byteType, \ + E ## isNameMin, \ + E ## isNmstrtMin, \ + E ## byteToAscii, \ + E ## charMatches, + +#else + +#define STANDARD_VTABLE(E) /* as nothing */ + +#endif + +#define NORMAL_VTABLE(E) \ + E ## isName2, \ + E ## isName3, \ + E ## isName4, \ + E ## isNmstrt2, \ + E ## isNmstrt3, \ + E ## isNmstrt4, \ + E ## isInvalid2, \ + E ## isInvalid3, \ + E ## isInvalid4 + +#define NULL_NORMAL_VTABLE \ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + +static int checkCharRefNumber(int); + +#include "xmltok_impl.h" +#include "ascii.h" + +#ifdef XML_MIN_SIZE +#define sb_isNameMin isNever +#define sb_isNmstrtMin isNever +#endif + +#ifdef XML_MIN_SIZE +#define MINBPC(enc) ((enc)->minBytesPerChar) +#else +/* minimum bytes per character */ +#define MINBPC(enc) 1 +#endif + +#define SB_BYTE_TYPE(enc, p) \ + (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) + +#ifdef XML_MIN_SIZE +static +int sb_byteType(const ENCODING *enc, const char *p) +{ + return SB_BYTE_TYPE(enc, p); +} +#define BYTE_TYPE(enc, p) \ + (((const struct normal_encoding *)(enc))->byteType(enc, p)) +#else +#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) +#endif + +#ifdef XML_MIN_SIZE +#define BYTE_TO_ASCII(enc, p) \ + (((const struct normal_encoding *)(enc))->byteToAscii(enc, p)) +static +int sb_byteToAscii(const ENCODING *enc, const char *p) +{ + return *p; +} +#else +#define BYTE_TO_ASCII(enc, p) (*(p)) +#endif + +#define IS_NAME_CHAR(enc, p, n) \ + (((const struct normal_encoding *)(enc))->isName ## n(enc, p)) +#define IS_NMSTRT_CHAR(enc, p, n) \ + (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p)) +#define IS_INVALID_CHAR(enc, p, n) \ + (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p)) + +#ifdef XML_MIN_SIZE +#define IS_NAME_CHAR_MINBPC(enc, p) \ + (((const struct normal_encoding *)(enc))->isNameMin(enc, p)) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) \ + (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p)) +#else +#define IS_NAME_CHAR_MINBPC(enc, p) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) +#endif + +#ifdef XML_MIN_SIZE +#define CHAR_MATCHES(enc, p, c) \ + (((const struct normal_encoding *)(enc))->charMatches(enc, p, c)) +static +int sb_charMatches(const ENCODING *enc, const char *p, int c) +{ + return *p == c; +} +#else +/* c is an ASCII character */ +#define CHAR_MATCHES(enc, p, c) (*(p) == c) +#endif + +#define PREFIX(ident) normal_ ## ident +#include "xmltok_impl.c" + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ + UTF8_cval1 = 0x00, + UTF8_cval2 = 0xc0, + UTF8_cval3 = 0xe0, + UTF8_cval4 = 0xf0 +}; + +static +void utf8_toUtf8(const ENCODING * enc ATTR_UNUSED, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + char *to; + const char *from; + if (fromLim - *fromP > toLim - *toP) { + /* Avoid copying partial characters. */ + for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--) + if (((unsigned char)fromLim[-1] & 0xc0) != 0x80) + break; + } + for (to = *toP, from = *fromP; from != fromLim; from++, to++) + *to = *from; + *fromP = from; + *toP = to; +} + +static +void utf8_toUtf16(const ENCODING *enc, + const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) +{ + unsigned short *to = *toP; + const char *from = *fromP; + while (from != fromLim && to != toLim) { + switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { + case BT_LEAD2: + *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f); + from += 2; + break; + case BT_LEAD3: + *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f); + from += 3; + break; + case BT_LEAD4: + { + unsigned long n; + if (to + 1 == toLim) + break; + n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); + n -= 0x10000; + to[0] = (unsigned short)((n >> 10) | 0xD800); + to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); + to += 2; + from += 4; + } + break; + default: + *to++ = *from++; + break; + } + } + *fromP = from; + *toP = to; +} + +static const struct normal_encoding utf8_encoding_ns = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#include "asciitab.h" +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + +static const struct normal_encoding utf8_encoding = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + +static const struct normal_encoding internal_utf8_encoding_ns = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#include "iasciitab.h" +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + +static const struct normal_encoding internal_utf8_encoding = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + + + +static Utf8Converter latin1_toUtf8; + +static void +latin1_toUtf8(const ENCODING * const enc ATTR_UNUSED, + const char ** const fromP, + const char * const fromLim, + char ** const toP, + const char * const toLim) { +/*---------------------------------------------------------------------------- + Convert the Latin1 string to UTF-8. + + This is a Utf8Converter subroutine. See documentation of the + Utf8Converter type for details. + + Note: a latin1 input character converts to 1 or 2 UTF-8 output + bytes. +-----------------------------------------------------------------------------*/ + bool bufferIsFull; + + assert(toLim - *toP >= 2); /* Calling condition */ + + for (bufferIsFull = false; *fromP != fromLim && !bufferIsFull;) { + unsigned char const c = (unsigned char)**fromP; + if (c & 0x80) { + if (toLim - *toP < 2) + bufferIsFull = true; + else { + *(*toP)++ = ((c >> 6) | UTF8_cval2); + *(*toP)++ = ((c & 0x3f) | 0x80); + ++(*fromP); + } + } else { + if (*toP == toLim) + bufferIsFull = true; + else + *(*toP)++ = *(*fromP)++; + } + } +} + + + +static +void latin1_toUtf16(const ENCODING *enc ATTR_UNUSED, + const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) +{ + while (*fromP != fromLim && *toP != toLim) + *(*toP)++ = (unsigned char)*(*fromP)++; +} + +static const struct normal_encoding latin1_encoding_ns = { + { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, + { +#include "asciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(sb_) NULL_NORMAL_VTABLE +}; + +static const struct normal_encoding latin1_encoding = { + { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(sb_) NULL_NORMAL_VTABLE +}; + +static +void ascii_toUtf8(const ENCODING *enc ATTR_UNUSED, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + while (*fromP != fromLim && *toP != toLim) + *(*toP)++ = *(*fromP)++; +} + +static const struct normal_encoding ascii_encoding_ns = { + { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, + { +#include "asciitab.h" +/* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) NULL_NORMAL_VTABLE +}; + +static const struct normal_encoding ascii_encoding = { + { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +/* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) NULL_NORMAL_VTABLE +}; + +static int unicode_byte_type(char hi, char lo) +{ + switch ((unsigned char)hi) { + case 0xD8: case 0xD9: case 0xDA: case 0xDB: + return BT_LEAD4; + case 0xDC: case 0xDD: case 0xDE: case 0xDF: + return BT_TRAIL; + case 0xFF: + switch ((unsigned char)lo) { + case 0xFF: + case 0xFE: + return BT_NONXML; + } + break; + } + return BT_NONASCII; +} + +#define DEFINE_UTF16_TO_UTF8(E) \ +static \ +void E ## toUtf8(const ENCODING *enc ATTR_UNUSED, \ + const char **fromP, const char *fromLim, \ + char **toP, const char *toLim) \ +{ \ + const char *from; \ + for (from = *fromP; from != fromLim; from += 2) { \ + int plane; \ + unsigned char lo2; \ + unsigned char lo = GET_LO(from); \ + unsigned char hi = GET_HI(from); \ + switch (hi) { \ + case 0: \ + if (lo < 0x80) { \ + if (*toP == toLim) { \ + *fromP = from; \ + return; \ + } \ + *(*toP)++ = lo; \ + break; \ + } \ + /* fall through */ \ + case 0x1: case 0x2: case 0x3: \ + case 0x4: case 0x5: case 0x6: case 0x7: \ + if (toLim - *toP < 2) { \ + *fromP = from; \ + return; \ + } \ + *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + default: \ + if (toLim - *toP < 3) { \ + *fromP = from; \ + return; \ + } \ + /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ + *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ + *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ + if (toLim - *toP < 4) { \ + *fromP = from; \ + return; \ + } \ + plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ + *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ + *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ + from += 2; \ + lo2 = GET_LO(from); \ + *(*toP)++ = (((lo & 0x3) << 4) \ + | ((GET_HI(from) & 0x3) << 2) \ + | (lo2 >> 6) \ + | 0x80); \ + *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ + break; \ + } \ + } \ + *fromP = from; \ +} + +#define DEFINE_UTF16_TO_UTF16(E) \ +static \ +void E ## toUtf16(const ENCODING *enc ATTR_UNUSED, \ + const char **fromP, const char *fromLim, \ + unsigned short **toP, const unsigned short *toLim) \ +{ \ + /* Avoid copying first half only of surrogate */ \ + if (fromLim - *fromP > ((toLim - *toP) << 1) \ + && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \ + fromLim -= 2; \ + for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \ + *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ +} + +#define SET2(ptr, ch) \ + (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8))) +#define GET_LO(ptr) ((unsigned char)(ptr)[0]) +#define GET_HI(ptr) ((unsigned char)(ptr)[1]) + +DEFINE_UTF16_TO_UTF8(little2_) +DEFINE_UTF16_TO_UTF16(little2_) + +#undef SET2 +#undef GET_LO +#undef GET_HI + +#define SET2(ptr, ch) \ + (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF))) +#define GET_LO(ptr) ((unsigned char)(ptr)[1]) +#define GET_HI(ptr) ((unsigned char)(ptr)[0]) + +DEFINE_UTF16_TO_UTF8(big2_) +DEFINE_UTF16_TO_UTF16(big2_) + +#undef SET2 +#undef GET_LO +#undef GET_HI + +#define LITTLE2_BYTE_TYPE(enc, p) \ + ((p)[1] == 0 \ + ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ + : unicode_byte_type((p)[1], (p)[0])) +#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1) +#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c) +#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) +#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) + +#ifdef XML_MIN_SIZE + +static +int little2_byteType(const ENCODING *enc, const char *p) +{ + return LITTLE2_BYTE_TYPE(enc, p); +} + +static +int little2_byteToAscii(const ENCODING *enc, const char *p) +{ + return LITTLE2_BYTE_TO_ASCII(enc, p); +} + +static +int little2_charMatches(const ENCODING *enc, const char *p, int c) +{ + return LITTLE2_CHAR_MATCHES(enc, p, c); +} + +static +int little2_isNameMin(const ENCODING *enc, const char *p) +{ + return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p); +} + +static +int little2_isNmstrtMin(const ENCODING *enc, const char *p) +{ + return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p); +} + +#undef VTABLE +#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +#undef PREFIX +#define PREFIX(ident) little2_ ## ident +#define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) +#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) +#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c) +#define IS_NAME_CHAR(enc, p, n) 0 +#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) +#define IS_NMSTRT_CHAR(enc, p, n) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) + +#include "xmltok_impl.c" + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +static const struct normal_encoding little2_encoding_ns = { + { VTABLE, 2, 0, +#if XML_BYTE_ORDER == 12 + 1 +#else + 0 +#endif + }, + { +#include "asciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_NORMAL_VTABLE +}; + +static const struct normal_encoding little2_encoding = { + { VTABLE, 2, 0, +#if XML_BYTE_ORDER == 12 + 1 +#else + 0 +#endif + }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_NORMAL_VTABLE +}; + +#if XML_BYTE_ORDER != 21 + +static const struct normal_encoding internal_little2_encoding_ns = { + { VTABLE, 2, 0, 1 }, + { +#include "iasciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_NORMAL_VTABLE +}; + +static const struct normal_encoding internal_little2_encoding = { + { VTABLE, 2, 0, 1 }, + { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_NORMAL_VTABLE +}; + +#endif + + +#define BIG2_BYTE_TYPE(enc, p) \ + ((p)[0] == 0 \ + ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ + : unicode_byte_type((p)[0], (p)[1])) +#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1) +#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c) +#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) +#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) + +#ifdef XML_MIN_SIZE + +static +int big2_byteType(const ENCODING *enc, const char *p) +{ + return BIG2_BYTE_TYPE(enc, p); +} + +static +int big2_byteToAscii(const ENCODING *enc, const char *p) +{ + return BIG2_BYTE_TO_ASCII(enc, p); +} + +static +int big2_charMatches(const ENCODING *enc, const char *p, int c) +{ + return BIG2_CHAR_MATCHES(enc, p, c); +} + +static +int big2_isNameMin(const ENCODING *enc, const char *p) +{ + return BIG2_IS_NAME_CHAR_MINBPC(enc, p); +} + +static +int big2_isNmstrtMin(const ENCODING *enc, const char *p) +{ + return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p); +} + +#undef VTABLE +#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +#undef PREFIX +#define PREFIX(ident) big2_ ## ident +#define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) +#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) +#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c) +#define IS_NAME_CHAR(enc, p, n) 0 +#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p) +#define IS_NMSTRT_CHAR(enc, p, n) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) + +#include "xmltok_impl.c" + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +static const struct normal_encoding big2_encoding_ns = { + { VTABLE, 2, 0, +#if XML_BYTE_ORDER == 21 + 1 +#else + 0 +#endif + }, + { +#include "asciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_NORMAL_VTABLE +}; + +static const struct normal_encoding big2_encoding = { + { VTABLE, 2, 0, +#if XML_BYTE_ORDER == 21 + 1 +#else + 0 +#endif + }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_NORMAL_VTABLE +}; + +#if XML_BYTE_ORDER != 12 + +static const struct normal_encoding internal_big2_encoding_ns = { + { VTABLE, 2, 0, 1 }, + { +#include "iasciitab.h" +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_NORMAL_VTABLE +}; + +static const struct normal_encoding internal_big2_encoding = { + { VTABLE, 2, 0, 1 }, + { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_NORMAL_VTABLE +}; + +#endif + +#undef PREFIX + +static +int streqci(const char *s1, const char *s2) +{ + for (;;) { + char c1 = *s1++; + char c2 = *s2++; + if (ASCII_a <= c1 && c1 <= ASCII_z) + c1 += ASCII_A - ASCII_a; + if (ASCII_a <= c2 && c2 <= ASCII_z) + c2 += ASCII_A - ASCII_a; + if (c1 != c2) + return 0; + if (!c1) + break; + } + return 1; +} + +static +void initUpdatePosition(const ENCODING *enc ATTR_UNUSED, const char *ptr, + const char *end, POSITION *pos) +{ + normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); +} + +static +int toAscii(const ENCODING *enc, const char *ptr, const char *end) +{ + char buf[1]; + char *p = buf; + XmlUtf8Convert(enc, &ptr, end, &p, p + 1); + if (p == buf) + return -1; + else + return buf[0]; +} + +static +int isSpace(int c) +{ + switch (c) { + case 0x20: + case 0xD: + case 0xA: + case 0x9: + return 1; + } + return 0; +} + +/* Return 1 if there's just optional white space +or there's an S followed by name=val. */ +static +int parsePseudoAttribute(const ENCODING *enc, + const char *ptr, + const char *end, + const char **namePtr, + const char **nameEndPtr, + const char **valPtr, + const char **nextTokPtr) +{ + int c; + char open; + if (ptr == end) { + *namePtr = 0; + return 1; + } + if (!isSpace(toAscii(enc, ptr, end))) { + *nextTokPtr = ptr; + return 0; + } + do { + ptr += enc->minBytesPerChar; + } while (isSpace(toAscii(enc, ptr, end))); + if (ptr == end) { + *namePtr = 0; + return 1; + } + *namePtr = ptr; + for (;;) { + c = toAscii(enc, ptr, end); + if (c == -1) { + *nextTokPtr = ptr; + return 0; + } + if (c == ASCII_EQUALS) { + *nameEndPtr = ptr; + break; + } + if (isSpace(c)) { + *nameEndPtr = ptr; + do { + ptr += enc->minBytesPerChar; + } while (isSpace(c = toAscii(enc, ptr, end))); + if (c != ASCII_EQUALS) { + *nextTokPtr = ptr; + return 0; + } + break; + } + ptr += enc->minBytesPerChar; + } + if (ptr == *namePtr) { + *nextTokPtr = ptr; + return 0; + } + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + while (isSpace(c)) { + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + } + if (c != ASCII_QUOT && c != ASCII_APOS) { + *nextTokPtr = ptr; + return 0; + } + open = c; + ptr += enc->minBytesPerChar; + *valPtr = ptr; + for (;; ptr += enc->minBytesPerChar) { + c = toAscii(enc, ptr, end); + if (c == open) + break; + if (!(ASCII_a <= c && c <= ASCII_z) + && !(ASCII_A <= c && c <= ASCII_Z) + && !(ASCII_0 <= c && c <= ASCII_9) + && c != ASCII_PERIOD + && c != ASCII_MINUS + && c != ASCII_UNDERSCORE) { + *nextTokPtr = ptr; + return 0; + } + } + *nextTokPtr = ptr + enc->minBytesPerChar; + return 1; +} + +static const char KW_version[] = { + ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0' +}; + +static const char KW_encoding[] = { + ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0' +}; + +static const char KW_standalone[] = { + ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0' +}; + +static const char KW_yes[] = { + ASCII_y, ASCII_e, ASCII_s, '\0' +}; + +static const char KW_no[] = { + ASCII_n, ASCII_o, '\0' +}; + +static +int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, + const char *, + const char *), + int isGeneralTextEntity, + const ENCODING *enc, + const char *ptr, + const char *end, + const char **badPtr, + const char **versionPtr, + const char **encodingName, + const ENCODING **encoding, + int *standalone) +{ + const char *val = 0; + const char *name = 0; + const char *nameEnd = 0; + ptr += 5 * enc->minBytesPerChar; + end -= 2 * enc->minBytesPerChar; + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) { + *badPtr = ptr; + return 0; + } + if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { + if (!isGeneralTextEntity) { + *badPtr = name; + return 0; + } + } + else { + if (versionPtr) + *versionPtr = val; + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (!name) { + if (isGeneralTextEntity) { + /* a TextDecl must have an EncodingDecl */ + *badPtr = ptr; + return 0; + } + return 1; + } + } + if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { + int c = toAscii(enc, val, end); + if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) { + *badPtr = val; + return 0; + } + if (encodingName) + *encodingName = val; + if (encoding) + *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); + if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (!name) + return 1; + } + if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) { + *badPtr = name; + return 0; + } + if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { + if (standalone) + *standalone = 1; + } + else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { + if (standalone) + *standalone = 0; + } + else { + *badPtr = val; + return 0; + } + while (isSpace(toAscii(enc, ptr, end))) + ptr += enc->minBytesPerChar; + if (ptr != end) { + *badPtr = ptr; + return 0; + } + return 1; +} + +static +int checkCharRefNumber(int result) +{ + switch (result >> 8) { + case 0xD8: case 0xD9: case 0xDA: case 0xDB: + case 0xDC: case 0xDD: case 0xDE: case 0xDF: + return -1; + case 0: + if (latin1_encoding.type[result] == BT_NONXML) + return -1; + break; + case 0xFF: + if (result == 0xFFFE || result == 0xFFFF) + return -1; + break; + } + return result; +} + + + +int +xmlrpc_XmlUtf8Encode(int const c, + char * const buf) { + + enum { + /* minN is minimum legal resulting value for N byte sequence */ + min2 = 0x80, + min3 = 0x800, + min4 = 0x10000 + }; + + if (c < 0) + return 0; + if (c < min2) { + buf[0] = (c | UTF8_cval1); + return 1; + } + if (c < min3) { + buf[0] = ((c >> 6) | UTF8_cval2); + buf[1] = ((c & 0x3f) | 0x80); + return 2; + } + if (c < min4) { + buf[0] = ((c >> 12) | UTF8_cval3); + buf[1] = (((c >> 6) & 0x3f) | 0x80); + buf[2] = ((c & 0x3f) | 0x80); + return 3; + } + if (c < 0x110000) { + buf[0] = ((c >> 18) | UTF8_cval4); + buf[1] = (((c >> 12) & 0x3f) | 0x80); + buf[2] = (((c >> 6) & 0x3f) | 0x80); + buf[3] = ((c & 0x3f) | 0x80); + return 4; + } + return 0; +} + + + +int +xmlrpc_XmlUtf16Encode(int const charNumArg, + unsigned short * const buf) { + + int charNum; + + charNum = charNumArg; /* initial value */ + + if (charNum < 0) + return 0; + if (charNum < 0x10000) { + buf[0] = charNum; + return 1; + } + if (charNum < 0x110000) { + charNum -= 0x10000; + buf[0] = (charNum >> 10) + 0xD800; + buf[1] = (charNum & 0x3FF) + 0xDC00; + return 2; + } + return 0; +} + + + +struct unknown_encoding { + struct normal_encoding normal; + int (*convert)(void *userData, const char *p); + void *userData; + unsigned short utf16[256]; + char utf8[256][4]; +}; + + + +int +xmlrpc_XmlSizeOfUnknownEncoding(void) { + + return sizeof(struct unknown_encoding); +} + + + +static +int unknown_isName(const ENCODING *enc, const char *p) +{ + int c = ((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); +} + +static +int unknown_isNmstrt(const ENCODING *enc, const char *p) +{ + int c = ((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); +} + +static +int unknown_isInvalid(const ENCODING *enc, const char *p) +{ + int c = ((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, p); + return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; +} + +static +void unknown_toUtf8(const ENCODING *enc, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + char buf[XML_UTF8_ENCODE_MAX]; + for (;;) { + const char *utf8; + int n; + if (*fromP == fromLim) + break; + utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP]; + n = *utf8++; + if (n == 0) { + int c = ((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, *fromP); + n = xmlrpc_XmlUtf8Encode(c, buf); + if (n > toLim - *toP) + break; + utf8 = buf; + *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2); + } + else { + if (n > toLim - *toP) + break; + (*fromP)++; + } + do { + *(*toP)++ = *utf8++; + } while (--n != 0); + } +} + +static +void unknown_toUtf16(const ENCODING *enc, + const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) +{ + while (*fromP != fromLim && *toP != toLim) { + unsigned short c + = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP]; + if (c == 0) { + c = (unsigned short)((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, *fromP); + *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2); + } + else + (*fromP)++; + *(*toP)++ = c; + } +} + +ENCODING * +xmlrpc_XmlInitUnknownEncoding(void * const mem, + int * const table, + int (*convert)(void *userData, const char *p), + void * const userData) { + + int i; + struct unknown_encoding *e = mem; + for (i = 0; i < (int)sizeof(struct normal_encoding); i++) + ((char *)mem)[i] = ((char *)&latin1_encoding)[i]; + for (i = 0; i < 128; i++) + if (latin1_encoding.type[i] != BT_OTHER + && latin1_encoding.type[i] != BT_NONXML + && table[i] != i) + return 0; + for (i = 0; i < 256; i++) { + int c = table[i]; + if (c == -1) { + e->normal.type[i] = BT_MALFORM; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } + else if (c < 0) { + if (c < -4) + return 0; + e->normal.type[i] = BT_LEAD2 - (c + 2); + e->utf8[i][0] = 0; + e->utf16[i] = 0; + } + else if (c < 0x80) { + if (latin1_encoding.type[c] != BT_OTHER + && latin1_encoding.type[c] != BT_NONXML + && c != i) + return 0; + e->normal.type[i] = latin1_encoding.type[c]; + e->utf8[i][0] = 1; + e->utf8[i][1] = (char)c; + e->utf16[i] = c == 0 ? 0xFFFF : c; + } + else if (checkCharRefNumber(c) < 0) { + e->normal.type[i] = BT_NONXML; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } + else { + if (c > 0xFFFF) + return 0; + if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NMSTRT; + else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NAME; + else + e->normal.type[i] = BT_OTHER; + e->utf8[i][0] = (char)xmlrpc_XmlUtf8Encode(c, e->utf8[i] + 1); + e->utf16[i] = c; + } + } + e->userData = userData; + e->convert = convert; + if (convert) { + e->normal.isName2 = unknown_isName; + e->normal.isName3 = unknown_isName; + e->normal.isName4 = unknown_isName; + e->normal.isNmstrt2 = unknown_isNmstrt; + e->normal.isNmstrt3 = unknown_isNmstrt; + e->normal.isNmstrt4 = unknown_isNmstrt; + e->normal.isInvalid2 = unknown_isInvalid; + e->normal.isInvalid3 = unknown_isInvalid; + e->normal.isInvalid4 = unknown_isInvalid; + } + e->normal.enc.utf8Convert = unknown_toUtf8; + e->normal.enc.utf16Convert = unknown_toUtf16; + return &(e->normal.enc); +} + +/* If this enumeration is changed, getEncodingIndex and encodings +must also be changed. */ +enum { + UNKNOWN_ENC = -1, + ISO_8859_1_ENC = 0, + US_ASCII_ENC, + UTF_8_ENC, + UTF_16_ENC, + UTF_16BE_ENC, + UTF_16LE_ENC, + /* must match encodingNames up to here */ + NO_ENC +}; + +static const char KW_ISO_8859_1[] = { + ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0' +}; +static const char KW_US_ASCII[] = { + ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, '\0' +}; +static const char KW_UTF_8[] = { + ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0' +}; +static const char KW_UTF_16[] = { + ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0' +}; +static const char KW_UTF_16BE[] = { + ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, '\0' +}; +static const char KW_UTF_16LE[] = { + ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, '\0' +}; + +static int +getEncodingIndex(const char * const name) { +/*---------------------------------------------------------------------------- + Return the index into the encodings[] table of the encoding named 'name'. + + If 'name' is NULL, return NO_ENC. + + If the name is non-NULL, but not one we recognize, return UNKNOWN_ENC. + Note that UNKNOWN_ENC is not actually an index (but NO_ENC is). +-----------------------------------------------------------------------------*/ + if (name == NULL) + return NO_ENC; + else { + static const char * const encodingNames[] = { + KW_ISO_8859_1, + KW_US_ASCII, + KW_UTF_8, + KW_UTF_16, + KW_UTF_16BE, + KW_UTF_16LE, + }; + unsigned int i; + for (i = 0; i < (unsigned int)(ARRAY_SIZE(encodingNames)); i++) { + if (streqci(name, encodingNames[i])) + return i; + } + return UNKNOWN_ENC; + } +} + +/* For binary compatibility, we store the index of the encoding specified +at initialization in the isUtf16 member. */ + +#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) +#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) + +/* This is what detects the encoding. +encodingTable maps from encoding indices to encodings; +INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding; +state is XML_CONTENT_STATE if we're parsing an external text entity, +and XML_PROLOG_STATE otherwise. +*/ + + +static +int initScan(const ENCODING **encodingTable, + const INIT_ENCODING *enc, + int state, + const char *ptr, + const char *end, + const char **nextTokPtr) +{ + const ENCODING **encPtr; + + if (ptr == end) + return XML_TOK_NONE; + encPtr = enc->encPtr; + if (ptr + 1 == end) { + /* only a single byte available for auto-detection */ + /* so we're parsing an external text entity... */ + /* if UTF-16 was externally specified, then we need at least 2 bytes */ + switch (INIT_ENC_INDEX(enc)) { + case UTF_16_ENC: + case UTF_16LE_ENC: + case UTF_16BE_ENC: + return XML_TOK_PARTIAL; + } + switch ((unsigned char)*ptr) { + case 0xFE: + case 0xFF: + case 0xEF: /* possibly first byte of UTF-8 BOM */ + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC + && state == XML_CONTENT_STATE) + break; + /* fall through */ + case 0x00: + case 0x3C: + return XML_TOK_PARTIAL; + } + } + else { + switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { + case 0xFEFF: + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC + && state == XML_CONTENT_STATE) + break; + *nextTokPtr = ptr + 2; + *encPtr = encodingTable[UTF_16BE_ENC]; + return XML_TOK_BOM; + /* 00 3C is handled in the default case */ + case 0x3C00: + if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC + || INIT_ENC_INDEX(enc) == UTF_16_ENC) + && state == XML_CONTENT_STATE) + break; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + case 0xFFFE: + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC + && state == XML_CONTENT_STATE) + break; + *nextTokPtr = ptr + 2; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XML_TOK_BOM; + case 0xEFBB: + /* Maybe a UTF-8 BOM (EF BB BF) */ + /* If there's an explicitly specified (external) encoding + of ISO-8859-1 or some flavour of UTF-16 + and this is an external text entity, + don't look for the BOM, + because it might be a legal data. */ + if (state == XML_CONTENT_STATE) { + int e = INIT_ENC_INDEX(enc); + if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC) + break; + } + if (ptr + 2 == end) + return XML_TOK_PARTIAL; + if ((unsigned char)ptr[2] == 0xBF) { + *encPtr = encodingTable[UTF_8_ENC]; + return XML_TOK_BOM; + } + break; + default: + if (ptr[0] == '\0') { + /* 0 isn't a legal data character. Furthermore a document entity can only + start with ASCII characters. So the only way this can fail to be big-endian + UTF-16 if it it's an external parsed general entity that's labelled as + UTF-16LE. */ + if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) + break; + *encPtr = encodingTable[UTF_16BE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + } + else if (ptr[1] == '\0') { + /* We could recover here in the case: + - parsing an external entity + - second byte is 0 + - no externally specified encoding + - no encoding declaration + by assuming UTF-16LE. But we don't, because this would mean when + presented just with a single byte, we couldn't reliably determine + whether we needed further bytes. */ + if (state == XML_CONTENT_STATE) + break; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + } + break; + } + } + *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); +} + + +#define NS(x) x +#define ns(x) x +#include "xmltok_ns.c" +#undef NS +#undef ns + +#define NS(x) x ## NS +#define ns(x) x ## _ns + +#include "xmltok_ns.c" + +#undef NS +#undef ns + +ENCODING * +xmlrpc_XmlInitUnknownEncodingNS(void * const mem, + int * const table, + int (*convert)(void *userData, const char *p), + void * const userData) { + + ENCODING * const enc = + xmlrpc_XmlInitUnknownEncoding(mem, table, convert, userData); + if (enc) + ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; + return enc; +} diff --git a/trunk/lib/expat/xmltok/xmltok.h b/trunk/lib/expat/xmltok/xmltok.h new file mode 100644 index 000000000..7d7bdf238 --- /dev/null +++ b/trunk/lib/expat/xmltok/xmltok.h @@ -0,0 +1,356 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#ifndef XMLTOK_H_INCLUDED +#define XMLTOK_H_INCLUDED + +#include "xmlrpc-c/c_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following token may be returned by XmlContentTok */ +#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of + illegal ]]> sequence */ +/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ +#define XML_TOK_NONE -4 /* The string to be scanned is empty */ +#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan; + might be part of CRLF sequence */ +#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ +#define XML_TOK_PARTIAL -1 /* only part of a token */ +#define XML_TOK_INVALID 0 + +/* The following tokens are returned by XmlContentTok; some are also + returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */ + +#define XML_TOK_START_TAG_WITH_ATTS 1 +#define XML_TOK_START_TAG_NO_ATTS 2 +#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag */ +#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 +#define XML_TOK_END_TAG 5 +#define XML_TOK_DATA_CHARS 6 +#define XML_TOK_DATA_NEWLINE 7 +#define XML_TOK_CDATA_SECT_OPEN 8 +#define XML_TOK_ENTITY_REF 9 +#define XML_TOK_CHAR_REF 10 /* numeric character reference */ + +/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ +#define XML_TOK_PI 11 /* processing instruction */ +#define XML_TOK_XML_DECL 12 /* XML decl or text decl */ +#define XML_TOK_COMMENT 13 +#define XML_TOK_BOM 14 /* Byte order mark */ + +/* The following tokens are returned only by XmlPrologTok */ +#define XML_TOK_PROLOG_S 15 +#define XML_TOK_DECL_OPEN 16 /* */ +#define XML_TOK_NAME 18 +#define XML_TOK_NMTOKEN 19 +#define XML_TOK_POUND_NAME 20 /* #name */ +#define XML_TOK_OR 21 /* | */ +#define XML_TOK_PERCENT 22 +#define XML_TOK_OPEN_PAREN 23 +#define XML_TOK_CLOSE_PAREN 24 +#define XML_TOK_OPEN_BRACKET 25 +#define XML_TOK_CLOSE_BRACKET 26 +#define XML_TOK_LITERAL 27 +#define XML_TOK_PARAM_ENTITY_REF 28 +#define XML_TOK_INSTANCE_START 29 + +/* The following occur only in element type declarations */ +#define XML_TOK_NAME_QUESTION 30 /* name? */ +#define XML_TOK_NAME_ASTERISK 31 /* name* */ +#define XML_TOK_NAME_PLUS 32 /* name+ */ +#define XML_TOK_COND_SECT_OPEN 33 /* */ +#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ +#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ +#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ +#define XML_TOK_COMMA 38 + +/* The following token is returned only by XmlAttributeValueTok */ +#define XML_TOK_ATTRIBUTE_VALUE_S 39 + +/* The following token is returned only by XmlCdataSectionTok */ +#define XML_TOK_CDATA_SECT_CLOSE 40 + +/* With namespace processing this is returned by XmlPrologTok + for a name with a colon. */ +#define XML_TOK_PREFIXED_NAME 41 + +#define XML_TOK_IGNORE_SECT 42 + +#define XML_N_STATES 4 + +#define XML_PROLOG_STATE 0 +#define XML_CONTENT_STATE 1 +#define XML_CDATA_SECTION_STATE 2 +#define XML_IGNORE_SECTION_STATE 3 + +#define XML_N_LITERAL_TYPES 2 +#define XML_ATTRIBUTE_VALUE_LITERAL 0 +#define XML_ENTITY_VALUE_LITERAL 1 + +/* The size of the buffer passed to XmlUtf8Encode must be at least this. */ +#define XML_UTF8_ENCODE_MAX 4 +/* The size of the buffer passed to XmlUtf16Encode must be at least this. */ +#define XML_UTF16_ENCODE_MAX 2 + +typedef struct position { + /* first line and first column are 0 not 1 */ + unsigned long lineNumber; + unsigned long columnNumber; +} POSITION; + +typedef struct { + const char *name; + const char *valuePtr; + const char *valueEnd; + char normalized; +} ATTRIBUTE; + +struct encoding; +typedef struct encoding ENCODING; + +/* It's pretty silly to have the 'const' on the argument names below, but MSVC + thinks the definitions of Utf8Converter functions that do have that + qualifier on the argument variables don't match this declaration if we + don't. +*/ +typedef void Utf8Converter(const ENCODING * const encP, + const char ** const fromP, + const char * const fromLim, + char ** const toP, + const char * const toLim); +/*---------------------------------------------------------------------------- + A Utf8Converter is an encoder method that converts from the encoder's + code to UTF-8: + + Convert the string that starts at *fromP and ends at 'fromLim' to UTF8 in + the buffer that starts at *toP and ends at 'toLim'. + + Go from left to right and stop when the output buffer is full. + + Note that the buffer can be full while still having a few bytes left in it + because an input character may require multiple bytes of the output buffer. + + The encoding may require up to 4 UTF-8 bytes for a single input character. + + Leave *fromP and *toP pointing after the last character converted. + + The output buffer must be at least 4 bytes. Results are undefined if not. + + We necessarily advance *fromP at least one character if 'fromLim' allows. +-----------------------------------------------------------------------------*/ + + + +struct encoding { + int (*scanners[XML_N_STATES])(const ENCODING *, + const char *, + const char *, + const char **); + int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *, + const char *, + const char *, + const char **); + int (*sameName)(const ENCODING *, + const char *, const char *); + int (*nameMatchesAscii)(const ENCODING *, + const char *, const char *, const char *); + size_t (*nameLength)(const ENCODING *, const char *); + const char *(*skipS)(const ENCODING *, const char *); + int (*getAtts)(const ENCODING *enc, const char *ptr, + int attsMax, ATTRIBUTE *atts); + int (*charRefNumber)(const ENCODING *enc, const char *ptr); + int (*predefinedEntityName)(const ENCODING *, const char *, const char *); + void (*updatePosition)(const ENCODING *, + const char *ptr, + const char *end, + POSITION *); + int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end, + const char **badPtr); + Utf8Converter * utf8Convert; + void (*utf16Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, + unsigned short **toP, + const unsigned short *toLim); + int minBytesPerChar; + char isUtf8; + char isUtf16; +}; + +/* +Scan the string starting at ptr until the end of the next complete token, +but do not scan past eptr. Return an integer giving the type of token. + +Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. + +Return XML_TOK_PARTIAL when the string does not contain a complete token; +nextTokPtr will not be set. + +Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr +will be set to point to the character which made the token invalid. + +Otherwise the string starts with a valid token; nextTokPtr will be set to point +to the character following the end of that token. + +Each data character counts as a single token, but adjacent data characters +may be returned together. Similarly for characters in the prolog outside +literals, comments and processing instructions. +*/ + + +#define XmlTok(enc, state, ptr, end, nextTokPtr) \ + (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) + +#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) + +#define XmlContentTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) + +#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) + +#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) + +/* This is used for performing a 2nd-level tokenization on +the content of a literal that has already been returned by XmlTok. */ + +#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ + (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) + +#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) + +#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ + (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) + +#define XmlNameLength(enc, ptr) \ + (((enc)->nameLength)(enc, ptr)) + +#define XmlSkipS(enc, ptr) \ + (((enc)->skipS)(enc, ptr)) + +#define XmlGetAttributes(enc, ptr, attsMax, atts) \ + (((enc)->getAtts)(enc, ptr, attsMax, atts)) + +#define XmlCharRefNumber(enc, ptr) \ + (((enc)->charRefNumber)(enc, ptr)) + +#define XmlPredefinedEntityName(enc, ptr, end) \ + (((enc)->predefinedEntityName)(enc, ptr, end)) + +#define XmlUpdatePosition(enc, ptr, end, pos) \ + (((enc)->updatePosition)(enc, ptr, end, pos)) + +#define XmlIsPublicId(enc, ptr, end, badPtr) \ + (((enc)->isPublicId)(enc, ptr, end, badPtr)) + +#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) + +#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) + +typedef struct { + ENCODING initEnc; + const ENCODING **encPtr; +} INIT_ENCODING; + +XMLRPC_DLLEXPORT +int +xmlrpc_XmlParseXmlDecl(int const isGeneralTextEntity, + const ENCODING * const enc, + const char * const ptr, + const char * const end, + const char ** const badPtr, + const char ** const versionPtr, + const char ** const encodingNamePtr, + const ENCODING ** const namedEncodingPtr, + int * const standalonePtr); + +XMLRPC_DLLEXPORT +const ENCODING * +xmlrpc_XmlGetUtf8InternalEncoding(void); + +XMLRPC_DLLEXPORT +const ENCODING * +xmlrpc_XmlGetUtf16InternalEncoding(void); + +XMLRPC_DLLEXPORT +int +xmlrpc_XmlInitEncoding(INIT_ENCODING * const p, + const ENCODING ** const encPtr, + const char * const name); + +XMLRPC_DLLEXPORT +int +xmlrpc_XmlUtf8Encode(int const c, + char * const buf); + +XMLRPC_DLLEXPORT +int +xmlrpc_XmlUtf16Encode(int const charNum, + unsigned short * const buf); + +XMLRPC_DLLEXPORT +int +xmlrpc_XmlSizeOfUnknownEncoding(void); + +XMLRPC_DLLEXPORT +ENCODING * +xmlrpc_XmlInitUnknownEncoding(void * const mem, + int * const table, + int (*convert)(void *userData, const char *p), + void * const userData); + +XMLRPC_DLLEXPORT +int +xmlrpc_XmlParseXmlDeclNS(int const isGeneralTextEntity, + const ENCODING * const enc, + const char * const ptr, + const char * const end, + const char ** const badPtr, + const char ** const versionPtr, + const char ** const encodingNamePtr, + const ENCODING ** const namedEncodingPtr, + int * const standalonePtr); + +XMLRPC_DLLEXPORT +int +xmlrpc_XmlInitEncodingNS(INIT_ENCODING * const p, + const ENCODING ** const encPtr, + const char * const name); + +XMLRPC_DLLEXPORT +const ENCODING * +xmlrpc_XmlGetUtf8InternalEncodingNS(void); + +XMLRPC_DLLEXPORT +const ENCODING * +xmlrpc_XmlGetUtf16InternalEncodingNS(void); + +XMLRPC_DLLEXPORT +ENCODING * +xmlrpc_XmlInitUnknownEncodingNS(void * const mem, + int * const table, + int (*convert)(void *userData, const char *p), + void * const userData); + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlTok_INCLUDED */ diff --git a/trunk/lib/expat/xmltok/xmltok_impl.c b/trunk/lib/expat/xmltok/xmltok_impl.c new file mode 100644 index 000000000..cf0091d1d --- /dev/null +++ b/trunk/lib/expat/xmltok/xmltok_impl.c @@ -0,0 +1,1889 @@ +/*============================================================================= + xmltok_impl.c +=============================================================================== + + This is an inclusion for xmltok.c. You define various macros to control + what code this file generates. xmltok.c includes it multiple times with + different macro definitions to get different code. + + For example, the PREFIX macro becomes part of the symbol names we define, + and can be "normal_", "little2_", or "big2_". +=============================================================================*/ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#ifndef IS_INVALID_CHAR +#define IS_INVALID_CHAR(enc, ptr, n) (0) +#endif + +#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n)) { \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +#define INVALID_CASES(ptr, nextTokPtr) \ + INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ + case BT_NONXML: \ + case BT_MALFORM: \ + case BT_TRAIL: \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID + +#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (!IS_NAME_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + case BT_NMSTRT: \ + case BT_HEX: \ + case BT_DIGIT: \ + case BT_NAME: \ + case BT_MINUS: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) + +#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + case BT_NMSTRT: \ + case BT_HEX: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) + +#ifndef PREFIX +#define PREFIX(ident) ident +#endif + +/* ptr points to character following " */ + switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { + case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr; + return XML_TOK_DECL_OPEN; + break; + case BT_S: case BT_CR: case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DECL_OPEN; + case BT_NMSTRT: + case BT_HEX: + ptr += MINBPC(enc); + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static +int PREFIX(checkPiTarget)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, + const char * end, + int * tokPtr) +{ + int upper = 0; + *tokPtr = XML_TOK_PI; + if (end - ptr != MINBPC(enc)*3) + return 1; + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_x: + break; + case ASCII_X: + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC(enc); + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_m: + break; + case ASCII_M: + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC(enc); + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_l: + break; + case ASCII_L: + upper = 1; + break; + default: + return 1; + } + if (upper) + return 0; + *tokPtr = XML_TOK_XML_DECL; + return 1; +} + +/* ptr points to character following " 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_RSQB: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + break; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr -= MINBPC(enc); + break; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CDATA_SECT_CLOSE; + case BT_CR: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + INVALID_CASES(ptr, nextTokPtr); + default: + ptr += MINBPC(enc); + break; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + case BT_RSQB: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following " 1) { + size_t const length = inputEnd - inputStart; + if (length & (MINBPC(enc) - 1)) { + size_t const roundedLen = length & ~(MINBPC(enc) - 1); + *choppedEndP = inputStart + roundedLen; + } else + *choppedEndP = inputEnd; + } else + *choppedEndP = inputEnd; +} + + + +static void +PREFIX(processBtRsqb)(const ENCODING * const enc ATTR_UNUSED, + const char * const start, + const char * const end, + unsigned int * const countP, + bool * const invalidP) { + + if (start + MINBPC(enc) < end) { + if (!CHAR_MATCHES(enc, start + MINBPC(enc), ASCII_RSQB)) { + *countP = MINBPC(enc); + *invalidP = false; + } else { + if (start + 2*MINBPC(enc) < end) { + if (!CHAR_MATCHES(enc, start + 2*MINBPC(enc), ASCII_GT)) { + *countP = MINBPC(enc); + *invalidP = false; + } else { + *countP = 2 * MINBPC(enc); + *invalidP = true; + } + } else { + *countP = 0; + *invalidP = false; + } + } + } else { + *countP = 0; + *invalidP = false; + } +} + + + +static int +PREFIX(contentTok)(const ENCODING * const enc, + const char * const inputStart, + const char * const inputEnd, + const char ** const nextTokPtr) { +/*---------------------------------------------------------------------------- + Parse off a token from the string that starts at 'inputStart' and ends at + 'inputEnd'. Return the class of that token. + + Return *nextTokPtr pointing just after the parsed-off token in the string. + + Sometimes, there is no token we can parse, so our return value is a + disposition code indicating that situation and *nextTokPtr points to the + beginning of the string. +-----------------------------------------------------------------------------*/ + if (inputEnd == inputStart) { + *nextTokPtr = inputStart; + return XML_TOK_NONE; + } else { + const char * ptr; + const char * end; + /* The virtual end of the string; we look at only whole + characters; e.g. if there are 2 bytes per character and the + buffer is 9 bytes, we look at only the first 8 and 'end' points + after the 8th byte. + */ + PREFIX(chopToWholeCharacters)(inputStart, inputEnd, &end); + + if (end == inputStart) { + *nextTokPtr = inputStart; + return XML_TOK_PARTIAL; + } + ptr = inputStart; /* Start at the beginning */ + + switch (BYTE_TYPE(enc, ptr)) { + case BT_LT: + return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_AMP: + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_CR: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + case BT_RSQB: + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_RSQB; + if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + break; + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_RSQB; + if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr -= MINBPC(enc); + break; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + INVALID_CASES(ptr, nextTokPtr); + default: + ptr += MINBPC(enc); + break; + } + while (ptr < end) { + switch (BYTE_TYPE(enc, ptr)) { + LEAD_CASE(2); + LEAD_CASE(3); + LEAD_CASE(4); + case BT_RSQB: { + bool invalid; + unsigned int count; + PREFIX(processBtRsqb)(enc, ptr, end, &count, &invalid); + ptr += count; + if (invalid) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + } break; + case BT_AMP: + case BT_LT: + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + } +} + +#undef LEAD_CASE + + + +/* ptr points to character following "%" */ + +static +int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_PERCENT; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_SEMI: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_PARAM_ENTITY_REF; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static +int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_CR: case BT_LF: case BT_S: + case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: + *nextTokPtr = ptr; + return XML_TOK_POUND_NAME; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -XML_TOK_POUND_NAME; +} + +static +int PREFIX(scanLit)(int open, const ENCODING *enc, + const char *ptr, const char *end, + const char **nextTokPtr) +{ + while (ptr != end) { + int t = BYTE_TYPE(enc, ptr); + switch (t) { + INVALID_CASES(ptr, nextTokPtr); + case BT_QUOT: + case BT_APOS: + ptr += MINBPC(enc); + if (t != open) + break; + if (ptr == end) + return -XML_TOK_LITERAL; + *nextTokPtr = ptr; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: case BT_CR: case BT_LF: + case BT_GT: case BT_PERCNT: case BT_LSQB: + return XML_TOK_LITERAL; + default: + return XML_TOK_INVALID; + } + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + +static +int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + int tok; + if (ptr == end) + return XML_TOK_NONE; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_QUOT: + return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_APOS: + return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_LT: + { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_EXCL: + return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_QUEST: + return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_NMSTRT: + case BT_HEX: + case BT_NONASCII: + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + *nextTokPtr = ptr - MINBPC(enc); + return XML_TOK_INSTANCE_START; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + case BT_CR: + if (ptr + MINBPC(enc) == end) + return -XML_TOK_PROLOG_S; + /* fall through */ + case BT_S: case BT_LF: + for (;;) { + ptr += MINBPC(enc); + if (ptr == end) + break; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: case BT_LF: + break; + case BT_CR: + /* don't split CR/LF pair */ + if (ptr + MINBPC(enc) == end) { + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + } + break; + default: + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + } + } + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + case BT_PERCNT: + return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_COMMA: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_COMMA; + case BT_LSQB: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OPEN_BRACKET; + case BT_RSQB: + ptr += MINBPC(enc); + if (ptr == end) + return -XML_TOK_CLOSE_BRACKET; + if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { + if (ptr + MINBPC(enc) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { + *nextTokPtr = ptr + 2*MINBPC(enc); + return XML_TOK_COND_SECT_CLOSE; + } + } + *nextTokPtr = ptr; + return XML_TOK_CLOSE_BRACKET; + case BT_LPAR: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OPEN_PAREN; + case BT_RPAR: + ptr += MINBPC(enc); + if (ptr == end) + return -XML_TOK_CLOSE_PAREN; + switch (BYTE_TYPE(enc, ptr)) { + case BT_AST: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_ASTERISK; + case BT_QUEST: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_QUESTION; + case BT_PLUS: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_PLUS; + case BT_CR: case BT_LF: case BT_S: + case BT_GT: case BT_COMMA: case BT_VERBAR: + case BT_RPAR: + *nextTokPtr = ptr; + return XML_TOK_CLOSE_PAREN; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_VERBAR: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OR; + case BT_GT: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DECL_CLOSE; + case BT_NUM: + return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ + break; \ + } \ + if (IS_NAME_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NMTOKEN; \ + break; \ + } \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NMSTRT: + case BT_HEX: + tok = XML_TOK_NAME; + ptr += MINBPC(enc); + break; + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + case BT_COLON: + tok = XML_TOK_NMTOKEN; + ptr += MINBPC(enc); + break; + case BT_NONASCII: + if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC(enc); + tok = XML_TOK_NAME; + break; + } + if (IS_NAME_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC(enc); + tok = XML_TOK_NMTOKEN; + } else { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: case BT_RPAR: case BT_COMMA: + case BT_VERBAR: case BT_LSQB: case BT_PERCNT: + case BT_S: case BT_CR: case BT_LF: + *nextTokPtr = ptr; + return tok; + case BT_COLON: + ptr += MINBPC(enc); + switch (tok) { + case XML_TOK_NAME: + if (ptr == end) + return XML_TOK_PARTIAL; + tok = XML_TOK_PREFIXED_NAME; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + default: + tok = XML_TOK_NMTOKEN; + break; + } + break; + case XML_TOK_PREFIXED_NAME: + tok = XML_TOK_NMTOKEN; + break; + } + break; + case BT_PLUS: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_PLUS; + case BT_AST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_ASTERISK; + case BT_QUEST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_QUESTION; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -tok; +} + +static +int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + const char *start; + if (ptr == end) + return XML_TOK_NONE; + start = ptr; + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: ptr += n; break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LT: + /* this is for inside entity references */ + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_S: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_ATTRIBUTE_VALUE_S; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +static +int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + const char *start; + if (ptr == end) + return XML_TOK_NONE; + start = ptr; + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: ptr += n; break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_PERCNT: + if (ptr == start) + return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC(enc); + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + + + +static +int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + int level = 0; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + end = ptr + n; + } + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + INVALID_CASES(ptr, nextTokPtr); + case BT_LT: + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { + ++level; + ptr += MINBPC(enc); + } + } + break; + case BT_RSQB: + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { + if ((ptr += MINBPC(enc)) == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr += MINBPC(enc); + if (level == 0) { + *nextTokPtr = ptr; + return XML_TOK_IGNORE_SECT; + } + --level; + } + } + break; + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + + + +static bool +PREFIX(isSpecialChar)(char const c) { + + switch (c) { + case 0x24: /* $ */ + case 0x40: /* @ */ + return true; + default: + return false; + } +} + + + +static +int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, + const char **badPtr) +{ + ptr += MINBPC(enc); + end -= MINBPC(enc); + for (; ptr != end; ptr += MINBPC(enc)) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_DIGIT: + case BT_HEX: + case BT_MINUS: + case BT_APOS: + case BT_LPAR: + case BT_RPAR: + case BT_PLUS: + case BT_COMMA: + case BT_SOL: + case BT_EQUALS: + case BT_QUEST: + case BT_CR: + case BT_LF: + case BT_SEMI: + case BT_EXCL: + case BT_AST: + case BT_PERCNT: + case BT_NUM: + case BT_COLON: + break; + case BT_S: + if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { + *badPtr = ptr; + return 0; + } + break; + case BT_NAME: + case BT_NMSTRT: + if (BYTE_TO_ASCII(enc, ptr) & ~0x7f) { + if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { + *badPtr = ptr; + return 0; + } + } + break; + default: + if (!PREFIX(isSpecialChar)(BYTE_TO_ASCII(enc, ptr))) { + *badPtr = ptr; + return 0; + } + } + } + return 1; +} + +/* This must only be called for a well-formed start-tag or empty element tag. +Returns the number of attributes. Pointers to the first attsMax attributes +are stored in atts. */ + +static +int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, + int attsMax, ATTRIBUTE *atts) +{ + enum { other, inName, inValue } state = inName; + int nAtts = 0; + int open = 0; /* defined when state == inValue; + initialization just to shut up compilers */ + + for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { + switch (BYTE_TYPE(enc, ptr)) { +#define START_NAME \ + if (state == other) { \ + if (nAtts < attsMax) { \ + atts[nAtts].name = ptr; \ + atts[nAtts].normalized = 1; \ + } \ + state = inName; \ + } +#define LEAD_CASE(n) \ + case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NONASCII: + case BT_NMSTRT: + case BT_HEX: + START_NAME + break; +#undef START_NAME + case BT_QUOT: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); + state = inValue; + open = BT_QUOT; + } + else if (open == BT_QUOT) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_APOS: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); + state = inValue; + open = BT_APOS; + } + else if (open == BT_APOS) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_AMP: + if (nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_S: + if (state == inName) + state = other; + else if (state == inValue + && nAtts < attsMax + && atts[nAtts].normalized + && (ptr == atts[nAtts].valuePtr + || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE + || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE + || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) + atts[nAtts].normalized = 0; + break; + case BT_CR: case BT_LF: + /* This case ensures that the first attribute name is counted + Apart from that we could just change state on the quote. */ + if (state == inName) + state = other; + else if (state == inValue && nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_GT: + case BT_SOL: + if (state != inValue) + return nAtts; + break; + default: + break; + } + } + /* not reached */ +} + +static +int PREFIX(charRefNumber)(const ENCODING *enc ATTR_UNUSED, const char *ptr) +{ + int result = 0; + /* skip &# */ + ptr += 2*MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_x)) { + for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { + int c = BYTE_TO_ASCII(enc, ptr); + switch (c) { + case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: + case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: + result <<= 4; + result |= (c - ASCII_0); + break; + case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F: + result <<= 4; + result += 10 + (c - ASCII_A); + break; + case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f: + result <<= 4; + result += 10 + (c - ASCII_a); + break; + } + if (result >= 0x110000) + return -1; + } + } + else { + for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { + int c = BYTE_TO_ASCII(enc, ptr); + result *= 10; + result += (c - ASCII_0); + if (result >= 0x110000) + return -1; + } + } + return checkCharRefNumber(result); +} + +static +int PREFIX(predefinedEntityName)(const ENCODING * enc ATTR_UNUSED, + const char * ptr, + const char * end) +{ + switch ((end - ptr)/MINBPC(enc)) { + case 2: + if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_l: + return ASCII_LT; + case ASCII_g: + return ASCII_GT; + } + } + break; + case 3: + if (CHAR_MATCHES(enc, ptr, ASCII_a)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_m)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) + return ASCII_AMP; + } + } + break; + case 4: + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_q: + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_u)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_t)) + return ASCII_QUOT; + } + } + break; + case ASCII_a: + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_s)) + return ASCII_APOS; + } + } + break; + } + } + return 0; +} + +static +int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) +{ + for (;;) { + switch (BYTE_TYPE(enc, ptr1)) { + case BT_LEAD4: + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_LEAD3: + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_LEAD2: + if (*ptr1++ != *ptr2++) + return 0; + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_NONASCII: + case BT_NMSTRT: + case BT_COLON: + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + if (*ptr2++ != *ptr1++) + return 0; + if (MINBPC(enc) > 1) { + if (*ptr2++ != *ptr1++) + return 0; + if (MINBPC(enc) > 2) { + if (*ptr2++ != *ptr1++) + return 0; + if (MINBPC(enc) > 3) { + if (*ptr2++ != *ptr1++) + return 0; + } + } + } + break; + default: + if (MINBPC(enc) == 1 && *ptr1 == *ptr2) + return 1; + switch (BYTE_TYPE(enc, ptr2)) { + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + case BT_NONASCII: + case BT_NMSTRT: + case BT_COLON: + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + return 0; + default: + return 1; + } + } + } + /* not reached */ +} + +static +int PREFIX(nameMatchesAscii)(const ENCODING * enc ATTR_UNUSED, + const char * ptr1, + const char * end1, + const char * ptr2) +{ + for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { + if (ptr1 == end1) + return 0; + if (!CHAR_MATCHES(enc, ptr1, *ptr2)) + return 0; + } + return ptr1 == end1; +} + + + +#define LEAD_CASE(n) case BT_LEAD ## n: ptr += n; break + +static size_t +PREFIX(nameLength)(const ENCODING * const enc, + const char * const start) { + + const char * ptr; + + for (ptr = start;;) { + switch (BYTE_TYPE(enc, ptr)) { + LEAD_CASE(2); + LEAD_CASE(3); + LEAD_CASE(4); + case BT_NONASCII: + case BT_NMSTRT: + case BT_COLON: + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + ptr += MINBPC(enc); + break; + default: + return ptr - start; + } + } +} +#undef LEAD_CASE + + + +static +const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr) +{ + for (;;) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_LF: + case BT_CR: + case BT_S: + ptr += MINBPC(enc); + break; + default: + return ptr; + } + } +} + + + +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + ptr += n; \ + break + +static void +PREFIX(updatePosition)(const ENCODING * const enc, + const char * const start, + const char * const end, + POSITION * const posP) { + + const char * ptr; + + for (ptr = start; ptr < end;) { + switch (BYTE_TYPE(enc, ptr)) { + LEAD_CASE(2); + LEAD_CASE(3); + LEAD_CASE(4); + case BT_LF: + posP->columnNumber = (unsigned)-1; + ++posP->lineNumber; + ptr += MINBPC(enc); + break; + case BT_CR: + ++posP->lineNumber; + ptr += MINBPC(enc); + if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + posP->columnNumber = (unsigned)-1; + break; + default: + ptr += MINBPC(enc); + break; + } + ++posP->columnNumber; + } +} + +#undef LEAD_CASE + + +#undef DO_LEAD_CASE +#undef MULTIBYTE_CASES +#undef INVALID_CASES +#undef CHECK_NAME_CASE +#undef CHECK_NAME_CASES +#undef CHECK_NMSTRT_CASE +#undef CHECK_NMSTRT_CASES diff --git a/trunk/lib/expat/xmltok/xmltok_impl.h b/trunk/lib/expat/xmltok/xmltok_impl.h new file mode 100644 index 000000000..eb92802a0 --- /dev/null +++ b/trunk/lib/expat/xmltok/xmltok_impl.h @@ -0,0 +1,46 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +enum { + BT_NONXML, + BT_MALFORM, + BT_LT, + BT_AMP, + BT_RSQB, + BT_LEAD2, + BT_LEAD3, + BT_LEAD4, + BT_TRAIL, + BT_CR, + BT_LF, + BT_GT, + BT_QUOT, + BT_APOS, + BT_EQUALS, + BT_QUEST, + BT_EXCL, + BT_SOL, + BT_SEMI, + BT_NUM, + BT_LSQB, + BT_S, + BT_NMSTRT, + BT_COLON, + BT_HEX, + BT_DIGIT, + BT_NAME, + BT_MINUS, + BT_OTHER, /* known not to be a name or name start character */ + BT_NONASCII, /* might be a name or name start character */ + BT_PERCNT, + BT_LPAR, + BT_RPAR, + BT_AST, + BT_PLUS, + BT_COMMA, + BT_VERBAR +}; + +#include diff --git a/trunk/lib/expat/xmltok/xmltok_ns.c b/trunk/lib/expat/xmltok/xmltok_ns.c new file mode 100644 index 000000000..739399b6b --- /dev/null +++ b/trunk/lib/expat/xmltok/xmltok_ns.c @@ -0,0 +1,148 @@ +const ENCODING * +NS(xmlrpc_XmlGetUtf8InternalEncoding)(void) { + + return &ns(internal_utf8_encoding).enc; +} + + + +const ENCODING * +NS(xmlrpc_XmlGetUtf16InternalEncoding)(void) { + +#if XML_BYTE_ORDER == 12 + return &ns(internal_little2_encoding).enc; +#elif XML_BYTE_ORDER == 21 + return &ns(internal_big2_encoding).enc; +#else + const short n = 1; + return *(const char *)&n ? + &ns(internal_little2_encoding).enc : + &ns(internal_big2_encoding).enc; +#endif +} + +static +const ENCODING *NS(encodings)[] = { + &ns(latin1_encoding).enc, + &ns(ascii_encoding).enc, + &ns(utf8_encoding).enc, + &ns(big2_encoding).enc, + &ns(big2_encoding).enc, + &ns(little2_encoding).enc, + &ns(utf8_encoding).enc /* NO_ENC */ +}; + +static +int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr); +} + +static +int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr); +} + + + +int +NS(xmlrpc_XmlInitEncoding)(INIT_ENCODING * const p, + const ENCODING ** const encPP, + const char * const name) { + + int const index = getEncodingIndex(name); + + int retval; + + if (index == UNKNOWN_ENC) + retval = 0; + else { + SET_INIT_ENC_INDEX(p, index); + p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); + p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); + p->initEnc.updatePosition = initUpdatePosition; + p->encPtr = encPP; + *encPP = &(p->initEnc); + + retval = 1; + } + return retval; +} + + + +static +const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) +{ +#define ENCODING_MAX 128 + char buf[ENCODING_MAX]; + char *p = buf; + int i; + XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); + if (ptr != end) + return 0; + *p = 0; + if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) + return enc; + i = getEncodingIndex(buf); + if (i == UNKNOWN_ENC) + return 0; + return NS(encodings)[i]; +} + + + +int +NS(xmlrpc_XmlParseXmlDecl)(int const isGeneralTextEntity, + const ENCODING * const encodingOfDecl, + const char * const piText, + const char * const end, + const char ** const badP, + const char ** const versionP, + const char ** const encodingNameP, + const ENCODING ** const encodingPP, + int * const standaloneP) { +/*---------------------------------------------------------------------------- + Parse an XML declaration XML Processing Instruction (PI), i.e. + ". + + 'piText' points to the beginning of the PI (to the "<"). + + 'end' points to the end of the PI (just past the ">"). + + 'encodingOfDecl' is the character encoding of the declaration. + + Return as *encodingNameP the value of the "encoding" pseudo-attribute in + the declaration. Furthermore, return as *encodingPP a handle for the + encoding so named, or NULL if we don't recognize the name. + + Return as *standaloneP 1 if the value of the "standalone" pseudo-attribute + in the declaration is "yes"; 0 if it is "no". + + Return as *versionP the value of the "version" pseudo-attribute in the + declaration. + + For all the return values, the pointer may be null, and in that case we + just don't return that information. + + For all the return values, if the pseudo-attribute does not appear in + the declaration, we just leave the pointed-to variable unchanged. + (THIS IS WRONG; WE NEED TO FIX THIS). + + Iff the declaration has invalid syntax, return return value 1 and return as + *badP a pointer to the part of the declaration that is bad. +-----------------------------------------------------------------------------*/ + return doParseXmlDecl(NS(findEncoding), + isGeneralTextEntity, + encodingOfDecl, + piText, + end, + badP, + versionP, + encodingNameP, + encodingPP, + standaloneP); +} diff --git a/trunk/lib/expat/xmlwf/Makefile.in b/trunk/lib/expat/xmlwf/Makefile.in new file mode 100644 index 000000000..08601470c --- /dev/null +++ b/trunk/lib/expat/xmlwf/Makefile.in @@ -0,0 +1,209 @@ +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +ABYSS_SUBDIR = @ABYSS_SUBDIR@ +AS = @AS@ +ASYNCH_CLIENT = @ASYNCH_CLIENT@ +AUTH_CLIENT = @AUTH_CLIENT@ +AVAILABLE_MODULES = @AVAILABLE_MODULES@ +CC = @CC@ +CC_WARN_FLAGS = @CC_WARN_FLAGS@ +CLIENTTEST = @CLIENTTEST@ +CONFIGURE_DATE = @CONFIGURE_DATE@ +CPPTEST = @CPPTEST@ +CPP_WARN_FLAGS = @CPP_WARN_FLAGS@ +CXX = @CXX@ +DLLTOOL = @DLLTOOL@ +EFRPCTEST = @EFRPCTEST@ +EFRPCTEST_WRAPPER = @EFRPCTEST_WRAPPER@ +INTEROP_CGI = @INTEROP_CGI@ +INTEROP_CLIENT_SUBDIR = @INTEROP_CLIENT_SUBDIR@ +LIBTOOL = @LIBTOOL@ +LIBWWW_CFLAGS = @LIBWWW_CFLAGS@ +LIBWWW_CONFIG = @LIBWWW_CONFIG@ +LIBWWW_LDADD = @LIBWWW_LDADD@ +LIBWWW_LIBDIR = @LIBWWW_LIBDIR@ +LIBWWW_RPATH = @LIBWWW_RPATH@ +LIBWWW_WL_RPATH = @LIBWWW_WL_RPATH@ +LIBXMLRPC_ABYSS_SERVER_LA = @LIBXMLRPC_ABYSS_SERVER_LA@ +LIBXMLRPC_CGI_LA = @LIBXMLRPC_CGI_LA@ +LIBXMLRPC_CLIENT_LA = @LIBXMLRPC_CLIENT_LA@ +LIBXMLRPC_CPP_A = @LIBXMLRPC_CPP_A@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +MEERKAT_APP_LIST = @MEERKAT_APP_LIST@ +OBJDUMP = @OBJDUMP@ +PACKAGE = @PACKAGE@ +QUERY_MEERKAT = @QUERY_MEERKAT@ +RANLIB = @RANLIB@ +SAMPLE_CGI_CGI = @SAMPLE_CGI_CGI@ +SERVER = @SERVER@ +SERVERTEST = @SERVERTEST@ +SYNCH_CLIENT = @SYNCH_CLIENT@ +VALIDATEE = @VALIDATEE@ +VERSION = @VERSION@ +VERSION_INFO = @VERSION_INFO@ +XMLRPCCPP_H = @XMLRPCCPP_H@ +XMLRPC_ABYSS_H = @XMLRPC_ABYSS_H@ +XMLRPC_CGI_H = @XMLRPC_CGI_H@ +XMLRPC_CLIENT_H = @XMLRPC_CLIENT_H@ +XML_RPC_API2CPP_SUBDIR = @XML_RPC_API2CPP_SUBDIR@ + +EXTRA_DIST = codepage.c filemap.h unixfilemap.c xmlfile.c xmltchar.h xmlwf.dsp codepage.h readfilemap.c win32filemap.c xmlfile.h xmlwf.c + +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../../xmlrpc_config.h +CONFIG_CLEAN_FILES = +DIST_COMMON = Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = lib/expat/xmlwf + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/trunk/lib/expat/xmlwf/codepage.c b/trunk/lib/expat/xmlwf/codepage.c new file mode 100644 index 000000000..2e1d13af5 --- /dev/null +++ b/trunk/lib/expat/xmlwf/codepage.c @@ -0,0 +1,66 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#include "xmlrpc_config.h" + +#include "codepage.h" + +#if MSVCRT +#define STRICT 1 +#define WIN32_LEAN_AND_MEAN +#include + +int codepageMap(int cp, int *map) +{ + int i; + CPINFO info; + if (!GetCPInfo(cp, &info) || info.MaxCharSize > 2) + return 0; + for (i = 0; i < 256; i++) + map[i] = -1; + if (info.MaxCharSize > 1) { + for (i = 0; i < MAX_LEADBYTES; i++) { + int j, lim; + if (info.LeadByte[i] == 0 && info.LeadByte[i + 1] == 0) + break; + lim = info.LeadByte[i + 1]; + for (j = info.LeadByte[i]; j < lim; j++) + map[j] = -2; + } + } + for (i = 0; i < 256; i++) { + if (map[i] == -1) { + char c = i; + unsigned short n; + if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, + &c, 1, &n, 1) == 1) + map[i] = n; + } + } + return 1; +} + +int codepageConvert(int cp, const char *p) +{ + unsigned short c; + if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, + p, 2, &c, 1) == 1) + return c; + return -1; +} + +#else /* MSVCRT */ + +int codepageMap(int cp, int *map) +{ + return 0; +} + +int codepageConvert(int cp, const char *p) +{ + return -1; +} + +#endif /* MSVCRT */ diff --git a/trunk/lib/expat/xmlwf/codepage.h b/trunk/lib/expat/xmlwf/codepage.h new file mode 100644 index 000000000..b19a7f66b --- /dev/null +++ b/trunk/lib/expat/xmlwf/codepage.h @@ -0,0 +1,7 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +int codepageMap(int cp, int *map); +int codepageConvert(int cp, const char *p); diff --git a/trunk/lib/expat/xmlwf/filemap.h b/trunk/lib/expat/xmlwf/filemap.h new file mode 100644 index 000000000..a0a18474f --- /dev/null +++ b/trunk/lib/expat/xmlwf/filemap.h @@ -0,0 +1,17 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + + +#include + +#ifdef XML_UNICODE +int filemap(const wchar_t *name, + void (*processor)(const void *, size_t, const wchar_t *, void *arg), + void *arg); +#else +int filemap(const char *name, + void (*processor)(const void *, size_t, const char *, void *arg), + void *arg); +#endif diff --git a/trunk/lib/expat/xmlwf/readfilemap.c b/trunk/lib/expat/xmlwf/readfilemap.c new file mode 100644 index 000000000..249af3ec0 --- /dev/null +++ b/trunk/lib/expat/xmlwf/readfilemap.c @@ -0,0 +1,74 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#include +#include +#include +#include +#include + +#ifndef S_ISREG +#ifndef S_IFREG +#define S_IFREG _S_IFREG +#endif +#ifndef S_IFMT +#define S_IFMT _S_IFMT +#endif +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif /* not S_ISREG */ + +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#else +#define O_BINARY 0 +#endif +#endif + +int filemap(const char *name, + void (*processor)(const void *, size_t, const char *, void *arg), + void *arg) +{ + size_t nbytes; + int fd; + int n; + struct stat sb; + void *p; + + fd = open(name, O_RDONLY|O_BINARY); + if (fd < 0) { + perror(name); + return 0; + } + if (fstat(fd, &sb) < 0) { + perror(name); + return 0; + } + if (!S_ISREG(sb.st_mode)) { + fprintf(stderr, "%s: not a regular file\n", name); + return 0; + } + nbytes = sb.st_size; + p = malloc(nbytes); + if (!p) { + fprintf(stderr, "%s: out of memory\n", name); + return 0; + } + n = read(fd, p, nbytes); + if (n < 0) { + perror(name); + close(fd); + return 0; + } + if (n != nbytes) { + fprintf(stderr, "%s: read unexpected number of bytes\n", name); + close(fd); + return 0; + } + processor(p, nbytes, name, arg); + free(p); + close(fd); + return 1; +} diff --git a/trunk/lib/expat/xmlwf/unixfilemap.c b/trunk/lib/expat/xmlwf/unixfilemap.c new file mode 100644 index 000000000..4944b02ac --- /dev/null +++ b/trunk/lib/expat/xmlwf/unixfilemap.c @@ -0,0 +1,57 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +#include "filemap.h" + +int filemap(const char *name, + void (*processor)(const void *, size_t, const char *, void *arg), + void *arg) +{ + int fd; + size_t nbytes; + struct stat sb; + void *p; + + fd = open(name, O_RDONLY); + if (fd < 0) { + perror(name); + return 0; + } + if (fstat(fd, &sb) < 0) { + perror(name); + close(fd); + return 0; + } + if (!S_ISREG(sb.st_mode)) { + close(fd); + fprintf(stderr, "%s: not a regular file\n", name); + return 0; + } + + nbytes = sb.st_size; + p = (void *)mmap((caddr_t)0, (size_t)nbytes, PROT_READ, + MAP_FILE|MAP_PRIVATE, fd, (off_t)0); + if (p == (void *)-1) { + perror(name); + close(fd); + return 0; + } + processor(p, nbytes, name, arg); + munmap((caddr_t)p, nbytes); + close(fd); + return 1; +} diff --git a/trunk/lib/expat/xmlwf/win32filemap.c b/trunk/lib/expat/xmlwf/win32filemap.c new file mode 100644 index 000000000..79b9f47d3 --- /dev/null +++ b/trunk/lib/expat/xmlwf/win32filemap.c @@ -0,0 +1,96 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#define STRICT 1 +#define WIN32_LEAN_AND_MEAN 1 + +#ifdef XML_UNICODE_WCHAR_T +#ifndef XML_UNICODE +#define XML_UNICODE +#endif +#endif + +#ifdef XML_UNICODE +#define UNICODE +#define _UNICODE +#endif /* XML_UNICODE */ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include "filemap.h" + +static void win32perror(const TCHAR *); + +int filemap(const TCHAR *name, + void (*processor)(const void *, size_t, const TCHAR *, void *arg), + void *arg) +{ + HANDLE f; + HANDLE m; + DWORD size; + DWORD sizeHi; + void *p; + + f = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (f == INVALID_HANDLE_VALUE) { + win32perror(name); + return 0; + } + size = GetFileSize(f, &sizeHi); + if (size == (DWORD)-1) { + win32perror(name); + return 0; + } + if (sizeHi) { + _ftprintf(stderr, _T("%s: bigger than 2Gb\n"), name); + return 0; + } + /* CreateFileMapping barfs on zero length files */ + if (size == 0) { + static const char c = '\0'; + processor(&c, 0, name, arg); + CloseHandle(f); + return 1; + } + m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL); + if (m == NULL) { + win32perror(name); + CloseHandle(f); + return 0; + } + p = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0); + if (p == NULL) { + win32perror(name); + CloseHandle(m); + CloseHandle(f); + return 0; + } + processor(p, size, name, arg); + UnmapViewOfFile(p); + CloseHandle(m); + CloseHandle(f); + return 1; +} + +static +void win32perror(const TCHAR *s) +{ + LPVOID buf; + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &buf, + 0, + NULL)) { + _ftprintf(stderr, _T("%s: %s"), s, buf); + fflush(stderr); + LocalFree(buf); + } + else + _ftprintf(stderr, _T("%s: unknown Windows error\n"), s); +} diff --git a/trunk/lib/expat/xmlwf/xmlfile.c b/trunk/lib/expat/xmlwf/xmlfile.c new file mode 100644 index 000000000..b7403d63e --- /dev/null +++ b/trunk/lib/expat/xmlwf/xmlfile.c @@ -0,0 +1,223 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "xmlparse.h" +#include "xmlfile.h" +#include "xmltchar.h" +#include "filemap.h" + +#if MSVCRT +#include +#endif + +#ifdef _XOPEN_SOURCE 600 +#include +#endif + +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#else +#define O_BINARY 0 +#endif +#endif + +#ifdef _DEBUG +#define READ_SIZE 16 +#else +#define READ_SIZE (1024*8) +#endif + + + +typedef struct { + XML_Parser parser; + int *retPtr; +} PROCESS_ARGS; + +static +void reportError(XML_Parser parser, const XML_Char *filename) +{ + int code = XML_GetErrorCode(parser); + const XML_Char *message = XML_ErrorString(code); + if (message) + ftprintf(stdout, T("%s:%d:%d: %s\n"), + filename, + XML_GetErrorLineNumber(parser), + XML_GetErrorColumnNumber(parser), + message); + else + ftprintf(stderr, T("%s: (unknown message %d)\n"), filename, code); +} + +static +void processFile(const void *data, + size_t size, + const XML_Char *filename, + void *args) +{ + XML_Parser parser = ((PROCESS_ARGS *)args)->parser; + int *retPtr = ((PROCESS_ARGS *)args)->retPtr; + if (!XML_Parse(parser, data, size, 1)) { + reportError(parser, filename); + *retPtr = 0; + } + else + *retPtr = 1; +} + +#if MSVCRT + +static +int isAsciiLetter(XML_Char c) +{ + return (T('a') <= c && c <= T('z')) || (T('A') <= c && c <= T('Z')); +} + +#endif /* MSVCRT */ + +static +const XML_Char * +resolveSystemId(const XML_Char *base, + const XML_Char *systemId, + XML_Char **toFree) +{ + XML_Char *s; + *toFree = 0; + if (!base + || *systemId == T('/') +#if MSVCRT + || *systemId == T('\\') + || (isAsciiLetter(systemId[0]) && systemId[1] == T(':')) +#endif + ) + return systemId; + *toFree = (XML_Char *) + malloc((tcslen(base) + tcslen(systemId) + 2)*sizeof(XML_Char)); + if (!*toFree) + return systemId; + tcscpy(*toFree, base); + s = *toFree; + if (tcsrchr(s, T('/'))) + s = tcsrchr(s, T('/')) + 1; +#if MSVCRT + if (tcsrchr(s, T('\\'))) + s = tcsrchr(s, T('\\')) + 1; +#endif + tcscpy(s, systemId); + return *toFree; +} + +static +int externalEntityRefFilemap(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) +{ + int result; + XML_Char *s; + const XML_Char *filename; + XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0); + PROCESS_ARGS args; + args.retPtr = &result; + args.parser = entParser; + filename = resolveSystemId(base, systemId, &s); + XML_SetBase(entParser, filename); + if (!filemap(filename, processFile, &args)) + result = 0; + free(s); + XML_ParserFree(entParser); + return result; +} + +static +int processStream(const XML_Char *filename, XML_Parser parser) +{ + int fd = topen(filename, O_BINARY|O_RDONLY); + if (fd < 0) { + tperror(filename); + return 0; + } + for (;;) { + int nread; + char *buf = XML_GetBuffer(parser, READ_SIZE); + if (!buf) { + close(fd); + ftprintf(stderr, T("%s: out of memory\n"), filename); + return 0; + } + nread = read(fd, buf, READ_SIZE); + if (nread < 0) { + tperror(filename); + close(fd); + return 0; + } + if (!XML_ParseBuffer(parser, nread, nread == 0)) { + reportError(parser, filename); + close(fd); + return 0; + } + if (nread == 0) { + close(fd); + break;; + } + } + return 1; +} + +static +int externalEntityRefStream(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) +{ + XML_Char *s; + const XML_Char *filename; + int ret; + XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0); + filename = resolveSystemId(base, systemId, &s); + XML_SetBase(entParser, filename); + ret = processStream(filename, entParser); + free(s); + XML_ParserFree(entParser); + return ret; +} + +int XML_ProcessFile(XML_Parser parser, + const XML_Char *filename, + unsigned flags) +{ + int result; + + if (!XML_SetBase(parser, filename)) { + ftprintf(stderr, T("%s: out of memory"), filename); + exit(1); + } + + if (flags & XML_EXTERNAL_ENTITIES) + XML_SetExternalEntityRefHandler(parser, + (flags & XML_MAP_FILE) + ? externalEntityRefFilemap + : externalEntityRefStream); + if (flags & XML_MAP_FILE) { + PROCESS_ARGS args; + args.retPtr = &result; + args.parser = parser; + if (!filemap(filename, processFile, &args)) + result = 0; + } + else + result = processStream(filename, parser); + return result; +} diff --git a/trunk/lib/expat/xmlwf/xmlfile.h b/trunk/lib/expat/xmlwf/xmlfile.h new file mode 100644 index 000000000..0c7ac1935 --- /dev/null +++ b/trunk/lib/expat/xmlwf/xmlfile.h @@ -0,0 +1,11 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#define XML_MAP_FILE 01 +#define XML_EXTERNAL_ENTITIES 02 + +extern int XML_ProcessFile(XML_Parser parser, + const XML_Char *filename, + unsigned flags); diff --git a/trunk/lib/expat/xmlwf/xmltchar.h b/trunk/lib/expat/xmlwf/xmltchar.h new file mode 100644 index 000000000..108857551 --- /dev/null +++ b/trunk/lib/expat/xmlwf/xmltchar.h @@ -0,0 +1,36 @@ +#ifdef XML_UNICODE +#ifndef XML_UNICODE_WCHAR_T +#error xmlwf requires a 16-bit Unicode-compatible wchar_t +#endif +#define T(x) L ## x +#define ftprintf fwprintf +#define tfopen _wfopen +#define fputts fputws +#define puttc putwc +#define tcscmp wcscmp +#define tcscpy wcscpy +#define tcscat wcscat +#define tcschr wcschr +#define tcsrchr wcsrchr +#define tcslen wcslen +#define tperror _wperror +#define topen _wopen +#define tmain wmain +#define tremove _wremove +#else /* not XML_UNICODE */ +#define T(x) x +#define ftprintf fprintf +#define tfopen fopen +#define fputts fputs +#define puttc putc +#define tcscmp strcmp +#define tcscpy strcpy +#define tcscat strcat +#define tcschr strchr +#define tcsrchr strrchr +#define tcslen strlen +#define tperror perror +#define topen open +#define tmain main +#define tremove remove +#endif /* not XML_UNICODE */ diff --git a/trunk/lib/expat/xmlwf/xmlwf.c b/trunk/lib/expat/xmlwf/xmlwf.c new file mode 100644 index 000000000..cdfc21c87 --- /dev/null +++ b/trunk/lib/expat/xmlwf/xmlwf.c @@ -0,0 +1,767 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file copying.txt for copying permission. +*/ + +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "xmlparse.h" +#include "codepage.h" +#include "xmlfile.h" +#include "xmltchar.h" + +#if MSVCRT +#include +#endif + +/* This ensures proper sorting. */ + +#define NSSEP T('\001') + +static void characterData(void *userData, const XML_Char *s, int len) +{ + FILE *fp = userData; + for (; len > 0; --len, ++s) { + switch (*s) { + case T('&'): + fputts(T("&"), fp); + break; + case T('<'): + fputts(T("<"), fp); + break; + case T('>'): + fputts(T(">"), fp); + break; +#ifdef W3C14N + case 13: + fputts(T(" "), fp); + break; +#else + case T('"'): + fputts(T("""), fp); + break; + case 9: + case 10: + case 13: + ftprintf(fp, T("&#%d;"), *s); + break; +#endif + default: + puttc(*s, fp); + break; + } + } +} + +static void attributeValue(FILE *fp, const XML_Char *s) +{ + puttc(T('='), fp); + puttc(T('"'), fp); + for (;;) { + switch (*s) { + case 0: + case NSSEP: + puttc(T('"'), fp); + return; + case T('&'): + fputts(T("&"), fp); + break; + case T('<'): + fputts(T("<"), fp); + break; + case T('"'): + fputts(T("""), fp); + break; +#ifdef W3C14N + case 9: + fputts(T(" "), fp); + break; + case 10: + fputts(T(" "), fp); + break; + case 13: + fputts(T(" "), fp); + break; +#else + case T('>'): + fputts(T(">"), fp); + break; + case 9: + case 10: + case 13: + ftprintf(fp, T("&#%d;"), *s); + break; +#endif + default: + puttc(*s, fp); + break; + } + s++; + } +} + +/* Lexicographically comparing UTF-8 encoded attribute values, +is equivalent to lexicographically comparing based on the character number. */ + +static int attcmp(const void *att1, const void *att2) +{ + return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2); +} + +static void startElement(void *userData, const XML_Char *name, const XML_Char **atts) +{ + int nAtts; + const XML_Char **p; + FILE *fp = userData; + puttc(T('<'), fp); + fputts(name, fp); + + p = atts; + while (*p) + ++p; + nAtts = (p - atts) >> 1; + if (nAtts > 1) + qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp); + while (*atts) { + puttc(T(' '), fp); + fputts(*atts++, fp); + attributeValue(fp, *atts); + atts++; + } + puttc(T('>'), fp); +} + +static void endElement(void *userData, const XML_Char *name) +{ + FILE *fp = userData; + puttc(T('<'), fp); + puttc(T('/'), fp); + fputts(name, fp); + puttc(T('>'), fp); +} + +static int nsattcmp(const void *p1, const void *p2) +{ + const XML_Char *att1 = *(const XML_Char **)p1; + const XML_Char *att2 = *(const XML_Char **)p2; + int sep1 = (tcsrchr(att1, NSSEP) != 0); + int sep2 = (tcsrchr(att1, NSSEP) != 0); + if (sep1 != sep2) + return sep1 - sep2; + return tcscmp(att1, att2); +} + +static void startElementNS(void *userData, const XML_Char *name, const XML_Char **atts) +{ + int nAtts; + int nsi; + const XML_Char **p; + FILE *fp = userData; + const XML_Char *sep; + puttc(T('<'), fp); + + sep = tcsrchr(name, NSSEP); + if (sep) { + fputts(T("n1:"), fp); + fputts(sep + 1, fp); + fputts(T(" xmlns:n1"), fp); + attributeValue(fp, name); + nsi = 2; + } + else { + fputts(name, fp); + nsi = 1; + } + + p = atts; + while (*p) + ++p; + nAtts = (p - atts) >> 1; + if (nAtts > 1) + qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, nsattcmp); + while (*atts) { + name = *atts++; + sep = tcsrchr(name, NSSEP); + puttc(T(' '), fp); + if (sep) { + ftprintf(fp, T("n%d:"), nsi); + fputts(sep + 1, fp); + } + else + fputts(name, fp); + attributeValue(fp, *atts); + if (sep) { + ftprintf(fp, T(" xmlns:n%d"), nsi++); + attributeValue(fp, name); + } + atts++; + } + puttc(T('>'), fp); +} + +static void endElementNS(void *userData, const XML_Char *name) +{ + FILE *fp = userData; + const XML_Char *sep; + puttc(T('<'), fp); + puttc(T('/'), fp); + sep = tcsrchr(name, NSSEP); + if (sep) { + fputts(T("n1:"), fp); + fputts(sep + 1, fp); + } + else + fputts(name, fp); + puttc(T('>'), fp); +} + +#ifndef W3C14N + +static void processingInstruction(void *userData, const XML_Char *target, const XML_Char *data) +{ + FILE *fp = userData; + puttc(T('<'), fp); + puttc(T('?'), fp); + fputts(target, fp); + puttc(T(' '), fp); + fputts(data, fp); + puttc(T('?'), fp); + puttc(T('>'), fp); +} + +#endif /* not W3C14N */ + +static void defaultCharacterData(XML_Parser parser, const XML_Char *s, int len) +{ + XML_DefaultCurrent(parser); +} + +static void defaultStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts) +{ + XML_DefaultCurrent(parser); +} + +static void defaultEndElement(XML_Parser parser, const XML_Char *name) +{ + XML_DefaultCurrent(parser); +} + +static void defaultProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data) +{ + XML_DefaultCurrent(parser); +} + +static void nopCharacterData(XML_Parser parser, const XML_Char *s, int len) +{ +} + +static void nopStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts) +{ +} + +static void nopEndElement(XML_Parser parser, const XML_Char *name) +{ +} + +static void nopProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data) +{ +} + +static void markup(XML_Parser parser, const XML_Char *s, int len) +{ + FILE *fp = XML_GetUserData(parser); + for (; len > 0; --len, ++s) + puttc(*s, fp); +} + +static +void metaLocation(XML_Parser parser) +{ + const XML_Char *uri = XML_GetBase(parser); + if (uri) + ftprintf(XML_GetUserData(parser), T(" uri=\"%s\""), uri); + ftprintf(XML_GetUserData(parser), + T(" byte=\"%ld\" nbytes=\"%d\" line=\"%d\" col=\"%d\""), + XML_GetCurrentByteIndex(parser), + XML_GetCurrentByteCount(parser), + XML_GetCurrentLineNumber(parser), + XML_GetCurrentColumnNumber(parser)); +} + +static +void metaStartDocument(XML_Parser parser) +{ + fputts(T("\n"), XML_GetUserData(parser)); +} + +static +void metaEndDocument(XML_Parser parser) +{ + fputts(T("\n"), XML_GetUserData(parser)); +} + +static +void metaStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts) +{ + FILE *fp = XML_GetUserData(parser); + const XML_Char **specifiedAttsEnd + = atts + XML_GetSpecifiedAttributeCount(parser); + const XML_Char **idAttPtr; + int idAttIndex = XML_GetIdAttributeIndex(parser); + if (idAttIndex < 0) + idAttPtr = 0; + else + idAttPtr = atts + idAttIndex; + + ftprintf(fp, T("\n"), fp); + do { + ftprintf(fp, T("= specifiedAttsEnd) + fputts(T("\" defaulted=\"yes\"/>\n"), fp); + else if (atts == idAttPtr) + fputts(T("\" id=\"yes\"/>\n"), fp); + else + fputts(T("\"/>\n"), fp); + } while (*(atts += 2)); + fputts(T("\n"), fp); + } + else + fputts(T("/>\n"), fp); +} + +static +void metaEndElement(XML_Parser parser, const XML_Char *name) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + +static +void metaProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + +static +void metaComment(XML_Parser parser, const XML_Char *data) +{ + FILE *fp = XML_GetUserData(parser); + fputts(T("\n"), fp); +} + +static +void metaStartCdataSection(XML_Parser parser) +{ + FILE *fp = XML_GetUserData(parser); + fputts(T("\n"), fp); +} + +static +void metaEndCdataSection(XML_Parser parser) +{ + FILE *fp = XML_GetUserData(parser); + fputts(T("\n"), fp); +} + +static +void metaCharacterData(XML_Parser parser, const XML_Char *s, int len) +{ + FILE *fp = XML_GetUserData(parser); + fputts(T("\n"), fp); +} + +static +void metaStartDoctypeDecl(XML_Parser parser, const XML_Char *doctypeName) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + +static +void metaEndDoctypeDecl(XML_Parser parser) +{ + FILE *fp = XML_GetUserData(parser); + fputts(T("\n"), fp); +} + +static +void metaUnparsedEntityDecl(XML_Parser parser, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + +static +void metaNotationDecl(XML_Parser parser, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + + +static +void metaExternalParsedEntityDecl(XML_Parser parser, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + +static +void metaInternalParsedEntityDecl(XML_Parser parser, + const XML_Char *entityName, + const XML_Char *text, + int textLen) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("'), fp); + characterData(fp, text, textLen); + fputts(T("\n"), fp); +} + +static +void metaStartNamespaceDecl(XML_Parser parser, + const XML_Char *prefix, + const XML_Char *uri) +{ + FILE *fp = XML_GetUserData(parser); + fputts(T("\n"), fp); + } + else + fputts(T("/>\n"), fp); +} + +static +void metaEndNamespaceDecl(XML_Parser parser, const XML_Char *prefix) +{ + FILE *fp = XML_GetUserData(parser); + if (!prefix) + fputts(T("\n"), fp); + else + ftprintf(fp, T("\n"), prefix); +} + +static +int unknownEncodingConvert(void *data, const char *p) +{ + return codepageConvert(*(int *)data, p); +} + +static +int unknownEncoding(void *userData, + const XML_Char *name, + XML_Encoding *info) +{ + int cp; + static const XML_Char prefixL[] = T("windows-"); + static const XML_Char prefixU[] = T("WINDOWS-"); + int i; + + for (i = 0; prefixU[i]; i++) + if (name[i] != prefixU[i] && name[i] != prefixL[i]) + return 0; + + cp = 0; + for (; name[i]; i++) { + static const XML_Char digits[] = T("0123456789"); + const XML_Char *s = tcschr(digits, name[i]); + if (!s) + return 0; + cp *= 10; + cp += s - digits; + if (cp >= 0x10000) + return 0; + } + if (!codepageMap(cp, info->map)) + return 0; + info->convert = unknownEncodingConvert; + /* We could just cast the code page integer to a void *, + and avoid the use of release. */ + info->release = free; + info->data = malloc(sizeof(int)); + if (!info->data) + return 0; + *(int *)info->data = cp; + return 1; +} + +static +int notStandalone(void *userData) +{ + return 0; +} + +static +void usage(const XML_Char *prog) +{ + ftprintf(stderr, T("usage: %s [-n] [-p] [-r] [-s] [-w] [-x] [-d output-dir] [-e encoding] file ...\n"), prog); + exit(1); +} + +int tmain(int argc, XML_Char **argv) +{ + int i, j; + const XML_Char *outputDir = 0; + const XML_Char *encoding = 0; + unsigned processFlags = XML_MAP_FILE; + int windowsCodePages = 0; + int outputType = 0; + int useNamespaces = 0; + int requireStandalone = 0; + int paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; + +#if MSVCRT + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF); +#endif + + i = 1; + j = 0; + while (i < argc) { + if (j == 0) { + if (argv[i][0] != T('-')) + break; + if (argv[i][1] == T('-') && argv[i][2] == T('\0')) { + i++; + break; + } + j++; + } + switch (argv[i][j]) { + case T('r'): + processFlags &= ~XML_MAP_FILE; + j++; + break; + case T('s'): + requireStandalone = 1; + j++; + break; + case T('n'): + useNamespaces = 1; + j++; + break; + case T('p'): + paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS; + /* fall through */ + case T('x'): + processFlags |= XML_EXTERNAL_ENTITIES; + j++; + break; + case T('w'): + windowsCodePages = 1; + j++; + break; + case T('m'): + outputType = 'm'; + j++; + break; + case T('c'): + outputType = 'c'; + useNamespaces = 0; + j++; + break; + case T('t'): + outputType = 't'; + j++; + break; + case T('d'): + if (argv[i][j + 1] == T('\0')) { + if (++i == argc) + usage(argv[0]); + outputDir = argv[i]; + } + else + outputDir = argv[i] + j + 1; + i++; + j = 0; + break; + case T('e'): + if (argv[i][j + 1] == T('\0')) { + if (++i == argc) + usage(argv[0]); + encoding = argv[i]; + } + else + encoding = argv[i] + j + 1; + i++; + j = 0; + break; + case T('\0'): + if (j > 1) { + i++; + j = 0; + break; + } + /* fall through */ + default: + usage(argv[0]); + } + } + if (i == argc) + usage(argv[0]); + for (; i < argc; i++) { + FILE *fp = 0; + XML_Char *outName = 0; + int result; + XML_Parser parser; + if (useNamespaces) + parser = XML_ParserCreateNS(encoding, NSSEP); + else + parser = XML_ParserCreate(encoding); + if (requireStandalone) + XML_SetNotStandaloneHandler(parser, notStandalone); + XML_SetParamEntityParsing(parser, paramEntityParsing); + if (outputType == 't') { + /* This is for doing timings; this gives a more realistic estimate of + the parsing time. */ + outputDir = 0; + XML_SetElementHandler(parser, nopStartElement, nopEndElement); + XML_SetCharacterDataHandler(parser, nopCharacterData); + XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction); + } + else if (outputDir) { + const XML_Char *file = argv[i]; + if (tcsrchr(file, T('/'))) + file = tcsrchr(file, T('/')) + 1; +#if MSVCRT + if (tcsrchr(file, T('\\'))) + file = tcsrchr(file, T('\\')) + 1; +#endif + outName = malloc((tcslen(outputDir) + tcslen(file) + 2) * sizeof(XML_Char)); + tcscpy(outName, outputDir); + tcscat(outName, T("/")); + tcscat(outName, file); + fp = tfopen(outName, T("wb")); + if (!fp) { + tperror(outName); + exit(1); + } + setvbuf(fp, NULL, _IOFBF, 16384); +#ifdef XML_UNICODE + puttc(0xFEFF, fp); +#endif + XML_SetUserData(parser, fp); + switch (outputType) { + case 'm': + XML_UseParserAsHandlerArg(parser); + XML_SetElementHandler(parser, metaStartElement, metaEndElement); + XML_SetProcessingInstructionHandler(parser, metaProcessingInstruction); + XML_SetCommentHandler(parser, metaComment); + XML_SetCdataSectionHandler(parser, metaStartCdataSection, metaEndCdataSection); + XML_SetCharacterDataHandler(parser, metaCharacterData); + XML_SetDoctypeDeclHandler(parser, metaStartDoctypeDecl, metaEndDoctypeDecl); + XML_SetUnparsedEntityDeclHandler(parser, metaUnparsedEntityDecl); + XML_SetNotationDeclHandler(parser, metaNotationDecl); + XML_SetExternalParsedEntityDeclHandler(parser, metaExternalParsedEntityDecl); + XML_SetInternalParsedEntityDeclHandler(parser, metaInternalParsedEntityDecl); + XML_SetNamespaceDeclHandler(parser, metaStartNamespaceDecl, metaEndNamespaceDecl); + metaStartDocument(parser); + break; + case 'c': + XML_UseParserAsHandlerArg(parser); + XML_SetDefaultHandler(parser, markup); + XML_SetElementHandler(parser, defaultStartElement, defaultEndElement); + XML_SetCharacterDataHandler(parser, defaultCharacterData); + XML_SetProcessingInstructionHandler(parser, defaultProcessingInstruction); + break; + default: + if (useNamespaces) + XML_SetElementHandler(parser, startElementNS, endElementNS); + else + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, characterData); +#ifndef W3C14N + XML_SetProcessingInstructionHandler(parser, processingInstruction); +#endif /* not W3C14N */ + break; + } + } + if (windowsCodePages) + XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0); + result = XML_ProcessFile(parser, argv[i], processFlags); + if (outputDir) { + if (outputType == 'm') + metaEndDocument(parser); + fclose(fp); + if (!result) + tremove(outName); + free(outName); + } + XML_ParserFree(parser); + } + return 0; +} diff --git a/trunk/lib/expat/xmlwf/xmlwf.dsp b/trunk/lib/expat/xmlwf/xmlwf.dsp new file mode 100644 index 000000000..1ca4f42e9 --- /dev/null +++ b/trunk/lib/expat/xmlwf/xmlwf.dsp @@ -0,0 +1,136 @@ +# Microsoft Developer Studio Project File - Name="xmlwf" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=xmlwf - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "xmlwf.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "xmlwf.mak" CFG="xmlwf - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "xmlwf - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "xmlwf - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "xmlwf - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "." +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "." +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\xmlparse" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllimport) /YX /FD /c +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 setargv.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"..\bin\xmlwf.exe" + +!ELSEIF "$(CFG)" == "xmlwf - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "." +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "." +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".\xmlparse" /I "..\xmlparse" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D XMLTOKAPI=__declspec(dllimport) /D XMLPARSEAPI=__declspec(dllimport) /YX /FD /c +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 setargv.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\dbgbin\xmlwf.exe" + +!ENDIF + +# Begin Target + +# Name "xmlwf - Win32 Release" +# Name "xmlwf - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\codepage.c +# End Source File +# Begin Source File + +SOURCE=.\readfilemap.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\unixfilemap.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\win32filemap.c +# End Source File +# Begin Source File + +SOURCE=.\xmlfile.c +# End Source File +# Begin Source File + +SOURCE=.\xmlwf.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\codepage.h +# End Source File +# Begin Source File + +SOURCE=.\xmlfile.h +# End Source File +# Begin Source File + +SOURCE=.\xmltchar.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/trunk/lib/libutil++/Lock.cpp b/trunk/lib/libutil++/Lock.cpp new file mode 100644 index 000000000..a2895a23f --- /dev/null +++ b/trunk/lib/libutil++/Lock.cpp @@ -0,0 +1,65 @@ +#include +#include +#include "xmlrpc-c/girerr.hpp" +using girerr::error; + +#include "xmlrpc-c/Lock.hpp" + + +namespace xmlrpc_c { + +Lock::Holder::Holder(Lock * const lockP) +/*----------------------------------------------------------------------------- + Construct a holder of lock *lockP -- as long as this object exists, *lockP + is locked. + + If *lockP is already locked, wait for it to be unlocked. +-----------------------------------------------------------------------------*/ + : + lockP(lockP) +{ + lockP->acquire(); +} + + + +Lock::Holder::~Holder() { + + this->lockP->release(); +} + + + +Lock::Lock() : + c_lockP(xmlrpc_lock_create()){ + + if (this->c_lockP == NULL) + throw(error("Failed to create lock. xmlrpc_lock_create() failed")); +} + + + +Lock::~Lock() { + + this->c_lockP->destroy(this->c_lockP); +} + + + +void +Lock::acquire() { + + this->c_lockP->acquire(this->c_lockP); +} + + + +void +Lock::release() { + + this->c_lockP->release(this->c_lockP); +} + + + +} // namespace diff --git a/trunk/lib/libutil++/Makefile b/trunk/lib/libutil++/Makefile new file mode 100644 index 000000000..9c1fba11f --- /dev/null +++ b/trunk/lib/libutil++/Makefile @@ -0,0 +1,133 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + srcDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(srcDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/libutil++ + +include $(BLDDIR)/config.mk + +default: all + +TARGET_LIB_NAMES_PP = libxmlrpc_util++ + +STATIC_LIBRARIES_TO_INSTALL = $(TARGET_STATIC_LIBRARIES) + +SHARED_LIBS_TO_BUILD = $(TARGET_LIB_NAMES_PP) +SHARED_LIBS_TO_INSTALL = $(TARGET_LIB_NAMES_PP) + +# INCLUDES and DEP_SOURCES are used by dep-common target +INCLUDES = $(BASIC_INCLUDES) +DEP_SOURCES = *.cpp + +LIBXMLRPC_UTILPP_MODS = Lock base64 env_wrap girerr girmem + +TARGET_MODS_PP = \ + $(LIBXMLRPC_UTILPP_MODS) \ + +PKGCONFIG_FILES_TO_INSTALL := xmlrpc_util++.pc + +OMIT_LIBXMLRPC_UTILPP_RULE = Y +MAJ = 8 + # Major number of shared libraries in this directory + +include $(SRCDIR)/common.mk + + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +BASIC_INCLUDES = \ + -Iblddir/include \ + -Isrcdir/include \ + -Iblddir \ + -Isrcdir/lib/util/include + + +# TARGET_STATIC_LIBARIES, etc. are set by common.mk, based on +# TARGET_LIB_NAMES_PP. + +all: \ + $(TARGET_STATIC_LIBRARIES) \ + $(TARGET_SHARED_LIBS_PP) \ + $(TARGET_SHARED_LE_LIBS) \ + $(PKGCONFIG_FILES_TO_INSTALL) \ + + +#----------------------------------------------------------------------------- +# RULES TO LINK LIBRARIES +#----------------------------------------------------------------------------- + +# Rules for these are in common.mk, courtesy of TARGET_LIB_NAMES_PP: + +# shlibfn generates e.g. libxmlrpc.so.3.1 +# shliblefn generates e.g. libxmlrpc.so + +# Sometimes -lpthread is necessary when link-editing a shared library that +# uses pthread services, and sometimes it is not. We've seen links on +# Windows and AIX fail without it. It seems to be a good idea in all cases, +# as it declares an actual dependency of the shared library. + +LIBXMLRPC_UTILPP_SH = $(call shlibfn, libxmlrpc_util++) + +$(LIBXMLRPC_UTILPP_SH): $(LIBXMLRPC_UTILPP_MODS:%=%.osh) \ + $(LIBXMLRPC_UTIL) \ + +$(LIBXMLRPC_UTILPP_SH): LIBOBJECTS = $(LIBXMLRPC_UTILPP_MODS:%=%.osh) +$(LIBXMLRPC_UTILPP_SH): LIBDEP = \ + -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ + $(THREAD_LIBS) \ + +libxmlrpc_util++.a: $(LIBXMLRPC_UTILPP_MODS:%=%.o) +libxmlrpc_util++.a: LIBOBJECTS = $(LIBXMLRPC_UTILPP_MODS:%=%.o) + +#----------------------------------------------------------------------------- +# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES +#----------------------------------------------------------------------------- + +# Rules for these are in common.mk, courtesy of TARGET_MODS_PP. + + +#----------------------------------------------------------------------------- +# RULES TO MAKE PKGCONFIG FILES +# +# (These are files used by the 'pkg-config' program to get information about +# using the libraries we build) +#----------------------------------------------------------------------------- + +xmlrpc_util++.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_util++" >>$@ + @echo "Description: Xmlrpc-c C++ utility functions library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_util++" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +#----------------------------------------------------------------------------- +# MISCELLANEOUS RULES +#----------------------------------------------------------------------------- + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean clean-local distclean distclean-local +clean: clean-common clean-local +clean-local: + +distclean: clean distclean-local distclean-common + +distclean-local: + +.PHONY: dep +dep: dep-common + +include depend.mk diff --git a/trunk/lib/libutil++/base64.cpp b/trunk/lib/libutil++/base64.cpp new file mode 100644 index 000000000..c72707a06 --- /dev/null +++ b/trunk/lib/libutil++/base64.cpp @@ -0,0 +1,254 @@ +#include +#include +#include +#include +#include // min + +using namespace std; + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/base64.hpp" + +using namespace xmlrpc_c; + + + +namespace { + +char const base64Pad('='); +size_t const base64MaxChunkSize(57); + // Max binary chunk size (76 character line) +#define BASE64_LINE_SZ 128 /* Buffer size for a single line. */ + +unsigned char const table_b2a_base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +} // namespace + + + +class bitBuffer { +public: + bitBuffer() : bitsInBuffer(0) {}; + + void + shiftIn8Bits(unsigned char const newBits) { + // Shift in 8 bits to the right end of the buffer + + this->buffer = (this->buffer << 8) | newBits; + this->bitsInBuffer += 8; + + assert(this->bitsInBuffer <= 12); + } + + void + shiftIn6Bits(unsigned char const newBits) { + // Shift in 6 bits to the right end of the buffer + + this->buffer = (this->buffer << 6) | newBits; + this->bitsInBuffer += 6; + + assert(this->bitsInBuffer <= 12); + } + + void + shiftOut6Bits(unsigned char * const outputP) { + // Shift out 6 bits from the left end of the buffer + + assert(bitsInBuffer >= 6); + + *outputP = (this->buffer >> (this->bitsInBuffer - 6)) & 0x3f; + this->bitsInBuffer -= 6; + } + + void + shiftOut8Bits(unsigned char * const outputP) { + // Shift out 8 bits from the left end of the buffer + + assert(bitsInBuffer >= 8); + + *outputP = (this->buffer >> (this->bitsInBuffer - 8)) & 0xff; + this->bitsInBuffer -= 8; + } + + void + shiftOutResidue(unsigned char * const outputP) { + // Shift out the residual 2 or 4 bits, padded on the right with 0 + // to 6 bits. + + while (this->bitsInBuffer < 6) { + this->buffer <<= 2; + this->bitsInBuffer += 2; + } + + this->shiftOut6Bits(outputP); + } + + void + discardResidue() { + assert(bitsInBuffer < 8); + + this->bitsInBuffer = 0; + } + + unsigned int + bitCount() { + return bitsInBuffer; + } + +private: + unsigned int buffer; + unsigned int bitsInBuffer; +}; + + +namespace xmlrpc_c { + + +static void +encodeChunk(vector const& bytes, + size_t const lineStart, + size_t const chunkSize, + string * const outputP) { + + bitBuffer buffer; + // A buffer in which we accumulate bits (up to 12 bits) + // until we have enough (6) for a base64 character. + + // I suppose this would be more efficient with an iterator on + // 'bytes' and/or *outputP. I'd have to find out how to use one. + + for (size_t linePos = 0; linePos < chunkSize; ++linePos) { + // Shift the data into our buffer + buffer.shiftIn8Bits(bytes[lineStart + linePos]); + + // Encode any complete 6 bit groups + while (buffer.bitCount() >= 6) { + unsigned char theseBits; + buffer.shiftOut6Bits(&theseBits); + outputP->append(1, table_b2a_base64[theseBits]); + } + } + if (buffer.bitCount() > 0) { + // Handle residual bits in the buffer + unsigned char theseBits; + buffer.shiftOutResidue(&theseBits); + + outputP->append(1, table_b2a_base64[theseBits]); + + // Pad to a multiple of 4 characters (24 bits) + assert(outputP->length() % 4 > 0); + outputP->append(4-outputP->length() % 4, base64Pad); + } else { + assert(outputP->length() % 4 == 0); + } +} + + + +string +base64FromBytes(vector const& bytes, + newlineCtl const newlineCtl) { + + string retval; + + if (bytes.size() == 0) { + if (newlineCtl == NEWLINE_YES) + retval = "\r\n"; + else + retval = ""; + } else { + // It would be good to preallocate retval. Need to look up + // how to do that. + for (size_t chunkStart = 0; + chunkStart < bytes.size(); + chunkStart += base64MaxChunkSize) { + + size_t const chunkSize( + min(base64MaxChunkSize, bytes.size() - chunkStart)); + + encodeChunk(bytes, chunkStart, chunkSize, &retval); + + if (newlineCtl == NEWLINE_YES) + // Append a courtesy crlf + retval += "\r\n"; + } + } + return retval; +} + + + +static unsigned char +base64CharValue(char const base64Char) { +/*---------------------------------------------------------------------------- + The 6 bits represented by 'base64Char' in Base 64. + + Throw an error if 'base64Char' is not a valid Base64 character. +-----------------------------------------------------------------------------*/ + static int const table_a2b_base64[] = { + /* Indexed by the ASCII code for a base64 character, this gives the + numerical value that that character encodes. When indexed by + anything else, this gives -1. Note that the table size is 128, so + you can't index it with just any old byte. + */ + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */ + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 + }; + + assert((unsigned int)base64Char < 128); + + unsigned int const tableIndex(base64Char); + + if (table_a2b_base64[tableIndex] < 0) + throwf("Contains non-base64 character " + "with ASCII code 0x%02x", base64Char); + + return (unsigned char)table_a2b_base64[tableIndex]; +} + + + +vector +bytesFromBase64(string const& base64) { + + vector retval; + bitBuffer buffer; + + for (unsigned int cursor = 0; cursor < base64.length(); ++cursor) { + char const thisChar(base64[cursor] & 0x7f); + + if (thisChar == '\r' || thisChar == '\n' || thisChar == ' ') { + // ignore this punctuation + } else { + if (thisChar == base64Pad) { + // This pad character is here to synchronize a chunk to + // a multiple of 24 bits (4 base64 characters; 3 bytes). + buffer.discardResidue(); + } else { + buffer.shiftIn6Bits(base64CharValue(thisChar)); + + if (buffer.bitCount() >= 8) { + unsigned char thisByte; + buffer.shiftOut8Bits(&thisByte); + retval.push_back(thisByte); + } + } + } + } + + if (buffer.bitCount() > 0) + throwf("Not a multiple of 4 characters"); + + return retval; +} + +} //namespace diff --git a/trunk/lib/libutil++/env_wrap.cpp b/trunk/lib/libutil++/env_wrap.cpp new file mode 100644 index 000000000..64cae0ac3 --- /dev/null +++ b/trunk/lib/libutil++/env_wrap.cpp @@ -0,0 +1,18 @@ +#include "xmlrpc-c/util.h" + +#include "xmlrpc-c/env_wrap.hpp" + +namespace xmlrpc_c { + +env_wrap::env_wrap() { + xmlrpc_env_init(&this->env_c); +} + + + +env_wrap::~env_wrap() { + xmlrpc_env_clean(&this->env_c); +} + + +} // namespace diff --git a/trunk/lib/libutil++/girerr.cpp b/trunk/lib/libutil++/girerr.cpp new file mode 100644 index 000000000..953a2f9d6 --- /dev/null +++ b/trunk/lib/libutil++/girerr.cpp @@ -0,0 +1,28 @@ +#include + +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/girerr.hpp" + +using namespace std; + +namespace girerr { + +void +throwf(const char * const format, ...) { + + va_list varargs; + va_start(varargs, format); + + const char * value; + xmlrpc_vasprintf(&value, format, varargs); + + string const valueString(value); + + xmlrpc_strfree(value); + + throw(girerr::error(valueString)); + + va_end(varargs); +} + +} // namespace diff --git a/trunk/lib/libutil++/girmem.cpp b/trunk/lib/libutil++/girmem.cpp new file mode 100644 index 000000000..f9825507d --- /dev/null +++ b/trunk/lib/libutil++/girmem.cpp @@ -0,0 +1,209 @@ +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "xmlrpc-c/Lock.hpp" + +#include "xmlrpc-c/girmem.hpp" + +using namespace std; +using namespace xmlrpc_c; + + +namespace girmem { + + +class autoObject::Impl { + + Lock refcountLock; + unsigned int refcount; + +public: + Impl(); + + ~Impl(); + + void + incref(); + + void + decref(bool * const unreferencedP); +}; + + + +autoObject::Impl::Impl() { + + this->refcount = 0; +} + + + +autoObject::Impl::~Impl() { + + assert(this->refcount == 0); +} + + + +void +autoObject::Impl::incref() { + + Lock::Holder(&this->refcountLock); + + ++this->refcount; +} + + + +void +autoObject::Impl::decref(bool * const unreferencedP) { + + if (this->refcount == 0) + throw(error("Decrementing ref count of unreferenced object")); + + Lock::Holder(&this->refcountLock); + + --this->refcount; + *unreferencedP = (this->refcount == 0); +} + + + +autoObject::autoObject() : implP(auto_ptr(new Impl)) {} + + + +autoObject::autoObject(autoObject const&) { + // This method is declared private, so we can be running now: + assert(false); +} + + + +autoObject::~autoObject() {} + + + +void +autoObject::incref() { + this->implP->incref(); +} + + + +void +autoObject::decref(bool * const unreferencedP) { + this->implP->decref(unreferencedP); +} + + + +autoObjectPtr::autoObjectPtr() : objectP(NULL) {} + + + +autoObjectPtr::autoObjectPtr(autoObject * const objectP) { + + // Note: When someone attempts to use this constructor with a null + // argument, it's normally because a 'new' of the autoObject + // failed, before calling the autoObject's constructor, thus + // generating a null pointer. + + // E.g. the following code, where the system is out of memory: + // + // class client : public autoObject { ... } + // class clientPtr : public autoObjectPtr { ... } + // clientPtr clientP(new client); + + if (objectP == NULL) + throw(error("Object creation failed; trying to create autoObjectPtr " + "with a null autoObject pointer")); + + this->objectP = objectP; + objectP->incref(); +} + + + +autoObjectPtr::autoObjectPtr(autoObjectPtr const& autoObjectPtr) { + // copy constructor + + this->objectP = autoObjectPtr.objectP; + if (this->objectP) + this->objectP->incref(); +} + + + +autoObjectPtr::~autoObjectPtr() { + + this->unpoint(); +} + + + +void +autoObjectPtr::point(autoObject * const objectP) { + + if (this->objectP != NULL) + throw(error("Already pointing")); + this->objectP = objectP; + objectP->incref(); +} + + + +void +autoObjectPtr::unpoint() { + + if (this->objectP) { + bool dead; + this->objectP->decref(&dead); + if (dead) { + delete(this->objectP); + this->objectP = NULL; + } + } +} + + + +autoObjectPtr +autoObjectPtr::operator=(autoObjectPtr const& source) { + + // If we're overwriting a variable that already points to something, + // we have to unpoint it from what it points to now before we can point + // it to what 'source' points to. But if the source and destination + // are the same object, we just want to leave the pointing alone. + + if (this == &source) { + // Assignment of variable to itself; no-op + } else { + this->unpoint(); + this->objectP = source.objectP; + if (this->objectP) + this->objectP->incref(); + } + return *this; +} + + + +autoObject * +autoObjectPtr::operator->() const { + if (this->objectP == NULL) + throw(error("attempt to dereference autoObjectPtr " + "which does not point to anything")); + return this->objectP; +} + + + +autoObject * +autoObjectPtr::get() const { + + return this->objectP; +} + +} // namespace diff --git a/trunk/lib/libutil/Makefile b/trunk/lib/libutil/Makefile new file mode 100644 index 000000000..71c99ad17 --- /dev/null +++ b/trunk/lib/libutil/Makefile @@ -0,0 +1,137 @@ +############################################################################### +# This directory builds libxmlrpc_util, which contains utility +# functions that are used by the Xmlprc-c libraries, and also +# directly by Xmlrpc-c programs. Some of them are documented for use +# by Xmlrpc-c users, as facilities of the libxmlrpc library (which +# prerequires libxmlrpc_util). +# +# The functions in this library are characterized by being general purpose +# programming functions, such as one might wish were in the standard C +# library, which have nothing in particular to do with XML-RPC. +############################################################################### + +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + LIBDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/libutil + +include $(BLDDIR)/config.mk + +default: all + +TARGET_LIBRARY_NAMES := libxmlrpc_util + +STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_util.a + +SHARED_LIBS_TO_BUILD := libxmlrpc_util +SHARED_LIBS_TO_INSTALL := libxmlrpc_util + +ifeq ($(HAVE_PTHREAD),yes) + LOCK_PTHREAD = lock_pthread +else + LOCK_PTHREAD = +endif + +ifeq ($(MSVCRT),yes) + LOCK_WINDOWS = lock_windows +else + LOCK_WINDOWS = +endif + +TARGET_MODS = \ + asprintf \ + base64 \ + error \ + lock_platform \ + $(LOCK_PTHREAD) \ + $(LOCK_WINDOWS) \ + lock_none \ + make_printable \ + memblock \ + mempool \ + select \ + sleep \ + string_number \ + time \ + utf8 \ + +OMIT_LIBXMLRPC_UTIL_RULE=Y +MAJ=4 + # Major number of shared libraries in this directory + +include $(SRCDIR)/common.mk + +INCLUDES = -I$(BLDDIR) -Isrcdir \ + -I$(BLDDIR)/include -Isrcdir/include -Isrcdir/lib/util/include + +UTIL_SHLIB = $(call shlibfn,libxmlrpc_util) +#UTIL_SHLIB is e.g. libxmlrpc_util.so.3.1 +UTIL_SHLIBLE = $(call shliblefn,libxmlrpc_util) +#UTIL_SHLIBLE is e.g. libxmlrpc_util.so + +PKGCONFIG_FILES_TO_INSTALL := xmlrpc_util.pc + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +.PHONY: all +all: libxmlrpc_util.a \ + $(TARGET_SHARED_LIBRARIES) \ + $(TARGET_SHARED_LE_LIBS) \ + $(PKGCONFIG_FILES_TO_INSTALL) \ + +# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES: +$(UTIL_SHLIB): $(TARGET_MODS:%=%.osh) +$(UTIL_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) +$(UTIL_SHLIB): LIBDEP += $(SOCKET_LIBOPT) $(THREAD_LIBS) + +# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES: + +libxmlrpc_util.a: $(TARGET_MODS:%=%.o) +libxmlrpc_util.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) + +#----------------------------------------------------------------------------- +# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES +#----------------------------------------------------------------------------- + +# Rules to compile object modules from which to build the static and shared +# library are in common.mk, courtesy of TARGET_MODS. + +#----------------------------------------------------------------------------- +# RULES TO MAKE PKGCONFIG FILES +# +# (These are files used by the 'pkg-config' program to get information about +# using the libraries we build) +#----------------------------------------------------------------------------- + +xmlrpc_util.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_util" >>$@ + @echo "Description: Xmlrpc-c utility functions library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: " >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_util" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean distclean +clean: clean-common + +distclean: clean distclean-common + +.PHONY: dep +dep: dep-common + +include depend.mk diff --git a/trunk/lib/libutil/asprintf.c b/trunk/lib/libutil/asprintf.c new file mode 100644 index 000000000..d79e1bad7 --- /dev/null +++ b/trunk/lib/libutil/asprintf.c @@ -0,0 +1,199 @@ +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ +#define _GNU_SOURCE /* But only when HAVE_ASPRINTF */ +#include +#include +#include +#include + +#include "xmlrpc_config.h" /* For HAVE_ASPRINTF, __inline__ */ +#include "xmlrpc-c/string_int.h" +#include "bool.h" + + + +static __inline__ void +newVsnprintf(char * const buffer, + size_t const bufferSize, + const char * const fmt, + va_list varargs, + size_t * const formattedSizeP) { +/*---------------------------------------------------------------------------- + This is vsnprintf() with the new behavior, where not fitting in the buffer + is not a failure. + + Unfortunately, we can't practically return the size of the formatted string + if the C library has old vsnprintf() and the formatted string doesn't fit + in the buffer, so in that case we just return something larger than the + buffer. +-----------------------------------------------------------------------------*/ + if (bufferSize > INT_MAX/2) { + /* There's a danger we won't be able to coerce the return value + of XMLRPC_VSNPRINTF to an integer (which we have to do because, + while for POSIX its return value is ssize_t, on Windows it is int), + or return double the buffer size. + */ + *formattedSizeP = 0; + } else { + int rc; + + rc = XMLRPC_VSNPRINTF(buffer, bufferSize, fmt, varargs); + + if (rc < 0) { + /* We have old vsnprintf() (or Windows) and the formatted value + doesn't fit in the buffer, but we don't know how big a buffer it + needs. + */ + *formattedSizeP = bufferSize * 2; + } else { + /* Either the string fits in the buffer or we have new vsnprintf() + which tells us how big the string is regardless. + */ + *formattedSizeP = rc; + } + } +} + + + +static __inline__ int +simpleVasprintf(char ** const resultP, + const char * const fmt, + va_list varargs) { +/*---------------------------------------------------------------------------- + This is a poor man's implementation of vasprintf(), of GNU fame. +-----------------------------------------------------------------------------*/ + int retval; + char * buffer; + size_t bufferSize; + bool outOfMemory; + + for (buffer = NULL, bufferSize = 4096, outOfMemory = false; + !buffer && !outOfMemory; + ) { + + buffer = malloc(bufferSize); + if (!buffer) + outOfMemory = true; + else { + size_t bytesNeeded; + newVsnprintf(buffer, bufferSize, fmt, varargs, &bytesNeeded); + if (bytesNeeded > bufferSize) { + free(buffer); + buffer = NULL; + bufferSize = bytesNeeded; + } + } + } + if (outOfMemory) + retval = -1; + else { + retval = strlen(buffer); + *resultP = buffer; + } + return retval; +} + + + +static const char * const xmlrpc_strsol = + "[insufficient memory to build string]"; + + + +bool +xmlrpc_strnomem(const char * const string) { +/*---------------------------------------------------------------------------- + The string 'string' was generated by a function in this file because it + couldn't get enough memory to generate the string that it was supposed to + generate. I.e. a preceding call to a string function failed. +-----------------------------------------------------------------------------*/ + return string == xmlrpc_strsol; +} + + + +const char * +xmlrpc_strnomemval() { + + return xmlrpc_strsol; +} + + + +void +xmlrpc_vasprintf(const char ** const retvalP, + const char * const fmt, + va_list varargs) { + + char * string; + int rc; + +#if HAVE_ASPRINTF + rc = vasprintf(&string, fmt, varargs); +#else + rc = simpleVasprintf(&string, fmt, varargs); +#endif + + if (rc < 0) + *retvalP = xmlrpc_strsol; + else + *retvalP = string; +} + + + +void XMLRPC_PRINTF_ATTR(2,3) +xmlrpc_asprintf(const char ** const retvalP, const char * const fmt, ...) { + + va_list varargs; /* mysterious structure used by variable arg facility */ + + va_start(varargs, fmt); /* start up the mysterious variable arg facility */ + + xmlrpc_vasprintf(retvalP, fmt, varargs); + + va_end(varargs); +} + + + +const char * +xmlrpc_strdupsol(const char * const string) { + + const char * retvalOrNull; + + retvalOrNull = strdup(string); + + return retvalOrNull ? retvalOrNull : xmlrpc_strsol; +} + + + +void +xmlrpc_strfree(const char * const string) { + + if (string != xmlrpc_strsol) + free((void *)string); +} + + + +const char * +xmlrpc_strdupnull(const char * const string) { + + if (string) + return strdup(string); + else + return NULL; +} + + + +void +xmlrpc_strfreenull(const char * const string) { + + if (string) + xmlrpc_strfree(string); +} + + + diff --git a/trunk/lib/libutil/base64.c b/trunk/lib/libutil/base64.c new file mode 100644 index 000000000..1e7c6e705 --- /dev/null +++ b/trunk/lib/libutil/base64.c @@ -0,0 +1,333 @@ +#include + +#include "xmlrpc_config.h" + +#include "bool.h" +#include "xmlrpc-c/util_int.h" +#include "int.h" +#include "xmlrpc-c/base64_int.h" + + + +void +xmlrpc_base64Encode(const char * const chars, + char * const base64) { +/*---------------------------------------------------------------------------- + This is for internal use by Xmlrpc-c libraries. It is useful for + libraries such as Abyss that don't use xmlrpc_memblock and xmlrpc_env. +-----------------------------------------------------------------------------*/ + /* Conversion table. */ + static char tbl[64] = { + 'A','B','C','D','E','F','G','H', + 'I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X', + 'Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n', + 'o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3', + '4','5','6','7','8','9','+','/' + }; + + unsigned int i; + uint32_t length; + char * p; + const char * s; + + length = strlen(chars); /* initial value */ + s = &chars[0]; /* initial value */ + p = &base64[0]; /* initial value */ + /* Transform the 3x8 bits to 4x6 bits, as required by base64. */ + for (i = 0; i < length; i += 3) { + *p++ = tbl[s[0] >> 2]; + *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)]; + *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)]; + *p++ = tbl[s[2] & 0x3f]; + s += 3; + } + + /* Pad the result if necessary... */ + if (i == length + 1) + *(p - 1) = '='; + else if (i == length + 2) + *(p - 1) = *(p - 2) = '='; + + /* ...and zero-terminate it. */ + *p = '\0'; +} + + + +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +** There is more copyright information in the bottom half of this file. +** Please see it for more details. */ + + +/*========================================================================= +** XML-RPC Base64 Utilities +**========================================================================= +** This code was swiped from Jack Jansen's code in Python 1.5.2 and +** modified to work with our data types. +*/ + +#define CRLF "\015\012" +#define CR '\015' +#define LF '\012' + + +/*********************************************************** +Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum, +Amsterdam, The Netherlands. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Stichting Mathematisch +Centrum or CWI or Corporation for National Research Initiatives or +CNRI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +While CWI is the initial source for this software, a modified version +is made available by the Corporation for National Research Initiatives +(CNRI) at the Internet address ftp://ftp.python.org. + +STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH +CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +******************************************************************/ + +static char table_a2b_base64[] = { + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */ + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +}; + +#define BASE64_PAD '=' +#define BASE64_MAXBIN 57 /* Max binary chunk size (76 char line) */ +#define BASE64_LINE_SZ 128 /* Buffer size for a single line. */ + +static unsigned char const table_b2a_base64[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + + +static xmlrpc_mem_block * +base64Encode(xmlrpc_env * const envP, + const unsigned char * const binData, + size_t const binLen, + bool const wantNewlines) { + + size_t chunkStart, chunkLeft; + unsigned char * asciiData; + int leftbits; + unsigned char thisCh; + unsigned int leftchar; + xmlrpc_mem_block * outputP; + unsigned char lineBuffer[BASE64_LINE_SZ]; + const unsigned char * cursor; + + /* Create a block to hold our lines when we finish them. */ + outputP = xmlrpc_mem_block_new(envP, 0); + XMLRPC_FAIL_IF_FAULT(envP); + + /* Deal with empty data blocks gracefully. Yuck. */ + if (binLen == 0) { + if (wantNewlines) + XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, CRLF, 2); + goto cleanup; + } + + /* Process our binary data in line-sized chunks. */ + for (chunkStart = 0, cursor = &binData[0]; + chunkStart < binLen; + chunkStart += BASE64_MAXBIN) { + + /* Set up our per-line state. */ + asciiData = &lineBuffer[0]; + chunkLeft = binLen - chunkStart; + if (chunkLeft > BASE64_MAXBIN) + chunkLeft = BASE64_MAXBIN; + leftbits = 0; + leftchar = 0; + + for(; chunkLeft > 0; --chunkLeft, ++cursor) { + /* Shift the data into our buffer */ + leftchar = (leftchar << 8) | *cursor; + leftbits += 8; + + /* See if there are 6-bit groups ready */ + while (leftbits >= 6) { + thisCh = (leftchar >> (leftbits-6)) & 0x3f; + leftbits -= 6; + *asciiData++ = table_b2a_base64[thisCh]; + } + } + if (leftbits == 2) { + *asciiData++ = table_b2a_base64[(leftchar&3) << 4]; + *asciiData++ = BASE64_PAD; + *asciiData++ = BASE64_PAD; + } else if (leftbits == 4) { + *asciiData++ = table_b2a_base64[(leftchar&0xf) << 2]; + *asciiData++ = BASE64_PAD; + } + + /* Append a courtesy CRLF. */ + if (wantNewlines) { + *asciiData++ = CR; + *asciiData++ = LF; + } + + /* Save our line. */ + XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, lineBuffer, + asciiData - &lineBuffer[0]); + XMLRPC_FAIL_IF_FAULT(envP); + } + + cleanup: + if (envP->fault_occurred) { + if (outputP) + xmlrpc_mem_block_free(outputP); + return NULL; + } + return outputP; +} + + + +xmlrpc_mem_block * +xmlrpc_base64_encode(xmlrpc_env * const envP, + const unsigned char * const binData, + size_t const binLen) { + + return base64Encode(envP, binData, binLen, true); +} + + + +xmlrpc_mem_block * +xmlrpc_base64_encode_without_newlines(xmlrpc_env * const envP, + const unsigned char * const binData, + size_t const binLen) { + + return base64Encode(envP, binData, binLen, false); +} + + + +xmlrpc_mem_block * +xmlrpc_base64_decode(xmlrpc_env * const envP, + const char * const asciiData, + size_t const acsiiLen) { + + unsigned char * binData; + int leftbits; + unsigned char thisCh; + unsigned int leftchar; + size_t npad; + size_t binLen, bufferSize; + xmlrpc_mem_block * outputP; + const char * nextCharP; + size_t remainingLen; + + /* Create a block to hold our chunks when we finish them. + ** We overestimate the size now, and fix it later. */ + bufferSize = ((acsiiLen + 3) / 4) * 3; + outputP = xmlrpc_mem_block_new(envP, bufferSize); + XMLRPC_FAIL_IF_FAULT(envP); + + /* Set up our decoder state. */ + leftbits = 0; + leftchar = 0; + npad = 0; + binData = XMLRPC_MEMBLOCK_CONTENTS(unsigned char, outputP); + binLen = 0; + + for (remainingLen = acsiiLen, nextCharP = asciiData; + remainingLen > 0; + --remainingLen, ++nextCharP) { + + /* Skip some punctuation. */ + thisCh = (*nextCharP & 0x7f); + if (thisCh == '\r' || thisCh == '\n' || thisCh == ' ') + continue; + if (thisCh == BASE64_PAD) + ++npad; + thisCh = table_a2b_base64[(*nextCharP) & 0x7f]; + + /* XXX - We just throw away invalid characters. Is this right? */ + if (thisCh == (unsigned char) -1) + continue; + + /* Shift it in on the low end, and see if there's a byte ready for + output. + */ + leftchar = (leftchar << 6) | (thisCh); + leftbits += 6; + if (leftbits >= 8) { + leftbits -= 8; + XMLRPC_ASSERT(binLen < bufferSize); + *binData++ = (leftchar >> leftbits) & 0xFF; + leftchar &= ((1 << leftbits) - 1); + ++binLen; + } + } + + /* Check that no bits are left. */ + if (leftbits) + XMLRPC_FAIL(envP, XMLRPC_PARSE_ERROR, "Incorrect Base64 padding"); + + /* Check to make sure we have a sane amount of padding. */ + if (npad > binLen || npad > 2) + XMLRPC_FAIL(envP, XMLRPC_PARSE_ERROR, "Malformed Base64 data"); + + /* Remove any padding and set the correct size. */ + binLen -= npad; + XMLRPC_MEMBLOCK_RESIZE(char, envP, outputP, binLen); + XMLRPC_ASSERT(!envP->fault_occurred); + + cleanup: + if (envP->fault_occurred) { + if (outputP) + xmlrpc_mem_block_free(outputP); + return NULL; + } + return outputP; +} diff --git a/trunk/lib/libutil/error.c b/trunk/lib/libutil/error.c new file mode 100644 index 000000000..473755773 --- /dev/null +++ b/trunk/lib/libutil/error.c @@ -0,0 +1,167 @@ +/* Copyright information is at end of file */ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include + +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/util.h" + + + +void +xmlrpc_assertion_failed(const char * const fileName, + int const lineNumber) { + + fprintf(stderr, "%s:%d: assertion failed\n", fileName, lineNumber); + abort(); +} + + + +static const char * const default_fault_string = + "Not enough memory for error message"; + +void +xmlrpc_env_init (xmlrpc_env* env) { + XMLRPC_ASSERT(env != NULL); + + env->fault_occurred = 0; + env->fault_code = 0; + env->fault_string = NULL; +} + + + +void +xmlrpc_env_clean(xmlrpc_env * const envP) { + + XMLRPC_ASSERT(envP != NULL); + XMLRPC_ASSERT(envP->fault_string != XMLRPC_BAD_POINTER); + + /* env->fault_string may be one of three things: + ** 1) a NULL pointer + ** 2) a pointer to the default_fault_string + ** 3) a pointer to a malloc'd fault string + ** If we have case (3), we'll need to free it. */ + if (envP->fault_string && envP->fault_string != default_fault_string) + free(envP->fault_string); + envP->fault_string = XMLRPC_BAD_POINTER; +} + + + +void +xmlrpc_env_set_fault(xmlrpc_env * const envP, + int const faultCode, + const char * const faultDescription) { + + char * buffer; + + XMLRPC_ASSERT(envP != NULL); + XMLRPC_ASSERT(faultDescription != NULL); + + /* Clean up any leftover pointers. */ + xmlrpc_env_clean(envP); + + envP->fault_occurred = 1; + envP->fault_code = faultCode; + + /* Try to copy the fault string. If this fails, use a default. */ + buffer = strdup(faultDescription); + if (buffer == NULL) + envP->fault_string = (char *)default_fault_string; + else { + xmlrpc_force_to_utf8(buffer); + xmlrpc_force_to_xml_chars(buffer); + envP->fault_string = buffer; + } +} + + + +void +xmlrpc_set_fault_formatted_v(xmlrpc_env * const envP, + int const code, + const char * const format, + va_list args) { + + const char * faultDescription; + + xmlrpc_vasprintf(&faultDescription, format, args); + + xmlrpc_env_set_fault(envP, code, faultDescription); + + xmlrpc_strfree(faultDescription); +} + + + +void +xmlrpc_env_set_fault_formatted(xmlrpc_env * const envP, + int const code, + const char * const format, + ...) { + va_list args; + + XMLRPC_ASSERT(envP != NULL); + XMLRPC_ASSERT(format != NULL); + + /* Print our error message to the buffer. */ + va_start(args, format); + xmlrpc_set_fault_formatted_v(envP, code, format, args); + va_end(args); +} + + + +void +xmlrpc_faultf(xmlrpc_env * const envP, + const char * const format, + ...) { + + va_list args; + + XMLRPC_ASSERT(envP != NULL); + XMLRPC_ASSERT(format != NULL); + + /* Print our error message to the buffer. */ + va_start(args, format); + xmlrpc_set_fault_formatted_v(envP, XMLRPC_INTERNAL_ERROR, format, args); + va_end(args); + +} + + + +/* 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. */ + diff --git a/trunk/lib/libutil/lock_none.c b/trunk/lib/libutil/lock_none.c new file mode 100644 index 000000000..6a577fdc4 --- /dev/null +++ b/trunk/lib/libutil/lock_none.c @@ -0,0 +1,61 @@ +/*============================================================================= + lock_none +=============================================================================== + This is an inter-thread lock class for a system in which there is no + inter-thread conflict, e.g. where no two threads every share memory. + + The locking is therefore trivial: no-op +=============================================================================*/ +#include + +#include "mallocvar.h" +#include "xmlrpc-c/lock.h" + +#include "xmlrpc-c/lock_none.h" + +static lockAcquireFn acquire; + +static void +acquire(struct lock * const lockP ATTR_UNUSED) { + +} + + + +static lockReleaseFn release; + +static void +release(struct lock * const lockP ATTR_UNUSED) { + +} + + + +static lockDestroyFn destroy; + +static void +destroy(struct lock * const lockP ATTR_UNUSED) { + + free(lockP); +} + + + +struct lock * +xmlrpc_lock_create_none(void) { + + struct lock * lockP; + + MALLOCVAR(lockP); + + if (lockP) { + lockP->implementationP = NULL; + lockP->acquire = &acquire; + lockP->release = &release; + lockP->destroy = &destroy; + } + return lockP; +} + + + diff --git a/trunk/lib/libutil/lock_platform.c b/trunk/lib/libutil/lock_platform.c new file mode 100644 index 000000000..387a5cf85 --- /dev/null +++ b/trunk/lib/libutil/lock_platform.c @@ -0,0 +1,48 @@ +/*============================================================================= + lock_platform +=============================================================================== + + This module provides locking services appropriate for the platform for + which Xmlrpc-c is being built. I.e. services chosen by the build + configuration. + +============================================================================*/ + +#include "xmlrpc_config.h" + +#include "xmlrpc-c/lock_platform.h" + +#if HAVE_PTHREAD +#include "xmlrpc-c/lock_pthread.h" +#endif + +#if HAVE_WINDOWS_THREAD +#include "xmlrpc-c/lock_windows.h" +#endif + +struct lock * +xmlrpc_lock_create(void) { + +#if HAVE_PTHREAD + return xmlrpc_lock_create_pthread(); +#elif HAVE_WINDOWS_THREAD + return xmlrpc_lock_create_windows(); +#else + #error "You don't have any thread facility. (According to " + #error "HAVE_PTHREAD and HAVE_WINDOWS_THREAD macros defined in " + #error "xmlrpc_config.h)" + + /* One might consider using xmlrpc_lock_create_none() here, but that would + be dangerous. If the system really does have threads that share memory, + and there's just some configuration error here (which is the most likely + case), we would silently build a broken library, which breakage would be + difficult for the user to detect and then diagnose. + + If we encounter some actual need for lock_none in the future, we'll + revisit the issue of when the build system should select it + */ +#endif + +} + + diff --git a/trunk/lib/libutil/lock_pthread.c b/trunk/lib/libutil/lock_pthread.c new file mode 100644 index 000000000..cab9b445b --- /dev/null +++ b/trunk/lib/libutil/lock_pthread.c @@ -0,0 +1,78 @@ +#include +#include + +#include "mallocvar.h" + +#include "xmlrpc-c/lock.h" + +#include "xmlrpc-c/lock_pthread.h" + +static lockAcquireFn acquire; + +static void +acquire(struct lock * const lockP) { + + pthread_mutex_t * const mutexP = lockP->implementationP; + + pthread_mutex_lock(mutexP); +} + + + +static lockReleaseFn release; + +static void +release(struct lock * const lockP) { + + pthread_mutex_t * const mutexP = lockP->implementationP; + + pthread_mutex_unlock(mutexP); +} + + + +static lockDestroyFn destroy; + +static void +destroy(struct lock * const lockP) { + + pthread_mutex_t * const mutexP = lockP->implementationP; + + pthread_mutex_destroy(mutexP); + + free(mutexP); + + free(lockP); +} + + + +struct lock * +xmlrpc_lock_create_pthread(void) { + + struct lock * lockP; + + MALLOCVAR(lockP); + + if (lockP) { + pthread_mutex_t * mutexP; + + MALLOCVAR(mutexP); + + if (mutexP) { + pthread_mutex_init(mutexP, NULL); + + lockP->implementationP = mutexP; + lockP->acquire = &acquire; + lockP->release = &release; + lockP->destroy = &destroy; + } else { + free(lockP); + lockP = NULL; + } + } + return lockP; +} + + + diff --git a/trunk/lib/libutil/lock_windows.c b/trunk/lib/libutil/lock_windows.c new file mode 100644 index 000000000..22631536f --- /dev/null +++ b/trunk/lib/libutil/lock_windows.c @@ -0,0 +1,85 @@ +#include "xmlrpc_config.h" + +/* We define WIN32_WIN_LEAN_AND_MEAN to make contain less + junk; nothing in Xmlrpc-c needs that stuff. One significant thing it cuts + out is , which would conflict with the that our + includer might use. +*/ +#define WIN32_WIN_LEAN_AND_MEAN +#include + +#include "mallocvar.h" + +#include "xmlrpc-c/lock.h" + +#include "xmlrpc-c/lock_windows.h" + +static lockAcquireFn acquire; + +static void +acquire(struct lock * lockP) { + + CRITICAL_SECTION * const criticalSectionP = lockP->implementationP; + + EnterCriticalSection(criticalSectionP); +} + + + +static lockReleaseFn release; + +static void +release(struct lock * lockP) { + + CRITICAL_SECTION * const criticalSectionP = lockP->implementationP; + + LeaveCriticalSection(criticalSectionP); +} + + + +static lockDestroyFn destroy; + +static void +destroy(struct lock * const lockP) { + + CRITICAL_SECTION * const criticalSectionP = lockP->implementationP; + + DeleteCriticalSection(criticalSectionP); + + free(criticalSectionP); + + free(lockP); +} + + + +struct lock * +xmlrpc_lock_create_windows(void) { + + struct lock * lockP; + + MALLOCVAR(lockP); + + if (lockP) { + CRITICAL_SECTION * criticalSectionP; + + MALLOCVAR(criticalSectionP); + + if (criticalSectionP) { + InitializeCriticalSection(criticalSectionP); + + lockP->implementationP = criticalSectionP; + lockP->acquire = &acquire; + lockP->release = &release; + lockP->destroy = &destroy; + } else { + free(lockP); + lockP = NULL; + } + } + return lockP; +} + + + diff --git a/trunk/lib/libutil/make_printable.c b/trunk/lib/libutil/make_printable.c new file mode 100644 index 000000000..e9415ea5e --- /dev/null +++ b/trunk/lib/libutil/make_printable.c @@ -0,0 +1,101 @@ +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "xmlrpc-c/string_int.h" + + + +const char * +xmlrpc_makePrintable_lp(const char * const input, + size_t const inputLength) { +/*---------------------------------------------------------------------------- + Convert an arbitrary string of characters in length-pointer form to + printable ASCII. E.g. convert newlines to "\n". + + Return the result in newly malloc'ed storage. Return NULL if we can't + get the storage. +-----------------------------------------------------------------------------*/ + char * output; + + output = malloc(inputLength*4+1); + /* Worst case, we render a character like \x01 -- 4 characters */ + + if (output != NULL) { + unsigned int inputCursor, outputCursor; + + for (inputCursor = 0, outputCursor = 0; + inputCursor < inputLength; + ++inputCursor) { + + if (0) { + } else if (input[inputCursor] == '\\') { + output[outputCursor++] = '\\'; + output[outputCursor++] = '\\'; + } else if (input[inputCursor] == '\n') { + output[outputCursor++] = '\\'; + output[outputCursor++] = 'n'; + } else if (input[inputCursor] == '\t') { + output[outputCursor++] = '\\'; + output[outputCursor++] = 't'; + } else if (input[inputCursor] == '\a') { + output[outputCursor++] = '\\'; + output[outputCursor++] = 'a'; + } else if (input[inputCursor] == '\r') { + output[outputCursor++] = '\\'; + output[outputCursor++] = 'r'; + } else if (isprint(input[inputCursor])) { + output[outputCursor++] = input[inputCursor]; + } else { + XMLRPC_SNPRINTF(&output[outputCursor], 5, "\\x%02x", + (unsigned char)input[inputCursor]); + outputCursor += 4; + } + } + output[outputCursor++] = '\0'; + } + return output; +} + + + +const char * +xmlrpc_makePrintable(const char * const input) { +/*---------------------------------------------------------------------------- + Convert an arbitrary string of characters (NUL-terminated, though) to + printable ASCII. E.g. convert newlines to "\n". + + Return the result in newly malloc'ed storage. Return NULL if we can't + get the storage. +-----------------------------------------------------------------------------*/ + return xmlrpc_makePrintable_lp(input, strlen(input)); +} + + + +const char * +xmlrpc_makePrintableChar(char const input) { +/*---------------------------------------------------------------------------- + Return an ASCIIZ string consisting of the character 'input', + properly escaped so as to be printable. E.g., in C notation, '\n' + turns into "\\n" +-----------------------------------------------------------------------------*/ + const char * retval; + + if (input == '\0') + retval = strdup("\\0"); + else { + char buffer[2]; + + buffer[0] = input; + buffer[1] = '\0'; + + retval = xmlrpc_makePrintable(buffer); + } + return retval; +} diff --git a/trunk/lib/libutil/memblock.c b/trunk/lib/libutil/memblock.c new file mode 100644 index 000000000..9469d0118 --- /dev/null +++ b/trunk/lib/libutil/memblock.c @@ -0,0 +1,272 @@ +/* Copyright information is at end of file */ +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include + +#include "bool.h" +#include "girmath.h" +#include "mallocvar.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/util.h" + +#define BLOCK_ALLOC_MIN (16) + +static bool const tracingMemory = +#ifdef EFENCE + true +#else + false +#endif + ; + + + +struct _xmlrpc_mem_block { + xmlrpc_mem_pool * poolP; + /* Pool this block is in; NULL if it is not in a pool */ + size_t size; + /* Size of the block */ + size_t allocated; + /* How much memory we've allocated from the system for this block + (pointed to by 'blockP') + */ + void * blockP; +}; + + + +xmlrpc_mem_block * +xmlrpc_mem_block_new_pool(xmlrpc_env * const envP, + size_t const size, + xmlrpc_mem_pool * const poolP) { +/*---------------------------------------------------------------------------- + Create an xmlrpc_mem_block of size 'size' in pool *poolP. + + If 'poolP' is NULL, don't put it in any pool. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * blockP; + + XMLRPC_ASSERT_ENV_OK(envP); + + if (!envP->fault_occurred) { + MALLOCVAR(blockP); + + if (blockP == NULL) + xmlrpc_faultf(envP, "Can't allocate memory block descriptor"); + else { + blockP->poolP = poolP; + + blockP->size = size; + + if (tracingMemory) + blockP->allocated = size; + else + blockP->allocated = MAX(BLOCK_ALLOC_MIN, size); + + if (poolP) + xmlrpc_mem_pool_alloc(envP, poolP, blockP->allocated); + + if (!envP->fault_occurred) { + blockP->blockP = malloc(blockP->allocated); + if (!blockP->blockP) + xmlrpc_faultf(envP, "Can't allocate %u-byte memory block", + (unsigned)blockP->allocated); + + + if (envP->fault_occurred) + xmlrpc_mem_pool_release(poolP, blockP->allocated); + } + if (envP->fault_occurred) { + free(blockP); + blockP = NULL; + } + } + } + return blockP; +} + + + +xmlrpc_mem_block * +xmlrpc_mem_block_new(xmlrpc_env * const envP, + size_t const size) { +/*---------------------------------------------------------------------------- + Create an xmlrpc_mem_block of size 'size', not in any pool +-----------------------------------------------------------------------------*/ + return xmlrpc_mem_block_new_pool(envP, size, NULL); +} + + + +void +xmlrpc_mem_block_free(xmlrpc_mem_block * const blockP) { +/*---------------------------------------------------------------------------- + Destroy xmlrpc_mem_block *blockP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(blockP != NULL); + XMLRPC_ASSERT(blockP->blockP != NULL); + + if (blockP->poolP) + xmlrpc_mem_pool_release(blockP->poolP, blockP->allocated); + + free(blockP->blockP); + + free(blockP); +} + + + +size_t +xmlrpc_mem_block_size(const xmlrpc_mem_block * const blockP) { +/*---------------------------------------------------------------------------- + The size of the xmlrpc_mem_block. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(blockP != NULL); + return blockP->size; +} + + + +void * +xmlrpc_mem_block_contents(const xmlrpc_mem_block * const blockP) { +/*---------------------------------------------------------------------------- + The contents of the xmlrpc_mem_block +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(blockP != NULL); + return blockP->blockP; +} + + + +static size_t +allocSize(size_t const requestedSize) { +/*---------------------------------------------------------------------------- + The size we allocate when the user requests to resize to 'requesteddSize'. + + We give him more than he requested in an attempt to avoid lots of copying + when Caller repeatedly resizes by small amounts. + + We make some arbitrary judgments about how much memory or copying + constitutes lots. +-----------------------------------------------------------------------------*/ + size_t const oneMegabyte = 1024*1024; + + size_t retval; + + if (tracingMemory) + retval = requestedSize; + else { + /* We make it a power of two unless it is more than a megabyte, + in which case we just make it a multiple of a megabyte. + */ + if (requestedSize >= oneMegabyte) + retval = ROUNDUPU(requestedSize, oneMegabyte); + else { + unsigned int i; + for (i = BLOCK_ALLOC_MIN; i < requestedSize; i *= 2); + retval = i; + } + } + return retval; +} + + + +void +xmlrpc_mem_block_resize(xmlrpc_env * const envP, + xmlrpc_mem_block * const blockP, + size_t const size) { +/*---------------------------------------------------------------------------- + Resize an xmlrpc_mem_block by allocating new memory for it and copying + whatever might be in it to the new memory. +-----------------------------------------------------------------------------*/ + size_t const newAllocSize = allocSize(size); + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(blockP != NULL); + + if (newAllocSize > blockP->allocated) { + /* Reallocate */ + + if (blockP->poolP) + xmlrpc_mem_pool_alloc(envP, blockP->poolP, + newAllocSize - blockP->allocated); + + if (!envP->fault_occurred) { + void * newMem; + + newMem = malloc(newAllocSize); + if (!newMem) + xmlrpc_faultf(envP, + "Failed to allocate %u bytes of memory " + "from the OS", + (unsigned) size); + else { + /* Copy over the data */ + size_t const sizeToCopy = MIN(blockP->size, size); + assert(sizeToCopy <= newAllocSize); + memcpy(newMem, blockP->blockP, sizeToCopy); + + free(blockP->blockP); + + blockP->blockP = newMem; + blockP->allocated = newAllocSize; + } + if (envP->fault_occurred) + xmlrpc_mem_pool_release(blockP->poolP, + newAllocSize - blockP->allocated); + } + } + blockP->size = size; +} + + + +void +xmlrpc_mem_block_append(xmlrpc_env * const envP, + xmlrpc_mem_block * const blockP, + const void * const data, + size_t const len) { + + size_t const originalSize = blockP->size; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(blockP != NULL); + + xmlrpc_mem_block_resize(envP, blockP, originalSize + len); + if (!envP->fault_occurred) { + memcpy(((unsigned char*) blockP->blockP) + originalSize, data, 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. +*/ diff --git a/trunk/lib/libutil/mempool.c b/trunk/lib/libutil/mempool.c new file mode 100644 index 000000000..52584ec14 --- /dev/null +++ b/trunk/lib/libutil/mempool.c @@ -0,0 +1,98 @@ +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include + +#include "bool.h" +#include "girmath.h" +#include "mallocvar.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/util.h" + +struct _xmlrpc_mem_pool { + size_t size; + size_t allocated; +}; + + + +xmlrpc_mem_pool * +xmlrpc_mem_pool_new(xmlrpc_env * const envP, + size_t const size) { +/*---------------------------------------------------------------------------- + Create an xmlrpc_mem_pool of size 'size' bytes. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_pool * poolP; + + XMLRPC_ASSERT_ENV_OK(envP); + + MALLOCVAR(poolP); + + if (poolP == NULL) + xmlrpc_faultf(envP, "Can't allocate memory pool descriptor"); + else { + poolP->size = size; + + poolP->allocated = 0; + + if (envP->fault_occurred) + free(poolP); + } + return poolP; +} + + + +void +xmlrpc_mem_pool_free(xmlrpc_mem_pool * const poolP) { +/*---------------------------------------------------------------------------- + Destroy xmlrpc_mem_pool *poolP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(poolP != NULL); + + XMLRPC_ASSERT(poolP->allocated == 0); + + free(poolP); +} + + + +void +xmlrpc_mem_pool_alloc(xmlrpc_env * const envP, + xmlrpc_mem_pool * const poolP, + size_t const size) { +/*---------------------------------------------------------------------------- + Take 'size' bytes from pool *poolP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(poolP->allocated <= poolP->size); + + if (poolP->size - poolP->allocated < size) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_LIMIT_EXCEEDED_ERROR, + "Memory pool is out of memory. %u-byte pool is %u bytes short", + (unsigned)poolP->size, + (unsigned)(poolP->allocated + size - poolP->size)); + else + poolP->allocated += size; +} + + + +void +xmlrpc_mem_pool_release(xmlrpc_mem_pool * const poolP, + size_t const size) { +/*---------------------------------------------------------------------------- + Return 'size' bytes to pool *poolP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(poolP != NULL); + + XMLRPC_ASSERT(poolP->allocated >= size); + + poolP->allocated -= size; +} + + + diff --git a/trunk/lib/libutil/select.c b/trunk/lib/libutil/select.c new file mode 100644 index 000000000..01856adcb --- /dev/null +++ b/trunk/lib/libutil/select.c @@ -0,0 +1,62 @@ +#define _XOPEN_SOURCE 600 /* Get pselect() in */ + +#include "xmlrpc_config.h" + +#if MSVCRT +#include +#else +/* In some systems (SUS), the select() interface comes from ; + in others, from , and others from both. Including both + in this order appears to work on all. +*/ +#include +#if HAVE_SYS_SELECT_H +#include +#include /* For struct timespec on some systems */ +#endif +#endif +#include + +#include "xmlrpc-c/select_int.h" + + +/* xmlrpc_pselect() is just for use with sockets. In a POSIX system, + it technically works for any file descriptor, but in Windows, select() + is part of the socket facility. +*/ + +int +xmlrpc_pselect(int const n, + fd_set * const readfdsP, + fd_set * const writefdsP, + fd_set * const exceptfdsP, + const xmlrpc_timespec * const timeoutP, + sigset_t * const sigmaskP) { + + int retval; + +#if HAVE_PSELECT +#if !HAVE_TIMESPEC + #error "Impossible configuration -- has pselect(), but not struct timespec" +#else + retval = pselect(n, readfdsP, writefdsP, exceptfdsP, timeoutP, sigmaskP); +#endif +#else /* HAVE_PSELECT */ + struct timeval timeout; + + timeout.tv_sec = timeoutP->tv_sec; + timeout.tv_usec = timeoutP->tv_nsec/1000; +#if MSVCRT + retval = select(n, readfdsP, writefdsP, exceptfdsP, &timeout); +#else + { + sigset_t origmask; + sigprocmask(SIG_SETMASK, sigmaskP, &origmask); + retval = select(n, readfdsP, writefdsP, exceptfdsP, &timeout); + sigprocmask(SIG_SETMASK, &origmask, NULL); + } +#endif +#endif + + return retval; +} diff --git a/trunk/lib/libutil/sleep.c b/trunk/lib/libutil/sleep.c new file mode 100644 index 000000000..a708b1280 --- /dev/null +++ b/trunk/lib/libutil/sleep.c @@ -0,0 +1,23 @@ +#include "xmlrpc_config.h" +#include "bool.h" + +#include "xmlrpc-c/sleep_int.h" + +#if MSVCRT +# define WIN32_LEAN_AND_MEAN +# include +# include +#else +# include +#endif + + +void +xmlrpc_millisecond_sleep(unsigned int const milliseconds) { + +#if MSVCRT + SleepEx(milliseconds, true); +#else + usleep(milliseconds * 1000); +#endif +} diff --git a/trunk/lib/libutil/string_number.c b/trunk/lib/libutil/string_number.c new file mode 100644 index 000000000..1c284afdf --- /dev/null +++ b/trunk/lib/libutil/string_number.c @@ -0,0 +1,46 @@ +/*============================================================================ + string_number +============================================================================== + This file contains utilities for dealing with text string representation + of numbers. +============================================================================*/ +#include +#include +#include + +#include +#include +#include +#include "xmlrpc_config.h" +#include "int.h" + +#include + + + +void +xmlrpc_parse_int64(xmlrpc_env * const envP, + const char * const str, + xmlrpc_int64 * const i64P) { + + xmlrpc_int64 i64val; + + char * tail; + + errno = 0; + i64val = XMLRPC_STRTOLL(str, &tail, 10); + + if (errno == ERANGE) + xmlrpc_faultf(envP, "Number cannot be represented in 64 bits. " + "Must be in the range " + "[%" XMLRPC_PRId64 " - %" XMLRPC_PRId64 "]", + XMLRPC_INT64_MIN, XMLRPC_INT64_MAX); + else if (errno != 0) + xmlrpc_faultf(envP, "unexpected error: " + "strtoll() failed with errno %d (%s)", + errno, strerror(errno)); + else if (tail[0] != '\0') + xmlrpc_faultf(envP, "contains non-numerical junk: '%s'", tail); + else + *i64P = i64val; +} diff --git a/trunk/lib/libutil/time.c b/trunk/lib/libutil/time.c new file mode 100644 index 000000000..6eee1d458 --- /dev/null +++ b/trunk/lib/libutil/time.c @@ -0,0 +1,174 @@ +#include "xmlrpc_config.h" +#include +#include + +#if HAVE_GETTIMEOFDAY +# include +#endif + +#if MSVCRT +# define WIN32_LEAN_AND_MEAN +# include +#endif + +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/time_int.h" + + +/* A note about struct timeval and Windows: There is a 'struct + timeval' type in Windows, but it is just an argument to select(), + which is just part of the sockets interface. It's defined + identically to the POSIX type of the same name, but not meant for + general timekeeping as the POSIX type is. +*/ + +#if HAVE_GETTIMEOFDAY +static void +gettimeofdayPosix(xmlrpc_timespec * const todP) { + + struct timeval tv; + + gettimeofday(&tv, NULL); + + todP->tv_sec = tv.tv_sec; + todP->tv_nsec = tv.tv_usec * 1000; +} +#endif + + + +#if MSVCRT +static void +gettimeofdayWindows(xmlrpc_timespec * const todP) { + + __int64 const epochOffset = 116444736000000000ll; + /* Number of 100-nanosecond units between the beginning of the + Windows epoch (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970). + */ + FILETIME ft; + LARGE_INTEGER li; + __int64 t; + + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + t = (li.QuadPart - epochOffset) * 100; /* nanoseconds */ + todP->tv_sec = (long)(t / 1E9); + todP->tv_nsec = (long)(t - (__int64)todP->tv_sec * 1E9); +} +#endif + + + +void +xmlrpc_gettimeofday(xmlrpc_timespec * const todP) { + + assert(todP); + +#if HAVE_GETTIMEOFDAY + gettimeofdayPosix(todP); +#else +#if MSVCRT + gettimeofdayWindows(todP); +#else + #error "We don't know how to get the time of day on this system" +#endif +#endif /* HAVE_GETTIMEOFDAY */ +} + + + +static bool +isLeapYear(unsigned int const yearOfAd) { + + return + (yearOfAd % 4) == 0 && + ((yearOfAd % 100) != 0 || (yearOfAd % 400) == 0); +} + + + +void +xmlrpc_timegm(const struct tm * const tmP, + time_t * const timeValueP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + This does what GNU libc's timegm() does. +-----------------------------------------------------------------------------*/ + if (tmP->tm_year < 70 || + tmP->tm_mon > 11 || + tmP->tm_mon < 0 || + tmP->tm_mday > 31 || + tmP->tm_min > 60 || + tmP->tm_sec > 60 || + tmP->tm_hour > 24) { + + xmlrpc_asprintf(errorP, "Invalid time specification; a member " + "of struct tm is out of range"); + } else { + static unsigned int const monthDaysNonLeap[12] = + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + unsigned int totalDays; + unsigned int year; + unsigned int month; + + totalDays = 0; /* initial value */ + + for (year = 70; year < (unsigned int)tmP->tm_year; ++year) + totalDays += isLeapYear(1900 + year) ? 366 : 365; + + for (month = 0; month < (unsigned int)tmP->tm_mon; ++month) + totalDays += monthDaysNonLeap[month]; + + if (tmP->tm_mon > 1 && isLeapYear(1900 + tmP->tm_year)) + totalDays += 1; + + totalDays += tmP->tm_mday - 1; + + *errorP = NULL; + + *timeValueP = ((totalDays * 24 + + tmP->tm_hour) * 60 + + tmP->tm_min) * 60 + + tmP->tm_sec; + } +} + + + +void +xmlrpc_localtime(time_t const datetime, + struct tm * const tmP) { +/*---------------------------------------------------------------------------- + Convert datetime from standard to broken-down format in the local + time zone. + + For Windows, this is not thread-safe. If you run a version of Abyss + with multiple threads, you can get arbitrary results here. +-----------------------------------------------------------------------------*/ +#if HAVE_LOCALTIME_R + localtime_r(&datetime, tmP); +#else + *tmP = *localtime(&datetime); +#endif +} + + + +void +xmlrpc_gmtime(time_t const datetime, + struct tm * const resultP) { +/*---------------------------------------------------------------------------- + Convert datetime from standard to broken-down UTC format. + + For Windows, this is not thread-safe. If you run a version of Abyss + with multiple threads, you can get arbitrary results here. +-----------------------------------------------------------------------------*/ + +#if HAVE_GMTIME_R + gmtime_r(&datetime, resultP); +#else + *resultP = *gmtime(&datetime); +#endif +} diff --git a/trunk/lib/libutil/utf8.c b/trunk/lib/libutil/utf8.c new file mode 100644 index 000000000..7f749dc1b --- /dev/null +++ b/trunk/lib/libutil/utf8.c @@ -0,0 +1,608 @@ +/* Copyright (C) 2001 by Eric Kidd. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ + + +/*========================================================================= +** XML-RPC UTF-8 Utilities +**========================================================================= +** Routines for validating, encoding and decoding UTF-8 data. We try to +** be very, very strict about invalid UTF-8 data. +** +** All of the code in this file assumes that your machine represents +** wchar_t as a 16-bit (or wider) character containing UCS-2 data. If this +** assumption is incorrect, you may need to replace this file. +** +** For lots of information on Unicode and UTF-8 decoding, see: +** http://www.cl.cam.ac.uk/~mgk25/unicode.html +*/ + +#include +#include "int.h" + +#include "xmlrpc_config.h" +#include "bool.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/util_int.h" + +/*========================================================================= +** Tables and Constants +**========================================================================= +** We use a variety of tables and constants to help decode and validate +** UTF-8 data. +*/ + +static unsigned char utf8SeqLength[256] = { + + /* utf8SeqLength[B] is the number of bytes in a UTF-8 sequence that starts + with byte B. Except zero indicates an illegal initial byte. + + Fredrik Lundh's UTF-8 decoder Python 2.0 uses a similar table. But since + Python 2.0 has the icky CNRI license, I generated this table from scratch + and wrote my own decoder. + */ + + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 1 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 2 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 3 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 5 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 6 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 7 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* A */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* B */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* C */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + /* D */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + /* E */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + /* F */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0 +}; + +/* The minimum legal character value for a UTF-8 sequence of the given +** length. We have to check this to avoid accepting "overlong" UTF-8 +** sequences, which use more bytes than necessary to encode a given +** character. Such sequences are commonly used by evil people to bypass +** filters and security checks. This table is based on the UTF-8-test.txt +** file by Markus Kuhn . */ +static uint32_t const utf8_min_char_for_length[] = { + 0, /* Length 0: Not used (meaningless) */ + 0x0000, /* Length 1: Not used (special-cased) */ + 0x0080, /* Length 2 */ + 0x0800, /* Length 3 */ + 0x00010000, /* Length 4 */ + 0x00200000, /* Length 5 */ + 0x04000000 /* Length 6 */ +}; + +/* This is the maximum legal 16-byte (UCS-2) character. Again, this +** information is based on UTF-8-test.txt. */ +#define UCS2_MAX_LEGAL_CHARACTER (0xFFFD) + +/* First and last UTF-16 surrogate characters. These are *not* legal UCS-2 +** characters--they're used to code for UCS-4 characters when using +** UTF-16. They should never appear in decoded UTF-8 data! Again, these +** could hypothetically be used to bypass security measures on some machines. +** Based on UTF-8-test.txt. */ +#define UTF16_FIRST_SURROGATE (0xD800) +#define UTF16_LAST_SURROGATE (0xDFFF) + +/* Is the character 'c' a UTF-8 continuation character? */ +#define IS_CONTINUATION(c) (((c) & 0xC0) == 0x80) + +#define MAX_ENCODED_BYTES (3) + /* Maximum number of bytes needed to encode in UTF-8 a character + in the Basic Multilingual Plane. + */ + + +#if HAVE_UNICODE_WCHAR + + +static void +validateContinuation(xmlrpc_env * const envP, + char const c) { + + if (!IS_CONTINUATION(c)) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INVALID_UTF8_ERROR, + "UTF-8 multibyte sequence contains character 0x%02x, " + "which does not indicate continuation.", c); +} + + + +static void +validateUtf16(xmlrpc_env * const envP, + wchar_t const wc) { +/*---------------------------------------------------------------------------- + Validate that the string is a legal UTF16 encoding of a Unicode + character. + + Actually, we validate that it is UCS-2. The set of UCS-2 encodings is a + subset of the set of UTF16 encodings. In particular, it is the set of + UTF16 encodings that are 16 bits. UCS-2 is a fixed-length encoding, with + 16 bits per character, whereas UTF16 is variable length, with 1 or more 16 + bit units per character. + + The name of the subroutine reflects the fact that in concept, we _should_ + accept any UTF16, but we haven't taken the time yet to figure out how to do + that (in the big picture, not just this subroutine). The user will notice + only if he uses those really arcane 3.1% of the Unicode characters that + take more than 16 bits to represent in UTF16. +-----------------------------------------------------------------------------*/ + if (wc > UCS2_MAX_LEGAL_CHARACTER) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INVALID_UTF8_ERROR, + "Xmlrpc-c is not capable of handling UTF16 character encodings " + "longer than 16 bits, which means you can't have a code point " + "> U+FFFD. " + "This string contains 0x%04x", + (unsigned)wc); + else if (UTF16_FIRST_SURROGATE <= wc && wc <= UTF16_LAST_SURROGATE) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INVALID_UTF8_ERROR, + "UTF-16 surrogates may not appear in UTF-8 data. " + "String contains %04x", (unsigned)wc); +} + + + +/* Microsoft Visual C in debug mode produces code that complains about + returning an undefined value from xmlrpc_datetime_new_str(). It's a bogus + complaint, because this function is defined to return nothing meaningful + those cases. So we disable the check. +*/ +#pragma runtime_checks("u", off) + +static void +decodeMultibyte(xmlrpc_env * const envP, + const char * const utf8_seq, + size_t const length, + wchar_t * const wcP) { +/*---------------------------------------------------------------------------- + Decode the multibyte UTF-8 sequence which is 'length' characters + at 'utf8_data'. + + Return the character in UTF-16 format as *wcP. +-----------------------------------------------------------------------------*/ + wchar_t wc; + + assert(utf8_seq[0] & 0x80); /* High bit set: this is multibyte seq */ + + switch (length) { + case 2: + /* 110xxxxx 10xxxxxx */ + validateContinuation(envP, utf8_seq[1]); + + if (!envP->fault_occurred) + wc = ((((wchar_t) (utf8_seq[0] & 0x1F)) << 6) | + (((wchar_t) (utf8_seq[1] & 0x3F)))); + break; + + case 3: + /* 1110xxxx 10xxxxxx 10xxxxxx */ + validateContinuation(envP, utf8_seq[1]); + if (!envP->fault_occurred) { + validateContinuation(envP, utf8_seq[2]); + if (!envP->fault_occurred) + wc = ((((wchar_t) (utf8_seq[0] & 0x0F)) << 12) | + (((wchar_t) (utf8_seq[1] & 0x3F)) << 6) | + (((wchar_t) (utf8_seq[2] & 0x3F)))); + } + break; + + case 4: + /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + case 5: + /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + case 6: + /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + /* This would require more than 16 bits in UTF-16, so + it can't be represented in UCS-2, so it's beyond + our capability. Characters in the BMP fit in 16 + bits. + */ + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INVALID_UTF8_ERROR, + "UTF-8 string contains a character not in the " + "Basic Multilingual Plane (first byte 0x%02x)", + utf8_seq[0]); + break; + + default: + xmlrpc_faultf(envP, + "Internal error: Impossible UTF-8 sequence length %u", + (unsigned)length); + } + + if (!envP->fault_occurred) + validateUtf16(envP, wc); + + if (!envP->fault_occurred) + if ((uint32_t)wc < utf8_min_char_for_length[length]) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INVALID_UTF8_ERROR, + "Overlong UTF-8 sequence not allowed"); + + *wcP = wc; +} + +#pragma runtime_checks("u", restore) + + + +static void +decodeUtf8(xmlrpc_env * const envP, + const char * const utf8_data, + size_t const utf8_len, + wchar_t * const ioBuff, + size_t * const outBuffLenP) { +/*---------------------------------------------------------------------------- + Decode to UCS-2 (or validate as UTF-8 that can be decoded to UCS-2) + a UTF-8 string. To validate, set ioBuff and outBuffLenP to NULL. + To decode, allocate a sufficiently large buffer, pass it as ioBuff, + and pass a pointer as as outBuffLenP. The data will be written to + the buffer, and the length to outBuffLenP. + + We assume that wchar_t holds a single UCS-2 character in native-endian + byte ordering. +-----------------------------------------------------------------------------*/ + size_t utf8Cursor; + size_t outPos; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(utf8_data); + XMLRPC_ASSERT((!ioBuff && !outBuffLenP) || (ioBuff && outBuffLenP)); + + for (utf8Cursor = 0, outPos = 0; + utf8Cursor < utf8_len && !envP->fault_occurred; + ) { + + char const init = utf8_data[utf8Cursor]; + /* Initial byte of the UTF-8 sequence */ + + wchar_t wc; + + if ((init & 0x80) == 0x00) { + /* Convert ASCII character to wide character. */ + wc = init; + ++utf8Cursor; + } else { + /* Look up the length of this UTF-8 sequence. */ + size_t const length = utf8SeqLength[(unsigned char) init]; + /* Special value 0 means no length could be determined because + it is not a valid initial byte for a UTF-8 sequence. + */ + if (length == 0) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INVALID_UTF8_ERROR, + "Unrecognized UTF-8 initial byte value 0x%02x", + (unsigned char)init); + else { + /* Make sure we have enough bytes to convert. */ + if (utf8Cursor + length > utf8_len) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INVALID_UTF8_ERROR, + "Invalid UTF-8 sequence indicates a %u-byte sequence " + "when only %u bytes are left in the string", + (unsigned)length, (unsigned)(utf8_len - utf8Cursor)); + } else { + decodeMultibyte(envP, &utf8_data[utf8Cursor], length, &wc); + + /* Advance to the end of the sequence. */ + utf8Cursor += length; + } + } + } + + if (!envP->fault_occurred) { + /* If we have a buffer, write our character to it. */ + if (ioBuff) + ioBuff[outPos++] = wc; + } + } + + if (outBuffLenP) + *outBuffLenP = envP->fault_occurred ? 0 : outPos; +} + + + +xmlrpc_mem_block * +xmlrpc_utf8_to_wcs(xmlrpc_env * const envP, + const char * const utf8_data, + size_t const utf8_len) { +/*---------------------------------------------------------------------------- + Decode UTF-8 string to a "wide character string". This function + returns an xmlrpc_mem_block with an element type of wchar_t. Don't + try to intepret the block in a bytewise fashion--it won't work in + any useful or portable fashion. + + For backward compatibility, we return a meaningful value even when we + fail. We return NULL when we fail. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * wcsP; + size_t wcs_length; + + /* Allocate a memory block large enough to hold any possible output. + We assume that each byte of the input may decode to a whcar_t. + */ + wcsP = XMLRPC_MEMBLOCK_NEW(wchar_t, envP, utf8_len); + if (!envP->fault_occurred) { + /* Decode the UTF-8 data. */ + decodeUtf8(envP, utf8_data, utf8_len, + XMLRPC_MEMBLOCK_CONTENTS(wchar_t, wcsP), + &wcs_length); + if (!envP->fault_occurred) { + /* We can't have overrun our buffer. */ + XMLRPC_ASSERT(wcs_length <= utf8_len); + + /* Correct the length of the memory block. */ + XMLRPC_MEMBLOCK_RESIZE(wchar_t, envP, wcsP, wcs_length); + } + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(wchar_t, wcsP); + } + if (envP->fault_occurred) + return NULL; + else + return wcsP; +} + + + +xmlrpc_mem_block * +xmlrpc_wcs_to_utf8(xmlrpc_env * const envP, + const wchar_t * const wcs_data, + size_t const wcs_len) { +/*---------------------------------------------------------------------------- + Encode a "wide character string" as UTF-8. + + For backward compatibility, we return a meaningful value even when we + fail. We return NULL when we fail. +-----------------------------------------------------------------------------*/ + size_t const estimate = wcs_len * MAX_ENCODED_BYTES; + /* Our conservative estimate of how big the output will be; + i.e. we know it won't be larger than this. For the estimate, + we assume that every wchar might encode to the maximum length. + */ + xmlrpc_mem_block * utf8P; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(wcs_data); + + utf8P = XMLRPC_MEMBLOCK_NEW(char, envP, estimate); + if (!envP->fault_occurred) { + unsigned char * const buffer = + XMLRPC_MEMBLOCK_CONTENTS(unsigned char, utf8P); + size_t bytesUsed; + size_t i; + + bytesUsed = 0; + for (i = 0; i < wcs_len && !envP->fault_occurred; ++i) { + wchar_t const wc = wcs_data[i]; + if (wc <= 0x007F) + buffer[bytesUsed++] = wc & 0x7F; + else if (wc <= 0x07FF) { + /* 110xxxxx 10xxxxxx */ + buffer[bytesUsed++] = 0xC0 | (wc >> 6); + buffer[bytesUsed++] = 0x80 | (wc & 0x3F); + } else if (wc <= 0xFFFF) { + /* 1110xxxx 10xxxxxx 10xxxxxx */ + buffer[bytesUsed++] = 0xE0 | (wc >> 12); + buffer[bytesUsed++] = 0x80 | ((wc >> 6) & 0x3F); + buffer[bytesUsed++] = 0x80 | (wc & 0x3F); + } else + xmlrpc_faultf(envP, + "Don't know how to encode UCS-4 characters yet"); + } + if (!envP->fault_occurred) { + XMLRPC_ASSERT(bytesUsed <= estimate); + + XMLRPC_MEMBLOCK_RESIZE(char, envP, utf8P, bytesUsed); + } + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, utf8P); + } + + if (envP->fault_occurred) + return NULL; + else + return utf8P; +} + + + +#else /* HAVE_UNICODE_WCHAR */ + +xmlrpc_mem_block * +xmlrpc_utf8_to_wcs(xmlrpc_env * const envP, + const char * const utf8_data ATTR_UNUSED, + size_t const utf8_len ATTR_UNUSED) { + + xmlrpc_faultf(envP, "INTERNAL ERROR: xmlrpc_utf8_to_wcs() called " + "on a system that doesn't do Unicode!"); + + return NULL; +} +#endif /* HAVE_UNICODE_WCHAR */ + + +void +xmlrpc_force_to_utf8(char * const buffer) { +/*---------------------------------------------------------------------------- + Force the contents of 'buffer' to be valid UTF-8, any way possible. + The buffer ends with a NUL character, and the mutation does not make + it longer. + + The most common reason for a string that's supposed to be UTF-8 not to be + UTF-8 is that it was supposed to be ASCII but instead includes garbage with + the high bit on (ASCII characters always have the high bit off), or maybe a + primitive 8-bit ASCII extension such as Latin1 (ISO 8859-1). Therefore, + we force it to UTF-8 by replacing some bytes that have the high bit set + with DEL (0x7F). That would leave the other characters meaningful. + + I've heard a standard way to do this is to substitute the Unicode character + U+FFFD for the garbage. But that makes it harder to keep the length of + the code the same, and in the case that the originator of these bits + wasn't thinking UTF-8 at all, it does more violence to the string than + our DEL method. +-----------------------------------------------------------------------------*/ + char * p; + + for (p = &buffer[0]; *p;) { + unsigned int const length = utf8SeqLength[(unsigned char) *p]; + + bool forceDel; + uint32_t decoded; + + forceDel = false; /* initial value */ + + switch (length) { + case 1: + /* One-byte UTF-8 characters are easy. */ + decoded = *p; + break; + case 2: + /* 110xxxxx 10xxxxxx */ + if (!*(p+1) || !(*p+2)) + forceDel = true; + else if (!IS_CONTINUATION(*(p+1))) + forceDel = true; + else + decoded = + ((uint32_t)(*(p+0) & 0x1F) << 6) | + ((uint32_t)(*(p+1) & 0x3F) << 0); + break; + case 3: + /* 1110xxxx 10xxxxxx 10xxxxxx */ + if (!*(p+1) || !(*p+2) || !(*p+3)) + forceDel = true; + else if (!IS_CONTINUATION(*(p+1)) || !IS_CONTINUATION(*(p+2))) + forceDel = true; + else + decoded = + ((uint32_t)(*(p+0) & 0x0F) << 12) | + ((uint32_t)(*(p+1) & 0x3F) << 6) | + ((uint32_t)(*(p+2) & 0x3F) << 0); + break; + default: + forceDel = true; + } + + if (!forceDel) { + if (decoded > UCS2_MAX_LEGAL_CHARACTER) + forceDel = true; + else if (UTF16_FIRST_SURROGATE <= decoded && + decoded <= UTF16_LAST_SURROGATE) + forceDel = true; + else if (decoded < utf8_min_char_for_length[length]) + forceDel = true; + } + + if (forceDel) { + /* Not a valid UTF-8 character, so replace the first byte + with a nice simple ASCII DEL. + */ + *p = 0x7F; + p += 1; + } else + p += length; + } +} + + + +void +xmlrpc_force_to_xml_chars(char * const buffer) { +/*---------------------------------------------------------------------------- + Modify 'buffer' so that it contains nothing but valid XML + characters. The buffer ends with a NUL character, and the mutation + does not make it longer. + + Note that the valid characters in an XML document are all Unicode + codepoints except the ASCII control characters, plus CR, LF, and + Tab. + + We change all non-XML characters to DEL (0x7F). + + Assume input is valid UTF-8. +-----------------------------------------------------------------------------*/ + char * p; + + for (p = &buffer[0]; *p;) { + unsigned int const length = utf8SeqLength[(unsigned char) *p]; + + if (length == 1) { + if (*p < 0x20 && *p != '\r' && *p != '\n' && *p != '\t') + /* Not valid XML. Force to DEL */ + *p = 0x7f; + } else { + /* We assume here that all other UTF-8 characters are + valid XML, but it's apparently not actually true. + */ + } + + { + unsigned int i; + /* Advance to next UTF-8 character */ + for (i = 0; i < length && *p; ++i) + ++p; + } + } +} + + + +void +xmlrpc_validate_utf8(xmlrpc_env * const envP, + const char * const utf8_data, + size_t const utf8_len) { +/*---------------------------------------------------------------------------- + Validate that a string is valid UTF-8. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + + xmlrpc_env_init(&env); + +#if HAVE_UNICODE_WCHAR + decodeUtf8(&env, utf8_data, utf8_len, NULL, NULL); +#else + /* We don't have a convenient way to validate, so we just fake it and + call it valid. + */ +#endif + + if (env.fault_occurred) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INVALID_UTF8_ERROR, + "%" XMLRPC_PRId64 "-byte " + "supposed UTF-8 string is not valid UTF-8. %s", + (XMLRPC_INT64)utf8_len, env.fault_string); + } + xmlrpc_env_clean(&env); +} diff --git a/trunk/lib/libwww_transport/Makefile b/trunk/lib/libwww_transport/Makefile new file mode 100644 index 000000000..ed5c0aa69 --- /dev/null +++ b/trunk/lib/libwww_transport/Makefile @@ -0,0 +1,64 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + LIBDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/libwww_transport + +include $(BLDDIR)/config.mk + +default: all + +.PHONY: all +all: xmlrpc_libwww_transport.o xmlrpc_libwww_transport.osh + +# Rules for the above dependencies are in common.mk, +# courtesy of TARGET_MODS. + +TARGET_MODS = xmlrpc_libwww_transport + +OMIT_LIBWWW_TRANSPORT_RULE=Y + +include $(SRCDIR)/common.mk + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +LIBWWW_INCLUDES := $(shell libwww-config --cflags) + +INCLUDES = \ + -I$(BLDDIR) \ + -I$(BLDDIR)/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include \ + $(LIBWWW_INCLUDES) + +.PHONY: clean +clean: clean-common + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: tags +tags: TAGS + +.PHONY: distdir +distdir: + +.PHONY: install +install: + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: dep +dep: dep-common + +include depend.mk + +# Need this dependency for those who don't use depend.mk. +# Without it, version.h doesn't get created. +xmlrpc_libwww_transport.o xmlrpc_libwww_transport.osh: version.h diff --git a/trunk/lib/libwww_transport/xmlrpc_libwww_transport.c b/trunk/lib/libwww_transport/xmlrpc_libwww_transport.c new file mode 100644 index 000000000..c5594f915 --- /dev/null +++ b/trunk/lib/libwww_transport/xmlrpc_libwww_transport.c @@ -0,0 +1,956 @@ +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ + +#include "xmlrpc_config.h" + +#include + +#include "bool.h" +#include "mallocvar.h" + +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/client_int.h" +#include "xmlrpc-c/transport.h" + +/* The libwww interface */ + +/* These headers mistakenly define the macro PACKAGE. As + xmlrpc_config.h already defines PACKAGE according to the package we're + actually part of, this causes a conflict. So we undef here and then + to avoid possible problems with an incorrect PACKAGE, we undef it again + after. +*/ +#undef PACKAGE +#include "WWWLib.h" +#include "WWWHTTP.h" +#include "WWWInit.h" +#undef PACKAGE + +/* Include our libwww SSL headers, if available. */ +#if HAVE_LIBWWW_SSL +#include "WWWSSL.h" +#endif + +/* This value was discovered by Rick Blair. His efforts shaved two seconds +** off of every request processed. Many thanks. */ +#define SMALLEST_LEGAL_LIBWWW_TIMEOUT (21) + +#define XMLRPC_CLIENT_USE_TIMEOUT (2) + + +struct xmlrpc_client_transport { + int saved_flags; + HTList *xmlrpc_conversions; + void * cookieJarP; + /* This is a collection of all the cookies that servers have set + via responses to prior requests. It's not implemented today. + */ + bool tracingOn; +}; + +static struct xmlrpc_client_transport clientTransport; + + +typedef struct { +/*---------------------------------------------------------------------------- + This object represents one RPC. +-----------------------------------------------------------------------------*/ + struct xmlrpc_client_transport * clientTransportP; + + /* These fields are used when performing synchronous calls. */ + bool is_done; + int http_status; + + /* Low-level information used by libwww. */ + HTRequest * request; + HTChunk * response_data; + HTParentAnchor * source_anchor; + HTAnchor * dest_anchor; + + xmlrpc_transport_asynch_complete complete; + struct xmlrpc_call_info * callInfoP; +} rpc; + + + +static void +createCookieJar(xmlrpc_env * const envP ATTR_UNUSED, + void ** const cookieJarP ATTR_UNUSED) { + + /* Cookies not implemented yet */ +} + + + +static void +destroyCookieJar(void * cookieJarP ATTR_UNUSED) { + + /* Cookies not implemented yet */ +} + + + +static void +initLibwww(const char * const appname, + const char * const appversion) { + + /* We initialize the library using a robot profile, because we don't + care about redirects or HTTP authentication, and we want to + reduce our application footprint as much as possible. + + This takes the place of HTLibInit(). + */ + HTProfile_newRobot(appname, appversion); + + /* Ilya Goldberg provided the following code to access + ** SSL-protected servers. */ +#if HAVE_LIBWWW_SSL + /* Set the SSL protocol method. By default, it is the highest + ** available protocol. Setting it up to SSL_V23 allows the client + ** to negotiate with the server and set up either TSLv1, SSLv3, + ** or SSLv2 */ + HTSSL_protMethod_set(HTSSL_V23); + + /* Set the certificate verification depth to 2 in order to be able to + ** validate self-signed certificates */ + HTSSL_verifyDepth_set(2); + + /* Register SSL stuff for handling ssl access. The parameter we pass + ** is NO because we can't be pre-emptive with POST */ + HTSSLhttps_init(NO); +#endif /* HAVE_LIBWWW_SSL */ + + /* For interoperability with Frontier, we need to tell libwww *not* + ** to send 'Expect: 100-continue' headers. But if we're not sending + ** these, we shouldn't wait for them. So set our built-in delays to + ** the smallest legal values. */ + HTTP_setBodyWriteDelay (SMALLEST_LEGAL_LIBWWW_TIMEOUT, + SMALLEST_LEGAL_LIBWWW_TIMEOUT); + + /* We attempt to disable all of libwww's chatty, interactive + ** prompts. Let's hope this works. */ + HTAlert_setInteractive(NO); + + /* Here are some alternate setup calls which will help greatly + ** with debugging, should the need arise. + ** + ** HTProfile_newNoCacheClient(appname, appversion); + ** HTAlert_setInteractive(YES); + ** HTPrint_setCallback(printer); + ** HTTrace_setCallback(tracer); */ +} + + + +static void +create(xmlrpc_env * const envP, + int const flags, + const char * const appname, + const char * const appversion, + const void * const transportParmsP ATTR_UNUSED, + size_t const parm_size ATTR_UNUSED, + struct xmlrpc_client_transport ** const handlePP) { +/*---------------------------------------------------------------------------- + This does the 'create' operation for a Libwww client transport. + + TODO: put 'appname' and 'appversion' in *transportParmsP and + deprecate the create() arguments. Reason: these are particular to + the Libwww transport. They're create() arguments because originally, + Libwww was the only transport. +-----------------------------------------------------------------------------*/ + /* The Libwww transport is not re-entrant -- you can have only one + per program instance. Even if we changed the Xmlrpc-c code not + to use global variables, that wouldn't help because Libwww + itself is not re-entrant. + + So we use a global variable ('clientTransport') for our transport state. + */ + struct xmlrpc_client_transport * const clientTransportP = &clientTransport; + *handlePP = clientTransportP; + + clientTransportP->saved_flags = flags; + + createCookieJar(envP, &clientTransportP->cookieJarP); + if (!envP->fault_occurred) { + if (!(clientTransportP->saved_flags & + XMLRPC_CLIENT_SKIP_LIBWWW_INIT)) + initLibwww(appname, appversion); + + /* Set up our list of conversions for XML-RPC requests. This is a + ** massively stripped-down version of the list in libwww's HTInit.c. + ** XXX - This is hackish; 10.0 is an arbitrary, large quality factor + ** designed to override the built-in converter for XML. */ + clientTransportP->xmlrpc_conversions = HTList_new(); + HTConversion_add(clientTransportP->xmlrpc_conversions, + "text/xml", "*/*", + HTThroughLine, 10.0, 0.0, 0.0); + + if (envP->fault_occurred) + destroyCookieJar(clientTransportP->cookieJarP); + } + if (getenv("XMLRPC_LIBWWW_TRACE")) + clientTransportP->tracingOn = TRUE; + else + clientTransportP->tracingOn = FALSE; +} + + + +static void +destroy(struct xmlrpc_client_transport * const clientTransportP) { +/*---------------------------------------------------------------------------- + This does the 'destroy' operation for a Libwww client transport. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(clientTransportP != NULL); + + if (!(clientTransportP->saved_flags & XMLRPC_CLIENT_SKIP_LIBWWW_INIT)) { + HTProfile_delete(); + /* This takes the place of HTLibTerminate() */ + } + destroyCookieJar(clientTransportP->cookieJarP); + HTConversion_deleteAll(clientTransportP->xmlrpc_conversions); + HTProfile_delete(); +} + + + +/*========================================================================= +** HTTP Error Reporting +**=======================================================================*/ + +static void +formatLibwwwError(HTRequest * const requestP, + const char ** const msgP) { +/*---------------------------------------------------------------------------- + When something fails in a Libwww request, Libwww generates a stack + of error information (precious little information, of course, in the + Unix tradition) and attaches it to the request object. We make a message + out of that information. + + We rely on Libwww's HTDialog_errorMessage() to do the bulk of the + formatting; we might be able to coax more information out of the request + if we interpreted the error stack directly. +-----------------------------------------------------------------------------*/ + HTList * const errStack = HTRequest_error(requestP); + + if (errStack == NULL) + xmlrpc_asprintf(msgP, "Libwww supplied no error details"); + else { + /* Get an error message from libwww. The middle three + parameters to HTDialog_errorMessage appear to be ignored. + XXX - The documentation for this API is terrible, so we may + be using it incorrectly. + */ + const char * const msg = + HTDialog_errorMessage(requestP, HT_A_MESSAGE, HT_MSG_NULL, + "An error occurred", errStack); + + if (msg == NULL) + xmlrpc_asprintf(msgP, "Libwww supplied some error detail, " + "but its HTDialog_errorMessage() subroutine " + "mysteriously failed to interpret it for us."); + else + *msgP = msg; + } +} + + + +static void +set_fault_from_http_request(xmlrpc_env * const envP, + int const status, + HTRequest * const requestP) { +/*---------------------------------------------------------------------------- + Assuming 'requestP' identifies a completed libwww HTTP request, set + *envP according to its success/error status. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_PTR_OK(requestP); + + if (status == 200) { + /* No error. Don't set one in *envP */ + } else { + const char * libwwwMsg; + formatLibwwwError(requestP, &libwwwMsg); + + if (status == -1) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_NETWORK_ERROR, + "Unable to complete the HTTP request. %s", libwwwMsg); + else { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_NETWORK_ERROR, + "HTTP request completed with HTTp error %d. %s", + status, libwwwMsg); + } + xmlrpc_strfree(libwwwMsg); + } +} + + + +static BOOL +setCookie(HTRequest * const request, + HTCookie * const cookieP ATTR_UNUSED, + void * const param ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + This is the callback from libwww to tell us the server (according to + its response) wants us to store a cookie (and include it in future + requests). + + We assume that the cookies "domain" is the server's host name + (there are options on the libwww connection to make libwww call this + callback only when that's the case). +-----------------------------------------------------------------------------*/ + rpc * const rpcP = HTRequest_context(request); + struct xmlrpc_client_transport * const clientTransportP = + rpcP->clientTransportP; + + BOOL retval; + + /* Avoid unused variable warning */ + if (clientTransportP->cookieJarP == clientTransportP->cookieJarP) {} + /* Cookies are not implemented today */ + retval = NO; + + return retval; +} + + + +static HTAssocList * +cookiesForHost(const char * const host ATTR_UNUSED, + void * const cookieJarP ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + Find and return all the cookies in jar 'cookieJarP' that are for the + host 'host'. +-----------------------------------------------------------------------------*/ + HTAssocList * hisCookiesP; + + hisCookiesP = HTAssocList_new(); + + if (hisCookiesP) { + /* Cookies are not implemented yet */ + /* Library/Examples/cookie.c in the w3c-libwww source tree contains + an example of constructing the cookie list we are supposed to + return. But today, we return an empty list. + */ + } + return hisCookiesP; +} + + + +static HTAssocList * +findCookie(HTRequest * const request, + void * const param ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + This is the callback from libwww to get the cookies to include in a + request (presumably values the server set via a prior response). +-----------------------------------------------------------------------------*/ + rpc * const rpcP = HTRequest_context(request); + struct xmlrpc_client_transport * const clientTransportP = + rpcP->clientTransportP; + const char * const addr = + HTAnchor_address((HTAnchor *) HTRequest_anchor(request)); + const char * const host = HTParse(addr, "", PARSE_HOST); + + return cookiesForHost(host, clientTransportP->cookieJarP); +} + + + +static void +deleteSourceAnchor(HTParentAnchor * const anchor) { + + /* We need to clear the document first, or else libwww won't + ** really delete the anchor. */ + HTAnchor_setDocument(anchor, NULL); + + /* XXX - Deleting this anchor causes HTLibTerminate to dump core. */ + /* HTAnchor_delete(anchor); */ +} + + + +static void +createSourceAnchor(xmlrpc_env * const envP, + HTParentAnchor ** const sourceAnchorPP, + xmlrpc_mem_block * const xmlP) { + + HTParentAnchor * const sourceAnchorP = HTTmpAnchor(NULL); + + if (sourceAnchorP == NULL) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INTERNAL_ERROR, + "Unable to build source anchor. HTTmpAnchor() failed."); + else { + HTAnchor_setDocument(sourceAnchorP, + XMLRPC_MEMBLOCK_CONTENTS(char, xmlP)); + HTAnchor_setFormat(sourceAnchorP, HTAtom_for("text/xml")); + HTAnchor_setLength(sourceAnchorP, XMLRPC_MEMBLOCK_SIZE(char, xmlP)); + + *sourceAnchorPP = sourceAnchorP; + } +} + + + +static void +createDestAnchor(xmlrpc_env * const envP, + HTAnchor ** const destAnchorPP, + const xmlrpc_server_info * const serverP) { + + *destAnchorPP = HTAnchor_findAddress(serverP->serverUrl); + + if (*destAnchorPP == NULL) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INTERNAL_ERROR, + "Could not build destination anchor. HTAnchor_findAddress() " + "failed."); +} + + + +static void +rpcCreate(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, + rpc ** const rpcPP) { + + rpc *rpcP; + HTRqHd request_headers; + HTStream *target_stream; + + /* Allocate our structure. */ + MALLOCVAR(rpcP); + XMLRPC_FAIL_IF_NULL(rpcP, envP, XMLRPC_INTERNAL_ERROR, + "Out of memory in rpcCreate()"); + + /* Set up our basic members. */ + rpcP->clientTransportP = clientTransportP; + rpcP->is_done = FALSE; + rpcP->http_status = 0; + rpcP->complete = complete; + rpcP->callInfoP = callInfoP; + + /* Start cookie handler. */ + HTCookie_init(); + HTCookie_setCallbacks(setCookie, NULL, findCookie, NULL); + HTCookie_setCookieMode(HT_COOKIE_ACCEPT | + HT_COOKIE_SEND | + HT_COOKIE_SAME_HOST); + + /* Cookies aren't implemented today; reset. */ + HTCookie_setCookieMode(0); + + /* Create a HTRequest object. */ + rpcP->request = HTRequest_new(); + XMLRPC_FAIL_IF_NULL(rpcP, envP, XMLRPC_INTERNAL_ERROR, + "HTRequest_new failed"); + + /* Install ourselves as the request context. */ + HTRequest_setContext(rpcP->request, rpcP); + + /* XXX - Disable the 'Expect:' header so we can talk to Frontier. */ + request_headers = HTRequest_rqHd(rpcP->request); + request_headers = request_headers & ~HT_C_EXPECT; + HTRequest_setRqHd(rpcP->request, request_headers); + + /* Send an authorization header if we need one. */ + if (serverP->allowedAuth.basic) + HTRequest_addCredentials(rpcP->request, "Authorization", + (char *)serverP->basicAuthHdrValue); + + /* Make sure there is no XML conversion handler to steal our data. + ** The 'override' parameter is currently ignored by libwww, so our + ** list of conversions must be designed to co-exist with the built-in + ** conversions. */ + HTRequest_setConversion(rpcP->request, + clientTransportP->xmlrpc_conversions, NO); + + /* Set up our response buffer. */ + target_stream = HTStreamToChunk(rpcP->request, &rpcP->response_data, 0); + XMLRPC_FAIL_IF_NULL(rpcP->response_data, envP, XMLRPC_INTERNAL_ERROR, + "HTStreamToChunk failed"); + XMLRPC_ASSERT(target_stream != NULL); + HTRequest_setOutputStream(rpcP->request, target_stream); + HTRequest_setOutputFormat(rpcP->request, WWW_SOURCE); + + createSourceAnchor(envP, &rpcP->source_anchor, xmlP); + + if (!envP->fault_occurred) { + createDestAnchor(envP, &rpcP->dest_anchor, serverP); + + if (envP->fault_occurred) + /* See below for comments about deleting the source and dest + ** anchors. This is a bit of a black art. */ + deleteSourceAnchor(rpcP->source_anchor); + } + + cleanup: + if (envP->fault_occurred) { + if (rpcP) { + if (rpcP->request) + HTRequest_delete(rpcP->request); + if (rpcP->response_data) + HTChunk_delete(rpcP->response_data); + free(rpcP); + } + } + *rpcPP = rpcP; +} + + + +static void +rpcDestroy(rpc * const rpcP) { + + XMLRPC_ASSERT_PTR_OK(rpcP); + XMLRPC_ASSERT(rpcP->request != NULL); + XMLRPC_ASSERT(rpcP->response_data != NULL); + + /* Junji Kanemaru reports on 05.04.11 that with asynch calls, he + get a segfault, and reversing the order of deleting the request + and the response chunk buffer cured it. But we find no reason + that should be so, so we're waiting for someone to arrive at an + explanation before changing anything. HTRequest_delete() does + destroy the output stream, and the output stream refers to the + response chunk, but HTRequest_delete() explicitly refrains from + destroying the response chunk. And the response chunk does not + refer to the request. + */ + + HTRequest_delete(rpcP->request); + rpcP->request = NULL; + HTChunk_delete(rpcP->response_data); + rpcP->response_data = NULL; + + /* This anchor points to private data, so we're allowed to delete it. */ + deleteSourceAnchor(rpcP->source_anchor); + + /* WARNING: We can't delete the destination anchor, because this points + ** to something in the outside world, and lives in a libwww hash table. + ** Under certain circumstances, this anchor may have been reissued to + ** somebody else. So over time, the anchor cache will grow. If this + ** is a problem for your application, read the documentation for + ** HTAnchor_deleteAll. + ** + ** However, we CAN check to make sure that no documents have been + ** attached to the anchor. This assertion may fail if you're using + ** libwww for something else, so please feel free to comment it out. */ + /* XMLRPC_ASSERT(HTAnchor_document(rpcP->dest_anchor) == NULL); + */ + + HTCookie_deleteCallbacks(); + HTCookie_terminate(); + + free(rpcP); +} + + + +static void +extract_response_chunk(xmlrpc_env * const envP, + rpc * const rpcP, + xmlrpc_mem_block ** const responseXmlPP) { + + /* Implementation warning: A Libwww chunk has nothing to do with + an HTTP chunk. HTTP chunks (as in a chunked response) are not + visible to us; Libwww delivers the entire unchunked body to us + at once (we never see chunk headers and trailers). This + subroutine is about a Libwww chunk, which is just a memory + buffer. (Libwww is capable of delivering the response in a + number of ways other than a chunk, e.g. it can write it to a + file. + */ + + /* Check to make sure that w3c-libwww actually sent us some data. + ** XXX - This may happen if libwww is shut down prematurely, believe it + ** or not--we'll get a 200 OK and no data. Gag me with a bogus design + ** decision. This may also fail if some naughty libwww converter + ** ate our data unexpectedly. */ + if (!HTChunk_data(rpcP->response_data)) + xmlrpc_env_set_fault(envP, XMLRPC_NETWORK_ERROR, + "w3c-libwww returned no data"); + else { + *responseXmlPP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + if (!envP->fault_occurred) { + if (rpcP->clientTransportP->tracingOn) { + fprintf(stderr, "HTTP chunk received: %u bytes: '%.*s'", + HTChunk_size(rpcP->response_data), + HTChunk_size(rpcP->response_data), + HTChunk_data(rpcP->response_data)); + } + + XMLRPC_MEMBLOCK_APPEND(char, envP, *responseXmlPP, + HTChunk_data(rpcP->response_data), + HTChunk_size(rpcP->response_data)); + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, *responseXmlPP); + } + } +} + + + +static int +synch_terminate_handler(HTRequest * const request, + HTResponse * const response ATTR_UNUSED, + void * const param ATTR_UNUSED, + int const status) { +/*---------------------------------------------------------------------------- + This is a libwww request completion handler. + + HTEventList_newLoop() calls this when it completes a request (with this + registered as the completion handler). +-----------------------------------------------------------------------------*/ + rpc *rpcP; + + rpcP = HTRequest_context(request); + + rpcP->is_done = TRUE; + rpcP->http_status = status; + + HTEventList_stopLoop(); + + return HT_OK; +} + + + +static void +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) { +/*---------------------------------------------------------------------------- + This does the 'call' operation for a Libwww client transport. +-----------------------------------------------------------------------------*/ + rpc * rpcP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(serverP); + XMLRPC_ASSERT_PTR_OK(xmlP); + XMLRPC_ASSERT_PTR_OK(responsePP); + + rpcCreate(envP, clientTransportP, serverP, xmlP, NULL, NULL, &rpcP); + if (!envP->fault_occurred) { + int ok; + + /* Install our request handler. */ + HTRequest_addAfter(rpcP->request, &synch_terminate_handler, + NULL, NULL, HT_ALL, HT_FILTER_LAST, NO); + + /* Start our request running. */ + ok = HTPostAnchor(rpcP->source_anchor, + rpcP->dest_anchor, + rpcP->request); + if (!ok) + xmlrpc_env_set_fault( + envP, XMLRPC_NETWORK_ERROR, + "Libwww HTPostAnchor() failed to start POST request"); + else { + /* Run our event-processing loop. HTEventList_newLoop() + is what calls synch_terminate_handler(), by virtue of + it being registered as a handler. It may return for + other reasons than the request being complete, though. + so we call it in a loop until synch_terminate_handler() + really has been called. + */ + while (!rpcP->is_done) + HTEventList_newLoop(); + + /* Fail if we didn't get a "200 OK" response from the server */ + if (rpcP->http_status != 200) + set_fault_from_http_request( + envP, rpcP->http_status, + rpcP->request); + else { + /* XXX - Check to make sure response type is text/xml here. */ + + extract_response_chunk(envP, rpcP, responsePP); + } + } + rpcDestroy(rpcP); + } +} + + + +/*========================================================================= +** Event Loop +**========================================================================= +** We manage a fair bit of internal state about our event loop. This is +** needed to determine when (and if) we should exit the loop. +*/ + +static int outstanding_asynch_calls = 0; +static int event_loop_flags = 0; +static int timer_called = 0; + +static void +register_asynch_call(void) { + XMLRPC_ASSERT(outstanding_asynch_calls >= 0); + ++outstanding_asynch_calls; +} + + + +static void +unregister_asynch_call(void) { + + XMLRPC_ASSERT(outstanding_asynch_calls > 0); + --outstanding_asynch_calls; + if (outstanding_asynch_calls == 0) + HTEventList_stopLoop(); +} + + + +static int +timer_callback(HTTimer * const timer ATTR_UNUSED, + void * const user_data ATTR_UNUSED, + HTEventType const event ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + A handy timer callback which cancels the running event loop. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(event == HTEvent_TIMEOUT); + timer_called = 1; + HTEventList_stopLoop(); + + /* XXX - The meaning of this return value is undocumented, but close + ** inspection of libwww's source suggests that we want to return HT_OK. */ + return HT_OK; +} + + + +static void +eventLoopRun(int const flags, + xmlrpc_timeout const milliseconds) { +/*---------------------------------------------------------------------------- + Process all responses from outstanding requests as they come in. + Return when there are no more outstanding responses. + + Or, if 'flags' has the XMLRPC_CLIENT_USE_TIMEOUT flag set, return + when 'milliseconds' milliseconds have elapsed, regardless of whether + there are still outstanding responses. + + The processing we do consists of telling libwww to process the + completion of the libwww request. That normally includes calling + the xmlrpc_libwww_transport request termination handler, because + the submitter of the libwww request would have registered that as a + callback. +-----------------------------------------------------------------------------*/ + if (outstanding_asynch_calls > 0) { + HTTimer *timer; + + event_loop_flags = flags; + + /* Run an appropriate event loop. The HTEeventList_newLoop() + is what calls asynch_terminate_handler(), by virtue of it + being registered as a handler. + */ + if (event_loop_flags & XMLRPC_CLIENT_USE_TIMEOUT) { + + /* Run our event loop with a timer. Note that we need to be very + ** careful about race conditions--timers can be fired in either + ** HTimer_new or HTEventList_newLoop. And if our callback were to + ** get called before we entered the loop, we would never exit. + ** So we use a private flag of our own--we can't even rely on + ** HTTimer_hasTimerExpired, because that only checks the time, + ** not whether our callback has been run. Yuck. */ + timer_called = 0; + timer = HTTimer_new(NULL, &timer_callback, NULL, + milliseconds, YES, NO); + XMLRPC_ASSERT(timer != NULL); + if (!timer_called) + HTEventList_newLoop(); + HTTimer_delete(timer); + + } else { + /* Run our event loop without a timer. */ + HTEventList_newLoop(); + } + + /* Reset our flags, so we don't interfere with direct calls to the + ** libwww event loop functions. */ + event_loop_flags = 0; + } else { + /* There are *no* calls to process. This may mean that none + of the asynch calls were ever set up, and the client's + callbacks have already been called with an error, or that + all outstanding calls were completed during a previous + synchronous call. + */ + } +} + + + +static void +finishAsynch( + struct xmlrpc_client_transport * const clientTransportP ATTR_UNUSED, + xmlrpc_timeoutType const timeoutType, + xmlrpc_timeout const timeout) { +/*---------------------------------------------------------------------------- + This does the 'finish_asynch' operation for a Libwww client transport. +-----------------------------------------------------------------------------*/ + eventLoopRun(timeoutType == timeout_yes ? XMLRPC_CLIENT_USE_TIMEOUT : 0, + timeout); +} + + + +static int +asynch_terminate_handler(HTRequest * const request, + HTResponse * const response ATTR_UNUSED, + void * const param ATTR_UNUSED, + int const status) { +/*---------------------------------------------------------------------------- + Handle the completion of a libwww request. + + This is the bottom half of the xmlrpc_libwww_transport asynchronous + call dispatcher. It's what the dispatcher registers with libwww as + a "local after filter" so that libwww calls it when a request that + xmlrpc_libwww_transport submitted to it is complete. + + We destroy the RPC, including the request which is our argument. + Strange as that may seem, it is apparently legal for an after filter + to destroy the request that was passed to it -- or not. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + rpc * rpcP; + xmlrpc_mem_block * responseXmlP; + + XMLRPC_ASSERT_PTR_OK(request); + + xmlrpc_env_init(&env); + + rpcP = HTRequest_context(request); + + /* Unregister this call from the event loop. Among other things, this + ** may decide to stop the event loop. + **/ + unregister_asynch_call(); + + /* Give up if an error occurred. */ + if (status != 200) + set_fault_from_http_request(&env, status, request); + else { + /* XXX - Check to make sure response type is text/xml here. */ + extract_response_chunk(&env, rpcP, &responseXmlP); + } + rpcP->complete(rpcP->callInfoP, responseXmlP, env); + + if (!env.fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, responseXmlP); + + rpcDestroy(rpcP); + + xmlrpc_env_clean(&env); + return HT_OK; +} + + + +static void +sendRequest(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, + xmlrpc_transport_progress progress ATTR_UNUSED, + struct xmlrpc_call_info * const callInfoP) { +/*---------------------------------------------------------------------------- + Initiate an XML-RPC rpc asynchronously. Don't wait for it to go to + the server. + + Unless we return failure, we arrange to have complete() called when + the rpc completes. + + This does the 'send_request' operation for a Libwww client transport. +-----------------------------------------------------------------------------*/ + rpc * rpcP; + + XMLRPC_ASSERT_PTR_OK(envP); + XMLRPC_ASSERT_PTR_OK(serverP); + XMLRPC_ASSERT_PTR_OK(xmlP); + XMLRPC_ASSERT_PTR_OK(callInfoP); + + rpcCreate(envP, clientTransportP, serverP, xmlP, complete, callInfoP, + &rpcP); + if (!envP->fault_occurred) { + int ok; + + /* Install our request handler. */ + HTRequest_addAfter(rpcP->request, &asynch_terminate_handler, + NULL, NULL, HT_ALL, HT_FILTER_LAST, NO); + + /* Register our asynchronous call with the event loop. This means + the user's callback is guaranteed to be called eventually. + */ + register_asynch_call(); + + /* This makes the TCP connection and sends the XML to the server + as an HTTP POST request. + + There was a comment here that said this might return failure + (!ok) and still invoke our completion handler + (asynch_terminate_handler(). The code attempted to deal with + that. Well, it's impossible to deal with that, so if it really + happens, we must fix Libwww. -Bryan 04.11.23. + */ + + ok = HTPostAnchor(rpcP->source_anchor, + rpcP->dest_anchor, + rpcP->request); + if (!ok) { + unregister_asynch_call(); + xmlrpc_env_set_fault(envP, XMLRPC_NETWORK_ERROR, + "Libwww (HTPostAnchor()) failed to start the " + "POST request."); + } + if (envP->fault_occurred) + rpcDestroy(rpcP); + } +} + + + +struct xmlrpc_client_transport_ops xmlrpc_libwww_transport_ops = { + NULL, + NULL, + &create, + &destroy, + &sendRequest, + &call, + &finishAsynch, + NULL, +}; diff --git a/trunk/lib/openssl/Makefile b/trunk/lib/openssl/Makefile new file mode 100644 index 000000000..87fda28af --- /dev/null +++ b/trunk/lib/openssl/Makefile @@ -0,0 +1,121 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + LIBDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/openssl + +include $(BLDDIR)/config.mk + +default: all + +MODS := xmlrpc_openssl_thread + +TARGET_MODS = $(MODS) + +TARGET_LIBRARY_NAMES := libxmlrpc_openssl + +STATIC_LIBRARIES_TO_INSTALL = libxmlrpc_openssl.a + +SHARED_LIBS_TO_BUILD := libxmlrpc_openssl +SHARED_LIBS_TO_INSTALL := libxmlrpc_openssl + +PKGCONFIG_FILES_TO_INSTALL := xmlrpc_openssl.pc + +MAJ := 1 + +OPENSSL_INCLUDES := $(shell pkg-config openssl --cflags) +OPENSSL_LIBS := $(shell pkg-config openssl --libs) + +include $(SRCDIR)/common.mk + +OPENSSL_SHLIB = $(call shlibfn,libxmlrpc_openssl) +#OPENSSL_SHLIB is e.g. libxmlrpc_openssl.so.3.1 +OPENSSL_SHLIBLE = $(call shliblefn,libxmlrpc_openssl) +#OPENSSL_SHLIBLE is e.g. libxmlrpc_openssl.so + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +.PHONY: all +all: libxmlrpc_openssl.a \ + $(TARGET_SHARED_LIBRARIES) \ + $(TARGET_SHARED_LE_LIBS) \ + $(PKGCONFIG_FILES_TO_INSTALL) \ + +# Rules for the above dependencies are in common.mk, +# courtesy of TARGET_MODS. + +# Rule for this is in common.mk, courtesy of TARGET_LIBRARY_NAMES +$(OPENSSL_SHLIB): $(TARGET_MODS:%=%.osh) \ + $(LIBXMLRPC_UTIL) +$(OPENSSL_SHLIB): LIBOBJECTS = $(TARGET_MODS:%=%.osh) +$(OPENSSL_SHLIB): LIBDEP = $(LIBXMLRPC_UTIL_LIBDEP) $(OPENSSL_LIBS) + +# Rule for this is in common.mk, courtesy of TARGET_STATIC_LIBRARIES: + +libxmlrpc_openssl.a: $(TARGET_MODS:%=%.o) +libxmlrpc_openssl.a: LIBOBJECTS = $(TARGET_MODS:%=%.o) + +#----------------------------------------------------------------------------- +# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES +#----------------------------------------------------------------------------- + +INCLUDES = \ + -I$(BLDDIR) \ + -I$(BLDDIR)/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include \ + $(OPENSSL_INCLUDES) + +#----------------------------------------------------------------------------- +# RULES TO MAKE PKGCONFIG FILES +# +# (These are files used by the 'pkg-config' program to get information about +# using the libraries we build) +#----------------------------------------------------------------------------- + +xmlrpc_openssl.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_openssl" >>$@ + @echo "Description: Openssl convenience function from Xmlrpc-c package" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_openssl" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +#----------------------------------------------------------------------------- +# MISCELLANEOUS +#----------------------------------------------------------------------------- + +.PHONY: clean +clean: clean-common + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: tags +tags: TAGS + +.PHONY: distdir +distdir: + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: dep +dep: dep-common + +include depend.mk + +# Need this dependency for those who don't use depend.mk. +# Without it, version.h doesn't get created. +xmlrpc_curl_transport.o xmlrpc_curl_transport.osh: version.h diff --git a/trunk/lib/openssl/xmlrpc_openssl_thread.c b/trunk/lib/openssl/xmlrpc_openssl_thread.c new file mode 100644 index 000000000..a7a7b46fe --- /dev/null +++ b/trunk/lib/openssl/xmlrpc_openssl_thread.c @@ -0,0 +1,124 @@ +#include "xmlrpc_config.h" +#include +#include +#include + +#include "mallocvar.h" + +#include "xmlrpc-c/string_int.h" + +#include "xmlrpc-c/openssl_thread.h" + + +/* These ugly global variables are necessary and appropriate because our + purpose is to manipulate OpenSSL's ugly global state. +*/ + +static pthread_mutex_t * opensslMutex; + /* Dynamically allocated array with an entry for each lock OpenSSL + has created. opensslMutex[N] is the mutex for the lock known by + OpenSSL with ID N. + */ + +static unsigned int maxLockCt; + + + +static void +lock(int const mode, + int const lockId, + const char * const fileName ATTR_UNUSED, + int const lineNum ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + This is a locking function for OpenSSL to call when it wants to lock or + unlock a lock. +-----------------------------------------------------------------------------*/ + assert(lockId >= 0); + assert((unsigned int)lockId < maxLockCt); + + pthread_mutex_t * const mutexP = &opensslMutex[lockId]; + + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(mutexP); + else + pthread_mutex_unlock(mutexP); +} + + + +static unsigned long +id(void) { +/*---------------------------------------------------------------------------- + This is an ID function for OpenSSL to call when it wants a unique + identifier of the executing thread. +-----------------------------------------------------------------------------*/ + return ((unsigned long)pthread_self()); +} + + + +void +xmlrpc_openssl_thread_setup(const char ** const errorP) { +/*---------------------------------------------------------------------------- + Set up the OpenSSL library to handle being called by multiple threads + concurrently. + + This setup is process-global, so this must be called exactly once in the + program (ergo a subroutine library cannot normally call this under the + covers; if a subroutine library want to use OpenSSL in a thread-safe + manner, it must depend upon its user to call this). + + This needs to be called as the program starts up, when it is only one + thread. + + (But this need not be called at all in a program that will never call + OpenSSL functions from multiple threads). +-----------------------------------------------------------------------------*/ + maxLockCt = CRYPTO_num_locks(); + + MALLOCARRAY(opensslMutex, maxLockCt); + + if (!opensslMutex) + xmlrpc_asprintf(errorP, "Failed to allocate an array for %u " + "potential OpenSSL locks", maxLockCt); + else { + *errorP = NULL; + + unsigned int i; + + for (i = 0; i < maxLockCt; ++i) + pthread_mutex_init(&opensslMutex[i], NULL); + + CRYPTO_set_id_callback(id); + + CRYPTO_set_locking_callback(lock); + } +} + + + +void +xmlrpc_openssl_thread_cleanup() { +/*---------------------------------------------------------------------------- + Undo 'xmlrpc_openssl_thread_setup'. + + This should be called at the end of a program, when there is only one + thread left. + + (As a practical matter, there's really no need to call this at all; if the + program is just going to exit afterward, any cleanup we do is moot). +-----------------------------------------------------------------------------*/ + CRYPTO_set_locking_callback(NULL); + + CRYPTO_set_id_callback(NULL); + + { + unsigned int i; + + for (i = 0; i < maxLockCt; ++i) + pthread_mutex_destroy(&opensslMutex[i]); + } + free(opensslMutex); +} + + diff --git a/trunk/lib/util/Makefile b/trunk/lib/util/Makefile new file mode 100644 index 000000000..0d406b6ef --- /dev/null +++ b/trunk/lib/util/Makefile @@ -0,0 +1,84 @@ +############################################################################### +# This directory builds object modules that provide utility functions that +# programs can use. Not libraries, though -- just programs. The reason +# we don't want any library to use object modules in here is that they'll +# probably pollute the name space when users link those libraries to their +# programs. In fact, if more than one Xmlrpc-c library included one of these +# modules, the libraries would conflict with each other. +# +# So a utility function that is to be used by libraries (and, optionally, +# programs) should go in libxmlrpc_util. libxmlrpc_util is a prerequisite +# for many Xmlrpc-c libraries, gets included in a program link only once, +# and uses external symbol names that have the "xmlrpc_" prefix to avoid +# collision with users' code. +# +# If we knew a portable way to link multiple object modules into one and +# restrict the symbols exported by the whole, we could avoid this mess and +# just link utility object modules into each Xmlrpc-c library. +############################################################################## + +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + LIBDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/util + +default: all + +include $(BLDDIR)/config.mk + +OMIT_UTILS_RULE = Y + +include $(SRCDIR)/common.mk + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +LIBOBJS = \ + casprintf.o \ + cmdline_parser.o \ + getoptx.o \ + string_parser.o \ + stripcaseeq.o \ + +# If the overall build is not building C++ libraries, then it isn't building +# any tools that use them, and it's a good assumption that it isn't building +# any program written in C++. Since the main reason for not building C++ +# libraries is that your build system can't compile C++, it makes sense not to +# attempt to compile any C++ code if we're not building C++ libraries. Hence, +# we don't build any C++ code here if ENABLE_CPLUSPLUS is "no". + +ifeq ($(ENABLE_CPLUSPLUS),yes) + LIBOBJS += cmdline_parser_cpp.o +endif + +.PHONY: all +all: $(LIBOBJS) + +INCLUDES = -Isrcdir/$(SUBDIR)/include -I$(BLDDIR) + +%.o:%.c + $(CC) -c $(CFLAGS_ALL) $< + +%.o:%.cpp + $(CXX) -c $(CXXFLAGS_ALL) $< + +include depend.mk + +.PHONY: clean distclean +clean: clean-common + +distclean: clean distclean-common + +.PHONY: dep +dep: dep-common + +.PHONY: install +install: + +.PHONY: uninstall +uninstall: \ No newline at end of file diff --git a/trunk/lib/util/casprintf.c b/trunk/lib/util/casprintf.c new file mode 100644 index 000000000..5953f166c --- /dev/null +++ b/trunk/lib/util/casprintf.c @@ -0,0 +1,143 @@ +#define _GNU_SOURCE /* But only when HAVE_ASPRINTF */ +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" /* For HAVE_ASPRINTF, __inline__ */ +#include "bool.h" +#include "casprintf.h" + + + +static __inline__ void +newVsnprintf(char * const buffer, + size_t const bufferSize, + const char * const fmt, + va_list varargs, + size_t * const formattedSizeP) { +/*---------------------------------------------------------------------------- + This is vsnprintf() with the new behavior, where not fitting in the buffer + is not a failure. + + Unfortunately, we can't practically return the size of the formatted string + if the C library has old vsnprintf() and the formatted string doesn't fit + in the buffer, so in that case we just return something larger than the + buffer. +-----------------------------------------------------------------------------*/ + if (bufferSize > INT_MAX/2) { + /* There's a danger we won't be able to coerce the return value + of XMLRPC_VSNPRINTF to an integer (which we have to do because, + while for POSIX its return value is ssize_t, on Windows it is int), + or return double the buffer size. + */ + *formattedSizeP = 0; + } else { + int rc; + + rc = XMLRPC_VSNPRINTF(buffer, bufferSize, fmt, varargs); + + if (rc < 0) { + /* We have old vsnprintf() (or Windows) and the formatted value + doesn't fit in the buffer, but we don't know how big a buffer it + needs. + */ + *formattedSizeP = bufferSize * 2; + } else { + /* Either the string fits in the buffer or we have new vsnprintf() + which tells us how big the string is regardless. + */ + *formattedSizeP = rc; + } + } +} + + + +static __inline__ int +simpleVasprintf(char ** const resultP, + const char * const fmt, + va_list varargs) { +/*---------------------------------------------------------------------------- + This is a poor man's implementation of vasprintf(), of GNU fame. +-----------------------------------------------------------------------------*/ + int retval; + char * buffer; + size_t bufferSize; + bool outOfMemory; + + for (buffer = NULL, bufferSize = 4096, outOfMemory = false; + !buffer && !outOfMemory; + ) { + + buffer = malloc(bufferSize); + if (!buffer) + outOfMemory = true; + else { + size_t bytesNeeded; + newVsnprintf(buffer, bufferSize, fmt, varargs, &bytesNeeded); + if (bytesNeeded > bufferSize) { + free(buffer); + buffer = NULL; + bufferSize = bytesNeeded; + } + } + } + if (outOfMemory) + retval = -1; + else { + retval = strlen(buffer); + *resultP = buffer; + } + return retval; +} + + + +const char * const strsol = "[Insufficient memory to build string]"; + + + +void +cvasprintf(const char ** const retvalP, + const char * const fmt, + va_list varargs) { + + char * string; + int rc; + +#if HAVE_ASPRINTF + rc = vasprintf(&string, fmt, varargs); +#else + rc = simpleVasprintf(&string, fmt, varargs); +#endif + + if (rc < 0) + *retvalP = strsol; + else + *retvalP = string; +} + + + +void GNU_PRINTF_ATTR(2,3) +casprintf(const char ** const retvalP, const char * const fmt, ...) { + + va_list varargs; /* mysterious structure used by variable arg facility */ + + va_start(varargs, fmt); /* start up the mysterious variable arg facility */ + + cvasprintf(retvalP, fmt, varargs); + + va_end(varargs); +} + + + +void +strfree(const char * const string) { + + if (string != strsol) + free((void *)string); +} diff --git a/trunk/lib/util/cmdline_parser.c b/trunk/lib/util/cmdline_parser.c new file mode 100644 index 000000000..d8f127cde --- /dev/null +++ b/trunk/lib/util/cmdline_parser.c @@ -0,0 +1,589 @@ +#define _XOPEN_SOURCE 600 /* Make sure has strdup() */ + +#include "xmlrpc_config.h" /* prereq for mallocvar.h -- defines __inline__ */ + +#include +#include +#include +#include +#include + +#include "bool.h" +#include "int.h" +#include "mallocvar.h" +#include "casprintf.h" +#include "getoptx.h" +#include "string_parser.h" + +#include "cmdline_parser.h" + +#define MAXOPTS 100 + +struct optionDesc { + const char * name; + enum optiontype type; + bool present; + union { + unsigned int u; + int i; + const char * s; + uint64_t llu; + double d; + } value; +}; + + + +struct cmdlineParserCtl { + struct optionDesc * optionDescArray; + unsigned int numOptions; + const char ** argumentArray; + unsigned int numArguments; +}; + + + +static struct optionx * +createLongOptsArray(struct optionDesc * const optionDescArray, + unsigned int const numOptions) { + + struct optionx * longopts; + + MALLOCARRAY(longopts, numOptions+1); + if (longopts != NULL) { + unsigned int i; + + for (i = 0; i < numOptions; ++i) { + longopts[i].name = optionDescArray[i].name; + /* If the option takes a value, we say it is optional even + though it never is. That's because if we say it is + mandatory, getopt_long_only() pretends it doesn't even + recognize the option if the user doesn't give a value. + We prefer to generate a meaningful error message when + the user omits a required option value. + */ + longopts[i].has_arg = + optionDescArray[i].type == OPTTYPE_FLAG ? + no_argument : optional_argument; + longopts[i].flag = NULL; + longopts[i].val = i; + } + longopts[numOptions].name = 0; + longopts[numOptions].has_arg = 0; + longopts[numOptions].flag = 0; + longopts[numOptions].val = 0; + } + return longopts; +} + + + +static void +parseInt(enum optiontype const type, + const char * const optarg, + unsigned int * const valueUintP, + int * const valueIntP, + const char ** const errorP) { + + if (optarg == NULL) + casprintf(errorP, "Option requires a value"); + else if (strlen(optarg) == 0) + casprintf(errorP, "Numeric option value is null string"); + else { + char * tailptr; + long const longvalue = strtol(optarg, &tailptr, 10); + + if (*tailptr != '\0') + casprintf(errorP, "Non-numeric value " + "for numeric option value: '%s'", optarg); + else if (errno == ERANGE || longvalue > INT_MAX) + casprintf(errorP, "Numeric value out of range: %s", optarg); + else { + if (type == OPTTYPE_UINT) { + if (longvalue < 0) + casprintf(errorP, "Unsigned numeric value is " + "negative: %ld", longvalue); + else { + *errorP = NULL; + *valueUintP = (unsigned int) longvalue; + } + } else { + *errorP = NULL; + *valueIntP = (int) longvalue; + } + } + } +} + + + +static void +parseBinUint(const char * const optarg, + uint64_t * const valueP, + const char ** const errorP) { + + if (optarg == NULL) + casprintf(errorP, "Option requires a value"); + else if (strlen(optarg) == 0) + casprintf(errorP, "Numeric option value is null string"); + else { + const char * error; + interpretBinUint(optarg, valueP, &error); + + if (error) { + casprintf(errorP, "Invalid numeric option value '%s'. %s", + optarg, error); + strfree(error); + } + } +} + + + +static void +parseFloat(const char * const optarg, + double * const valueP, + const char ** const errorP) { + + if (optarg == NULL) + casprintf(errorP, "Option requires a value"); + else if (strlen(optarg) == 0) + casprintf(errorP, "Numeric option value is null string"); + else { + char * tailptr; + double const doublevalue = strtod(optarg, &tailptr); + + if (*tailptr != '\0') + casprintf(errorP, "Non-numeric value " + "for numeric option value: '%s'", optarg); + else if (errno == ERANGE) + casprintf(errorP, "Numeric value out of range: %s", optarg); + else { + *errorP = NULL; + *valueP = doublevalue; + } + } +} + + + +static void +parseOptionValue(const char * const optarg, + struct optionDesc * const optionP, + const char ** const errorP) { + + switch (optionP->type) { + case OPTTYPE_FLAG: + *errorP = NULL; + break; + case OPTTYPE_INT: + case OPTTYPE_UINT: + parseInt(optionP->type, optarg, &optionP->value.u, &optionP->value.i, + errorP); + break; + case OPTTYPE_STRING: + if (optarg == NULL) + casprintf(errorP, "Option requires a value"); + else { + *errorP = NULL; + optionP->value.s = strdup(optarg); + } + break; + case OPTTYPE_BINUINT: + parseBinUint(optarg, &optionP->value.llu, errorP); + break; + case OPTTYPE_FLOAT: + parseFloat(optarg, &optionP->value.d, errorP); + break; + } +} + + + +static void +processOption(struct optionDesc * const optionP, + const char * const optarg, + const char ** const errorP) { + + const char * error; + + parseOptionValue(optarg, optionP, &error); + if (error) + casprintf(errorP, "Error in '%s' option: %s", optionP->name, error); + else + optionP->present = true; +} + + + +static void +extractArguments(struct cmdlineParserCtl * const cpP, + unsigned int const argc, + const char ** const argv) { + + cpP->numArguments = argc - getopt_argstart(); + MALLOCARRAY(cpP->argumentArray, cpP->numArguments); + + if (cpP->argumentArray == NULL) { + fprintf(stderr, "Unable to allocate memory for argument array " + "(%u arguments)\n", cpP->numArguments); + abort(); + } else { + unsigned int i; + + for (i = 0; i < cpP->numArguments; ++i) { + cpP->argumentArray[i] = strdup(argv[getopt_argstart() + i]); + if (cpP->argumentArray[i] == NULL) { + fprintf(stderr, "Unable to allocate memory for Argument %u\n", + i); + abort(); + } + } + } +} + + + +void +cmd_processOptions(cmdlineParser const cpP, + int const argc, + const char ** const argv, + const char ** const errorP) { + + struct optionx * longopts; + + longopts = createLongOptsArray(cpP->optionDescArray, cpP->numOptions); + + if (longopts == NULL) + casprintf(errorP, "Unable to get memory for longopts array"); + else { + int endOfOptions; + unsigned int i; + + *errorP = NULL; + + /* Set up initial assumption: No options present */ + + for (i = 0; i < cpP->numOptions; ++i) + cpP->optionDescArray[i].present = false; + + endOfOptions = false; /* initial value */ + + while (!endOfOptions && !*errorP) { + int const opterr0 = 0; + /* Don't let getopt_long_only() print an error message */ + unsigned int longoptsIndex; + const char * unrecognizedOption; + const char * optarg; + + getopt_long_onlyx(argc, (char**) argv, "", longopts, + &longoptsIndex, opterr0, + &endOfOptions, &optarg, &unrecognizedOption); + + if (unrecognizedOption) + casprintf(errorP, "Unrecognized option: '%s'", + unrecognizedOption); + else { + if (!endOfOptions) + processOption(&cpP->optionDescArray[longoptsIndex], optarg, + errorP); + } + } + if (!*errorP) + extractArguments(cpP, argc, argv); + + free(longopts); + } +} + + + +cmdlineParser +cmd_createOptionParser(void) { + + struct cmdlineParserCtl * cpP; + + MALLOCVAR(cpP); + + if (cpP != NULL) { + struct optionDesc * optionDescArray; + + cpP->numOptions = 0; + MALLOCARRAY(optionDescArray, MAXOPTS); + if (optionDescArray == NULL) { + free(cpP); + cpP = NULL; + } else + cpP->optionDescArray = optionDescArray; + } + return cpP; +} + + + +void +cmd_destroyOptionParser(cmdlineParser const cpP) { + + unsigned int i; + + for (i = 0; i < cpP->numOptions; ++i) { + struct optionDesc const option = cpP->optionDescArray[i]; + if (option.type == OPTTYPE_STRING && option.present) + strfree(option.value.s); + strfree(option.name); + } + + for (i = 0; i < cpP->numArguments; ++i) + strfree(cpP->argumentArray[i]); + + free(cpP->optionDescArray); + free(cpP); +} + + + +void +cmd_defineOption(cmdlineParser const cpP, + const char * const name, + enum optiontype const type) { + + if (cpP->numOptions < MAXOPTS) { + cpP->optionDescArray[cpP->numOptions].name = strdup(name); + cpP->optionDescArray[cpP->numOptions].type = type; + + ++cpP->numOptions; + } +} + + + +static struct optionDesc * +findOptionDesc(struct cmdlineParserCtl * const cpP, + const char * const name) { + + struct optionDesc * retval; + unsigned int i; + + retval = NULL; + + for (i = 0; i < cpP->numOptions && !retval; ++i) + if (strcmp(cpP->optionDescArray[i].name, name) == 0) + retval = &cpP->optionDescArray[i]; + + return retval; +} + + + +int +cmd_optionIsPresent(cmdlineParser const cpP, + const char * const name) { + + struct optionDesc * const optionDescP = findOptionDesc(cpP, name); + + bool present; + + if (!optionDescP) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "optionIsPresent() called for undefined option '%s'\n", + name); + abort(); + } else + present = optionDescP->present; + + return present; +} + + + +unsigned int +cmd_getOptionValueUint(cmdlineParser const cpP, + const char * const name) { + + struct optionDesc * const optionDescP = findOptionDesc(cpP, name); + + unsigned int retval; + + if (!optionDescP) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "cmd_getOptionValueUint() called for undefined option '%s'\n", + name); + abort(); + } else { + if (optionDescP->type != OPTTYPE_UINT) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "cmd_getOptionValueUint() called for non-unsigned integer " + "option '%s'\n", optionDescP->name); + abort(); + } else { + if (optionDescP->present) + retval = optionDescP->value.u; + else + retval = 0; + } + } + return retval; +} + + + +int +cmd_getOptionValueInt(cmdlineParser const cpP, + const char * const name) { + + struct optionDesc * const optionDescP = findOptionDesc(cpP, name); + + int retval; + + if (!optionDescP) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "cmd_getOptionValueInt() called for undefined option '%s'\n", + name); + abort(); + } else { + if (optionDescP->type != OPTTYPE_INT) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "cmd_getOptionValueInt() called for non-integer " + "option '%s'\n", optionDescP->name); + abort(); + } else { + if (optionDescP->present) + retval = optionDescP->value.i; + else + retval = 0; + } + } + + return retval; +} + + + +const char * +cmd_getOptionValueString(cmdlineParser const cpP, + const char * const name) { + + struct optionDesc * const optionDescP = findOptionDesc(cpP, name); + + const char * retval; + + if (!optionDescP) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "cmd_getOptionValueString() called for " + "undefined option '%s'\n", + name); + abort(); + } else { + if (optionDescP->type != OPTTYPE_STRING) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "getOptionValueString() called for non-string " + "option '%s'\n", optionDescP->name); + abort(); + } else { + if (optionDescP->present) { + retval = strdup(optionDescP->value.s); + if (retval == NULL) { + fprintf(stderr, + "out of memory in cmd_getOptionValueString()\n"); + abort(); + } + } else + retval = NULL; + } + } + return retval; +} + + + +uint64_t +cmd_getOptionValueBinUint(cmdlineParser const cpP, + const char * const name) { + + struct optionDesc * const optionDescP = findOptionDesc(cpP, name); + + uint64_t retval; + + if (!optionDescP) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "cmd_getOptionValueUint() called for undefined option '%s'\n", + name); + abort(); + } else { + if (optionDescP->type != OPTTYPE_BINUINT) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "cmd_getOptionValueBinUint() called for " + "non-OPTTYPE_BINUINT " + "option '%s'\n", optionDescP->name); + abort(); + } else { + if (optionDescP->present) + retval = optionDescP->value.llu; + else + retval = 0; + } + } + return retval; +} + + + +double +cmd_getOptionValueFloat(cmdlineParser const cpP, + const char * const name) { + + struct optionDesc * const optionDescP = findOptionDesc(cpP, name); + + double retval; + + if (!optionDescP) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "cmd_getOptionValueInt() called for undefined option '%s'\n", + name); + abort(); + } else { + if (optionDescP->type != OPTTYPE_FLOAT) { + fprintf(stderr, "cmdlineParser called incorrectly. " + "cmd_getOptionValueInt() called for non-float " + "option '%s'\n", optionDescP->name); + abort(); + } else { + if (optionDescP->present) + retval = optionDescP->value.d; + else + retval = 0.0; + } + } + return retval; +} + + + +unsigned int +cmd_argumentCount(cmdlineParser const cpP) { + + return cpP->numArguments; + +} + + + +const char * +cmd_getArgument(cmdlineParser const cpP, + unsigned int const argNumber) { + + const char * retval; + + if (argNumber >= cpP->numArguments) + retval = NULL; + else { + retval = strdup(cpP->argumentArray[argNumber]); + + if (retval == NULL) { + fprintf(stderr, + "out of memory in cmd_getArgument()\n"); + abort(); + } + } + return retval; +} diff --git a/trunk/lib/util/cmdline_parser_cpp.cpp b/trunk/lib/util/cmdline_parser_cpp.cpp new file mode 100644 index 000000000..0fc951eab --- /dev/null +++ b/trunk/lib/util/cmdline_parser_cpp.cpp @@ -0,0 +1,157 @@ +#include +#include + +#include "girstring.h" +#include "casprintf.h" +#include "cmdline_parser.h" + +#include "cmdline_parser.hpp" + +using namespace std; + + + +static enum optiontype +optTypeConvert( + CmdlineParser::optType const arg) { + + enum optiontype retval; + + retval = OPTTYPE_FLAG; // defeat compiler warning + + switch (arg) { + case CmdlineParser::FLAG: retval = OPTTYPE_FLAG; break; + case CmdlineParser::INT: retval = OPTTYPE_INT; break; + case CmdlineParser::UINT: retval = OPTTYPE_UINT; break; + case CmdlineParser::STRING: retval = OPTTYPE_STRING; break; + case CmdlineParser::BINUINT: retval = OPTTYPE_BINUINT; break; + case CmdlineParser::FLOAT: retval = OPTTYPE_FLOAT; break; + } + return retval; +} + + + +CmdlineParser::CmdlineParser() { + + this->cp = cmd_createOptionParser(); +} + + + +CmdlineParser::~CmdlineParser() { + cmd_destroyOptionParser(this->cp); +} + + + +void +CmdlineParser::defineOption( + string const optionName, + optType const optionType) { + + cmd_defineOption(this->cp, optionName.c_str(), + optTypeConvert(optionType)); +} + + + +void +CmdlineParser::processOptions( + int const argc, + const char ** const argv) { + + const char * error; + + cmd_processOptions(this->cp, argc, argv, &error); + if (error) { + string const errorS(error); + strfree(error); + throw(runtime_error(errorS)); + } +} + + + +bool +CmdlineParser::optionIsPresent( + string const optionName) const { + + return (cmd_optionIsPresent(this->cp, optionName.c_str()) ? true : false); +} + + + +int +CmdlineParser::getOptionValueInt( + string const optionName) const { + + return cmd_getOptionValueInt(this->cp, optionName.c_str()); +} + + + +unsigned int +CmdlineParser::getOptionValueUint( + string const optionName) const { + + return cmd_getOptionValueUint(this->cp, optionName.c_str()); +} + + + +unsigned long long +CmdlineParser::getOptionValueBinUint( + string const optionName) const { + + return cmd_getOptionValueBinUint(this->cp, optionName.c_str()); +} + + + +double +CmdlineParser::getOptionValueFloat( + string const optionName) const { + + return cmd_getOptionValueFloat(this->cp, optionName.c_str()); +} + + + +string +CmdlineParser::getOptionValueString( + string const optionName) const { + + const char * const value = + cmd_getOptionValueString(this->cp, optionName.c_str()); + + string retval; + + if (value) { + retval = string(value); + strfree(value); + } else + retval = ""; + + return retval; +} + + + +unsigned int +CmdlineParser::argumentCount() const { + + return cmd_argumentCount(this->cp); +} + + + +string +CmdlineParser::getArgument( + unsigned int const argNumber) const { + + const char * const value = cmd_getArgument(this->cp, argNumber); + string const retval(value); + strfree(value); + return retval; +} diff --git a/trunk/lib/util/getoptx.c b/trunk/lib/util/getoptx.c new file mode 100644 index 000000000..114bacc9f --- /dev/null +++ b/trunk/lib/util/getoptx.c @@ -0,0 +1,466 @@ +/* This version of `getopt' appears to the caller like standard Unix getopt() + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As getopt() works, it permutes the elements of `argv' so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable _POSIX_OPTION_ORDER disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. +*/ + +#include +#include +#include + +#include "getoptx.h" + +/* Note that on some systems, the header files above declare variables + for use with their native getopt facilities, and those variables have + the same names as we'd like to use. So we use things like optargx + instead of optarg to avoid the collision. +*/ + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. +*/ +static char *optargx = 0; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to getoptx(). + + On entry to getoptx(), zero means this is the first call; initialize. + + When getoptx() returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optindx' communicates from one call to the next + how much of ARGV has been scanned so far. +*/ + +static int optindx = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. +*/ + +static int opterrx; + +/* Index in _GETOPT_LONG_OPTIONS of the long-named option actually found. + Only valid when a long-named option was found. */ + +static int option_index; + +struct optionx * _getopt_long_options; + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optindx), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +static void +exchange(char ** const argv) { + unsigned int const nonopts_size = + (last_nonopt - first_nonopt) * sizeof (char *); + char **temp = (char **) malloc (nonopts_size); + + if (temp == NULL) + abort(); + + /* Interchange the two blocks of data in argv. */ + + memcpy (temp, &argv[first_nonopt], nonopts_size); + memcpy (&argv[first_nonopt], &argv[last_nonopt], + (optindx - last_nonopt) * sizeof (char *)); + memcpy (&argv[first_nonopt + optindx - last_nonopt], temp, + nonopts_size); + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optindx - last_nonopt); + last_nonopt = optindx; + + free(temp); +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If getoptx() + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If getoptx() finds another option character, it returns that character, + updating `optindx' and `nextchar' so that the next call to getoptx() can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, getoptx() returns `EOF'. + Then `optindx' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterrx' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optargx'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optargx', otherwise `optargx' is set to zero. + + If OPTSTRING starts with `-', it requests a different method of handling the + non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. + + Long-named options begin with `+' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + getoptx() returns 0 when it finds a long-named option. */ + +static int +getoptx(int const argc, + char ** const argv, + const char * const optstring) { + + optargx = 0; + + /* Initialize the internal data when the first call is made. + Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + if (optindx == 0) + { + first_nonopt = last_nonopt = optindx = 1; + + nextchar = 0; + + } + + if (nextchar == 0 || *nextchar == 0) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optindx) + exchange (argv); + else if (last_nonopt != optindx) + first_nonopt = optindx; + + /* Now skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optindx < argc + && (argv[optindx][0] != '-'|| argv[optindx][1] == 0) + && (argv[optindx][0] != '+'|| argv[optindx][1] == 0)) + optindx++; + last_nonopt = optindx; + + /* Special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optindx != argc && !strcmp (argv[optindx], "--")) + { + optindx++; + + if (first_nonopt != last_nonopt && last_nonopt != optindx) + exchange (argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optindx; + last_nonopt = argc; + + optindx = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optindx == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optindx = first_nonopt; + return EOF; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass + it by. + */ + + if ((argv[optindx][0] != '-' || argv[optindx][1] == 0) + && (argv[optindx][0] != '+' || argv[optindx][1] == 0)) + { + optargx = argv[optindx++]; + return 1; + } + + /* We have found another option-ARGV-element. + Start decoding its characters. */ + + nextchar = argv[optindx] + 1; + } + + if ((argv[optindx][0] == '+' || (argv[optindx][0] == '-')) + ) + { + struct optionx *p; + char *s = nextchar; + int exact = 0; + int ambig = 0; + struct optionx * pfound; + int indfound; + + while (*s && *s != '=') s++; + + indfound = 0; /* quite compiler warning */ + + /* Test all options for either exact match or abbreviated matches. */ + for (p = _getopt_long_options, option_index = 0, pfound = NULL; + p->name; + p++, option_index++) + if (!strncmp (p->name, nextchar, s - nextchar)) + { + if ((unsigned int)(s - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (!pfound) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optindx]); + nextchar += strlen (nextchar); + return '?'; + } + + if (pfound) + { + option_index = indfound; + optindx++; + if (*s) + { + if (pfound->has_arg > 0) + optargx = s + 1; + else + { + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optindx - 1][0], pfound->name); + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg) + { + if (optindx < argc) + optargx = argv[optindx++]; + else if (pfound->has_arg != 2) + { + fprintf (stderr, "%s: option `%s' requires an argument\n", + argv[0], argv[optindx - 1]); + nextchar += strlen (nextchar); + return '?'; + } + } + nextchar += strlen (nextchar); + if (pfound->flag) + *(pfound->flag) = pfound->val; + return 0; + } + if (argv[optindx][0] == '+' || strchr (optstring, *nextchar) == 0) + { + if (opterrx != 0) + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optindx][0], nextchar); + nextchar += strlen (nextchar); + return '?'; + } + } + + /* Look at and handle the next option-character. */ + + { + char c = *nextchar++; + char *temp = strchr (optstring, c); + + /* Increment `optindx' when we start to process its last character. */ + if (*nextchar == 0) + optindx++; + + if (temp == 0 || c == ':') + { + if (opterrx != 0) + { + if (c < 040 || c >= 0177) + fprintf (stderr, "%s: unrecognized option, " + "character code 0%o\n", + argv[0], c); + else + fprintf (stderr, "%s: unrecognized option `-%c'\n", + argv[0], c); + } + return '?'; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != 0) + { + optargx = nextchar; + optindx++; + } + else + optargx = 0; + nextchar = 0; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != 0) + { + optargx = nextchar; + /* If we end this ARGV-element by taking the rest + as an arg, we must advance to the next element + now. + */ + optindx++; + } + else if (optindx == argc) + { + if (opterrx != 0) + fprintf (stderr, + "%s: option `-%c' requires an argument\n", + argv[0], c); + c = '?'; + } + else + /* We already incremented `optindx' once; + increment it again when taking next ARGV-elt as + argument. + */ + optargx = argv[optindx++]; + nextchar = 0; + } + } + return c; + } +} + + + +void +getopt_long_onlyx(int const argc, + char ** const argv, + const char * const options, + struct optionx * const long_options, + unsigned int * const opt_index, + int const opterrArg, + int * const end_of_options, + const char ** const optarg_arg, + const char ** const unrecognized_option) { + + int rc; + + opterrx = opterrArg; + _getopt_long_options = long_options; + rc = getoptx(argc, argv, options); + if (rc == 0) + *opt_index = option_index; + + if (rc == '?') + *unrecognized_option = argv[optindx]; + else + *unrecognized_option = NULL; + + if (rc < 0) + *end_of_options = 1; + else + *end_of_options = 0; + + *optarg_arg = optargx; +} + + +unsigned int +getopt_argstart(void) { +/*---------------------------------------------------------------------------- + This is a replacement for what traditional getopt does with global + variables. + + You call this after getopt_long_onlyx() has returned "end of + options" +-----------------------------------------------------------------------------*/ + return optindx; +} + + +/* Getopt for GNU. + Copyright (C) 1987, 1989 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ diff --git a/trunk/lib/util/getoptx.h b/trunk/lib/util/getoptx.h new file mode 100644 index 000000000..c68833124 --- /dev/null +++ b/trunk/lib/util/getoptx.h @@ -0,0 +1,51 @@ +/* Interface to getopt_long_onlyx() */ + + +enum argreq {no_argument, required_argument, optional_argument}; + +struct optionx { + /* This describes an option. If the field `flag' is nonzero, it + points to a variable that is to be set to the value given in + the field `val' when the option is found, but left unchanged if + the option is not found. + */ + const char * name; + enum argreq has_arg; + int * flag; + int val; +}; + +/* long_options[] is a list terminated by an element that contains + a NULL 'name' member. +*/ +void +getopt_long_onlyx(int const argc, + char ** const argv, + const char * const options, + struct optionx * const long_options, + unsigned int * const opt_index, + int const opterrArg, + int * const end_of_options, + const char ** const optarg_arg, + const char ** const unrecognized_option); + +unsigned int +getopt_argstart(void); + +/* + Copyright (C) 1989 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + diff --git a/trunk/lib/util/include/assertx.hpp b/trunk/lib/util/include/assertx.hpp new file mode 100644 index 000000000..64e57faf1 --- /dev/null +++ b/trunk/lib/util/include/assertx.hpp @@ -0,0 +1,27 @@ +#ifndef ASSERTX_HPP_INCLUDED +#define ASSERTX_HPP_INCLUDED + +#include + +/* The compiler often warns you if you give a function formal parameter a + name, but don't use it. But because assert() disappears when doing an + optimized build, the compiler doesn't recognize your reference to the + parameter in the assert() argument. To avoid the bogus warning in + this case, we have ASSERT_ONLY_ARG(), which declares a name for a + formal parameter for purposes of assert() only. In cases where an + assert() would disappear, ASSERT_ONLY_ARG() disappears too. + + E.g. + + void foo(int const ASSERT_ONLY_ARG(arg1)) { + + assert(arg1 > 0); + } +*/ +#ifdef NDEBUG + #define ASSERT_ONLY_ARG(x) +#else + #define ASSERT_ONLY_ARG(x) x +#endif + +#endif diff --git a/trunk/lib/util/include/bool.h b/trunk/lib/util/include/bool.h new file mode 100644 index 000000000..312477c4c --- /dev/null +++ b/trunk/lib/util/include/bool.h @@ -0,0 +1,18 @@ +/* This takes the place of C99 stdbool.h, which at least some Windows + compilers don't have. (October 2005). + + One must not also include , because it might cause a name + collision. +*/ + +#ifndef __cplusplus +/* At least the GNU compiler defines __bool_true_false_are_defined */ +#ifndef __bool_true_false_are_defined +#define __bool_true_false_are_defined +typedef enum { + false = 0, + true = 1 +} bool; +#endif +#endif + diff --git a/trunk/lib/util/include/c_util.h b/trunk/lib/util/include/c_util.h new file mode 100644 index 000000000..5386b1330 --- /dev/null +++ b/trunk/lib/util/include/c_util.h @@ -0,0 +1,19 @@ +#ifndef C_UTIL_H_INCLUDED +#define C_UTIL_H_INCLUDED + +/* C language stuff. Doesn't involve any libraries that aren't part of + the compiler. +*/ + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +/* GNU_PRINTF_ATTR lets the GNU compiler check printf-type + calls to be sure the arguments match the format string, thus preventing + runtime segmentation faults and incorrect messages. +*/ +#ifdef __GNUC__ +#define GNU_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b))) +#else +#define GNU_PRINTF_ATTR(a,b) +#endif +#endif diff --git a/trunk/lib/util/include/casprintf.h b/trunk/lib/util/include/casprintf.h new file mode 100644 index 000000000..61098dc34 --- /dev/null +++ b/trunk/lib/util/include/casprintf.h @@ -0,0 +1,29 @@ +#ifndef CASPRINTF_H_INCLUDED +#define CASPRINTF_H_INCLUDED + +#include + +#include "c_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const char * const strsol; + +void +cvasprintf(const char ** const retvalP, + const char * const fmt, + va_list varargs); + +void GNU_PRINTF_ATTR(2,3) +casprintf(const char ** const retvalP, const char * const fmt, ...); + +void +strfree(const char * const string); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/trunk/lib/util/include/cmdline_parser.h b/trunk/lib/util/include/cmdline_parser.h new file mode 100644 index 000000000..cc8762527 --- /dev/null +++ b/trunk/lib/util/include/cmdline_parser.h @@ -0,0 +1,86 @@ +#ifndef CMDLINE_PARSER_H +#define CMDLINE_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif +#if 0 +} /* to fake out automatic code indenters */ +#endif + +#include "int.h" + +/* + + NOTE NOTE NOTE: cmd_getOptionValueString() and + cmd_getArgument() return malloc'ed memory (and abort the program if + out of memory). You must free it. + +*/ + +enum optiontype { + OPTTYPE_FLAG, + OPTTYPE_INT, + OPTTYPE_UINT, + OPTTYPE_STRING, + OPTTYPE_BINUINT, + OPTTYPE_FLOAT +}; + +struct cmdlineParserCtl; + +typedef struct cmdlineParserCtl * cmdlineParser; + +void +cmd_processOptions(cmdlineParser const cpP, + int const argc, + const char ** const argv, + const char ** const errorP); + +cmdlineParser +cmd_createOptionParser(void); + +void +cmd_destroyOptionParser(cmdlineParser const cpP); + +void +cmd_defineOption(cmdlineParser const cpP, + const char * const name, + enum optiontype const type); + +int +cmd_optionIsPresent(cmdlineParser const cpP, + const char * const name); + +int +cmd_getOptionValueInt(cmdlineParser const cpP, + const char * const name); + +unsigned int +cmd_getOptionValueUint(cmdlineParser const cpP, + const char * const name); + +const char * +cmd_getOptionValueString(cmdlineParser const cpP, + const char * const name); + +uint64_t +cmd_getOptionValueBinUint(cmdlineParser const cpP, + const char * const name); + +double +cmd_getOptionValueFloat(cmdlineParser const cpP, + const char * const name); + +unsigned int +cmd_argumentCount(cmdlineParser const cpP); + +const char * +cmd_getArgument(cmdlineParser const cpP, + unsigned int const argNumber); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/trunk/lib/util/include/cmdline_parser.hpp b/trunk/lib/util/include/cmdline_parser.hpp new file mode 100644 index 000000000..af93487c4 --- /dev/null +++ b/trunk/lib/util/include/cmdline_parser.hpp @@ -0,0 +1,59 @@ +#ifndef CMDLINE_PARSER_HPP_INCLUDED +#define CMDLINE_PARSER_HPP_INCLUDED + +#include + +struct cmdlineParserCtl; + +class CmdlineParser { +public: + CmdlineParser(); + + ~CmdlineParser(); + + enum optType {FLAG, INT, UINT, STRING, BINUINT, FLOAT}; + + void + defineOption(std::string const optionName, + optType const optionType); + + void + processOptions(int const argc, + const char ** const argv); + + bool + optionIsPresent(std::string const optionName) const; + + int + getOptionValueInt(std::string const optionName) const; + + unsigned int + getOptionValueUint(std::string const optionName) const; + + std::string + getOptionValueString(std::string const optionName) const; + + unsigned long long + getOptionValueBinUint(std::string const optionName) const; + + double + getOptionValueFloat(std::string const optionName) const; + + unsigned int + argumentCount() const; + + std::string + getArgument(unsigned int const argNumber) const; + +private: + struct cmdlineParserCtl * cp; + + // Make sure no one can copy this object, because if there are two + // copies, there will be two attempts to destroy *cp. + CmdlineParser(CmdlineParser const&) {}; + + CmdlineParser& + operator=(CmdlineParser const&) {return *this;} +}; + +#endif diff --git a/trunk/lib/util/include/girmath.h b/trunk/lib/util/include/girmath.h new file mode 100644 index 000000000..8b996ab6b --- /dev/null +++ b/trunk/lib/util/include/girmath.h @@ -0,0 +1,39 @@ +#ifndef __GIRMATH_H +#define __GIRMATH_H + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +#define SQR(a) ((a)*(a)) + +/* ROUNDUP(a,b) rounds a up to the next multiple of b. + ROUNDDN(a,b) rounds a down to the next multiple of b. + ROUND(a,b) rounds a to the nearest multiple of b. + + These are for signed integers. + + "down" means arithmetically less: -4.3 rounded down to the next unit + is -5. + + ROUNDUPU, etc. are the same for unsigned integers, but with no compiler + warning about a comparison that is always true. +*/ + +#define ROUNDUPU(a,b) (((a)+(b)-1)/(b)*(b)) +#define ROUNDDNU(a,b) ((a)/(b)*(b)) +#define ROUNDU(a,b) (((a)+((b)/2))/(b)*(b)) + +#define ROUNDUP(a,b) ((a) >= 0 ? ROUNDUPU(a,b) : -ROUNDDNU(-a,b)) +#define ROUNDDN(a,b) ((a) >= 0 ? ROUNDDNU(a,b) : -ROUNDUPU(-a,b)) +#define ROUND(a,b) ((a) >= 0 ? ROUNDU(a,b) : -ROUNDU(-a,b)) + +/* ROUNDUP_DIV gives the quotient rounded up to the next integer. + It works only on unsigned numbers +*/ + +#define ROUNDUP_DIV(dividend, divisor) ((dividend) + (divisor) - 1)/(divisor) + +#define IS_POWER_OF_TWO(n) ((((n)-1) & (n)) == 0x0) + +#endif + diff --git a/trunk/lib/util/include/girstring.h b/trunk/lib/util/include/girstring.h new file mode 100644 index 000000000..2728a5d2f --- /dev/null +++ b/trunk/lib/util/include/girstring.h @@ -0,0 +1,51 @@ +#ifndef GIRSTRING_H_INCLUDED +#define GIRSTRING_H_INCLUDED + +#include + +#include "xmlrpc_config.h" +#include "bool.h" + +bool +stripcaseeq(const char * const comparand, + const char * const comparator); + +static __inline__ bool +streq(const char * const comparator, + const char * const comparand) { + + return (strcmp(comparand, comparator) == 0); +} + +static __inline__ bool +memeq(const void * const comparator, + const void * const comparand, + size_t const size) { + + return (memcmp(comparator, comparand, size) == 0); +} + +#define MEMEQ(a,b,c) (memcmp(a, b, c) == 0) + +#define MEMSSET(a,b) (memset(a, b, sizeof(*a))) + +#define MEMSCPY(a,b) (memcpy(a, b, sizeof(*a))) + +#define MEMSZERO(a) (MEMSSET(a, 0)) + +static __inline__ const char * +sdup(const char * const input) { + return (const char *) strdup(input); +} + +/* Copy string pointed by B to array A with size checking. */ +#define STRSCPY(A,B) \ + (strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0') +#define STRSCMP(A,B) \ + (strncmp((A), (B), sizeof(A))) + +/* Concatenate string B onto string in array A with size checking */ +#define STRSCAT(A,B) \ + (strncat((A), (B), sizeof(A)-strlen(A)-1)) + +#endif diff --git a/trunk/lib/util/include/inline.h b/trunk/lib/util/include/inline.h new file mode 100644 index 000000000..f90032b28 --- /dev/null +++ b/trunk/lib/util/include/inline.h @@ -0,0 +1,19 @@ +#ifndef XMLRPC_INLINE_H_INCLUDED +#define XMLRPC_INLINE_H_INCLUDED + +/* Xmlrpc-c uses __inline__ to declare functions that should be + compiled as inline code. Some compilers, e.g. GNU, recognize the + __inline__ keyword. +*/ +#ifndef __GNUC__ +#ifndef __inline__ +#ifdef __sgi +#define __inline__ __inline +#else +#define __inline__ +#endif +#endif +#endif + + +#endif diff --git a/trunk/lib/util/include/int.h b/trunk/lib/util/include/int.h new file mode 100644 index 000000000..3c7b2163b --- /dev/null +++ b/trunk/lib/util/include/int.h @@ -0,0 +1,63 @@ +/* This takes the place of C99 inttypes.h, which at least some Windows + compilers don't have. (October 2007). +*/ + +/* PRId64 is the printf-style format specifier for a long long type, as in + long long mynumber = 5; + printf("My number is %" PRId64 ".\n", mynumber); + + The LL/ULL macro is for 64 bit integer literals, like this: + + long long mask= ULL(1) << 33; +*/ + +/* 'uint' is quite convenient, but there's no simple way have it everywhere. + Some systems have it in the base system (e.g. GNU C library has it in + , and others (e.g. Solaris - 08.12.02) don't. Since we + can't define it unless we know it's not defined already, and we don't + want to burden the reader with a special Xmlrpc-c name such as xuint, + we just use standard "unsigned int" instead. +*/ + +#ifdef _MSC_VER +# define PRId64 "I64d" +# define PRIu64 "I64u" + +#ifndef int16_t +typedef short int16_t; +#endif +#ifndef uint16_t +typedef unsigned short uint16_t; +#endif +#ifndef int32_t +typedef int int32_t; +#endif +#ifndef uint32_t +typedef unsigned int uint32_t; +#endif +#ifndef int64_t +typedef __int64 int64_t; +#endif +#ifndef uint64_t +typedef unsigned __int64 uint64_t; +#endif +#ifndef uint8_t +typedef unsigned char uint8_t; +#endif + +/* Older Microsoft compilers don't know the standard ll/ull suffixes */ +#define LL(x) x ## i64 +#define ULL(x) x ## u64 + +#elif defined(__INTERIX) +# include +# define PRId64 "I64d" +# define PRIu64 "I64u" + +#else + /* Not Microsoft compiler */ + #include + #define LL(x) x ## ll + #define ULL(x) x ## ull +#endif + diff --git a/trunk/lib/util/include/linklist.h b/trunk/lib/util/include/linklist.h new file mode 100644 index 000000000..f6f264129 --- /dev/null +++ b/trunk/lib/util/include/linklist.h @@ -0,0 +1,193 @@ +#ifndef LINKLIST_H_INCLUDED +#define LINKLIST_H_INCLUDED + +#include "inline.h" + +struct list_head { +/*---------------------------------------------------------------------------- + This is a header for an element of a doubly linked list, or an anchor + for such a list. + + itemP == NULL means it's an anchor; otherwise it's a header. + + Initialize a list header with list_init_header(). You don't have to + do anything to terminate a list header. + + Initialize an anchor with list_make_emtpy(). You don't have to do anything + to terminate a list header. +-----------------------------------------------------------------------------*/ + struct list_head * nextP; + /* For a header, this is the address of the list header for + the next element in the list. If there is no next element, + it points to the anchor. If the header is not in a list at + all, it is NULL. + + For an anchor, it is the address of the list header of the + first element. If the list is empty, it points to the + anchor itself. + */ + struct list_head * prevP; + /* For a header, this is the address of the list header for + the previous element in the list. If there is no previous element, + it points to the anchor. If the header is not in a list at + all, it is NULL. + + For an anchor, it is the address of the list header of the + last element. If the list is empty, it points to the + anchor itself. + */ + void * itemP; + /* For a header, this is the address of the list element to which it + belongs. For an anchor, this is NULL. + */ +}; + +static __inline__ void +list_init_header(struct list_head * const headerP, + void * const itemP) { + + headerP->prevP = NULL; + headerP->nextP = NULL; + headerP->itemP = itemP; +} + + + +static __inline__ int +list_is_linked(struct list_head * headerP) { + return headerP->prevP != NULL; +} + + + +static __inline__ int +list_is_empty(struct list_head * const anchorP) { + return anchorP->nextP == anchorP; +} + + + +static __inline__ unsigned int +list_count(struct list_head * const anchorP) { + unsigned int count; + + struct list_head * p; + + for (p = anchorP->nextP, count = 0; + p != anchorP; + p = p->nextP, ++count); + + return count; +} + + + +static __inline__ void +list_make_empty(struct list_head * const anchorP) { + anchorP->prevP = anchorP; + anchorP->nextP = anchorP; + anchorP->itemP = NULL; +} + +static __inline__ void +list_insert_after(struct list_head * const beforeHeaderP, + struct list_head * const newHeaderP) { + newHeaderP->prevP = beforeHeaderP; + newHeaderP->nextP = beforeHeaderP->nextP; + + beforeHeaderP->nextP = newHeaderP; + newHeaderP->nextP->prevP = newHeaderP; +} + + + +static __inline__ void +list_add_tail(struct list_head * const anchorP, + struct list_head * const headerP) { + list_insert_after(anchorP->prevP, headerP); +} + + + +static __inline__ void +list_add_head(struct list_head * const anchorP, + struct list_head * const headerP) { + list_insert_after(anchorP, headerP); +} + + + +static __inline__ void +list_remove(struct list_head * const headerP) { + headerP->prevP->nextP = headerP->nextP; + headerP->nextP->prevP = headerP->prevP; + headerP->prevP = NULL; + headerP->nextP = NULL; +} + + + +static __inline__ struct list_head * +list_remove_head(struct list_head * const anchorP) { + struct list_head * retval; + + if (list_is_empty(anchorP)) + retval = NULL; + else { + retval = anchorP->nextP; + list_remove(retval); + } + return retval; +} + + + +static __inline__ struct list_head * +list_remove_tail(struct list_head * const anchorP) { + struct list_head * retval; + + if (list_is_empty(anchorP)) + retval = NULL; + else { + retval = anchorP->prevP; + list_remove(retval); + } + return retval; +} + + + +static __inline__ void * +list_foreach(struct list_head * const anchorP, + void * functionP(struct list_head *, void *), + void * const context) { + + struct list_head * p; + struct list_head * nextP; + void * result; + + for (p = anchorP->nextP, nextP = p->nextP, result=NULL; + p != anchorP && result == NULL; + p = nextP, nextP = p->nextP) + result = (*functionP)(p, context); + + return result; +} + + + +static __inline__ void +list_append(struct list_head * const newAnchorP, + struct list_head * const baseAnchorP) { + + if (!list_is_empty(newAnchorP)) { + baseAnchorP->prevP->nextP = newAnchorP->nextP; + newAnchorP->nextP->prevP = baseAnchorP->prevP; + newAnchorP->prevP->nextP = baseAnchorP; + baseAnchorP->prevP = newAnchorP->prevP; + } +} + +#endif + + diff --git a/trunk/lib/util/include/mallocvar.h b/trunk/lib/util/include/mallocvar.h new file mode 100644 index 000000000..12ca9d92a --- /dev/null +++ b/trunk/lib/util/include/mallocvar.h @@ -0,0 +1,111 @@ +/* These are some dynamic memory allocation facilities. They are essentially + an extension to C, as they do allocations with a cognizance of C + variables. You can use them to make C read more like a high level + language. + + Before including this, you must define an __inline__ macro if your + compiler doesn't recognize it as a keyword. +*/ + +#ifndef MALLOCVAR_INCLUDED +#define MALLOCVAR_INCLUDED + +#include "xmlrpc_config.h" + +#include +#include + +static __inline__ void +mallocProduct(void ** const resultP, + unsigned int const factor1, + size_t const factor2) { +/*---------------------------------------------------------------------------- + malloc a space whose size in bytes is the product of 'factor1' and + 'factor2'. But if that size cannot be represented as an unsigned int, + return NULL without allocating anything. Also return NULL if the malloc + fails. + + If either factor is zero, malloc a single byte. + + Note that malloc() actually takes a size_t size argument, so the + proper test would be whether the size can be represented by size_t, + not unsigned int. But there is no reliable indication available to + us, like UINT_MAX, of what the limitations of size_t are. We + assume size_t is at least as expressive as unsigned int and that + nobody really needs to allocate more than 4GB of memory. +-----------------------------------------------------------------------------*/ + if (factor1 == 0 || factor2 == 0) + *resultP = malloc(1); + else { + if (UINT_MAX / factor2 < factor1) + *resultP = NULL; + else + *resultP = malloc(factor1 * factor2); + } +} + + + +static __inline__ void +reallocProduct(void ** const blockP, + unsigned int const factor1, + unsigned int const factor2) { + + void * const oldBlockP = *blockP; + + void * newBlockP; + + if (UINT_MAX / factor2 < factor1) + newBlockP = NULL; + else + newBlockP = realloc(oldBlockP, factor1 * factor2); + + if (newBlockP) + *blockP = newBlockP; + else { + free(oldBlockP); + *blockP = NULL; + } +} + + +/* IMPLEMENTATION NOTE: There are huge strict aliasing pitfalls here + if you cast pointers, e.g. (void **) +*/ + +#define MALLOCARRAY(arrayName, nElements) do { \ + void * array; \ + mallocProduct(&array, nElements, sizeof(arrayName[0])); \ + arrayName = array; \ +} while (0) + +#define REALLOCARRAY(arrayName, nElements) do { \ + void * array = arrayName; \ + reallocProduct(&array, nElements, sizeof(arrayName[0])); \ + arrayName = array; \ +} while (0) + + +#define MALLOCARRAY_NOFAIL(arrayName, nElements) \ +do { \ + MALLOCARRAY(arrayName, nElements); \ + if ((arrayName) == NULL) \ + abort(); \ +} while(0) + +#define REALLOCARRAY_NOFAIL(arrayName, nElements) \ +do { \ + REALLOCARRAY(arrayName, nElements); \ + if ((arrayName) == NULL) \ + abort(); \ +} while(0) + + +#define MALLOCVAR(varName) \ + varName = malloc(sizeof(*varName)) + +#define MALLOCVAR_NOFAIL(varName) \ + do {if ((varName = malloc(sizeof(*varName))) == NULL) abort();} while(0) + +#endif + diff --git a/trunk/lib/util/include/stdargx.h b/trunk/lib/util/include/stdargx.h new file mode 100644 index 000000000..cd4f2ec41 --- /dev/null +++ b/trunk/lib/util/include/stdargx.h @@ -0,0 +1,67 @@ +#ifndef STDARGX_H_INCLUDED +#define STDARGX_H_INCLUDED + +#include "xmlrpc_config.h" +#include +#include + +/*---------------------------------------------------------------------------- + We need a special version of va_list in order to pass around the + variable argument heap by reference, thus allowing a subroutine to + advance the heap's pointer. + + On some systems (e.g. Gcc for PPC or AMD64), va_list is an array. + That invites the scourge of array-to-pointer degeneration if you try + to take its address. Burying it inside a struct as we do with our + va_listx type makes it immune. + + Example of what would happen if we used va_list instead of va_listx, + on a system where va_list is an array: + + void sub2(va_list * argsP) [ + ... + } + + void sub1(va_list args) { + sub2(&args); + } + + This doesn't work. '&args' is the same thing as 'args', so is + va_list, not va_list *. The compiler will even warn you about the + pointer type mismatch. + + To use va_listx: + + void sub1_va(char * format, va_list args) { + va_listx argsx; + init_va_listx(&argsx, args); + sub2(format, &argsx); + } + +-----------------------------------------------------------------------------*/ + + +typedef struct { +/*---------------------------------------------------------------------------- + Same thing as va_list, but in a form that works everywhere. See above. +-----------------------------------------------------------------------------*/ + va_list v; +} va_listx; + + + +static __inline__ void +init_va_listx(va_listx * const argsxP, + va_list const args) { +#if VA_LIST_IS_ARRAY + /* 'args' is NOT a va_list. It is a pointer to the first element of a + 'va_list', which is the same address as a pointer to the va_list + itself. (That's what happens when you pass an array in C). + */ + memcpy(&argsxP->v, args, sizeof(argsxP->v)); +#else + argsxP->v = args; +#endif +} + +#endif diff --git a/trunk/lib/util/include/string_parser.h b/trunk/lib/util/include/string_parser.h new file mode 100644 index 000000000..290d749bd --- /dev/null +++ b/trunk/lib/util/include/string_parser.h @@ -0,0 +1,31 @@ +#ifndef STRING_PARSER_H_INCLUDED +#define STRING_PARSER_H_INCLUDED + +#include "int.h" + +void +interpretUll(const char * const string, + uint64_t * const ullP, + const char ** const errorP); + +void +interpretLl(const char * const string, + int64_t * const llP, + const char ** const errorP); + +void +interpretUint(const char * const string, + unsigned int * const uintP, + const char ** const errorP); + +void +interpretInt(const char * const string, + int * const uintP, + const char ** const errorP); + +void +interpretBinUint(const char * const string, + uint64_t * const valueP, + const char ** const errorP); + +#endif diff --git a/trunk/lib/util/include/unistdx.h b/trunk/lib/util/include/unistdx.h new file mode 100644 index 000000000..69f1f6bb7 --- /dev/null +++ b/trunk/lib/util/include/unistdx.h @@ -0,0 +1,14 @@ +#ifndef UNISTDX_H_INCLUDED +#define UNISTDX_H_INCLUDED + +/* Xmlrpc-c code #includes "unistdx.h" instead of because + does not exist on WIN32. +*/ + +#ifndef WIN32 +# include +#else + +#endif /* WIN32 */ + +#endif diff --git a/trunk/lib/util/string_parser.c b/trunk/lib/util/string_parser.c new file mode 100644 index 000000000..3c1fdf591 --- /dev/null +++ b/trunk/lib/util/string_parser.c @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "int.h" +#include "girstring.h" +#include "casprintf.h" + +#include "string_parser.h" + +static const char * +strippedSubstring(const char * const string) { + + const char * p; + + for (p = &string[0]; isspace(*p); ++p); + + return p; +} + + + +void +interpretUll(const char * const string, + uint64_t * const ullP, + const char ** const errorP) { + + /* strtoull() has the same disappointing weaknesses of strtoul(). + See interpretUint(). + */ + + const char * const strippedString = strippedSubstring(string); + + if (strippedString[0] == '\0') + casprintf(errorP, "Null (or all whitespace) string."); + else if (!isdigit(strippedString[0])) + casprintf(errorP, "First non-blank character is '%c', not a digit.", + strippedString[0]); + else { + /* strtoull() does a bizarre thing where if the number is out + of range, it returns a clamped value but tells you about it + by setting errno = ERANGE. If it is not out of range, + strtoull() leaves errno alone. + */ + char * tail; + + errno = 0; /* So we can tell if strtoull() overflowed */ + + *ullP = XMLRPC_STRTOULL(strippedString, &tail, 10); + + if (tail[0] != '\0') + casprintf(errorP, "Non-digit stuff in string: %s", tail); + else if (errno == ERANGE) + casprintf(errorP, "Number too large"); + else + *errorP = NULL; + } +} + + + +void +interpretLl(const char * const string, + int64_t * const llP, + const char ** const errorP) { + + if (string[0] == '\0') + casprintf(errorP, "Null string."); + else { + /* strtoll() does a bizarre thing where if the number is out + of range, it returns a clamped value but tells you about it + by setting errno = ERANGE. If it is not out of range, + strtoll() leaves errno alone. + */ + char * tail; + + errno = 0; /* So we can tell if strtoll() overflowed */ + + *llP = XMLRPC_STRTOLL(string, &tail, 10); + + if (tail[0] != '\0') + casprintf(errorP, "Non-digit stuff in string: %s", tail); + else if (errno == ERANGE) + casprintf(errorP, "Number too large"); + else + *errorP = NULL; + } +} + + + +void +interpretUint(const char * const string, + unsigned int * const uintP, + const char ** const errorP) { + + /* strtoul() does a lousy job of dealing with invalid numbers. A null + string is just zero; a negative number is a large positive one; a + positive (cf unsigned) number is accepted. strtoul is inconsistent + in its treatment of the tail; if there is no valid number at all, + it returns the entire string as the tail, including leading white + space and sign, which are not themselves invalid. + */ + + const char * const strippedString = strippedSubstring(string); + + if (strippedString[0] == '\0') + casprintf(errorP, "Null (or all whitespace) string."); + else if (!isdigit(strippedString[0])) + casprintf(errorP, "First non-blank character is '%c', not a digit.", + strippedString[0]); + else { + /* strtoul() does a bizarre thing where if the number is out + of range, it returns a clamped value but tells you about it + by setting errno = ERANGE. If it is not out of range, + strtoul() leaves errno alone. + */ + char * tail; + unsigned long ulongValue; + + errno = 0; /* So we can tell if strtoul() overflowed */ + + ulongValue = strtoul(strippedString, &tail, 10); + + if (tail[0] != '\0') + casprintf(errorP, "Non-digit stuff in string: %s", tail); + else if (errno == ERANGE) + casprintf(errorP, "Number too large"); + else if (ulongValue > UINT_MAX) + casprintf(errorP, "Number too large"); + else { + *uintP = ulongValue; + *errorP = NULL; + } + } +} + + + +void +interpretInt(const char * const string, + int * const intP, + const char ** const errorP) { + + if (string[0] == '\0') + casprintf(errorP, "Null string."); + else { + /* strtol() does a bizarre thing where if the number is out + of range, it returns a clamped value but tells you about it + by setting errno = ERANGE. If it is not out of range, + strtol() leaves errno alone. + */ + char * tail; + long longValue; + + errno = 0; /* So we can tell if strtol() overflowed */ + + longValue = strtol(string, &tail, 10); + + if (tail[0] != '\0') + casprintf(errorP, "Non-digit stuff in string: %s", tail); + else if (errno == ERANGE) + casprintf(errorP, "Number too large"); + else if (longValue > INT_MAX) + casprintf(errorP, "Number too large"); + else if (longValue < INT_MIN) + casprintf(errorP, "Number too negative"); + else { + *intP = longValue; + *errorP = NULL; + } + } +} + + + +void +interpretBinUint(const char * const string, + uint64_t * const valueP, + const char ** const errorP) { + + char * tailptr; + long const mantissa_long = strtol(string, &tailptr, 10); + + if (errno == ERANGE) + casprintf(errorP, + "Numeric value out of range for computation: '%s'. " + "Try a smaller number with a K, M, G, etc. suffix.", + string); + else { + int64_t const mantissa = mantissa_long; + + int64_t argNumber; + + *errorP = NULL; /* initial assumption */ + + if (*tailptr == '\0') + /* There's no suffix. A pure number */ + argNumber = mantissa * 1; + else if (stripcaseeq(tailptr, "K")) + argNumber = mantissa * 1024; + else if (stripcaseeq(tailptr, "M")) + argNumber = mantissa * 1024 * 1024; + else if (stripcaseeq(tailptr, "G")) + argNumber = mantissa * 1024 * 1024 * 1024; + else if (stripcaseeq(tailptr, "T")) + argNumber = mantissa * 1024 * 1024 * 1024 * 1024; + else if (stripcaseeq(tailptr, "P")) + argNumber = mantissa * 1024 * 1024 * 1024 * 1024 * 1024; + else { + argNumber = 0; /* quiet compiler warning */ + casprintf(errorP, "Garbage suffix '%s' on number", tailptr); + } + if (!*errorP) { + if (argNumber < 0) + casprintf(errorP, "Unsigned numeric value is " + "negative: %" PRId64, argNumber); + else + *valueP = (uint64_t) argNumber; + } + } +} diff --git a/trunk/lib/util/stripcaseeq.c b/trunk/lib/util/stripcaseeq.c new file mode 100644 index 000000000..861da1084 --- /dev/null +++ b/trunk/lib/util/stripcaseeq.c @@ -0,0 +1,68 @@ +#include + +#include "bool.h" +#include "girstring.h" + + + +bool +stripcaseeq(const char * const comparand, + const char * const comparator) { +/*---------------------------------------------------------------------------- + Compare two strings, ignoring leading and trailing blanks and case. + + Return true if the strings are identical, false otherwise. +-----------------------------------------------------------------------------*/ + const char *p, *q, *px, *qx; + bool equal; + + /* Make p and q point to the first non-blank character in each string. + If there are no non-blank characters, make them point to the terminating + NULL. + */ + + p = &comparand[0]; + while (*p == ' ') + ++p; + q = &comparator[0]; + while (*q == ' ') + ++q; + + /* Make px and qx point to the last non-blank character in each string. + If there are no nonblank characters (which implies the string is + null), make them point to the terminating NULL. + */ + + if (*p == '\0') + px = p; + else { + px = p + strlen(p) - 1; + while (*px == ' ') + --px; + } + + if (*q == '\0') + qx = q; + else { + qx = q + strlen(q) - 1; + while (*qx == ' ') + --qx; + } + + equal = true; /* initial assumption */ + + /* If the stripped strings aren't the same length, + we know they aren't equal + */ + if (px - p != qx - q) + equal = false; + + + while (p <= px) { + if (toupper(*p) != toupper(*q)) + equal = false; + ++p; ++q; + } + return equal; +} + diff --git a/trunk/lib/wininet_transport/Makefile b/trunk/lib/wininet_transport/Makefile new file mode 100644 index 000000000..9ee33f46e --- /dev/null +++ b/trunk/lib/wininet_transport/Makefile @@ -0,0 +1,61 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + LIBDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(LIBDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := lib/wininet_transport + +include $(BLDDIR)/config.mk + +default: all + +.PHONY: all +all: xmlrpc_wininet_transport.o xmlrpc_wininet_transport.osh + +# Rules for the above dependencies are in common.mk, +# courtesy of TARGET_MODS. + +TARGET_MODS = xmlrpc_wininet_transport + +OMIT_WININET_TRANSPORT_RULE=Y + +include $(SRCDIR)/common.mk + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +INCLUDES = \ + -I$(BLDDIR) \ + -I$(BLDDIR)/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include \ + +.PHONY: clean +clean: clean-common + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: tags +tags: TAGS + +.PHONY: distdir +distdir: + +.PHONY: install +install: + +.PHONY: uninstall +uninstall: + +.PHONY: dep +dep: dep-common + +include depend.mk + +# Need this dependency for those who don't use depend.mk. +# Without it, version.h doesn't get created. +xmlrpc_wininet_transport.o xmlrpc_wininet_transport.osh: version.h diff --git a/trunk/lib/wininet_transport/pthreadx.h b/trunk/lib/wininet_transport/pthreadx.h new file mode 100644 index 000000000..23ebabdc7 --- /dev/null +++ b/trunk/lib/wininet_transport/pthreadx.h @@ -0,0 +1,73 @@ +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ + +#ifndef PTHREADX_H_INCLUDED +#define PTHREADX_H_INCLUDED + +#include "xmlrpc_config.h" + +#if HAVE_PTHREAD +# define _REENTRANT +# include +#elif HAVE_WINDOWS_THREAD +/* We define WIN32_WIN_LEAN_AND_MEAN to make contain less + junk; nothing in Xmlrpc-c needs that stuff. One significant thing it cuts + out is , which would conflict with the that our + includer might use. +*/ +#define WIN32_WIN_LEAN_AND_MEAN +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef HANDLE pthread_t; + +typedef +struct { + int attrs; /* currently unused. placeholder. */ +} pthread_attr_t; + +typedef void * pthread_func(void *); + +extern int pthread_create(pthread_t * const new_thread_ID, + const pthread_attr_t * const attr, + pthread_func * start_func, + void * const arg); +extern int pthread_cancel(pthread_t target_thread); +extern int pthread_join(pthread_t target_thread, void **status); +extern int pthread_detach(pthread_t target_thread); + +#ifdef __cplusplus +} +#endif +#else /* HAVE_WINDOWS_THREAD */ + #error "You don't have any thread facility. (According to " + #error "HAVE_PTHREAD and HAVE_WINDOWS_THREAD macros defined in " + #error "xmlrpc_config.h)" +#endif + +#endif diff --git a/trunk/lib/wininet_transport/pthreadx_win32.c b/trunk/lib/wininet_transport/pthreadx_win32.c new file mode 100644 index 000000000..4055dcca8 --- /dev/null +++ b/trunk/lib/wininet_transport/pthreadx_win32.c @@ -0,0 +1,121 @@ +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ + +#include "xmlrpc_config.h" + +#include + +#include "mallocvar.h" + +#include "pthreadx.h" + +#undef PACKAGE +#undef VERSION + +struct winStartArg { + pthread_func * func; + void * arg; +}; + + + +static unsigned int __stdcall +winThreadStart(void * const arg) { +/*---------------------------------------------------------------------------- + This is a thread start/root function for the Windows threading facility + (i.e. this can be an argument to _beginthreadex()). + + All we do is call the real start/root function, which expects to be + called in the pthread format. +-----------------------------------------------------------------------------*/ + struct winStartArg * const winStartArgP = arg; + + winStartArgP->func(winStartArgP->arg); + + free(winStartArgP); + + return 0; +} + + + +int +pthread_create(pthread_t * const newThreadIdP, + const pthread_attr_t * const attr, + pthread_func * func, + void * const arg) { + + HANDLE hThread; + DWORD dwThreadID; + struct winStartArg * winStartArgP; + + MALLOCVAR_NOFAIL(winStartArgP); + + winStartArgP->func = func; + winStartArgP->arg = arg; + + hThread = (HANDLE) _beginthreadex( + NULL, 0, &winThreadStart, (LPVOID)winStartArgP, CREATE_SUSPENDED, + &dwThreadID); + + SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL); + ResumeThread(hThread); + + *newThreadIdP = hThread; + + return hThread ? 0 : -1; +} + + + +/* Just kill it. */ +int +pthread_cancel(pthread_t const target_thread) { + + CloseHandle(target_thread); + return 0; +} + + + +/* Waits for the thread to exit before continuing. */ +int +pthread_join(pthread_t const target_thread, + void ** const statusP) { + + DWORD dwResult = WaitForSingleObject(target_thread, INFINITE); + *statusP = (void *)dwResult; + return 0; +} + + + +int +pthread_detach(pthread_t const target_thread) { + return 0; +} + + + diff --git a/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c b/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c new file mode 100644 index 000000000..858a7b461 --- /dev/null +++ b/trunk/lib/wininet_transport/xmlrpc_wininet_transport.c @@ -0,0 +1,1001 @@ +/*============================================================================= + xmlrpc_wininet_transport +=============================================================================== + WinInet-based client transport for Xmlrpc-c. Copyright information at + the bottom of this file. + +=============================================================================*/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include "bool.h" +#include "mallocvar.h" +#include "linklist.h" +#include "casprintf.h" +#include "pthreadx.h" + +#include "xmlrpc-c/lock.h" +#include "xmlrpc-c/lock_platform.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/client_int.h" +#include "xmlrpc-c/transport.h" + +#if defined(_DEBUG) +# include +# define new DEBUG_NEW +# define malloc(size) _malloc_dbg( size, _NORMAL_BLOCK, __FILE__, __LINE__) +# undef THIS_FILE + static char THIS_FILE[] = __FILE__; +#endif + + +static HINTERNET hSyncInternetSession = NULL; + +/* Declare WinInet status callback. */ +void CALLBACK +statusCallback(HINTERNET const hInternet, + unsigned long const dwContext, + unsigned long const dwInternetStatus, + void * const lpvStatusInformation, + unsigned long const dwStatusInformationLength); + + +struct xmlrpc_client_transport { + struct lock * listLockP; + struct list_head rpcList; + /* List of all RPCs that exist for this transport. An RPC exists + from the time the user requests it until the time the user + acknowledges it is done. + */ + int allowInvalidSSLCerts; + /* Flag to specify if we ignore invalid SSL Certificates. If this + is set to zero, calling a XMLRPC server with an invalid SSL + certificate will fail. This is the default behavior of the other + transports, but invalid certificates were allowed in pre 1.2 + wininet xmlrpc-c transports. + */ +}; + +typedef struct { + unsigned long http_status; + HINTERNET hHttpRequest; + HINTERNET hURL; + INTERNET_PORT nPort; + char szHostName[255]; + char szUrlPath[255]; + BOOL bUseSSL; + char * headerList; + BYTE * pSendData; + xmlrpc_mem_block * pResponseData; +} winInetTransaction; + +typedef struct { + struct list_head link; /* link in transport's list of RPCs */ + winInetTransaction * winInetTransactionP; + /* The object which does the HTTP transaction, with no knowledge + of XML-RPC or Xmlrpc-c. + */ + xmlrpc_mem_block * responseXmlP; + xmlrpc_bool threadExists; + pthread_t thread; + xmlrpc_transport_asynch_complete complete; + /* Routine to call to complete the RPC after it is complete HTTP-wise. + NULL if none. + */ + struct xmlrpc_call_info * callInfoP; + /* User's identifier for this RPC */ + struct xmlrpc_client_transport * clientTransportP; +} rpc; + + + +static void +createWinInetHeaderList(xmlrpc_env * const envP, + const xmlrpc_server_info * const serverP, + char ** const headerListP) { + + const char * const szContentType = "Content-Type: text/xml\r\n"; + + char * szHeaderList; + + /* Send an authorization header if we need one. */ + if (serverP->allowedAuth.basic) { + /* Make the header with content type and authorization */ + /* NOTE: A newline is required between each added header */ + szHeaderList = malloc(strlen(szContentType) + 17 + + strlen(serverP->basicAuthHdrValue) + 1); + + if (szHeaderList == NULL) + xmlrpc_faultf(envP, + "Couldn't allocate memory for authorization header"); + else { + memcpy(szHeaderList, szContentType, strlen(szContentType)); + memcpy(szHeaderList + strlen(szContentType),"\r\nAuthorization: ", + 17); + memcpy(szHeaderList + strlen(szContentType) + 17, + serverP->basicAuthHdrValue, + strlen(serverP->basicAuthHdrValue) + 1); + } + } else { + /* Just the content type header is needed */ + szHeaderList = malloc(strlen(szContentType) + 1); + + if (szHeaderList == NULL) + xmlrpc_faultf(envP, + "Couldn't allocate memory for standard header"); + else + memcpy(szHeaderList, szContentType, strlen(szContentType) + 1); + } + *headerListP = szHeaderList; +} + + + +static void +createWinInetTransaction(xmlrpc_env * const envP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block * const responseXmlP, + winInetTransaction ** const winInetTranPP) { + + winInetTransaction * winInetTransactionP; + + MALLOCVAR(winInetTransactionP); + if (winInetTransactionP == NULL) + xmlrpc_faultf(envP, "No memory to create WinInet transaction."); + else { + char szExtraInfo[255]; + char szScheme[100]; + URL_COMPONENTS uc; + BOOL succeeded; + + /* Init to defaults */ + winInetTransactionP->http_status = 0; + winInetTransactionP->hHttpRequest = NULL; + winInetTransactionP->hURL = NULL; + winInetTransactionP->headerList = NULL; + winInetTransactionP->pSendData = NULL; + winInetTransactionP->pResponseData = responseXmlP; + + /* Parse the URL and store results into the winInetTransaction */ + + memset(&uc, 0, sizeof(uc)); + uc.dwStructSize = sizeof (uc); + uc.lpszScheme = szScheme; + uc.dwSchemeLength = 100; + uc.lpszHostName = winInetTransactionP->szHostName; + uc.dwHostNameLength = 255; + uc.lpszUrlPath = winInetTransactionP->szUrlPath; + uc.dwUrlPathLength = 255; + uc.lpszExtraInfo = szExtraInfo; + uc.dwExtraInfoLength = 255; + succeeded = InternetCrackUrl(serverP->serverUrl, + strlen(serverP->serverUrl), + ICU_ESCAPE, &uc); + if (!succeeded) + xmlrpc_faultf(envP, "Unable to parse the server URL."); + else { + winInetTransactionP->nPort = + uc.nPort ? uc.nPort : INTERNET_DEFAULT_HTTP_PORT; + if (_strnicmp(uc.lpszScheme, "https", 5) == 0) + winInetTransactionP->bUseSSL=TRUE; + else + winInetTransactionP->bUseSSL=FALSE; + createWinInetHeaderList(envP, serverP, + &winInetTransactionP->headerList); + + XMLRPC_MEMBLOCK_APPEND(char, envP, callXmlP, "\0", 1); + if (!envP->fault_occurred) { + winInetTransactionP->pSendData = + XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP); + } + } + + if (envP->fault_occurred) + free(winInetTransactionP); + } + *winInetTranPP = winInetTransactionP; +} + + + +static void +destroyWinInetTransaction(winInetTransaction * const winInetTransactionP) { + + XMLRPC_ASSERT_PTR_OK(winInetTransactionP); + + if (winInetTransactionP->hHttpRequest) + InternetCloseHandle(winInetTransactionP->hHttpRequest); + + if (winInetTransactionP->hURL) + InternetCloseHandle(winInetTransactionP->hURL); + + if (winInetTransactionP->headerList) + free(winInetTransactionP->headerList); + + free(winInetTransactionP); +} + + + +static void +get_wininet_response(xmlrpc_env * const envP, + winInetTransaction * const winInetTransactionP) { + + unsigned long dwLen; + INTERNET_BUFFERS inetBuffer; + unsigned long dwFlags; + unsigned long dwErr; + unsigned long nExpected; + void * body; + BOOL bOK; + PVOID pMsgMem; + + pMsgMem = NULL; /* initial value */ + dwErr = 0; /* initial value */ + body = NULL; /* initial value */ + dwLen = sizeof(unsigned long); /* initial value */ + + inetBuffer.dwStructSize = sizeof (INTERNET_BUFFERS); + inetBuffer.Next = NULL; + inetBuffer.lpcszHeader = NULL; + inetBuffer.dwHeadersTotal = 0; + inetBuffer.dwHeadersLength = 0; + inetBuffer.dwOffsetHigh = 0; + inetBuffer.dwOffsetLow = 0; + inetBuffer.dwBufferLength = 0; + + /* Note that while Content-Length is optional in HTTP 1.1, it is + required by XML-RPC. Following fails if server didn't send it. + */ + + bOK = HttpQueryInfo(winInetTransactionP->hHttpRequest, + HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, + &inetBuffer.dwBufferTotal, &dwLen, NULL); + if (!bOK) { + LPTSTR pMsg; + dwErr = GetLastError (); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &pMsgMem, + 1024,NULL); + + pMsg = pMsgMem ? (LPTSTR)pMsgMem : "Sync HttpQueryInfo failed."; + XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); + } + + if (inetBuffer.dwBufferTotal == 0) + XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, "WinInet returned no data"); + + inetBuffer.lpvBuffer = calloc(inetBuffer.dwBufferTotal, sizeof(TCHAR)); + body = inetBuffer.lpvBuffer; + dwFlags = IRF_SYNC; + nExpected = inetBuffer.dwBufferTotal; + inetBuffer.dwBufferLength = nExpected; + InternetQueryDataAvailable(winInetTransactionP->hHttpRequest, + &inetBuffer.dwBufferLength, 0, 0); + + /* Read Response from InternetFile */ + do { + if (inetBuffer.dwBufferLength != 0) + bOK = InternetReadFileEx(winInetTransactionP->hHttpRequest, + &inetBuffer, dwFlags, 1); + + if (!bOK) + dwErr = GetLastError(); + + if (dwErr) { + if (dwErr == WSAEWOULDBLOCK || dwErr == ERROR_IO_PENDING) { + /* Non-block socket operation wait 10 msecs */ + SleepEx(10, TRUE); + /* Reset dwErr to zero for next pass */ + dwErr = 0; + } else { + LPTSTR pMsg; + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &pMsgMem, + 1024,NULL); + pMsg = pMsgMem ? + (LPTSTR)pMsgMem : "ASync InternetReadFileEx failed."; + XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); + } + } + + if (inetBuffer.dwBufferLength) { + TCHAR * const oldBufptr = inetBuffer.lpvBuffer; + + inetBuffer.lpvBuffer = oldBufptr + inetBuffer.dwBufferLength; + nExpected -= inetBuffer.dwBufferLength; + /* Adjust inetBuffer.dwBufferLength when it is greater than the */ + /* expected end of file */ + if (inetBuffer.dwBufferLength > nExpected) + inetBuffer.dwBufferLength = nExpected; + + } else + inetBuffer.dwBufferLength = nExpected; + dwErr = 0; + } while (nExpected != 0); + + /* Add to the response buffer. */ + xmlrpc_mem_block_append(envP, winInetTransactionP->pResponseData, body, + inetBuffer.dwBufferTotal); + XMLRPC_FAIL_IF_FAULT(envP); + + cleanup: + /* Since the XMLRPC_FAIL calls goto cleanup, we must handle */ + /* the free'ing of the memory here. */ + if (pMsgMem != NULL) + LocalFree(pMsgMem); + + if (body) + free(body); +} + + + +static void +performWinInetTransaction( + xmlrpc_env * const envP, + winInetTransaction * const winInetTransactionP, + struct xmlrpc_client_transport * const clientTransportP) { + + const char * const acceptTypes[] = {"text/xml", NULL}; + + unsigned long queryLen; + LPVOID pMsgMem; + BOOL succeeded; + + unsigned long lastErr; + unsigned long reqFlags; + + pMsgMem = NULL; /* initial value */ + + reqFlags = INTERNET_FLAG_NO_UI; /* initial value */ + + winInetTransactionP->hURL = + InternetConnect(hSyncInternetSession, + winInetTransactionP->szHostName, + winInetTransactionP->nPort, + NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); + + /* Start our request running. */ + if (winInetTransactionP->bUseSSL == TRUE) + reqFlags |= + INTERNET_FLAG_SECURE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID; + + winInetTransactionP->hHttpRequest = + HttpOpenRequest(winInetTransactionP->hURL, "POST", + winInetTransactionP->szUrlPath, "HTTP/1.1", NULL, + (const char **)&acceptTypes, + reqFlags, 1); + + XMLRPC_FAIL_IF_NULL(winInetTransactionP->hHttpRequest, envP, + XMLRPC_INTERNAL_ERROR, + "Unable to open the requested URL."); + + succeeded = + HttpAddRequestHeaders(winInetTransactionP->hHttpRequest, + winInetTransactionP->headerList, + strlen (winInetTransactionP->headerList), + HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE); + + if (!succeeded) + XMLRPC_FAIL(envP, XMLRPC_INTERNAL_ERROR, + "Could not set Content-Type."); + + { + /* By default, a request times out after 30 seconds. We don't want + it to timeout at all, since we don't know what the user is doing. + */ + DWORD dwTimeOut = 0x7FFFFFFF; /* Approximation of infinity */ + InternetSetOption(winInetTransactionP->hHttpRequest, + INTERNET_OPTION_RECEIVE_TIMEOUT, + &dwTimeOut, sizeof(dwTimeOut)); + } +Again: + /* Send the requested XML remote procedure command */ + succeeded = HttpSendRequest(winInetTransactionP->hHttpRequest, NULL, 0, + winInetTransactionP->pSendData, + strlen(winInetTransactionP->pSendData)); + if (!succeeded) { + LPTSTR pMsg; + + lastErr = GetLastError(); + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &pMsgMem, + 0, NULL); + + if (pMsgMem == NULL) { + switch (lastErr) { + case ERROR_INTERNET_CANNOT_CONNECT: + pMsg = "Sync HttpSendRequest failed: Connection refused."; + break; + case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED: + pMsg = "Sync HttpSendRequest failed: " + "Client authorization certificate needed."; + break; + + /* The following conditions are recommendations that microsoft */ + /* provides in their knowledge base. */ + + /* HOWTO: Handle Invalid Certificate Authority Error with + WinInet (Q182888) + */ + case ERROR_INTERNET_INVALID_CA: + if (clientTransportP->allowInvalidSSLCerts){ + OutputDebugString( + "Sync HttpSendRequest failed: " + "The function is unfamiliar with the certificate " + "authority that generated the server's certificate. "); + reqFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; + + InternetSetOption(winInetTransactionP->hHttpRequest, + INTERNET_OPTION_SECURITY_FLAGS, + &reqFlags, sizeof(reqFlags)); + + goto Again; + } else + pMsg = "Invalid or unknown/untrusted " + "SSL Certificate Authority."; + break; + + /* HOWTO: Make SSL Requests Using WinInet (Q168151) */ + case ERROR_INTERNET_SEC_CERT_CN_INVALID: + if (clientTransportP->allowInvalidSSLCerts) { + OutputDebugString( + "Sync HttpSendRequest failed: " + "The SSL certificate common name (host name field) " + "is incorrect\r\n " + "for example, if you entered www.server.com " + "and the common name " + "on the certificate says www.different.com. "); + + reqFlags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID; + + InternetSetOption(winInetTransactionP->hHttpRequest, + INTERNET_OPTION_SECURITY_FLAGS, + &reqFlags, sizeof(reqFlags)); + + goto Again; + } else + pMsg = "The SSL certificate common name " + "(host name field) is incorrect."; + break; + + case ERROR_INTERNET_SEC_CERT_DATE_INVALID: + if (clientTransportP->allowInvalidSSLCerts) { + OutputDebugString( + "Sync HttpSendRequest failed: " + "The SSL certificate date that was received " + "from the server is " + "bad. The certificate is expired. "); + + reqFlags |= INTERNET_FLAG_IGNORE_CERT_DATE_INVALID; + + InternetSetOption(winInetTransactionP->hHttpRequest, + INTERNET_OPTION_SECURITY_FLAGS, + &reqFlags, sizeof(reqFlags)); + + goto Again; + } else + pMsg = "The SSL certificate date that was received " + "from the server is invalid."; + break; + + case ERROR_INTERNET_SEC_CERT_REV_FAILED: + if (clientTransportP->allowInvalidSSLCerts) { + OutputDebugString( + "Sync HttpSendRequest failed: " + "Check for revocation of the SSL certificate " + "failed. "); + + reqFlags |= SECURITY_FLAG_IGNORE_REVOCATION; + + InternetSetOption(winInetTransactionP->hHttpRequest, + INTERNET_OPTION_SECURITY_FLAGS, + &reqFlags, sizeof(reqFlags)); + + goto Again; + } else + pMsg = "Check for revocation of the SSL certificate " + "failed."; + break; + + default: + pMsg = (LPTSTR)pMsgMem = LocalAlloc(LPTR, MAX_PATH); + sprintf(pMsg, "Sync HttpSendRequest failed: " + "GetLastError (%d)", lastErr); + break; + + } + } else + pMsg = (LPTSTR)pMsgMem; + + XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); + } + + queryLen = sizeof(unsigned long); /* initial value */ + + succeeded = HttpQueryInfo(winInetTransactionP->hHttpRequest, + HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, + &winInetTransactionP->http_status, + &queryLen, NULL); + if (!succeeded) { + LPTSTR pMsg; + + lastErr = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + lastErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &pMsgMem, + 1024, NULL); + + pMsg = pMsgMem ? (LPTSTR)pMsgMem : "Sync HttpQueryInfo failed."; + XMLRPC_FAIL(envP, XMLRPC_NETWORK_ERROR, pMsg); + } + + /* Make sure we got a "200 OK" message from the remote server. */ + if (winInetTransactionP->http_status != 200) { + unsigned long msgLen; + char errMsg[1024]; + errMsg[0] = '\0'; + msgLen = 1024; /* initial value */ + + HttpQueryInfo(winInetTransactionP->hHttpRequest, + HTTP_QUERY_STATUS_TEXT, errMsg, &msgLen, NULL); + + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_NETWORK_ERROR, + "HTTP error #%d occurred\n %s", + winInetTransactionP->http_status, errMsg); + goto cleanup; + } + /* Read the response. */ + get_wininet_response(envP, winInetTransactionP); + XMLRPC_FAIL_IF_FAULT(envP); + + cleanup: + /* Since the XMLRPC_FAIL calls goto cleanup, we must handle */ + /* the free'ing of the memory here. */ + if (pMsgMem) + LocalFree(pMsgMem); +} + + + +static void * +doAsyncRpc(void * const arg) { + + rpc * const rpcP = arg; + + xmlrpc_env env; + xmlrpc_env_init(&env); + + performWinInetTransaction(&env, rpcP->winInetTransactionP, + rpcP->clientTransportP ); + + rpcP->complete(rpcP->callInfoP, rpcP->responseXmlP, env); + + xmlrpc_env_clean(&env); + + return NULL; +} + + + +static void +createRpcThread(xmlrpc_env * const envP, + rpc * const rpcP, + pthread_t * const threadP) { + + int rc; + + rc = pthread_create(threadP, NULL, doAsyncRpc, rpcP); + switch (rc) { + case 0: + break; + case EAGAIN: + xmlrpc_faultf(envP, "pthread_create() failed: " + "System Resources exceeded."); + break; + case EINVAL: + xmlrpc_faultf(envP, "pthread_create() failed: " + "Param Error for attr."); + break; + case ENOMEM: + xmlrpc_faultf(envP, "pthread_create() failed: " + "No memory for new thread."); + break; + default: + xmlrpc_faultf(envP, "pthread_create() failed: " + "Unrecognized error code %d.", rc); + break; + } +} + + + +static void +rpcCreate(xmlrpc_env * const envP, + struct xmlrpc_client_transport * const clientTransportP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block * const responseXmlP, + xmlrpc_transport_asynch_complete complete, + struct xmlrpc_call_info * const callInfoP, + rpc ** const rpcPP) { + + rpc * rpcP; + + MALLOCVAR(rpcP); + if (rpcP == NULL) + xmlrpc_faultf(envP, "Couldn't allocate memory for rpc object"); + else { + rpcP->callInfoP = callInfoP; + rpcP->complete = complete; + rpcP->responseXmlP = responseXmlP; + rpcP->threadExists = FALSE; + + createWinInetTransaction(envP, serverP, callXmlP, responseXmlP, + &rpcP->winInetTransactionP); + if (!envP->fault_occurred) { + if (complete) { + createRpcThread(envP, rpcP, &rpcP->thread); + if (!envP->fault_occurred) + rpcP->threadExists = TRUE; + } + if (!envP->fault_occurred) { + list_init_header(&rpcP->link, rpcP); + clientTransportP->listLockP->acquire( + clientTransportP->listLockP); + list_add_head(&clientTransportP->rpcList, &rpcP->link); + clientTransportP->listLockP->release( + clientTransportP->listLockP); + } + if (envP->fault_occurred) + destroyWinInetTransaction(rpcP->winInetTransactionP); + } + if (envP->fault_occurred) + free(rpcP); + } + *rpcPP = rpcP; +} + + + +static void +rpcDestroy(rpc * const rpcP) { + + XMLRPC_ASSERT_PTR_OK(rpcP); + XMLRPC_ASSERT(!rpcP->threadExists); + + destroyWinInetTransaction(rpcP->winInetTransactionP); + + list_remove(&rpcP->link); + + free(rpcP); +} + + + +static void * +finishRpc(struct list_head * const headerP, + void * const context ATTR_UNUSED) { + + rpc * const rpcP = headerP->itemP; + + if (rpcP->threadExists) { + void * status; + int result; + + result = pthread_join(rpcP->thread, &status); + + rpcP->threadExists = FALSE; + } + + XMLRPC_MEMBLOCK_FREE(char, rpcP->responseXmlP); + + rpcDestroy(rpcP); + + return NULL; +} + + +/* Used for debugging purposes to track the status of + your request. +*/ +void CALLBACK +statusCallback (HINTERNET const hInternet, + unsigned long const dwContext, + unsigned long const dwInternetStatus, + void * const lpvStatusInformation, + unsigned long const dwStatusInformationLength) { + + switch (dwInternetStatus) { + case INTERNET_STATUS_RESOLVING_NAME: + OutputDebugString("INTERNET_STATUS_RESOLVING_NAME\r\n"); + break; + + case INTERNET_STATUS_NAME_RESOLVED: + OutputDebugString("INTERNET_STATUS_NAME_RESOLVED\r\n"); + break; + + case INTERNET_STATUS_HANDLE_CREATED: + OutputDebugString("INTERNET_STATUS_HANDLE_CREATED\r\n"); + break; + + case INTERNET_STATUS_CONNECTING_TO_SERVER: + OutputDebugString("INTERNET_STATUS_CONNECTING_TO_SERVER\r\n"); + break; + + case INTERNET_STATUS_REQUEST_SENT: + OutputDebugString("INTERNET_STATUS_REQUEST_SENT\r\n"); + break; + + case INTERNET_STATUS_SENDING_REQUEST: + OutputDebugString("INTERNET_STATUS_SENDING_REQUEST\r\n"); + break; + + case INTERNET_STATUS_CONNECTED_TO_SERVER: + OutputDebugString("INTERNET_STATUS_CONNECTED_TO_SERVER\r\n"); + break; + + case INTERNET_STATUS_RECEIVING_RESPONSE: + OutputDebugString("INTERNET_STATUS_RECEIVING_RESPONSE\r\n"); + break; + + case INTERNET_STATUS_RESPONSE_RECEIVED: + OutputDebugString("INTERNET_STATUS_RESPONSE_RECEIVED\r\n"); + break; + + case INTERNET_STATUS_CLOSING_CONNECTION: + OutputDebugString("INTERNET_STATUS_CLOSING_CONNECTION\r\n"); + break; + + case INTERNET_STATUS_CONNECTION_CLOSED: + OutputDebugString("INTERNET_STATUS_CONNECTION_CLOSED\r\n"); + break; + + case INTERNET_STATUS_HANDLE_CLOSING: + OutputDebugString("INTERNET_STATUS_HANDLE_CLOSING\r\n"); + break; + + case INTERNET_STATUS_CTL_RESPONSE_RECEIVED: + OutputDebugString("INTERNET_STATUS_CTL_RESPONSE_RECEIVED\r\n"); + break; + + case INTERNET_STATUS_REDIRECT: + OutputDebugString("INTERNET_STATUS_REDIRECT\r\n"); + break; + + case INTERNET_STATUS_REQUEST_COMPLETE: + /* This indicates the data is ready. */ + OutputDebugString("INTERNET_STATUS_REQUEST_COMPLETE\r\n"); + break; + + default: + OutputDebugString("statusCallback, default case!\r\n"); + break; + } +} + + + +static void +create(xmlrpc_env * const envP, + int const flags ATTR_UNUSED, + const char * const appname ATTR_UNUSED, + const char * const appversion ATTR_UNUSED, + const void * const transportparmsP, + size_t const parm_size, + struct xmlrpc_client_transport ** const handlePP) { +/*---------------------------------------------------------------------------- + This does the 'create' operation for a WinInet client transport. +-----------------------------------------------------------------------------*/ + const struct xmlrpc_wininet_xportparms * const wininetXportParmsP = + transportparmsP; + + struct xmlrpc_client_transport * transportP; + + MALLOCVAR(transportP); + if (transportP == NULL) + xmlrpc_faultf(envP, "Unable to allocate transport descriptor."); + else { + transportP->listLockP = xmlrpc_lock_create(); + + list_make_empty(&transportP->rpcList); + + if (hSyncInternetSession == NULL) + hSyncInternetSession = + InternetOpen("xmlrpc-c wininet transport", + INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + + if (!wininetXportParmsP || + parm_size < XMLRPC_WXPSIZE(allowInvalidSSLCerts)) + transportP->allowInvalidSSLCerts = 0; + else + transportP->allowInvalidSSLCerts = + wininetXportParmsP->allowInvalidSSLCerts; + + *handlePP = transportP; + } +} + + + +static void +destroy(struct xmlrpc_client_transport * const clientTransportP) { +/*---------------------------------------------------------------------------- + This does the 'destroy' operation for a WinInet client transport. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(clientTransportP != NULL); + + XMLRPC_ASSERT(list_is_empty(&clientTransportP->rpcList)); + + if (hSyncInternetSession) + InternetCloseHandle(hSyncInternetSession); + hSyncInternetSession = NULL; + + clientTransportP->listLockP->destroy(clientTransportP->listLockP); + + free(clientTransportP); +} + + + +static void +sendRequest(xmlrpc_env * const envP, + struct xmlrpc_client_transport * const clientTransportP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_transport_asynch_complete complete, + xmlrpc_transport_progress progress, + struct xmlrpc_call_info * const callInfoP) { +/*---------------------------------------------------------------------------- + Initiate an XML-RPC rpc asynchronously. Don't wait for it to go to + the server. + + Unless we return failure, we arrange to have complete() called when + the rpc completes. + + This does the 'send_request' operation for a WinInet client transport. +-----------------------------------------------------------------------------*/ + rpc * rpcP; + xmlrpc_mem_block * responseXmlP; + + responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + if (!envP->fault_occurred) { + rpcCreate(envP, clientTransportP, serverP, callXmlP, responseXmlP, + complete, callInfoP, + &rpcP); + + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, responseXmlP); + } + /* The user's eventual finish_asynch call will destroy this RPC + and response buffer + */ +} + + + +static void +finishAsynch(struct xmlrpc_client_transport * const clientTransportP, + xmlrpc_timeoutType const timeoutType ATTR_UNUSED, + xmlrpc_timeout const timeout ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + Wait for the threads of all outstanding RPCs to exit and destroy those + RPCs. + + This does the 'finish_asynch' operation for a WinInet client transport. +-----------------------------------------------------------------------------*/ + /* We ignore any timeout request. Some day, we should figure out how + to set an alarm and interrupt running threads. + */ + + clientTransportP->listLockP->acquire(clientTransportP->listLockP); + + list_foreach(&clientTransportP->rpcList, finishRpc, NULL); + + clientTransportP->listLockP->release(clientTransportP->listLockP); +} + + + +static void +call(xmlrpc_env * const envP, + struct xmlrpc_client_transport * const clientTransportP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block ** const responsePP) { + + xmlrpc_mem_block * responseXmlP; + rpc * rpcP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(serverP); + XMLRPC_ASSERT_PTR_OK(callXmlP); + XMLRPC_ASSERT_PTR_OK(responsePP); + + responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + if (!envP->fault_occurred) { + rpcCreate(envP, clientTransportP, serverP, callXmlP, responseXmlP, + NULL, NULL, &rpcP); + if (!envP->fault_occurred) { + performWinInetTransaction(envP, rpcP->winInetTransactionP, + clientTransportP); + + *responsePP = responseXmlP; + + rpcDestroy(rpcP); + } + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, responseXmlP); + } +} + + + +struct xmlrpc_client_transport_ops xmlrpc_wininet_transport_ops = { + NULL, + NULL, + &create, + &destroy, + &sendRequest, + &call, + &finishAsynch, + NULL, +}; + + + +/* 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. */ diff --git a/trunk/missing b/trunk/missing new file mode 100755 index 000000000..7789652e8 --- /dev/null +++ b/trunk/missing @@ -0,0 +1,190 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`configure.in'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`configure.in'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`configure.in'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/trunk/mkinstalldirs b/trunk/mkinstalldirs new file mode 100755 index 000000000..4f58503ea --- /dev/null +++ b/trunk/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/trunk/src/Makefile b/trunk/src/Makefile new file mode 100644 index 000000000..1cdf8b021 --- /dev/null +++ b/trunk/src/Makefile @@ -0,0 +1,421 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + SRCDIR := $(call updir,$(CURDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := src + +include $(BLDDIR)/config.mk + +default: all + +SUBDIRS = + +ifeq ($(ENABLE_CPLUSPLUS),yes) + SUBDIRS += cpp +endif + +TARGET_LIBRARY_NAMES := libxmlrpc libxmlrpc_server + +# We cannot build libxmlrpc_server_abyss if we can't also build Abyss, +# because we need libxmlrpc_abyss in order to build the proper runtime +# dependencies into libxmlrpc_server_abyss. + +ifeq ($(ENABLE_ABYSS_SERVER),yes) + TARGET_LIBRARY_NAMES += libxmlrpc_server_abyss +endif + +ifeq ($(MUST_BUILD_CLIENT),yes) + TARGET_LIBRARY_NAMES += libxmlrpc_client +endif + +ifeq ($(ENABLE_CGI_SERVER),yes) + TARGET_LIBRARY_NAMES += libxmlrpc_server_cgi +endif + +STATIC_LIBRARIES_TO_INSTALL = $(TARGET_STATIC_LIBRARIES) + +SHARED_LIBS_TO_BUILD := $(TARGET_LIBRARY_NAMES) +SHARED_LIBS_TO_INSTALL := $(TARGET_LIBRARY_NAMES) + +# TRANSPORT_MODS is the list of modules that have to go into the client +# library to provide the client XML transport functions. + +# TRANSPORT_LIBDEP is linker -l options to declare what libraries contain +# things to which the transport objects refer. (like LIBxxx_LIBDEP -- +# see below) + +TRANSPORT_MODS = +TRANSPORT_LIBDEP = +TRANSPORT_INCLUDES = +ifeq ($(MUST_BUILD_WININET_CLIENT),yes) + TRANSPORT_MODS += $(BLDDIR)/lib/wininet_transport/xmlrpc_wininet_transport + TRANSPORT_LIBDEP += $(shell wininet-config --libs) + TRANSPORT_INCLUDES += -Isrcdir/lib/wininet_transport +endif +ifeq ($(MUST_BUILD_CURL_CLIENT),yes) + TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport + TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curltransaction + TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curlmulti + TRANSPORT_LIBDEP += $(shell $CURL_CONFIG --libs) + TRANSPORT_INCLUDES += -Isrcdir/lib/curl_transport +endif +ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) + TRANSPORT_MODS += $(BLDDIR)/lib/libwww_transport/xmlrpc_libwww_transport + TRANSPORT_LIBDEP += $(shell libwww-config --libs) + TRANSPORT_INCLUDES += -Isrcdir/lib/libwww_transport +endif + +ifeq ($(ENABLE_LIBXML2_BACKEND),yes) + XMLRPC_XML_PARSER = xmlrpc_libxml2 + XML_PARSER_LIBDEP = $(shell xml2-config --libs) + XML_PARSER_LIBDEP_DEP = + XML_PKGCONFIG_REQ = libxml-2.0 +else + XMLRPC_XML_PARSER = xmlrpc_expat + XML_PARSER_LIBDEP = \ + -Lblddir/lib/expat/xmlparse -lxmlrpc_xmlparse \ + -Lblddir/lib/expat/xmltok -lxmlrpc_xmltok + XML_PARSER_LIBDEP_DEP = $(LIBXMLRPC_XMLPARSE) $(LIBXMLRPC_XMLTOK) + XML_PKGCONFIG_REQ = xmlrpc_expat +endif + +# LIBxxx_OBJS is the list of object files that make up library libxxx. + +LIBXMLRPC_MODS = \ + base_global \ + double \ + json \ + parse_datetime \ + parse_value \ + resource \ + trace \ + version \ + xmlrpc_data \ + xmlrpc_datetime \ + xmlrpc_string \ + xmlrpc_array \ + xmlrpc_struct \ + xmlrpc_build \ + xmlrpc_decompose \ + $(XMLRPC_XML_PARSER) \ + xmlrpc_parse \ + xmlrpc_serialize \ + xmlrpc_authcookie \ + +LIBXMLRPC_CLIENT_MODS = xmlrpc_client xmlrpc_client_global xmlrpc_server_info + +LIBXMLRPC_SERVER_MODS = registry method system_method + +LIBXMLRPC_SERVER_ABYSS_MODS = xmlrpc_server_abyss abyss_handler + +LIBXMLRPC_SERVER_CGI_MODS = xmlrpc_server_cgi + +TARGET_MODS = \ + $(LIBXMLRPC_MODS) \ + $(LIBXMLRPC_SERVER_MODS) \ + $(LIBXMLRPC_SERVER_ABYSS_MODS) \ + $(LIBXMLRPC_SERVER_CGI_MODS) \ + $(LIBXMLRPC_CLIENT_MODS) \ + +PKGCONFIG_FILES_TO_INSTALL := \ + xmlrpc.pc \ + xmlrpc_client.pc \ + xmlrpc_server.pc \ + xmlrpc_server_abyss.pc \ + xmlrpc_server_cgi.pc \ + +OMIT_XMLRPC_LIB_RULE=Y +MAJ=3 + # Major number of shared libraries in this directory + +include $(SRCDIR)/common.mk + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +# TARGET_STATIC_LIBRARIES, etc. are set by common.mk, based on +# TARGET_LIBRARY_NAMES. + + +all: \ + $(TARGET_STATIC_LIBRARIES) \ + $(TARGET_SHARED_LIBRARIES) \ + $(TARGET_SHARED_LE_LIBS) \ + $(PKGCONFIG_FILES_TO_INSTALL) \ + $(SUBDIRS:%=%/all) \ + +# Extra dependencies to make parallel make work in spite of all the submakes +# (See top level make file for details) + +cpp/all: $(TARGET_SHARED_LE_LIBS) + +ifeq ($MUST_BUILD_CLIENT),yes) + cpp/all: $(BLDDIR)/transport_config.h +endif + +#----------------------------------------------------------------------------- +# RULES TO LINK LIBRARIES +#----------------------------------------------------------------------------- + +# Rules for these are in common.mk, courtesy of TARGET_LIBRARY_NAMES: + +# shlibfn generates e.g. libxmlrpc.so.3.1 +# shliblefn generates e.g. libxmlrpc.so + +LIBXMLRPC = $(call shlibfn, libxmlrpc) + +$(LIBXMLRPC): $(LIBXMLRPC_MODS:%=%.osh) \ + $(LIBXMLRPC_UTIL) \ + $(XML_PARSER_LIBDEP_DEP) +$(LIBXMLRPC): LIBOBJECTS = $(LIBXMLRPC_MODS:%=%.osh) +$(LIBXMLRPC): LIBDEP = \ + $(LIBXMLRPC_UTIL_LIBDEP) \ + $(XML_PARSER_LIBDEP) + +LIBXMLRPC_SERVER = $(call shlibfn, libxmlrpc_server) + +$(LIBXMLRPC_SERVER): \ + $(LIBXMLRPC_SERVER_MODS:%=%.osh) \ + $(LIBXMLRPC_UTIL) \ + $(call shliblefn, libxmlrpc) +$(LIBXMLRPC_SERVER): LIBOBJECTS = $(LIBXMLRPC_SERVER_MODS:%=%.osh) +$(LIBXMLRPC_SERVER): LIBDEP = \ + -L. -lxmlrpc $(XML_PARSER_LIBDEP) $(LIBXMLRPC_UTIL_LIBDEP) + +LIBXMLRPC_SERVER_ABYSS = $(call shlibfn, libxmlrpc_server_abyss) + +$(LIBXMLRPC_SERVER_ABYSS): \ + $(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.osh) \ + $(LIBXMLRPC_UTIL) \ + $(LIBXMLRPC_ABYSS) \ + $(call shliblefn, libxmlrpc_server) \ + $(call shliblefn, libxmlrpc) +$(LIBXMLRPC_SERVER_ABYSS): LIBOBJECTS = $(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.osh) +$(LIBXMLRPC_SERVER_ABYSS): LIBDEP = \ + -L. -lxmlrpc_server \ + -L$(LIBXMLRPC_ABYSS_DIR) -lxmlrpc_abyss \ + -L. -lxmlrpc $(XML_PARSER_LIBDEP) $(LIBXMLRPC_UTIL_LIBDEP) +ifeq ($(MSVCRT),yes) + $(LIBXMLRPC_SERVER_ABYSS): LIBDEP += -lws2_32 -lwsock32 +endif + +LIBXMLRPC_SERVER_CGI = $(call shlibfn, libxmlrpc_server_cgi) + +$(LIBXMLRPC_SERVER_CGI): \ + $(LIBXMLRPC_SERVER_CGI_MODS:%=%.osh) \ + $(LIBXMRPC_UTIL) \ + $(call shliblefn, libxmlrpc_server) \ + $(call shliblefn, libxmlrpc) +$(LIBXMLRPC_SERVER_CGI): LIBOBJECTS = $(LIBXMLRPC_SERVER_CGI_MODS:%=%.osh) +$(LIBXMLRPC_SERVER_CGI): LIBDEP = \ + -L. -lxmlrpc_server \ + -L. -lxmlrpc $(XML_PARSER_LIBDEP) $(LIBXMLRPC_UTIL_LIBDEP) + +LIBXMLRPC_CLIENT = $(call shlibfn, libxmlrpc_client) + +$(LIBXMLRPC_CLIENT): \ + $(LIBXMLRPC_CLIENT_MODS:%=%.osh) \ + $(TRANSPORT_MODS:%=%.osh) \ + $(LIBXMLRPC_UTIL) \ + $(call shliblefn, libxmlrpc) +$(LIBXMLRPC_CLIENT): LIBOBJECTS = \ + $(LIBXMLRPC_CLIENT_MODS:%=%.osh) \ + $(TRANSPORT_MODS:%=%.osh) + +# We try to get Xmlrpc-c directories early in the link library search +# path to avert problems with other versions of Xmlrpc-c being in more +# general directories (such as /usr/local/lib) that are added to the +# search path by curl-config, etc. That's why we separate the -L from +# the corresponding -l. +# +# Note that in a properly configured system, curl-config, etc. do not +# generate -L options for general directories. + +LIBXMLRPC_CLIENT_LIBDEP = \ + -Lblddir/src -Lblddir/lib/libutil \ + -lxmlrpc -lxmlrpc_util \ + $(XML_PARSER_LIBDEP) \ + $(TRANSPORT_LIBDEP) \ + +$(LIBXMLRPC_CLIENT): LIBDEP = \ + $(LIBXMLRPC_CLIENT_LIBDEP) \ + $(SOCKETLIBOPT) \ + $(THREAD_LIBS) \ + +libxmlrpc.a: $(LIBXMLRPC_MODS:%=%.o) +libxmlrpc.a: LIBOBJECTS = $(LIBXMLRPC_MODS:%=%.o) + +libxmlrpc_server.a: $(LIBXMLRPC_SERVER_MODS:%=%.o) +libxmlrpc_server.a: LIBOBJECTS = $(LIBXMLRPC_SERVER_MODS:%=%.o) + +libxmlrpc_server_abyss.a: $(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.o) +libxmlrpc_server_abyss.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.o) + +libxmlrpc_server_cgi.a: $(LIBXMLRPC_SERVER_CGI_MODS:%=%.o) +libxmlrpc_server_cgi.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_CGI_MODS:%=%.o) + +libxmlrpc_client.a: $(LIBXMLRPC_CLIENT_MODS:%=%.o) $(TRANSPORT_MODS:%=%.o) +libxmlrpc_client.a: LIBOBJECTS = \ + $(LIBXMLRPC_CLIENT_MODS:%=%.o) \ + $(TRANSPORT_MODS:%=%.o) + + +#----------------------------------------------------------------------------- +# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES +#----------------------------------------------------------------------------- + +# Rules for these are in common.mk, courtesy of TARGET_MODS: + +BASIC_INCLUDES = \ + -Iblddir \ + -Iblddir/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include \ + +ifeq ($(ENABLE_LIBXML2_BACKEND),yes) + LIBXML_INCLUDES = $(shell xml2-config --cflags) +else + LIBXML_INCLUDES = -Isrcdir/lib/expat/xmlparse +endif + +$(LIBXMLRPC_MODS:%=%.o) \ +$(LIBXMLRPC_MODS:%=%.osh): \ + INCLUDES = $(BASIC_INCLUDES) $(LIBXML_INCLUDES) + +$(LIBXMLRPC_CLIENT_MODS:%=%.o) \ +$(LIBXMLRPC_CLIENT_MODS:%=%.osh): \ + INCLUDES = $(BASIC_INCLUDES) $(TRANSPORT_INCLUDES) + +$(LIBXMLRPC_SERVER_MODS:%=%.o) \ +$(LIBXMLRPC_SERVER_MODS:%=%.osh): \ + INCLUDES = $(BASIC_INCLUDES) + +$(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.o) \ +$(LIBXMLRPC_SERVER_ABYSS_MODS:%=%.osh): \ + INCLUDES = $(BASIC_INCLUDES) -Isrcdir/lib/abyss/src + +$(LIBXMLRPC_SERVER_CGI_MODS:%=%.o) \ +$(LIBXMLRPC_SERVER_CGI_MODS:%=%.osh): \ + INCLUDES = $(BASIC_INCLUDES) + +#----------------------------------------------------------------------------- +# RULES TO MAKE CFLAGS/LDFLAGS FILES +# +# These are for builds in other directories of things that use libraries in +# this directory. E.g. when you build libxmlrpc_client++, it depends upon +# libxmlrpc_client from this directory. So the link of libxmlrpc_client++ +# must specify a dependency upon libxmlrpc_client and any library upon which +# libxmlrpc_client depends, so the link command for libxmlrpc_client++ +# should include $(shell cat libxmlrpc_client.ldflags). +# +# Note that some systems don't need this because there is information in +# libxmlrpc_client that tells libxmlrpc_client's dependencies, so you need +# only find libxmlrpc_client to generate libxmlrpc_client++. +#----------------------------------------------------------------------------- + +libxmlrpc_client.cflags: + echo "$(TRANSPORT_INCLUDES)" >$@ + +libxmlrpc_client.ldflags: + echo "-Lblddir/src -lxmlrpc_client $(LIBXMLRPC_CLIENT_LIBDEP)" >$@ + + +#----------------------------------------------------------------------------- +# RULES TO MAKE PKGCONFIG FILES +# +# (These are files used by the 'pkg-config' program to get information about +# using the libraries we build) +#----------------------------------------------------------------------------- + +xmlrpc.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc" >>$@ + @echo "Description: Xmlrpc-c basic XML-RPC library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc_util $(XML_PKGCONFIG_REQ)" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +xmlrpc_client.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_client" >>$@ + @echo "Description: Xmlrpc-c XML-RPC client library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_client" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +xmlrpc_server.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_server" >>$@ + @echo "Description: Xmlrpc-c XML-RPC server library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +xmlrpc_server_abyss.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_server_abyss" >>$@ + @echo "Description: Xmlrpc-c Abyss XML-RPC server library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc xmlrpc_server xmlrpc_abyss xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server_abyss" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +xmlrpc_server_cgi.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_server_cgi" >>$@ + @echo "Description: Xmlrpc-c CGI XML-RPC server library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc xmlrpc_server xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server_cgi" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +.PHONY: check +check: + +.PHONY: install +install: install-common $(SUBDIRS:%=%/install) + +.PHONY: uninstall +uninstall: uninstall-common $(SUBDIRS:%=%/uninstall) + +.PHONY: clean clean-local distclean distclean-local +clean: $(SUBDIRS:%=%/clean) clean-common clean-local +clean-local: + +distclean: $(SUBDIRS:%=%/distclean) \ + clean-common \ + clean-local \ + distclean-local \ + distclean-common \ + +distclean-local: + rm -f *.cflags *.ldflags + +.PHONY: dep +dep: $(SUBDIRS:%=%/dep) $(BLDDIR)/transport_config.h dep-common + +dep-common: + INCLUDES = $(BASIC_INCLUDES) $(TRANSPORT_INCLUDES) $(LIBXML_INCLUDES) + +xmlrpc_client.o xmlrpc_client.osh: $(BLDDIR)/transport_config.h +xmlrpc_client.o xmlrpc_client.osh: $(BLDDIR)/version.h +registry.o registry.osh: $(BLDDIR)/version.h +version.o version.osh: $(BLDDIR)/version.h + +include depend.mk diff --git a/trunk/src/abyss_handler.c b/trunk/src/abyss_handler.c new file mode 100644 index 000000000..7698703bb --- /dev/null +++ b/trunk/src/abyss_handler.c @@ -0,0 +1,642 @@ +#include "xmlrpc_config.h" + +#define _XOPEN_SOURCE 600 /* For strdup(), sigaction */ +#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ + +#include +#include +#include +#include +#include +#include +#include + +#include "bool.h" +#include "int.h" +#include "mallocvar.h" +#include "xmlrpc-c/abyss.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" + +#include "abyss_handler.h" + + + +static const char * trace_abyss; + + +void +xmlrpc_abyss_handler_trace(const char * const trace) { + + trace_abyss = trace; +} + + +static void +addAuthCookie(xmlrpc_env * const envP, + TSession * const abyssSessionP, + const char * const authCookie) { + + const char * cookieResponse; + + xmlrpc_asprintf(&cookieResponse, "auth=%s", authCookie); + + if (xmlrpc_strnomem(cookieResponse)) + xmlrpc_faultf(envP, "Insufficient memory to generate cookie " + "response header."); + else { + ResponseAddField(abyssSessionP, "Set-Cookie", cookieResponse); + + xmlrpc_strfree(cookieResponse); + } +} + + + +static void +sendResponse(xmlrpc_env * const envP, + TSession * const abyssSessionP, + const char * const body, + size_t const len, + bool const chunked, + ResponseAccessCtl const accessControl) { +/*---------------------------------------------------------------------------- + Generate an HTTP response containing body 'body' of length 'len' + characters. + + This is meant to run in the context of an Abyss URI handler for + Abyss session 'abyssSessionP'. + + 'chunked' means to make it a chunked response if possible. +-----------------------------------------------------------------------------*/ + const char * http_cookie = NULL; + /* This used to set http_cookie to getenv("HTTP_COOKIE"), but + that doesn't make any sense -- environment variables are not + appropriate for this. So for now, cookie code is disabled. + - Bryan 2004.10.03. + */ + + /* Various bugs before Xmlrpc-c 1.05 caused the response to be not + chunked in the most basic case, but chunked if the client explicitly + requested keepalive. I think it's better not to chunk, because + it's simpler, so I removed this in 1.05. I don't know what the + purpose of chunking would be, and an original comment suggests + the author wasn't sure chunking was a good idea. + + In 1.06 we added the user option to chunk. + */ + if (chunked) + ResponseChunked(abyssSessionP); + + ResponseStatus(abyssSessionP, 200); + + if (http_cookie) + /* There's an auth cookie, so pass it back in the response. */ + addAuthCookie(envP, abyssSessionP, http_cookie); + + if ((size_t)(uint32_t)len != len) + xmlrpc_faultf(envP, "XML-RPC method generated a response too " + "large for Abyss to send"); + else { + uint32_t const abyssLen = (uint32_t)len; + + /* See discussion below of quotes around "utf-8" */ + ResponseContentType(abyssSessionP, "text/xml; charset=utf-8"); + ResponseContentLength(abyssSessionP, abyssLen); + ResponseAccessControl(abyssSessionP, accessControl); + + ResponseWriteStart(abyssSessionP); + ResponseWriteBody(abyssSessionP, body, abyssLen); + ResponseWriteEnd(abyssSessionP); + } +} + + + +/* From 0.9.10 (May 2001) through 1.17 (December 2008), the content-type + header said charset="utf-8" (i.e. with the value of 'charset' an HTTP quoted + string). Before 0.9.10, the header didn't have charset at all. + + We got a complaint in January 2009 that some client didn't understand that, + saying + + apache2: XML-RPC: xmlrpcmsg::parseResponse: invalid charset encoding of + received response: "UTF-8" + + And that removing the quotation marks fixes this. + + From what I can tell, the module is wrong to distinguish between the + two, but I don't think it hurts anything to use a basic HTTP token instead + of an HTTP quoted string here, so starting in 1.18, we do. */ + + +static void +sendError(TSession * const abyssSessionP, + unsigned int const status, + const char * const explanation) { +/*---------------------------------------------------------------------------- + Send an error response back to the client. +-----------------------------------------------------------------------------*/ + ResponseStatus(abyssSessionP, (uint16_t) status); + ResponseError2(abyssSessionP, explanation); +} + + + +static void +traceChunkRead(TSession * const abyssSessionP) { + + fprintf(stderr, "XML-RPC handler got a chunk of %u bytes\n", + (unsigned int)SessionReadDataAvail(abyssSessionP)); +} + + + +static void +refillBufferFromConnection(xmlrpc_env * const envP, + TSession * const abyssSessionP, + const char * const trace) { +/*---------------------------------------------------------------------------- + Get the next chunk of data from the connection into the buffer. +-----------------------------------------------------------------------------*/ + bool succeeded; + + succeeded = SessionRefillBuffer(abyssSessionP); + + if (!succeeded) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TIMEOUT_ERROR, "Timed out waiting for " + "client to send its POST data"); + else { + if (trace) + traceChunkRead(abyssSessionP); + } +} + + + +static void +getBody(xmlrpc_env * const envP, + TSession * const abyssSessionP, + size_t const contentSize, + const char * const trace, + xmlrpc_mem_block ** const bodyP) { +/*---------------------------------------------------------------------------- + Get the entire body, which is of size 'contentSize' bytes, from the + Abyss session and return it as the new memblock *bodyP. + + The first chunk of the body may already be in Abyss's buffer. We + retrieve that before reading more. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * body; + + if (trace) + fprintf(stderr, "XML-RPC handler processing body. " + "Content Size = %u bytes\n", (unsigned)contentSize); + + body = xmlrpc_mem_block_new(envP, 0); + if (!envP->fault_occurred) { + size_t bytesRead; + + bytesRead = 0; + + while (!envP->fault_occurred && bytesRead < contentSize) { + const char * chunkPtr; + size_t chunkLen; + + SessionGetReadData(abyssSessionP, contentSize - bytesRead, + &chunkPtr, &chunkLen); + bytesRead += chunkLen; + + assert(bytesRead <= contentSize); + + XMLRPC_MEMBLOCK_APPEND(char, envP, body, chunkPtr, chunkLen); + if (bytesRead < contentSize) + refillBufferFromConnection(envP, abyssSessionP, trace); + } + if (envP->fault_occurred) + xmlrpc_mem_block_free(body); + } + *bodyP = body; +} + + + +static void +storeCookies(TSession * const httpRequestP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Get the cookie settings from the HTTP headers and remember them for + use in responses. +-----------------------------------------------------------------------------*/ + const char * const cookie = RequestHeaderValue(httpRequestP, "cookie"); + if (cookie) { + /* + Setting the value in an environment variable doesn't make + any sense. So for now, cookie code is disabled. + -Bryan 04.10.03. + + setenv("HTTP_COOKIE", cookie, 1); + */ + } + /* TODO: parse HTTP_COOKIE to find auth pair, if there is one */ + + *errorP = NULL; +} + + + + +static void +processContentLength(TSession * const httpRequestP, + size_t * const inputLenP, + bool * const missingP, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Make sure the content length is present and non-zero. This is + technically required by XML-RPC, but we only enforce it because we + don't want to figure out how to safely handle HTTP < 1.1 requests + without it. +-----------------------------------------------------------------------------*/ + const char * const content_length = + RequestHeaderValue(httpRequestP, "content-length"); + + if (content_length == NULL) { + *missingP = true; + *errorP = NULL; + } else { + *missingP = false; + *inputLenP = 0; /* quiet compiler warning */ + if (content_length[0] == '\0') + xmlrpc_asprintf(errorP, "The value in your content-length " + "HTTP header value is a null string"); + else { + unsigned long contentLengthValue; + char * tail; + + contentLengthValue = strtoul(content_length, &tail, 10); + + if (*tail != '\0') + xmlrpc_asprintf(errorP, "There's non-numeric crap in " + "the value of your content-length " + "HTTP header: '%s'", tail); + else if (contentLengthValue < 1) + xmlrpc_asprintf(errorP, "According to your content-length " + "HTTP header, your request is empty (zero " + "length)"); + else if ((unsigned long)(size_t)contentLengthValue + != contentLengthValue) + xmlrpc_asprintf(errorP, "According to your content-length " + "HTTP header, your request is too big to " + "process; we can't even do arithmetic on its " + "size: %s bytes", content_length); + else { + *errorP = NULL; + *inputLenP = (size_t)contentLengthValue; + } + } + } +} + + + +static void +traceHandlerCalled(TSession * const abyssSessionP) { + + const char * methodDesc; + const TRequestInfo * requestInfoP; + + fprintf(stderr, "xmlrpc_server_abyss URI path handler called.\n"); + + SessionGetRequestInfo(abyssSessionP, &requestInfoP); + + fprintf(stderr, "URI = '%s'\n", requestInfoP->uri); + + switch (requestInfoP->method) { + case m_unknown: methodDesc = "unknown"; break; + case m_get: methodDesc = "get"; break; + case m_put: methodDesc = "put"; break; + case m_head: methodDesc = "head"; break; + case m_post: methodDesc = "post"; break; + case m_delete: methodDesc = "delete"; break; + case m_trace: methodDesc = "trace"; break; + case m_options: methodDesc = "m_options"; break; + default: methodDesc = "?"; + } + fprintf(stderr, "HTTP method = '%s'\n", methodDesc); + + if (requestInfoP->query) + fprintf(stderr, "query (component of URL)='%s'\n", + requestInfoP->query); + else + fprintf(stderr, "URL has no query component\n"); +} + + + +static void +processCall(TSession * const abyssSessionP, + size_t const contentSize, + xmlrpc_call_processor xmlProcessor, + void * const xmlProcessorArg, + bool const wantChunk, + ResponseAccessCtl const accessControl, + const char * const trace) { +/*---------------------------------------------------------------------------- + Handle an RPC request. This is an HTTP request that has the proper form + to be an XML-RPC call. + + We get the body of the request, which is the text of the call, + via the Abyss session 'abyssSessionP'. + + Its content length is 'contentSize' bytes. + + We send the response to the request (which may contain the RPC response, + but may be an error indication) via the Abyss session 'abyssSessionP'. + + We use 'xmlProcessor', with argument 'xmlProcessorArg' to execute the + RPC, i.e. turn the XML-RPC call into an XML-RPC response. + + 'wantChunk' means Caller wants the HTTP reponse chunked. + + We use the Abyss session's memory pool for some memory allocations - + essentially those that aren't predictable because they depend upon the data + from the client. We do this because the session's memory pool has a size + limit designed to keep the client from monopolizing the server's memory. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + + if (trace) + fprintf(stderr, + "xmlrpc_server_abyss URI path handler processing RPC.\n"); + + xmlrpc_env_init(&env); + + if (contentSize > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) + xmlrpc_env_set_fault_formatted( + &env, XMLRPC_LIMIT_EXCEEDED_ERROR, + "XML-RPC request too large (%u bytes)", (unsigned)contentSize); + else { + xmlrpc_mem_block * body; + /* Read XML data off the wire. */ + getBody(&env, abyssSessionP, contentSize, trace, &body); + if (!env.fault_occurred) { + xmlrpc_mem_block * output; + + /* Process the RPC. */ + xmlProcessor( + &env, xmlProcessorArg, + XMLRPC_MEMBLOCK_CONTENTS(char, body), + XMLRPC_MEMBLOCK_SIZE(char, body), + abyssSessionP, + &output); + if (!env.fault_occurred) { + /* Send out the result. */ + sendResponse(&env, abyssSessionP, + XMLRPC_MEMBLOCK_CONTENTS(char, output), + XMLRPC_MEMBLOCK_SIZE(char, output), + wantChunk, accessControl); + + XMLRPC_MEMBLOCK_FREE(char, output); + } + XMLRPC_MEMBLOCK_FREE(char, body); + } + } + if (env.fault_occurred) { + uint16_t httpResponseStatus; + if (env.fault_code == XMLRPC_TIMEOUT_ERROR) + httpResponseStatus = 408; /* Request Timeout */ + else + httpResponseStatus = 500; /* Internal Server Error */ + + sendError(abyssSessionP, httpResponseStatus, env.fault_string); + } + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_initAccessCtl(ResponseAccessCtl * const accessCtlP, + const char * const allowOrigin, + bool const expires, + unsigned int const maxAge) { +/*---------------------------------------------------------------------------- + Set up *accessCtlP to reflect the HTTP access control parameters + 'allowOrigin', 'expires', and 'maxAge'. + + Note that 'maxAge' is irrelevant when 'expires' is false. +-----------------------------------------------------------------------------*/ + accessCtlP->allowOrigin = + allowOrigin ? xmlrpc_strdupsol(allowOrigin) : NULL; + accessCtlP->expires = expires; + accessCtlP->maxAge = maxAge; +} + + + +void +xmlrpc_termAccessControl(ResponseAccessCtl * const accessCtlP) { + + xmlrpc_strfreenull(accessCtlP->allowOrigin); +} + + + +void +xmlrpc_termUriHandler(void * const arg) { + + struct uriHandlerXmlrpc * const uriHandlerXmlrpcP = arg; + + xmlrpc_strfree(uriHandlerXmlrpcP->uriPath); + xmlrpc_termAccessControl(&uriHandlerXmlrpcP->accessControl); + free(uriHandlerXmlrpcP); +} + + + +static void +handleXmlRpcCallReq(TSession * const abyssSessionP, + const TRequestInfo * const requestInfoP ATTR_UNUSED, + xmlrpc_call_processor xmlProcessor, + void * const xmlProcessorArg, + bool const wantChunk, + ResponseAccessCtl const accessControl) { +/*---------------------------------------------------------------------------- + Handle the HTTP request described by *requestInfoP, which arrived over + Abyss HTTP session *abyssSessionP, which is an XML-RPC call + (i.e. a POST request to /RPC2 or whatever other URI our server is + supposed to handle). + + Handle it by feeding the XML which is its content to 'xmlProcessor' + along with argument 'xmlProcessorArg'. + + (There doesn't seem to be any way 'xmlProcessor' could ever be anything but + 'processXmlrpcCall' in xmlrpc_server_abyss.c (with 'xmlProcessorArg' being + the handle of a method registry), so I'm not sure why we didn't just put + that in this module and call it explicitly). +-----------------------------------------------------------------------------*/ + /* We used to reject the call if content-type was not present and + text/xml, on some security theory (a firewall may block text/xml with + the intent of blocking XML-RPC). Now, we believe that is silly, and we + have seen an incorrectly implemented client that says text/plain. + */ + const char * error; + + assert(requestInfoP->method == m_post); + + storeCookies(abyssSessionP, &error); + if (error) { + sendError(abyssSessionP, 400, error); + xmlrpc_strfree(error); + } else { + const char * error; + bool missing; + size_t contentSize; + + processContentLength(abyssSessionP, + &contentSize, &missing, &error); + if (error) { + sendError(abyssSessionP, 400, error); + xmlrpc_strfree(error); + } else { + if (missing) + sendError(abyssSessionP, 411, "You must send a " + "content-length HTTP header in an " + "XML-RPC call."); + else + processCall(abyssSessionP, contentSize, + xmlProcessor, xmlProcessorArg, + wantChunk, accessControl, + trace_abyss); + } + } +} + + + +static void +handleXmlRpcOptionsReq(TSession * const abyssSessionP, + ResponseAccessCtl const accessControl) { + + ResponseAddField(abyssSessionP, "Allow", "POST"); + + ResponseAccessControl(abyssSessionP, accessControl); + ResponseContentLength(abyssSessionP, 0); + ResponseStatus(abyssSessionP, 200); + ResponseWriteStart(abyssSessionP); + ResponseWriteEnd(abyssSessionP); +} + + + +void +xmlrpc_handleIfXmlrpcReq(void * const handlerArg, + TSession * const abyssSessionP, + abyss_bool * const handledP) { +/*---------------------------------------------------------------------------- + Our job is to look at this HTTP request that the Abyss server is + trying to process and see if we can handle it. If it's an XML-RPC + call for this XML-RPC server, we handle it. If it's not, we refuse + it and Abyss can try some other handler. + + We return *handledP true to mean we handled it; false to mean we didn't. + + Note that failing the request counts as handling it, and not handling + it does not mean we failed it. + + This is an Abyss HTTP Request handler -- type handleReqFn3. +-----------------------------------------------------------------------------*/ + struct uriHandlerXmlrpc * const uriHandlerXmlrpcP = handlerArg; + + const TRequestInfo * requestInfoP; + + if (trace_abyss) + traceHandlerCalled(abyssSessionP); + + SessionGetRequestInfo(abyssSessionP, &requestInfoP); + + /* Note that requestInfoP->uri is not the whole URI. It is just + the "file name" part of it. + */ + if (!xmlrpc_streq(requestInfoP->uri, uriHandlerXmlrpcP->uriPath)) + /* It's not for the path (e.g. "/RPC2") that we're supposed to + handle. + */ + *handledP = false; + else { + *handledP = true; + + switch (requestInfoP->method) { + case m_post: + handleXmlRpcCallReq(abyssSessionP, requestInfoP, + uriHandlerXmlrpcP->xmlProcessor, + uriHandlerXmlrpcP->xmlProcessorArg, + uriHandlerXmlrpcP->chunkResponse, + uriHandlerXmlrpcP->accessControl); + break; + case m_options: + handleXmlRpcOptionsReq(abyssSessionP, + uriHandlerXmlrpcP->accessControl); + break; + default: + sendError(abyssSessionP, 405, + "POST is the only HTTP method this server understands"); + /* 405 = Method Not Allowed */ + } + } + if (trace_abyss) + fprintf(stderr, "xmlrpc_server_abyss URI path handler returning.\n"); +} + + + +unsigned int +xmlrpc_abyss_handler_stacksize() { +/*---------------------------------------------------------------------------- + The maximum number of bytes an HTTP request handler in this file might + place on the stack. + + This doesn't include what the user's method function requires. +-----------------------------------------------------------------------------*/ + return 1024; +} + + + +abyss_bool +xmlrpc_serverAbyssDefaultUriHandler(TSession * const sessionP) { +/*---------------------------------------------------------------------------- + This is an Abyss default handler. It return a 404 Not Found for all + requests. +-----------------------------------------------------------------------------*/ + const TRequestInfo * requestInfoP; + + const char * explanation; + + if (trace_abyss) + fprintf(stderr, "xmlrpc_server_abyss default handler called.\n"); + + SessionGetRequestInfo(sessionP, &requestInfoP); + + xmlrpc_asprintf( + &explanation, + "This XML-RPC For C/C++ Abyss XML-RPC server " + "responds to only one URI path. " + "I don't know what URI path that is, " + "but it's not the one you requested: '%s'. (Typically, it's " + "'/RPC2')", requestInfoP->uri); + + sendError(sessionP, 404, explanation); + + xmlrpc_strfree(explanation); + + return true; +} + + + diff --git a/trunk/src/abyss_handler.h b/trunk/src/abyss_handler.h new file mode 100644 index 000000000..363f1ed6a --- /dev/null +++ b/trunk/src/abyss_handler.h @@ -0,0 +1,49 @@ +#ifndef ABYSS_HANDER_H_INCLUDED +#define ABYSS_HANDER_H_INCLUDED + +#include "xmlrpc-c/abyss.h" +#include "xmlrpc-c/server.h" +#include "xmlrpc-c/server_abyss.h" + +struct uriHandlerXmlrpc { +/*---------------------------------------------------------------------------- + This is the part of an Abyss HTTP request handler (aka URI handler) + that is specific to the Xmlrpc-c handler. +-----------------------------------------------------------------------------*/ + xmlrpc_registry * registryP; + const char * uriPath; /* malloc'ed */ + bool chunkResponse; + /* The handler should chunk its response whenever possible */ + xmlrpc_call_processor * xmlProcessor; + void * xmlProcessorArg; + ResponseAccessCtl accessControl; +}; + + +void +xmlrpc_termUriHandler(void * const arg); + +void +xmlrpc_handleIfXmlrpcReq(void * const handlerArg, + TSession * const abyssSessionP, + abyss_bool * const handledP); + +abyss_bool +xmlrpc_serverAbyssDefaultUriHandler(TSession * const sessionP); + +void +xmlrpc_initAccessCtl(ResponseAccessCtl * const accessCtlP, + const char * const allowOrigin, + bool const expires, + unsigned int const maxAge); + +void +xmlrpc_termAccessControl(ResponseAccessCtl * const accessCtlP); + +void +xmlrpc_abyss_handler_trace(const char * const trace); + +unsigned int +xmlrpc_abyss_handler_stacksize(void); + +#endif diff --git a/trunk/src/base_global.c b/trunk/src/base_global.c new file mode 100644 index 000000000..1c34a763f --- /dev/null +++ b/trunk/src/base_global.c @@ -0,0 +1,52 @@ +#include "xmlrpc-c/base.h" +#include "xmlparser.h" + + + +static unsigned int globallyInitialized = 0; + /* Initialization count */ + + +/* It ought to be a requirement for any user of libxmlrpc to call + xmlrpc_init(), but for ten years it wasn't, so we can't start requiring it + now except for new services. + + One thing we know requires it (and always did, but didn't show up as a + problem until 2012) is libxml2. Without a call to xmlrpc_init(), + if libxmlrpc was built to use libxml2, the program leaks lots of memory. +*/ + +void +xmlrpc_init(xmlrpc_env * const envP) { + + /* Note that this is specified as not thread safe; user calls it at + the beginning of his program, when it is only one thread. + */ + + XMLRPC_ASSERT_ENV_OK(envP); + + if (globallyInitialized == 0) { + xml_init(envP); /* Initialize the XML parser library */ + } + ++globallyInitialized; +} + + + +void +xmlrpc_term(void) { + + /* Note that this is specified as not thread safe; user calls it at + the end of his program, when it is only one thread. + */ + + XMLRPC_ASSERT(globallyInitialized > 0); + + --globallyInitialized; + + if (globallyInitialized == 0) { + xml_term(); + } +} + + diff --git a/trunk/src/cpp/Makefile b/trunk/src/cpp/Makefile new file mode 100644 index 000000000..cc654a0ac --- /dev/null +++ b/trunk/src/cpp/Makefile @@ -0,0 +1,432 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + srcDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(srcDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := src/cpp + +include $(BLDDIR)/config.mk + +default: all + +# libxmlrpc_cpp is the legacy C++ wrapper library. The others are the +# more elaborate replacements. + +TARGET_LIB_NAMES_PP = \ + libxmlrpc_cpp \ + lib$(LIBXMLRPCPP_NAME) \ + libxmlrpc_server++ \ + libxmlrpc_server_cgi++ \ + libxmlrpc_server_pstream++ \ + libxmlrpc_packetsocket \ + +ifeq ($(ENABLE_ABYSS_SERVER),yes) + TARGET_LIB_NAMES_PP += libxmlrpc_server_abyss++ +endif + +ifeq ($(MUST_BUILD_CLIENT),yes) + TARGET_LIB_NAMES_PP += libxmlrpc_client++ +endif + +STATIC_LIBRARIES_TO_INSTALL = $(TARGET_STATIC_LIBRARIES) + +SHARED_LIBS_TO_BUILD = $(TARGET_LIB_NAMES_PP) +SHARED_LIBS_TO_INSTALL = $(TARGET_LIB_NAMES_PP) + +# INCLUDES and DEP_SOURCES are used by dep-common target +INCLUDES = $(BASIC_INCLUDES) $(LIBXML_INCLUDES) \ + $(shell cat blddir/src/libxmlrpc_client.cflags) +DEP_SOURCES = *.cpp + +ifeq ($(ENABLE_LIBXML2_BACKEND),yes) + LIBXML_INCLUDES = $(LIBXML2_CFLAGS) +else + LIBXML_INCLUDES = -Isrcdir/lib/expat/xmlparse +endif + +ifeq ($(ENABLE_LIBXML2_BACKEND),yes) + XML_PARSER_LIBDEP = $(shell xml2-config --libs) +else + XML_PARSER_LIBDEP = \ + -L$(BLDDIR)/lib/expat/xmlparse -lxmlrpc_xmlparse \ + -L$(BLDDIR)/lib/expat/xmltok -lxmlrpc_xmltok +endif + +LIBXMLRPCPP_MODS = fault global outcome param_list value xml +LIBXMLRPC_SERVERPP_MODS = registry +LIBXMLRPC_SERVER_ABYSSPP_MODS = server_abyss abyss_reqhandler_xmlrpc +LIBXMLRPC_SERVER_CGIPP_MODS = server_cgi +LIBXMLRPC_SERVER_PSTREAMPP_MODS = server_pstream_conn server_pstream +LIBXMLRPC_CLIENTPP_MODS = client client_simple curl libwww wininet pstream +LIBXMLRPC_PACKETSOCKET_MODS = packetsocket + +TARGET_MODS_PP = \ + XmlRpcCpp \ + $(LIBXMLRPCPP_MODS) \ + $(LIBXMLRPC_SERVERPP_MODS) \ + $(LIBXMLRPC_SERVER_ABYSSPP_MODS) \ + $(LIBXMLRPC_SERVER_CGIPP_MODS) \ + $(LIBXMLRPC_SERVER_PSTREAMPP_MODS) \ + $(LIBXMLRPC_CLIENTPP_MODS) \ + $(LIBXMLRPC_PACKETSOCKET_MODS) \ + +PKGCONFIG_FILES_TO_INSTALL := \ + xmlrpc++.pc \ + xmlrpc_client++.pc \ + xmlrpc_server++.pc \ + xmlrpc_server_pstream++.pc \ + +OMIT_CPP_LIB_RULES = Y +MAJ = 8 + # Major number of shared libraries in this directory + +include $(SRCDIR)/common.mk + + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +BASIC_INCLUDES = \ + -Iblddir/include \ + -Isrcdir/include \ + -Iblddir \ + -Isrcdir/lib/util/include + + +# TARGET_STATIC_LIBARIES, etc. are set by common.mk, based on +# TARGET_LIB_NAMES_PP. + +all: \ + $(TARGET_STATIC_LIBRARIES) \ + $(TARGET_SHARED_LIBS_PP) \ + $(TARGET_SHARED_LE_LIBS) \ + $(PKGCONFIG_FILES_TO_INSTALL) \ + + +#----------------------------------------------------------------------------- +# RULES TO LINK LIBRARIES +#----------------------------------------------------------------------------- + +# Rules for these are in common.mk, courtesy of TARGET_LIB_NAMES_PP: + +# shlibfn generates e.g. libxmlrpc.so.3.1 +# shliblefn generates e.g. libxmlrpc.so + +LIBXMLRPC_CPP_SH = $(call shlibfn, libxmlrpc_cpp) + +# Sometimes -lpthread is necessary when link-editing a shared library that +# uses pthread services, and sometimes it is not. We've seen links on +# Windows and AIX fail without it. It seems to be a good idea in all cases, +# as it declares an actual dependency of the shared library. + +$(LIBXMLRPC_CPP_SH): XmlRpcCpp.osh \ + $(LIBXMLRPC_UTIL) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_SERVER) \ + $(LIBXMLRPC_UTIL) \ + +$(LIBXMLRPC_CPP_SH): LIBOBJECTS = XmlRpcCpp.osh +$(LIBXMLRPC_CPP_SH): LIBDEP = \ + -Lblddir/src -lxmlrpc_server -lxmlrpc \ + $(XML_PARSER_LIBDEP) \ + $(LIBXMLRPC_UTIL_LIBDEP) \ + +LIBXMLRPCPP_SH = $(call shlibfn, lib$(LIBXMLRPCPP_NAME)) + +$(LIBXMLRPCPP_SH): $(LIBXMLRPCPP_MODS:%=%.osh) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_UTILPP) \ + $(LIBXMLRPC_UTIL) \ + +$(LIBXMLRPCPP_SH): LIBOBJECTS = $(LIBXMLRPCPP_MODS:%=%.osh) +$(LIBXMLRPCPP_SH): LIBDEP = \ + -Lblddir/src -lxmlrpc \ + $(XML_PARSER_LIBDEP) \ + -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ + -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ + $(THREAD_LIBS) \ + +LIBXMLRPC_SERVERPP_SH = $(call shlibfn, libxmlrpc_server++) + +$(LIBXMLRPC_SERVERPP_SH): $(LIBXMLRPC_SERVERPP_MODS:%=%.osh) \ + $(LIBXMLRPC_SERVER) \ + $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ + $(LIBXMLRPC_UTILPP) \ + $(LIBXMLRPC_UTIL) \ + $(LIBXMLRPC) \ + +$(LIBXMLRPC_SERVERPP_SH): LIBOBJECTS = $(LIBXMLRPC_SERVERPP_MODS:%=%.osh) +$(LIBXMLRPC_SERVERPP_SH): LIBDEP = \ + -L. -l$(LIBXMLRPCPP_NAME) \ + -Lblddir/src -lxmlrpc_server -lxmlrpc \ + $(XML_PARSER_LIBDEP) \ + -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ + -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ + $(THREAD_LIBS) \ + +LIBXMLRPC_SERVER_ABYSSPP_SH = $(call shlibfn, libxmlrpc_server_abyss++) + +$(LIBXMLRPC_SERVER_ABYSSPP_SH): $(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.osh) \ + $(LIBXMLRPC_ABYSSPP) \ + $(LIBXMLRPC_ABYSS) \ + $(LIBXMLRPC_SERVER_ABYSS) \ + $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ + $(call shliblefn, libxmlrpc_server++) \ + $(LIBXMLRPC_UTILPP) \ + $(LIBXMLRPC_UTIL) \ + $(LIBXMLRPC) \ + +$(LIBXMLRPC_SERVER_ABYSSPP_SH): LIBOBJECTS = $(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.osh) +$(LIBXMLRPC_SERVER_ABYSSPP_SH): LIBDEP = \ + -L. -lxmlrpc_server++ -l$(LIBXMLRPCPP_NAME) \ + -Lblddir/src -lxmlrpc_server_abyss -lxmlrpc_server -lxmlrpc \ + $(XML_PARSER_LIBDEP) \ + -L$(LIBXMLRPC_ABYSSPP_DIR) -lxmlrpc_abyss++ \ + -L$(LIBXMLRPC_ABYSS_DIR) -lxmlrpc_abyss \ + -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ + -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ + $(SOCKETLIBOBT) \ + $(THREAD_LIBS) \ + +LIBXMLRPC_SERVER_CGIPP_SH = $(call shlibfn, libxmlrpc_server_cgi++) + +$(LIBXMLRPC_SERVER_CGIPP_SH): $(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.osh) \ + $(call shliblefn, libxmlrpc_server++) \ + $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ + $(LIBXMLRPC_UTILPP) \ + $(LIBXMLRPC_UTIL) \ + $(LIBXMLRPC) \ + +$(LIBXMLRPC_SERVER_CGIPP_SH): LIBOBJECTS = $(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.osh) +$(LIBXMLRPC_SERVER_CGIPP_SH): LIBDEP = \ + -L. -lxmlrpc_server++ -l$(LIBXMLRPCPP_NAME) \ + -Lblddir/src -lxmlrpc_server -lxmlrpc \ + $(XML_PARSER_LIBDEP) \ + -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ + -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ + $(THREAD_LIBS) \ + +LIBXMLRPC_SERVER_PSTREAMPP_SH = $(call shlibfn, libxmlrpc_server_pstream++) + +$(LIBXMLRPC_SERVER_PSTREAMPP_SH): $(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.osh) \ + $(LIBXMLRPC_SERVER) \ + $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ + $(call shliblefn, libxmlrpc_packetsocket) \ + $(call shliblefn, libxmlrpc_server++) \ + $(LIBXMLRPC_UTILPP) \ + $(LIBXMLRPC_UTIL) \ + +$(LIBXMLRPC_SERVER_PSTREAMPP_SH): LIBOBJECTS = $(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.osh) +$(LIBXMLRPC_SERVER_PSTREAMPP_SH): LIBDEP = \ + -L. -lxmlrpc_server++ -l$(LIBXMLRPCPP_NAME) -lxmlrpc_packetsocket \ + -Lblddir/src -lxmlrpc_server -lxmlrpc \ + $(XML_PARSER_LIBDEP) \ + -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ + -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ + $(SOCKETLIBOPT) \ + $(THREAD_LIBS) \ + +LIBXMLRPC_CLIENTPP_SH = $(call shlibfn, libxmlrpc_client++) + +$(LIBXMLRPC_CLIENTPP_SH): $(LIBXMLRPC_CLIENTPP_MODS:%=%.osh) \ + $(LIBXMLRPC_UTILPP) \ + $(LIBXMLRPC_UTIL) \ + $(call shliblefn, libxmlrpc_packetsocket) \ + $(LIBXMLRPC) \ + $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ + $(LIBXMLRPC_CLIENT) \ + $(BLDDIR)/src/libxmlrpc_client.ldflags \ + +$(LIBXMLRPC_CLIENTPP_SH): LIBOBJECTS = $(LIBXMLRPC_CLIENTPP_MODS:%=%.osh) +$(LIBXMLRPC_CLIENTPP_SH): LIBDEP = \ + -L. -l$(LIBXMLRPCPP_NAME) -lxmlrpc_packetsocket \ + $(shell cat blddir/src/libxmlrpc_client.ldflags) \ + -Lblddir/src -lxmlrpc_client -lxmlrpc \ + $(XML_PARSER_LIBDEP) \ + -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ + -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ + $(SOCKETLIBOPT) \ + $(THREAD_LIBS) \ + +LIBXMLRPC_PACKETSOCKET_SH = $(call shlibfn, libxmlrpc_packetsocket) + +$(LIBXMLRPC_PACKETSOCKET_SH): $(LIBXMLRPC_PACKETSOCKET_MODS:%=%.osh) \ + $(LIBXMLRPC_UTILPP) \ + $(LIBXMLRPC_UTIL) \ + $(call shliblefn, lib$(LIBXMLRPCPP_NAME)) \ + +$(LIBXMLRPC_PACKETSOCKET_SH): LIBOBJECTS = $(LIBXMLRPC_PACKETSOCKET_MODS:%=%.osh) +$(LIBXMLRPC_PACKETSOCKET_SH): LIBDEP = \ + -L. -l$(LIBXMLRPCPP_NAME) \ + -Lblddir/src -lxmlrpc \ + $(XML_PARSER_LIBDEP) \ + -L$(LIBXMLRPC_UTILPP_DIR) -lxmlrpc_util++ \ + -L$(LIBXMLRPC_UTIL_DIR) -lxmlrpc_util \ + $(SOCKETLIBOPT) \ + $(THREAD_LIBS) \ + +libxmlrpc_cpp.a: XmlRpcCpp.o +libxmlrpc_cpp.a: LIBOBJECTS = XmlRpcCpp.o + +lib$(LIBXMLRPCPP_NAME).a: $(LIBXMLRPCPP_MODS:%=%.o) +lib$(LIBXMLRPCPP_NAME).a: LIBOBJECTS = $(LIBXMLRPCPP_MODS:%=%.o) + +libxmlrpc_server++.a: $(LIBXMLRPC_SERVERPP_MODS:%=%.o) +libxmlrpc_server++.a: LIBOBJECTS = $(LIBXMLRPC_SERVERPP_MODS:%=%.o) + +libxmlrpc_server_abyss++.a: $(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.o) +libxmlrpc_server_abyss++.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.o) + +libxmlrpc_server_cgi++.a: $(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.o) +libxmlrpc_server_cgi++.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.o) + +libxmlrpc_server_pstream++.a: $(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.o) +libxmlrpc_server_pstream++.a: LIBOBJECTS=$(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.o) + +libxmlrpc_client++.a: $(LIBXMLRPC_CLIENTPP_MODS:%=%.o) +libxmlrpc_client++.a: LIBOBJECTS = $(LIBXMLRPC_CLIENTPP_MODS:%=%.o) + +libxmlrpc_packetsocket.a: $(LIBXMLRPC_PACKETSOCKET_MODS:%=%.o) +libxmlrpc_packetsocket.a: LIBOBJECTS = $(LIBXMLRPC_PACKETSOCKET_MODS:%=%.o) + +#----------------------------------------------------------------------------- +# RULES TO COMPILE OBJECT MODULES FOR LIBRARIES +#----------------------------------------------------------------------------- + +# Rules for these are in common.mk, courtesy of TARGET_MODS_PP: + +XmlRpcCpp.o% XmlrpcCpp.osh: \ + INCLUDES = $(BASIC_INCLUDES) + +$(LIBXMLRPCPP_MODS:%=%.o) \ +$(LIBXMLRPCPP_MODS:%=%.osh): \ + INCLUDES = $(BASIC_INCLUDES) + +SERVER_INCLUDES = $(BASIC_INCLUDES) $(LIBXML_INCLUDES) + +$(LIBXMLRPC_SERVERPP_MODS:%=%.o) \ +$(LIBXMLRPC_SERVERPP_MODS:%=%.osh): \ + INCLUDES = $(SERVER_INCLUDES) + +$(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.o) \ +$(LIBXMLRPC_SERVER_ABYSSPP_MODS:%=%.osh): \ + INCLUDES = $(SERVER_INCLUDES) + +$(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.o) \ +$(LIBXMLRPC_SERVER_CGIPP_MODS:%=%.osh): \ + INCLUDES = $(SERVER_INCLUDES) + +$(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.o) \ +$(LIBXMLRPC_SERVER_PSTREAMPP_MODS:%=%.osh): \ + INCLUDES = $(SERVER_INCLUDES) + +$(LIBXMLRPC_CLIENTPP_MODS:%=%.o) \ +$(LIBXMLRPC_CLIENTPP_MODS:%=%.osh): $(BLDDIR)/src/libxmlrpc_client.cflags + +$(LIBXMLRPC_CLIENTPP_MODS:%=%.o) \ +$(LIBXMLRPC_CLIENTPP_MODS:%=%.osh): \ + INCLUDES = $(BASIC_INCLUDES) $(LIBXML_INCLUDES) \ + $(shell cat blddir/src/libxmlrpc_client.cflags) + +$(LIBXMLRPC_PACKETSOCKET_MODS:%=%.o) \ +$(LIBXMLRPC_PACKETSOCKET_MODS:%=%.osh): \ + INCLUDES = $(BASIC_INCLUDES) + +# in Glibc 2.2 has some failed inlines, so we disable that warning: +$(LIBXMLRPC_PACKETSOCKET_MODS:%=%.o) \ +$(LIBXMLRPC_PACKETSOCKET_MODS:%=%.osh): \ + CFLAGS_LOCAL = $(CFLAGS_NO_INLINE_WARNING) + +TRANSPORT_CONFIG_USERS = client curl libwww wininet + +$(TRANSPORT_CONFIG_USERS:%=%.o) $(TRANSPORT_CONFIG_USERS:%=%.osh): \ + $(BLDDIR)/transport_config.h + +#----------------------------------------------------------------------------- +# RULES TO MAKE PKGCONFIG FILES +# +# (These are files used by the 'pkg-config' program to get information about +# using the libraries we build) +#----------------------------------------------------------------------------- + +xmlrpc++.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc++" >>$@ + @echo "Description: Xmlrpc-c basic XML-RPC C++ library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc++" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +xmlrpc_client++.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_client++" >>$@ + @echo "Description: Xmlrpc-c XML-RPC client C++ library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc++ xmlrpc_client xmlrpc_util++ xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_client++" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +xmlrpc_server++.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_server++" >>$@ + @echo "Description: Xmlrpc-c XML-RPC server C++ library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc++ xmlrpc xmlrpc_server xmlrpc_util++ xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server++" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +xmlrpc_server_abyss++.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_server_abyss++" >>$@ + @echo "Description: Xmlrpc-c Abyss XML-RPC server C++ library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc++ xmlrpc xmlrpc_server++ xmlrpc_abyss xmlrpc_util++ xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server_abyss" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +xmlrpc_server_pstream++.pc: + rm -f $@ + @echo "Echoes to '$@' suppressed here ..." + @echo "Name: xmlrpc_server_pstream" >>$@ + @echo "Description: Xmlrpc-c packet stream XML-RPC server library" >>$@ + @echo "Version: $(XMLRPC_VERSION_STRING)" >>$@ + @echo >>$@ + @echo "Requires: xmlrpc++ xmlrpc xmlrpc_server++ xmlrpc_util++ xmlrpc_util" >>$@ + @echo "Libs: -L$(LIBDESTDIR) -lxmlrpc_server_pstream++ -lxmlrpc_packetsocket" >>$@ + @echo "Cflags: -I$(HEADERDESTDIR)" >>$@ + +#----------------------------------------------------------------------------- +# MISCELLANEOUS RULES +#----------------------------------------------------------------------------- + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean clean-local distclean distclean-local +clean: clean-common clean-local +clean-local: + +distclean: clean distclean-local distclean-common + +distclean-local: + +.PHONY: dep +dep: dep-common $(BLDDIR)/transport_config.h +dep-common: $(BLDDIR)/src/libxmlrpc_client.cflags + +include depend.mk diff --git a/trunk/src/cpp/XmlRpcCpp.cpp b/trunk/src/cpp/XmlRpcCpp.cpp new file mode 100644 index 000000000..2270ee917 --- /dev/null +++ b/trunk/src/cpp/XmlRpcCpp.cpp @@ -0,0 +1,397 @@ +// Copyright (C) 2001 by Eric Kidd. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. The name of the author may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. + + +#include +#include + +#include "xmlrpc-c/util_int.h" + +#include "xmlrpc-c/oldcppwrapper.hpp" + +using std::string; + +//========================================================================= +// XmlRpcFault Methods +//========================================================================= + +XmlRpcFault::XmlRpcFault (const XmlRpcFault &fault) { + xmlrpc_env_init(&mFault); + xmlrpc_env_set_fault(&mFault, + fault.mFault.fault_code, + fault.mFault.fault_string); +} + +XmlRpcFault::XmlRpcFault (const int faultCode, const string faultString) { + xmlrpc_env_init(&mFault); + xmlrpc_env_set_fault(&mFault, faultCode, + const_cast(faultString.c_str())); +} + +XmlRpcFault::XmlRpcFault (const xmlrpc_env *env) { + if (!env->fault_string) + throw XmlRpcFault(XMLRPC_INTERNAL_ERROR, + "Tried to create empty fault"); + xmlrpc_env_init(&mFault); + xmlrpc_env_set_fault(&mFault, env->fault_code, + const_cast(env->fault_string)); +} + +XmlRpcFault::~XmlRpcFault (void) { + xmlrpc_env_clean(&mFault); +} + +string XmlRpcFault::getFaultString (void) const { + XMLRPC_ASSERT(mFault.fault_occurred); + return string(mFault.fault_string); +} + + +//========================================================================= +// XmlRpcEnv Methods +//========================================================================= + +XmlRpcEnv::XmlRpcEnv (const XmlRpcEnv &env) { + xmlrpc_env_init(&mEnv); + if (env.hasFaultOccurred()) + xmlrpc_env_set_fault(&mEnv, + env.mEnv.fault_code, + env.mEnv.fault_string); +} + +XmlRpcFault XmlRpcEnv::getFault (void) const { + return XmlRpcFault(&mEnv); +} + +void XmlRpcEnv::throwMe (void) const { + throw XmlRpcFault(&mEnv); +} + + +//========================================================================= +// XmlRpcValue Methods +//========================================================================= + +// If the user doesn't tell us what kind of value to create, use +// a false boolean value as the default. +XmlRpcValue::XmlRpcValue (void) { + XmlRpcEnv env; + mValue = xmlrpc_build_value(env, "b", (xmlrpc_bool) 0); + env.throwIfFaultOccurred(); +} + +XmlRpcValue XmlRpcValue::makeInt (const XmlRpcValue::int32 i) { + XmlRpcEnv env; + xmlrpc_value *value = xmlrpc_build_value(env, "i", i); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue XmlRpcValue::makeBool (const bool b) { + XmlRpcEnv env; + xmlrpc_value *value = xmlrpc_build_value(env, "b", (xmlrpc_bool) b); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue XmlRpcValue::makeDouble (const double d) { + XmlRpcEnv env; + xmlrpc_value *value = xmlrpc_build_value(env, "d", d); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue XmlRpcValue::makeDateTime (const string& dateTime) { + XmlRpcEnv env; + xmlrpc_value *value; + const char *data = dateTime.c_str(); // Make sure we're not using wchar_t. + value = xmlrpc_build_value(env, "8", data); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue XmlRpcValue::makeString (const string& str) { + XmlRpcEnv env; + const char *data = str.data(); // Make sure we're not using wchar_t. + size_t size = str.size(); + xmlrpc_value *value = xmlrpc_build_value(env, "s#", data, size); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue XmlRpcValue::makeString (const char *const str) { + XmlRpcEnv env; + xmlrpc_value *value = xmlrpc_build_value(env, "s", str); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue XmlRpcValue::makeString (const char *const str, size_t len) { + XmlRpcEnv env; + xmlrpc_value *value = xmlrpc_build_value(env, "s#", str, len); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue XmlRpcValue::makeArray (void) { + XmlRpcEnv env; + xmlrpc_value *value = xmlrpc_build_value(env, "()"); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue XmlRpcValue::makeStruct (void) { + XmlRpcEnv env; + xmlrpc_value *value = xmlrpc_struct_new(env); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue XmlRpcValue::makeBase64 (const unsigned char *const data, + size_t len) +{ + XmlRpcEnv env; + xmlrpc_value *value = xmlrpc_build_value(env, "6", data, len); + env.throwIfFaultOccurred(); + return XmlRpcValue(value, CONSUME_REFERENCE); +} + +XmlRpcValue::int32 XmlRpcValue::getInt (void) const { + XmlRpcEnv env; + XmlRpcValue::int32 result; + xmlrpc_parse_value(env, mValue, "i", &result); + env.throwIfFaultOccurred(); + return result; +} + +bool XmlRpcValue::getBool (void) const { + XmlRpcEnv env; + xmlrpc_bool result; + xmlrpc_parse_value(env, mValue, "b", &result); + env.throwIfFaultOccurred(); + return (result != 0); +} + +double XmlRpcValue::getDouble (void) const { + XmlRpcEnv env; + double result; + xmlrpc_parse_value(env, mValue, "d", &result); + env.throwIfFaultOccurred(); + return result; +} + +string XmlRpcValue::getRawDateTime (void) const { + XmlRpcEnv env; + char *result; + xmlrpc_parse_value(env, mValue, "8", &result); + env.throwIfFaultOccurred(); + return string(result); +} + +string XmlRpcValue::getString (void) const { + XmlRpcEnv env; + char *result; + size_t result_len; + xmlrpc_parse_value(env, mValue, "s#", &result, &result_len); + env.throwIfFaultOccurred(); + return string(result, result_len); + +} + +XmlRpcValue XmlRpcValue::getArray (void) const { + XmlRpcEnv env; + xmlrpc_value *result; + xmlrpc_parse_value(env, mValue, "A", &result); + env.throwIfFaultOccurred(); + return XmlRpcValue(result); +} + +XmlRpcValue XmlRpcValue::getStruct (void) const { + XmlRpcEnv env; + xmlrpc_value *result; + xmlrpc_parse_value(env, mValue, "S", &result); + env.throwIfFaultOccurred(); + return XmlRpcValue(result); +} + +void XmlRpcValue::getBase64 (const unsigned char *& out_data, + size_t& out_len) const +{ + XmlRpcEnv env; + xmlrpc_parse_value(env, mValue, "6", &out_data, &out_len); + env.throwIfFaultOccurred(); +} + +size_t XmlRpcValue::arraySize (void) const { + XmlRpcEnv env; + size_t result = xmlrpc_array_size(env, mValue); + env.throwIfFaultOccurred(); + return result; +} + +void XmlRpcValue::arrayAppendItem (const XmlRpcValue& value) { + XmlRpcEnv env; + xmlrpc_array_append_item(env, mValue, value.borrowReference()); + env.throwIfFaultOccurred(); +} + +XmlRpcValue XmlRpcValue::arrayGetItem (int index) const { + XmlRpcEnv env; + xmlrpc_value *result = xmlrpc_array_get_item(env, mValue, index); + env.throwIfFaultOccurred(); + return XmlRpcValue(result); +} + +size_t XmlRpcValue::structSize (void) const { + XmlRpcEnv env; + size_t result = xmlrpc_struct_size(env, mValue); + env.throwIfFaultOccurred(); + return result; +} + +bool XmlRpcValue::structHasKey (const string& key) const { + XmlRpcEnv env; + const char *keystr = key.data(); + size_t keylen = key.size(); + int result = xmlrpc_struct_has_key_n(env, mValue, + const_cast(keystr), keylen); + env.throwIfFaultOccurred(); + return (result != 0); +} + +XmlRpcValue XmlRpcValue::structGetValue (const string& key) const { + XmlRpcEnv env; + const char *keystr = key.data(); + size_t keylen = key.size(); + xmlrpc_value *result = + xmlrpc_struct_get_value_n(env, mValue, + const_cast(keystr), keylen); + env.throwIfFaultOccurred(); + return XmlRpcValue(result); +} + +void XmlRpcValue::structSetValue (const string& key, const XmlRpcValue& value) +{ + XmlRpcEnv env; + const char *keystr = key.data(); + size_t keylen = key.size(); + xmlrpc_struct_set_value_n(env, mValue, (char*) keystr, keylen, + value.borrowReference()); + env.throwIfFaultOccurred(); +} + +void XmlRpcValue::structGetKeyAndValue (const int index, + string& out_key, + XmlRpcValue& out_value) const +{ + XmlRpcEnv env; + + xmlrpc_value *key, *value; + xmlrpc_struct_get_key_and_value(env, mValue, index, &key, &value); + env.throwIfFaultOccurred(); + + out_key = XmlRpcValue(key).getString(); + out_value = XmlRpcValue(value); +} + +XmlRpcGenSrv& XmlRpcGenSrv::addMethod (const string& name, + xmlrpc_method method, + void *data) +{ + XmlRpcEnv env; + + xmlrpc_registry_add_method (env, mRegistry, NULL, + name.c_str (), + method, data); + + env.throwIfFaultOccurred (); + return (*this); +} + +XmlRpcGenSrv& XmlRpcGenSrv::addMethod (const string& name, + xmlrpc_method method, + void* data, + const string& signature, + const string& help) +{ + XmlRpcEnv env; + + xmlrpc_registry_add_method_w_doc (env, mRegistry, NULL, + name.c_str (), + method, data, + signature.c_str (), + help.c_str ()); + + env.throwIfFaultOccurred (); + return (*this); +} + +xmlrpc_mem_block* XmlRpcGenSrv::alloc (XmlRpcEnv& env, const string& body) const +{ + xmlrpc_mem_block* result = NULL; + char* contents; + + result = xmlrpc_mem_block_new (env, body.length ()); + env.throwIfFaultOccurred (); + + contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, result); + + memcpy (contents, body.c_str (), body.length ()); + return result; +} + +string XmlRpcGenSrv::handle (const string& body) const +{ + XmlRpcEnv env; + string result; + xmlrpc_mem_block* input = NULL, * output = NULL; + char* input_data, * output_data; + size_t input_size, output_size; + + if (body.length () > xmlrpc_limit_get (XMLRPC_XML_SIZE_LIMIT_ID)) + throw XmlRpcFault (XMLRPC_LIMIT_EXCEEDED_ERROR, "XML-RPC request too large"); + + input = alloc (env, body); + input_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, input); + input_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, input); + + output = xmlrpc_registry_process_call (env, mRegistry, NULL, + input_data, input_size); + + if (output) + { + output_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output); + output_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); + + result.assign (output_data, output_size); + xmlrpc_mem_block_free (output); + } + + xmlrpc_mem_block_free (input); + if (!result.length ()) + throw XmlRpcFault (env); + + return result; +} diff --git a/trunk/src/cpp/abyss_reqhandler_xmlrpc.cpp b/trunk/src/cpp/abyss_reqhandler_xmlrpc.cpp new file mode 100644 index 000000000..2565b8143 --- /dev/null +++ b/trunk/src/cpp/abyss_reqhandler_xmlrpc.cpp @@ -0,0 +1,109 @@ +#include + +using namespace std; + +#include "xmlrpc-c/AbyssServer.hpp" +using xmlrpc_c::AbyssServer; +#include "xmlrpc-c/registry.hpp" + +#include "xmlrpc-c/abyss_reqhandler_xmlrpc.hpp" + + +namespace xmlrpc_c { + +abyssReqhandlerXmlrpc::abyssReqhandlerXmlrpc( + xmlrpc_c::registryPtr const& registryP) : + registryP(registryP) +{} + + + +static void +handleXmlRpc(AbyssServer::Session * const sessionP, + xmlrpc_c::registry * const registryP, + bool * const responseStartedP) { + + string const callXml(sessionP->body()); + string responseXml; + + registryP->processCall(callXml, &responseXml); + + sessionP->setRespStatus(200); + + sessionP->setRespContentType("text/xml charset=utf-8"); + + sessionP->setRespContentLength(responseXml.size()); + + *responseStartedP = true; + + sessionP->writeResponse(responseXml); +} + + + +void +abyssReqhandlerXmlrpc::abortRequest( + AbyssServer::Session * const sessionP, + bool const responseStarted, + AbyssServer::Exception const& e) { + + if (responseStarted) { + // We can't send an error response because we failed + // partway through sending a non-error response. All we can + // do is perhaps log the error and then close the connection. + this->handleUnreportableFailure(e); + } else + sessionP->sendErrorResponse(e); +} + + + +void +abyssReqhandlerXmlrpc::handleRequest( + AbyssServer::Session * const sessionP, + bool * const handledP) { + + bool responseStarted; + // We have at least started to send an HTTP response. (This is + // important in error handling, because it means it is too late to + // send an error response). + + responseStarted = false; + + try { + switch (sessionP->method()) { + case AbyssServer::Session::METHOD_POST: { + if (sessionP->uriPathName() == "/RPC2") { + + handleXmlRpc(sessionP, this->registryP.get(), + &responseStarted); + *handledP = true; + } else + *handledP = false; + } break; + default: + *handledP = false; + } + } catch (AbyssServer::Exception const& e) { + this->abortRequest(sessionP, responseStarted, e); + *handledP = true; + } catch (exception const& e) { + this->abortRequest(sessionP, responseStarted, + AbyssServer::Exception(500, e.what())); + *handledP = true; + } +} + + + +void +abyssReqhandlerXmlrpc::handleUnreportableFailure( + AbyssServer::Exception const& ) { +/*----------------------------------------------------------------------------- + This is the default implementation of the virtual method. +-----------------------------------------------------------------------------*/ +} + + + +} // namespace diff --git a/trunk/src/cpp/client.cpp b/trunk/src/cpp/client.cpp new file mode 100644 index 000000000..0e8184c14 --- /dev/null +++ b/trunk/src/cpp/client.cpp @@ -0,0 +1,1279 @@ +/*============================================================================= + client.cpp +=============================================================================== + This is the C++ XML-RPC client library for Xmlrpc-c. + + Note that unlike most of Xmlprc-c's C++ API, this is _not_ based on the + C client library. This code is independent of the C client library, and + is based directly on the client XML transport libraries (with a little + help from internal C utility libraries). +=============================================================================*/ + +#include +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/girmem.hpp" +using girmem::autoObjectPtr; +using girmem::autoObject; +#include "xmlrpc-c/env_wrap.hpp" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/transport.h" +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/xml.hpp" +#include "xmlrpc-c/timeout.hpp" +#include "xmlrpc-c/client.hpp" +#include "transport_config.h" + +using namespace std; +using namespace xmlrpc_c; + + +namespace { + +void +throwIfError(env_wrap const& env) { + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +class memblockStringWrapper { + +public: + memblockStringWrapper(string const value) { + + env_wrap env; + + this->memblockP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); + throwIfError(env); + + XMLRPC_MEMBLOCK_APPEND(char, &env.env_c, this->memblockP, + value.c_str(), value.size()); + throwIfError(env); + } + + memblockStringWrapper(xmlrpc_mem_block * const memblockP) : + memblockP(memblockP) {}; + + ~memblockStringWrapper() { + XMLRPC_MEMBLOCK_FREE(char, this->memblockP); + } + + xmlrpc_mem_block * memblockP; +}; + +} // namespace + +namespace xmlrpc_c { + +struct client_xml_impl { + /* We have both kinds of pointers to give the user flexibility -- we + have constructors that take both. But the simple pointer + 'transportP' is valid in both cases. + */ + clientXmlTransport * transportP; + clientXmlTransportPtr transportPtr; + xmlrpc_dialect dialect; + + client_xml_impl(clientXmlTransport * const transportP, + xmlrpc_dialect const dialect = xmlrpc_dialect_i8) : + transportP(transportP), + dialect(dialect) {} + + client_xml_impl(clientXmlTransportPtr const transportPtr, + clientXmlTransport * const transportP, + xmlrpc_dialect const dialect = xmlrpc_dialect_i8) : + transportP(transportP), + transportPtr(transportPtr), + dialect(dialect) {} +}; + + + +carriageParm::carriageParm() {} + + + +carriageParm::~carriageParm() {} + + + +carriageParmPtr::carriageParmPtr() { + // Base class constructor will construct pointer that points to nothing +} + + + +carriageParmPtr::carriageParmPtr( +carriageParm * const carriageParmP) : autoObjectPtr(carriageParmP) {} + + + +carriageParm * +carriageParmPtr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +carriageParm * +carriageParmPtr::get() const { + return dynamic_cast(this->objectP); +} + + + +carriageParm_http0::carriageParm_http0() : + c_serverInfoP(NULL) {} + + + +carriageParm_http0::carriageParm_http0(string const serverUrl) { + this->c_serverInfoP = NULL; + + this->instantiate(serverUrl); +} + + + +carriageParm_http0::~carriageParm_http0() { + + if (this->c_serverInfoP) + xmlrpc_server_info_free(this->c_serverInfoP); +} + + + +void +carriageParm_http0::instantiate(string const serverUrl) { + + if (c_serverInfoP) + throw(error("object already instantiated")); + + env_wrap env; + + this->c_serverInfoP = + xmlrpc_server_info_new(&env.env_c, serverUrl.c_str()); + throwIfError(env); +} + + + +void +carriageParm_http0::setUser(string const userid, + string const password) { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_set_user( + &env.env_c, this->c_serverInfoP, userid.c_str(), password.c_str()); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +carriageParm_http0::allowAuthBasic() { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_allow_auth_basic(&env.env_c, this->c_serverInfoP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +carriageParm_http0::disallowAuthBasic() { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_disallow_auth_basic(&env.env_c, this->c_serverInfoP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +carriageParm_http0::allowAuthDigest() { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_allow_auth_digest(&env.env_c, this->c_serverInfoP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +carriageParm_http0::disallowAuthDigest() { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_disallow_auth_digest(&env.env_c, this->c_serverInfoP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +carriageParm_http0::allowAuthNegotiate() { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_allow_auth_negotiate(&env.env_c, this->c_serverInfoP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +carriageParm_http0::disallowAuthNegotiate() { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_disallow_auth_negotiate( + &env.env_c, this->c_serverInfoP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +carriageParm_http0::allowAuthNtlm() { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_allow_auth_ntlm(&env.env_c, this->c_serverInfoP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +carriageParm_http0::disallowAuthNtlm() { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_disallow_auth_ntlm(&env.env_c, this->c_serverInfoP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +carriageParm_http0::setBasicAuth(string const username, + string const password) { + + if (!this->c_serverInfoP) + throw(error("object not instantiated")); + + env_wrap env; + + xmlrpc_server_info_set_basic_auth( + &env.env_c, this->c_serverInfoP, username.c_str(), password.c_str()); + throwIfError(env); +} + + + +carriageParm_http0Ptr::carriageParm_http0Ptr() { + // Base class constructor will construct pointer that points to nothing +} + + + +carriageParm_http0Ptr::carriageParm_http0Ptr( + carriageParm_http0 * const carriageParmP) : + carriageParmPtr(carriageParmP) {} + + + +carriageParm_http0 * +carriageParm_http0Ptr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +xmlTransaction::xmlTransaction() {} + + + +void +xmlTransaction::finish(string const& responseXml) const { + + xml::trace("XML-RPC RESPONSE", responseXml); +} + + + +void +xmlTransaction::finishErr(error const&) const { + +} + + + +void +xmlTransaction::progress(struct xmlrpc_progress_data const&) const { + + // This is just the base class method. A derived class may override + // this with something substantial. +} + + + +xmlTransactionPtr::xmlTransactionPtr() {} + + + +xmlTransactionPtr::xmlTransactionPtr(xmlTransaction * xmlTransP) : + autoObjectPtr(xmlTransP) {} + + + +xmlTransaction * +xmlTransactionPtr::operator->() const { + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +struct xmlTranCtl { +/*---------------------------------------------------------------------------- + This contains information needed to conduct a transaction. You + construct it as you start the transaction and destroy it after the + work is done. You need this only for an asynchronous one, because + where the user starts and finishes the RPC in the same + libxmlrpc_client call, you can just keep this information in + various stack variables, and it's faster and easier to understand + that way. + + The C transport is designed to take a xmlrpc_call_info argument for + similar stuff needed by the the C client object. But it's really + opaque to the transport, so we just let xmlTranCtl masquerade as + xmlprc_call_info in our call to the C transport. +-----------------------------------------------------------------------------*/ + xmlTranCtl(xmlTransactionPtr const& xmlTranP, + string const& callXml) : + + xmlTranP(xmlTranP) { + + env_wrap env; + + this->callXmlP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); + throwIfError(env); + + XMLRPC_MEMBLOCK_APPEND(char, &env.env_c, this->callXmlP, + callXml.c_str(), callXml.size()); + throwIfError(env); + } + + ~xmlTranCtl() { + XMLRPC_MEMBLOCK_FREE(char, this->callXmlP); + } + + xmlTransactionPtr const xmlTranP; + // The transaction we're controlling. Most notable use of this is + // that this object we inform when the transaction is done. This + // is where the response XML and other transaction results go. + + xmlrpc_mem_block * callXmlP; + // The XML of the call. This is what the transport transports. +}; + + + +clientXmlTransport::~clientXmlTransport() {} + + + +void +clientXmlTransport::start(carriageParm * const carriageParmP, + string const& callXml, + xmlTransactionPtr const& xmlTranP) { + + // Note: derived class clientXmlTransport_http overrides this, + // so it doesn't normally get used. + + string responseXml; + + this->call(carriageParmP, callXml, &responseXml); + + xmlTranP->finish(responseXml); +} + + + +void +clientXmlTransport::finishAsync(xmlrpc_c::timeout) { + + // Since our start() does the whole thing, there's nothing for + // us to do. + + // A derived class that overrides start() with something properly + // asynchronous had better also override finishAsync() with something + // substantial. +} + + + +void +clientXmlTransport::asyncComplete( + struct xmlrpc_call_info * const callInfoP, + xmlrpc_mem_block * const responseXmlMP, + xmlrpc_env const transportEnv) { + + xmlTranCtl * const xmlTranCtlP = reinterpret_cast(callInfoP); + + try { + if (transportEnv.fault_occurred) { + xmlTranCtlP->xmlTranP->finishErr(error(transportEnv.fault_string)); + } else { + string const responseXml( + XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlMP), + XMLRPC_MEMBLOCK_SIZE(char, responseXmlMP)); + xmlTranCtlP->xmlTranP->finish(responseXml); + } + } catch(exception const&) { + /* We can't throw an error back to C code, and the async_complete + interface does not provide for failure, so we define ->finish() + as not being capable of throwing an error. + */ + assert(false); + } + delete(xmlTranCtlP); + + /* Ordinarily, *xmlTranCtlP is the last reference to + xmlTranCtlP->xmlTranP, so that will get destroyed too. But + ->finish() could conceivably create a new reference to + xmlTranCtlP->xmlTranP, and then it would keep living. + */ +} + + + +void +clientXmlTransport::progress( + struct xmlrpc_call_info * const callInfoP, + struct xmlrpc_progress_data const progressData) { + + xmlTranCtl * const xmlTranCtlP = reinterpret_cast(callInfoP); + + xmlTranCtlP->xmlTranP->progress(progressData); +} + + + +void +clientXmlTransport::setInterrupt(int *) { + + throwf("The client XML transport is not interruptible"); +} + + + +clientXmlTransportPtr::clientXmlTransportPtr() { + // Base class constructor will construct pointer that points to nothing +} + + + +clientXmlTransportPtr::clientXmlTransportPtr( + clientXmlTransport * const transportP) : autoObjectPtr(transportP) {} + + + +clientXmlTransport * +clientXmlTransportPtr::get() const { + return dynamic_cast(objectP); +} + + + +clientXmlTransport * +clientXmlTransportPtr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +clientXmlTransport_http::~clientXmlTransport_http() {} + + + +void +clientXmlTransport_http::call( + carriageParm * const carriageParmP, + string const& callXml, + string * const responseXmlP) { + + carriageParm_http0 * const carriageParmHttpP = + dynamic_cast(carriageParmP); + + if (carriageParmHttpP == NULL) + throw(error("HTTP client XML transport called with carriage " + "parameter object not of class carriageParm_http")); + + memblockStringWrapper callXmlM(callXml); + + xmlrpc_mem_block * responseXmlMP; + + env_wrap env; + + this->c_transportOpsP->call(&env.env_c, + this->c_transportP, + carriageParmHttpP->c_serverInfoP, + callXmlM.memblockP, + &responseXmlMP); + + throwIfError(env); + + memblockStringWrapper responseHolder(responseXmlMP); + // Makes responseXmlMP get freed at end of scope + + *responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlMP), + XMLRPC_MEMBLOCK_SIZE(char, responseXmlMP)); +} + + + +void +clientXmlTransport_http::start( + carriageParm * const carriageParmP, + string const& callXml, + xmlTransactionPtr const& xmlTranP) { + + env_wrap env; + + carriageParm_http0 * const carriageParmHttpP = + dynamic_cast(carriageParmP); + + if (carriageParmHttpP == NULL) + throw(error("HTTP client XML transport called with carriage " + "parameter object not of type carriageParm_http")); + + xmlTranCtl * const tranCtlP(new xmlTranCtl(xmlTranP, callXml)); + + try { + this->c_transportOpsP->send_request( + &env.env_c, + this->c_transportP, + carriageParmHttpP->c_serverInfoP, + tranCtlP->callXmlP, + &this->asyncComplete, &this->progress, + reinterpret_cast(tranCtlP)); + + throwIfError(env); + } catch (...) { + delete tranCtlP; + throw; + } +} + + + +void +clientXmlTransport_http::finishAsync(xmlrpc_c::timeout const timeout) { + + xmlrpc_timeoutType const c_timeoutType( + timeout.finite ? timeout_yes : timeout_no); + xmlrpc_timeout const c_timeout(timeout.duration); + + this->c_transportOpsP->finish_asynch( + this->c_transportP, c_timeoutType, c_timeout); +} + + + +void +clientXmlTransport_http::setInterrupt(int * const interruptP) { + + if (this->c_transportOpsP->set_interrupt) + this->c_transportOpsP->set_interrupt(this->c_transportP, interruptP); +} + + + +bool const haveCurl( +#if MUST_BUILD_CURL_CLIENT +true +#else +false +#endif +); + +bool const haveLibwww( +#if MUST_BUILD_LIBWWW_CLIENT +true +#else +false +#endif +); + +bool const haveWininet( +#if MUST_BUILD_WININET_CLIENT +true +#else +false +#endif +); + + + +vector +clientXmlTransport_http::availableTypes() { + + vector retval; + + if (haveCurl) + retval.push_back("curl"); + + if (haveLibwww) + retval.push_back("libwww"); + + if (haveWininet) + retval.push_back("wininet"); + + return retval; +} + + + +clientXmlTransportPtr +clientXmlTransport_http::create() { +/*---------------------------------------------------------------------------- + Make an HTTP Client XML transport of any kind (Caller doesn't care). + + Caller can find out what kind he got by trying dynamic casts. + + Caller can use a carriageParm_http0 with the transport. +-----------------------------------------------------------------------------*/ + if (haveCurl) + return clientXmlTransportPtr(new clientXmlTransport_curl()); + else if (haveLibwww) + return clientXmlTransportPtr(new clientXmlTransport_libwww()); + else if (haveWininet) + return clientXmlTransportPtr(new clientXmlTransport_wininet()); + else + throwf("This XML-RPC client library contains no HTTP XML transports"); +} + + + +clientTransaction::clientTransaction() {} + + + +clientTransactionPtr::clientTransactionPtr() {} + + + +clientTransactionPtr::clientTransactionPtr( + clientTransaction * const transP) : autoObjectPtr(transP) {} + + + +clientTransactionPtr::~clientTransactionPtr() {} + + + +clientTransaction * +clientTransactionPtr::operator->() const { + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +client::~client() {} + + + +void +client::start(carriageParm * const carriageParmP, + string const& methodName, + paramList const& paramList, + clientTransactionPtr const& tranP) { +/*---------------------------------------------------------------------------- + Start an RPC, wait for it to complete, and finish it. + + Usually, a derived class overrides this with something that does + not wait for the RPC to complete, but rather arranges for something + to finish the RPC later when the RPC does complete. +-----------------------------------------------------------------------------*/ + rpcOutcome outcome; + + this->call(carriageParmP, methodName, paramList, &outcome); + + tranP->finish(outcome); +} + + + +void +client::finishAsync(xmlrpc_c::timeout) { + + // Since our start() does the whole thing, there's nothing for + // us to do. + + // A derived class that overrides start() with something properly + // asynchronous had better also override finishAsync() with something + // substantial. +} + + + +void +client::setInterrupt(int *) { + + throwf("Clients of this type are not interruptible"); +} + + + +clientPtr::clientPtr() { + // Base class constructor will construct pointer that points to nothing +} + + + +clientPtr::clientPtr( + client * const clientP) : autoObjectPtr(clientP) {} + + + +client * +clientPtr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +client * +clientPtr::get() const { + return dynamic_cast(objectP); +} + + + +client_xml::client_xml(clientXmlTransport * const transportP) { + + this->implP = new client_xml_impl(transportP); +} + + + +client_xml::client_xml(clientXmlTransportPtr const transportPtr) { + + this->implP = new client_xml_impl(transportPtr, transportPtr.get()); +} + + + +client_xml::client_xml(clientXmlTransport * const transportP, + xmlrpc_dialect const dialect) { + + this->implP = new client_xml_impl(transportP, dialect); +} + + + +client_xml::client_xml(clientXmlTransportPtr const transportPtr, + xmlrpc_dialect const dialect) { + + this->implP = new client_xml_impl(transportPtr, transportPtr.get(), + dialect); +} + + + +client_xml::~client_xml() { + + delete(this->implP); +} + + + +void +client_xml::call(carriageParm * const carriageParmP, + string const& methodName, + paramList const& paramList, + rpcOutcome * const outcomeP) { + + string callXml; + string responseXml; + + xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); + + xml::trace("XML-RPC CALL", callXml); + + try { + this->implP->transportP->call(carriageParmP, callXml, &responseXml); + } catch (exception const& e) { + throwf("Unable to transport XML to server and " + "get XML response back. %s", e.what()); + } + xml::trace("XML-RPC RESPONSE", responseXml); + + try { + xml::parseResponse(responseXml, outcomeP); + } catch (exception const& e) { + throwf("Response XML from server is not valid XML-RPC response. %s", + e.what()); + } +} + + + +void +client_xml::start(carriageParm * const carriageParmP, + string const& methodName, + paramList const& paramList, + clientTransactionPtr const& tranP) { + + string callXml; + + xml::generateCall(methodName, paramList, this->implP->dialect, &callXml); + + xml::trace("XML-RPC CALL", callXml); + + xmlTransaction_clientPtr const xmlTranP(tranP); + + this->implP->transportP->start(carriageParmP, callXml, xmlTranP); +} + + + +void +client_xml::finishAsync(xmlrpc_c::timeout const timeout) { + + this->implP->transportP->finishAsync(timeout); +} + + + +void +client_xml::setInterrupt(int * const interruptP) { + + this->implP->transportP->setInterrupt(interruptP); +} + + + +serverAccessor::serverAccessor(clientPtr const clientP, + carriageParmPtr const carriageParmP) : + + clientP(clientP), carriageParmP(carriageParmP) {}; + + + +void +serverAccessor::call(std::string const& methodName, + xmlrpc_c::paramList const& paramList, + xmlrpc_c::rpcOutcome * const outcomeP) const { + + this->clientP->call(this->carriageParmP.get(), + methodName, + paramList, + outcomeP); +} + + + +serverAccessorPtr::serverAccessorPtr() { + // Base class constructor will construct pointer that points to nothing +} + + + +serverAccessorPtr::serverAccessorPtr( + serverAccessor * const serverAccessorParmP) : + autoObjectPtr(serverAccessorParmP) {} + + + +serverAccessor * +serverAccessorPtr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +serverAccessor * +serverAccessorPtr::get() const { + return dynamic_cast(objectP); +} + + + +connection::connection(client * const clientP, + carriageParm * const carriageParmP) : + clientP(clientP), carriageParmP(carriageParmP) {} + + + +connection::~connection() {} + + + +struct rpc_impl { + 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 + rpcOutcome outcome; + // Defined only in STATE_FAILED and STATE_SUCCEEDED + string methodName; + xmlrpc_c::paramList paramList; + + rpc_impl(string const& methodName, + xmlrpc_c::paramList const& paramList) : + state(STATE_UNFINISHED), + methodName(methodName), + paramList(paramList) {} +}; + + + +rpc::rpc(string const methodName, + paramList const& paramList) { + + this->implP = new rpc_impl(methodName, paramList); +} + + + +rpc::~rpc() { + + if (this->implP->state == rpc_impl::STATE_ERROR) + delete(this->implP->errorP); + + delete(this->implP); +} + + + +void +rpc::call(client * const clientP, + carriageParm * const carriageParmP) { + + if (this->implP->state != rpc_impl::STATE_UNFINISHED) + throw(error("Attempt to execute an RPC that has already been " + "executed")); + + clientP->call(carriageParmP, + this->implP->methodName, + this->implP->paramList, + &this->implP->outcome); + + this->implP->state = this->implP->outcome.succeeded() ? + rpc_impl::STATE_SUCCEEDED : rpc_impl::STATE_FAILED; +} + + + +void +rpc::call(connection const& connection) { + + this->call(connection.clientP, connection.carriageParmP); + +} + + + +void +rpc::start(client * const clientP, + carriageParm * const carriageParmP) { + + if (this->implP->state != rpc_impl::STATE_UNFINISHED) + throw(error("Attempt to execute an RPC that has already been " + "executed")); + + clientP->start(carriageParmP, + this->implP->methodName, + this->implP->paramList, + rpcPtr(this)); +} + + + +void +rpc::start(xmlrpc_c::connection const& connection) { + + this->start(connection.clientP, connection.carriageParmP); +} + + + +void +rpc::finish(rpcOutcome const& outcome) { + + this->implP->state = + outcome.succeeded() ? + rpc_impl::STATE_SUCCEEDED : rpc_impl::STATE_FAILED; + + this->implP->outcome = outcome; + + this->notifyComplete(); +} + + + +void +rpc::finishErr(error const& error) { + + this->implP->state = rpc_impl::STATE_ERROR; + this->implP->errorP = new girerr::error(error); + this->notifyComplete(); +} + + + +void +rpc::notifyComplete() { +/*---------------------------------------------------------------------------- + Anyone who does RPCs asynchronously and doesn't use polling will + want to make his own class derived from 'rpc' and override this + with a notifyFinish() that does something. + + Typically, notifyFinish() will queue the RPC so some other thread + will deal with the fact that the RPC is finished. + + + In the absence of the aforementioned queueing, the RPC becomes + unreferenced as soon as our Caller releases his reference, so the + RPC gets destroyed when we return. +-----------------------------------------------------------------------------*/ + +} + + + +void +rpc::progress(struct xmlrpc_progress_data const&) const { +/*---------------------------------------------------------------------------- + If the user is interested in tracking the progress of the RPC, he will + derive a class from xmlrpc_c::rpc and override this with a progress() + that does something, such as display a progress bar. +-----------------------------------------------------------------------------*/ + +} + + + +value +rpc::getResult() const { + + switch (this->implP->state) { + case rpc_impl::STATE_UNFINISHED: + throw(error("Attempt to get result of RPC that is not finished.")); + break; + case rpc_impl::STATE_ERROR: + throw(*this->implP->errorP); + break; + case rpc_impl::STATE_FAILED: + throw(error("RPC response indicates failure. " + + this->implP->outcome.getFault().getDescription())); + break; + case rpc_impl::STATE_SUCCEEDED: { + // All normal + } + } + + return this->implP->outcome.getResult(); +} + + + + +fault +rpc::getFault() const { + + switch (this->implP->state) { + case rpc_impl::STATE_UNFINISHED: + throw(error("Attempt to get fault from RPC that is not finished")); + break; + case rpc_impl::STATE_ERROR: + throw(*this->implP->errorP); + break; + case rpc_impl::STATE_SUCCEEDED: + throw(error("Attempt to get fault from an RPC that succeeded")); + break; + case rpc_impl::STATE_FAILED: { + // All normal + } + } + + return this->implP->outcome.getFault(); +} + + + +bool +rpc::isFinished() const { + return (this->implP->state != rpc_impl::STATE_UNFINISHED); +} + + + +bool +rpc::isSuccessful() const { + return (this->implP->state == rpc_impl::STATE_SUCCEEDED); +} + + + +rpcPtr::rpcPtr() {} + + + +rpcPtr::rpcPtr(rpc * const rpcP) : clientTransactionPtr(rpcP) {} + + + +rpcPtr::rpcPtr(string const methodName, + xmlrpc_c::paramList const& paramList) : + clientTransactionPtr(new rpc(methodName, paramList)) {} + + + +rpc * +rpcPtr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +xmlTransaction_client::xmlTransaction_client( + clientTransactionPtr const& tranP) : + tranP(tranP) {} + + + +void +xmlTransaction_client::finish(string const& responseXml) const { + + xml::trace("XML-RPC RESPONSE", responseXml); + + try { + rpcOutcome outcome; + + xml::parseResponse(responseXml, &outcome); + + this->tranP->finish(outcome); + } catch (error const& error) { + this->tranP->finishErr(error); + } +} + + + +void +xmlTransaction_client::finishErr(error const& error) const { + + this->tranP->finishErr(error); +} + + + +void +xmlTransaction_client::progress( + struct xmlrpc_progress_data const& progressData) const { + + this->tranP->progress(progressData); +} + + + +xmlTransaction_clientPtr::xmlTransaction_clientPtr() {} + + + +xmlTransaction_clientPtr::xmlTransaction_clientPtr( + clientTransactionPtr const& tranP) : + xmlTransactionPtr(new xmlTransaction_client(tranP)) {} + + + +xmlTransaction_client * +xmlTransaction_clientPtr::operator->() const { + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +} // namespace diff --git a/trunk/src/cpp/client_simple.cpp b/trunk/src/cpp/client_simple.cpp new file mode 100644 index 000000000..abd198452 --- /dev/null +++ b/trunk/src/cpp/client_simple.cpp @@ -0,0 +1,161 @@ +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "xmlrpc-c/env_wrap.hpp" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/client.hpp" +#include + +#include "xmlrpc-c/client_simple.hpp" + +using namespace std; +using namespace xmlrpc_c; + +namespace xmlrpc_c { + + +namespace { + +class cValueWrapper { +/*---------------------------------------------------------------------------- + Use an object of this class to set up to remove a reference to an + xmlrpc_value object (a C object with manual reference management) + at then end of a scope -- even if the scope ends with a throw. +-----------------------------------------------------------------------------*/ + xmlrpc_value * valueP; +public: + cValueWrapper(xmlrpc_value * valueP) : valueP(valueP) {} + ~cValueWrapper() { xmlrpc_DECREF(valueP); } +}; + +} // namespace + + + +clientSimple::clientSimple() { + + clientXmlTransportPtr const transportP(clientXmlTransport_http::create()); + + this->clientP = clientPtr(new client_xml(transportP)); +} + + + +void +clientSimple::call(string const serverUrl, + string const methodName, + value * const resultP) { + + carriageParm_http0 carriageParm(serverUrl); + + rpcPtr rpcPtr(methodName, paramList()); + + rpcPtr->call(this->clientP.get(), &carriageParm); + + *resultP = rpcPtr->getResult(); +} + + +namespace { + +void +makeParamArray(string const format, + xmlrpc_value ** const paramArrayPP, + va_list args) { + + env_wrap env; + + /* The format is a sequence of parameter specifications, such as + "iiii" for 4 integer parameters. We add parentheses to make it + an array of those parameters: "(iiii)". + */ + string const arrayFormat("(" + string(format) + ")"); + const char * tail; + + xmlrpc_build_value_va(&env.env_c, arrayFormat.c_str(), + args, paramArrayPP, &tail); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); + + if (strlen(tail) != 0) { + /* xmlrpc_build_value_va() parses off a single value specification + from its format string, and 'tail' points to whatever is after + it. Our format string should have been a single array value, + meaning tail is end-of-string. If it's not, that means + something closed our array early. + */ + xmlrpc_DECREF(*paramArrayPP); + throw(error("format string is invalid. It apparently has a " + "stray right parenthesis")); + } +} + +} // namespace + + +void +clientSimple::call(string const serverUrl, + string const methodName, + string const format, + value * const resultP, + ...) { + + carriageParm_http0 carriageParm(serverUrl); + + env_wrap env; + xmlrpc_value * paramArrayP; + + va_list args; + va_start(args, resultP); + makeParamArray(format, ¶mArrayP, args); + va_end(args); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); + else { + cValueWrapper paramArrayWrapper(paramArrayP); // ensure destruction + unsigned int const paramCount( + xmlrpc_array_size(&env.env_c, paramArrayP)); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); + + paramList paramList; + for (unsigned int i = 0; i < paramCount; ++i) { + xmlrpc_value * paramP; + xmlrpc_array_read_item(&env.env_c, paramArrayP, i, ¶mP); + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); + else { + cValueWrapper paramWrapper(paramP); // ensure destruction + paramList.add(value(paramP)); + } + } + rpcPtr rpcPtr(methodName, paramList); + rpcPtr->call(this->clientP.get(), &carriageParm); + *resultP = rpcPtr->getResult(); + } +} + + + +void +clientSimple::call(string const serverUrl, + string const methodName, + paramList const& paramList, + value * const resultP) { + + carriageParm_http0 carriageParm(serverUrl); + + rpcPtr rpcPtr(methodName, paramList); + + rpcPtr->call(this->clientP.get(), &carriageParm); + + *resultP = rpcPtr->getResult(); +} + +} // namespace diff --git a/trunk/src/cpp/curl.cpp b/trunk/src/cpp/curl.cpp new file mode 100644 index 000000000..d69783d27 --- /dev/null +++ b/trunk/src/cpp/curl.cpp @@ -0,0 +1,412 @@ +/*============================================================================= + curl.cpp +=============================================================================== + This is the Curl XML transport of the C++ XML-RPC client library for + Xmlrpc-c. + + Note that unlike most of Xmlprc-c's C++ API, this is _not_ based on the + C client library. This code is independent of the C client library, and + is based directly on the client XML transport libraries (with a little + help from internal C utility libraries). +=============================================================================*/ + +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/girmem.hpp" +using girmem::autoObjectPtr; +using girmem::autoObject; +#include "xmlrpc-c/env_wrap.hpp" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/transport.h" +#include "xmlrpc-c/base_int.h" + +/* transport_config.h defines MUST_BUILD_CURL_CLIENT */ +#include "transport_config.h" + +#include "xmlrpc-c/client_transport.hpp" + + +using namespace std; +using namespace xmlrpc_c; + + + +namespace { + +class globalConstant { +public: + globalConstant(); + ~globalConstant(); +}; + + + +globalConstant::globalConstant() { + + // Not thread safe + + xmlrpc_transport_setup setupFn; + +#if MUST_BUILD_CURL_CLIENT + setupFn = xmlrpc_curl_transport_ops.setup_global_const; +#else + setupFn = NULL; +#endif + if (setupFn) { + env_wrap env; + + setupFn(&env.env_c); // Not thread safe + + if (env.env_c.fault_occurred) + throwf("Failed to do global initialization " + "of Curl transport code. %s", env.env_c.fault_string); + } +} + + + +globalConstant::~globalConstant() { + + // Not thread safe + + xmlrpc_transport_teardown teardownFn; + +#if MUST_BUILD_CURL_CLIENT + teardownFn = xmlrpc_curl_transport_ops.teardown_global_const; +#else + teardownFn = NULL; +#endif + if (teardownFn) + teardownFn(); // not thread safe +} + +globalConstant globalConst; + // This object is never accessed. Its whole purpose to to be born and + // to die, which it does automatically as part of C++ program + // program initialization and termination. + +} // namespace + + +namespace xmlrpc_c { + +carriageParm_curl0::carriageParm_curl0( + string const serverUrl + ) { + + this->instantiate(serverUrl); +} + + + +carriageParm_curl0Ptr::carriageParm_curl0Ptr() { + // Base class constructor will construct pointer that points to nothing +} + + + +carriageParm_curl0Ptr::carriageParm_curl0Ptr( + carriageParm_curl0 * const carriageParmP) { + this->point(carriageParmP); +} + + + +carriageParm_curl0 * +carriageParm_curl0Ptr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +struct clientXmlTransport_curl::constrOpt_impl { + + constrOpt_impl(); + + struct { + std::string network_interface; + bool dont_advertise; + std::string user_agent; + std::string referer; + bool no_ssl_verifypeer; + bool no_ssl_verifyhost; + std::string ssl_cert; + std::string sslcerttype; + std::string sslcertpasswd; + std::string sslkey; + std::string sslkeytype; + std::string sslkeypasswd; + std::string sslengine; + bool sslengine_default; + xmlrpc_sslversion sslversion; + std::string cainfo; + std::string capath; + std::string randomfile; + std::string egdsocket; + std::string ssl_cipher_list; + unsigned int timeout; + std::string proxy; + unsigned int proxy_auth; + unsigned int proxy_port; + std::string proxy_userpwd; + xmlrpc_httpproxytype proxy_type; + bool gssapi_delegation; + unsigned int connect_timeout; + } value; + struct { + bool network_interface; + bool dont_advertise; + bool user_agent; + bool referer; + bool no_ssl_verifypeer; + bool no_ssl_verifyhost; + bool ssl_cert; + bool sslcerttype; + bool sslcertpasswd; + bool sslkey; + bool sslkeytype; + bool sslkeypasswd; + bool sslengine; + bool sslengine_default; + bool sslversion; + bool cainfo; + bool capath; + bool randomfile; + bool egdsocket; + bool ssl_cipher_list; + bool timeout; + bool proxy; + bool proxy_auth; + bool proxy_port; + bool proxy_userpwd; + bool proxy_type; + bool gssapi_delegation; + bool connect_timeout; + } present; +}; + +clientXmlTransport_curl::constrOpt_impl::constrOpt_impl() { + + present.network_interface = false; + present.dont_advertise = false; + present.user_agent = false; + present.referer = false; + present.no_ssl_verifypeer = false; + present.no_ssl_verifyhost = false; + present.ssl_cert = false; + present.sslcerttype = false; + present.sslcertpasswd = false; + present.sslkey = false; + present.sslkeytype = false; + present.sslkeypasswd = false; + present.sslengine = false; + present.sslengine_default = false; + present.sslversion = false; + present.cainfo = false; + present.capath = false; + present.randomfile = false; + present.egdsocket = false; + present.ssl_cipher_list = false; + present.timeout = false; + present.proxy = false; + present.proxy_port = false; + present.proxy_auth = false; + present.proxy_userpwd = false; + present.proxy_type = false; + present.gssapi_delegation = false; + present.connect_timeout = false; +} + + + +#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ +clientXmlTransport_curl::constrOpt & \ +clientXmlTransport_curl::constrOpt::OPTION_NAME(TYPE const& arg) { \ + this->implP->value.OPTION_NAME = arg; \ + this->implP->present.OPTION_NAME = true; \ + return *this; \ +} + +DEFINE_OPTION_SETTER(network_interface, string); +DEFINE_OPTION_SETTER(dont_advertise, bool); +DEFINE_OPTION_SETTER(referer, string); +DEFINE_OPTION_SETTER(user_agent, string); +DEFINE_OPTION_SETTER(no_ssl_verifypeer, bool); +DEFINE_OPTION_SETTER(no_ssl_verifyhost, bool); +DEFINE_OPTION_SETTER(ssl_cert, string); +DEFINE_OPTION_SETTER(sslcerttype, string); +DEFINE_OPTION_SETTER(sslcertpasswd, string); +DEFINE_OPTION_SETTER(sslkey, string); +DEFINE_OPTION_SETTER(sslkeytype, string); +DEFINE_OPTION_SETTER(sslkeypasswd, string); +DEFINE_OPTION_SETTER(sslengine, string); +DEFINE_OPTION_SETTER(sslengine_default, bool); +DEFINE_OPTION_SETTER(sslversion, xmlrpc_sslversion); +DEFINE_OPTION_SETTER(cainfo, string); +DEFINE_OPTION_SETTER(capath, string); +DEFINE_OPTION_SETTER(randomfile, string); +DEFINE_OPTION_SETTER(egdsocket, string); +DEFINE_OPTION_SETTER(ssl_cipher_list, string); +DEFINE_OPTION_SETTER(timeout, unsigned int); +DEFINE_OPTION_SETTER(proxy, string); +DEFINE_OPTION_SETTER(proxy_port, unsigned int); +DEFINE_OPTION_SETTER(proxy_auth, unsigned int); +DEFINE_OPTION_SETTER(proxy_userpwd, string); +DEFINE_OPTION_SETTER(proxy_type, xmlrpc_httpproxytype); +DEFINE_OPTION_SETTER(gssapi_delegation, bool); +DEFINE_OPTION_SETTER(connect_timeout, unsigned int); + +#undef DEFINE_OPTION_SETTER + +clientXmlTransport_curl::constrOpt::constrOpt() { + + this->implP = new clientXmlTransport_curl::constrOpt_impl(); +} + + + +clientXmlTransport_curl::constrOpt::~constrOpt() { + + delete(this->implP); +} + + + +clientXmlTransport_curl::constrOpt::constrOpt(constrOpt& arg) { + + this->implP = new constrOpt_impl(*arg.implP); +} + + + +#if MUST_BUILD_CURL_CLIENT + +void +clientXmlTransport_curl::initialize(constrOpt const& optExt) { + constrOpt_impl const opt(*optExt.implP); + + struct xmlrpc_curl_xportparms transportParms; + + transportParms.network_interface = opt.present.network_interface ? + opt.value.network_interface.c_str() : NULL; + transportParms.referer = opt.present.referer ? + opt.value.referer.c_str() : NULL; + transportParms.dont_advertise = opt.present.dont_advertise ? + opt.value.dont_advertise : false; + transportParms.user_agent = opt.present.user_agent ? + opt.value.user_agent.c_str() : NULL; + transportParms.no_ssl_verifypeer = opt.present.no_ssl_verifypeer ? + opt.value.no_ssl_verifypeer : false; + transportParms.no_ssl_verifyhost = opt.present.no_ssl_verifyhost ? + opt.value.no_ssl_verifyhost : false; + transportParms.ssl_cert = opt.present.ssl_cert ? + opt.value.ssl_cert.c_str() : NULL; + transportParms.sslcerttype = opt.present.sslcerttype ? + opt.value.sslcerttype.c_str() : NULL; + transportParms.sslcertpasswd = opt.present.sslcertpasswd ? + opt.value.sslcertpasswd.c_str() : NULL; + transportParms.sslkey = opt.present.sslkey ? + opt.value.sslkey.c_str() : NULL; + transportParms.sslkeytype = opt.present.sslkeytype ? + opt.value.sslkeytype.c_str() : NULL; + transportParms.sslkeypasswd = opt.present.sslkeypasswd ? + opt.value.sslkeypasswd.c_str() : NULL; + transportParms.sslengine = opt.present.sslengine ? + opt.value.sslengine.c_str() : NULL; + transportParms.sslengine_default = opt.present.sslengine_default ? + opt.value.sslengine_default : false; + transportParms.sslversion = opt.present.sslversion ? + opt.value.sslversion : XMLRPC_SSLVERSION_DEFAULT; + transportParms.cainfo = opt.present.cainfo ? + opt.value.cainfo.c_str() : NULL; + transportParms.capath = opt.present.capath ? + opt.value.capath.c_str() : NULL; + transportParms.randomfile = opt.present.randomfile ? + opt.value.randomfile.c_str() : NULL; + transportParms.egdsocket = opt.present.egdsocket ? + opt.value.egdsocket.c_str() : NULL; + transportParms.ssl_cipher_list = opt.present.ssl_cipher_list ? + opt.value.ssl_cipher_list.c_str() : NULL; + transportParms.timeout = opt.present.timeout ? + opt.value.timeout : 0; + transportParms.proxy = opt.present.proxy ? + opt.value.proxy.c_str() : NULL; + transportParms.proxy_port = opt.present.proxy_port ? + opt.value.proxy_port : 0; + transportParms.proxy_auth = opt.present.proxy_auth ? + opt.value.proxy_auth : XMLRPC_HTTPAUTH_NONE; + transportParms.proxy_userpwd = opt.present.proxy_userpwd ? + opt.value.proxy_userpwd.c_str() : NULL; + transportParms.proxy_type = opt.present.proxy_type ? + opt.value.proxy_type : XMLRPC_HTTPPROXY_HTTP; + transportParms.gssapi_delegation = opt.present.gssapi_delegation ? + opt.value.gssapi_delegation : false; + transportParms.connect_timeout = opt.present.connect_timeout ? + opt.value.connect_timeout : 0; + + this->c_transportOpsP = &xmlrpc_curl_transport_ops; + + env_wrap env; + + xmlrpc_curl_transport_ops.create( + &env.env_c, 0, "", "", + &transportParms, XMLRPC_CXPSIZE(gssapi_delegation), + &this->c_transportP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + +#else // MUST_BUILD_CURL_CLIENT + +void +clientXmlTransport_curl::initialize(constrOpt const& opt) { + + throw(error("There is no Curl client XML transport in this XML-RPC client " + "library")); +} + +#endif + +clientXmlTransport_curl::clientXmlTransport_curl(constrOpt const& opt) { + + this->initialize(opt); +} + + + +clientXmlTransport_curl::clientXmlTransport_curl( + string const networkInterface, + bool const noSslVerifyPeer, + bool const noSslVerifyHost, + string const userAgent) { + + clientXmlTransport_curl::constrOpt opt; + + if (networkInterface.size() > 0) + opt.network_interface(networkInterface); + opt.no_ssl_verifypeer(noSslVerifyPeer); + opt.no_ssl_verifyhost(noSslVerifyHost); + if (userAgent.size() > 0) + opt.user_agent(userAgent); + + this->initialize(opt); +} + + + +clientXmlTransport_curl::~clientXmlTransport_curl() { + + this->c_transportOpsP->destroy(this->c_transportP); +} + + +} // namespace diff --git a/trunk/src/cpp/fault.cpp b/trunk/src/cpp/fault.cpp new file mode 100644 index 000000000..4db6bc865 --- /dev/null +++ b/trunk/src/cpp/fault.cpp @@ -0,0 +1,35 @@ +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "xmlrpc-c/base.hpp" + +using namespace std; + +namespace xmlrpc_c { + +fault::fault() : valid(false) {}; + +fault::fault(string const _description, + xmlrpc_c::fault::code_t const _code + ) : + valid(true), + code(_code), + description(_description) + {} + +xmlrpc_c::fault::code_t +fault::getCode() const { + if (!valid) + throw(error("Attempt to access placeholder xmlrpc_c::fault object")); + return this->code; +} + +string +fault::getDescription() const { + if (!valid) + throw(error("Attempt to access placeholder xmlrpc_c::fault object")); + return this->description; +} + +} // namespace diff --git a/trunk/src/cpp/global.cpp b/trunk/src/cpp/global.cpp new file mode 100644 index 000000000..563681949 --- /dev/null +++ b/trunk/src/cpp/global.cpp @@ -0,0 +1,30 @@ +#include + +using namespace std; + +#include +using girerr::throwf; +#include + + +class LibxmlrpcGlobalState { + +public: + LibxmlrpcGlobalState() { + xmlrpc_env env; + xmlrpc_env_init(&env); + xmlrpc_init(&env); + if (env.fault_occurred) { + string const fault(env.fault_string); + xmlrpc_env_clean(&env); + throwf("Failed to initailize libxmlrpc. %s", fault.c_str()); + } + } + + ~LibxmlrpcGlobalState() { + xmlrpc_term(); + } +}; + +static LibxmlrpcGlobalState libxmlrpcGlobalState; + diff --git a/trunk/src/cpp/libwww.cpp b/trunk/src/cpp/libwww.cpp new file mode 100644 index 000000000..f7cf01122 --- /dev/null +++ b/trunk/src/cpp/libwww.cpp @@ -0,0 +1,159 @@ +/*============================================================================= + libwww.cpp +=============================================================================== + This is the Libwww XML transport of the C++ XML-RPC client library for + Xmlrpc-c. +=============================================================================*/ + +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/girmem.hpp" +using girmem::autoObjectPtr; +using girmem::autoObject; +#include "xmlrpc-c/env_wrap.hpp" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/transport.h" +#include "xmlrpc-c/base_int.h" + +/* transport_config.h defines MUST_BUILD_LIBWWW_CLIENT */ +#include "transport_config.h" + +#include "xmlrpc-c/client_transport.hpp" + + +using namespace std; +using namespace xmlrpc_c; + + +namespace { + +class globalConstant { +public: + globalConstant(); + ~globalConstant(); +}; + + + +globalConstant::globalConstant() { + + // Not thread safe + + xmlrpc_transport_setup setupFn; + +#if MUST_BUILD_LIBWWW_CLIENT + setupFn = xmlrpc_libwww_transport_ops.setup_global_const; +#else + setupFn = NULL; +#endif + if (setupFn) { + env_wrap env; + + setupFn(&env.env_c); // Not thread safe + + if (env.env_c.fault_occurred) + throwf("Failed to do global initialization " + "of Libwww transport code. %s", env.env_c.fault_string); + } +} + + + +globalConstant::~globalConstant() { + + // Not thread safe + + xmlrpc_transport_teardown teardownFn; + +#if MUST_BUILD_LIBWWW_CLIENT + teardownFn = xmlrpc_libwww_transport_ops.teardown_global_const; +#else + teardownFn = NULL; +#endif + if (teardownFn) + teardownFn(); // not thread safe +} + + +globalConstant globalConst; + // This object is never accessed. Its whole purpose to to be born and + // to die, which it does automatically as part of C++ program + // program initialization and termination. + +} // namespace + + +namespace xmlrpc_c { + +carriageParm_libwww0::carriageParm_libwww0( + string const serverUrl + ) { + + this->instantiate(serverUrl); +} + + + +carriageParm_libwww0Ptr::carriageParm_libwww0Ptr() { + // Base class constructor will construct pointer that points to nothing +} + + + +carriageParm_libwww0Ptr::carriageParm_libwww0Ptr( + carriageParm_libwww0 * const carriageParmP) { + this->point(carriageParmP); +} + + + +carriageParm_libwww0 * +carriageParm_libwww0Ptr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +#if MUST_BUILD_LIBWWW_CLIENT + +clientXmlTransport_libwww::clientXmlTransport_libwww( + string const appname, + string const appversion) { + + this->c_transportOpsP = &xmlrpc_libwww_transport_ops; + + env_wrap env; + + xmlrpc_libwww_transport_ops.create( + &env.env_c, 0, appname.c_str(), appversion.c_str(), NULL, 0, + &this->c_transportP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + +#else // MUST_BUILD_LIBWWW_CLIENT + clientXmlTransport_libwww::clientXmlTransport_libwww(string const, + string const) { + + throw(error("There is no Libwww client XML transport " + "in this XML-RPC client library")); +} + +#endif + + +clientXmlTransport_libwww::~clientXmlTransport_libwww() { + + this->c_transportOpsP->destroy(this->c_transportP); +} + +} // namespace diff --git a/trunk/src/cpp/outcome.cpp b/trunk/src/cpp/outcome.cpp new file mode 100644 index 000000000..e004ef880 --- /dev/null +++ b/trunk/src/cpp/outcome.cpp @@ -0,0 +1,57 @@ +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "xmlrpc-c/base.hpp" + +using namespace std; + +namespace xmlrpc_c { + +rpcOutcome::rpcOutcome() : valid(false) {} + +rpcOutcome::rpcOutcome(xmlrpc_c::value const result) : + valid(true), _succeeded(true), result(result) + {} + + + +rpcOutcome::rpcOutcome(xmlrpc_c::fault const fault) : + valid(true), _succeeded(false), fault(fault) + {} + + + +bool +rpcOutcome::succeeded() const { + if (!valid) + throw(error("Attempt to access rpcOutcome object before setting it")); + return _succeeded; +} + + + +fault +rpcOutcome::getFault() const { + + if (!valid) + throw(error("Attempt to access rpcOutcome object before setting it")); + if (_succeeded) + throw(error("Attempt to get fault description from a non-failure " + "RPC outcome")); + return fault; +} + + + +value +rpcOutcome::getResult() const { + + if (!valid) + throw(error("Attempt to access rpcOutcome object before setting it")); + if (!_succeeded) + throw(error("Attempt to get result from an unsuccessful RPC outcome")); + return result; +} + + +} // namespace + diff --git a/trunk/src/cpp/packetsocket.cpp b/trunk/src/cpp/packetsocket.cpp new file mode 100644 index 000000000..3719357a2 --- /dev/null +++ b/trunk/src/cpp/packetsocket.cpp @@ -0,0 +1,1106 @@ +/*============================================================================ + packetsocket +============================================================================== + + This is a facility for communicating socket-style, with defined + packets like a datagram socket but with reliable delivery like a + stream socket. It's like a POSIX "sequential packet" socket, except + it is built on top of a stream socket, so it is usable on the many + systems that have stream sockets but not sequential packet sockets. + + By Bryan Henderson 2007.05.12 + + Contributed to the public domain by its author. +============================================================================*/ + + +/*============================================================================ + The protocol for carrying packets on a character stream: + + The protocol consists of the actual bytes to be transported with a bare + minimum of framing information added: + + An ASCII Escape ( == 0x1B) character marks the start of a + 4-ASCII-character control word. These are defined: + + PKT : marks the beginning of a packet. + END : marks the end of a packet. + ESC : represents an character in the packet + NOP : no meaning + + Any other bytes after is a protocol error. + + A stream is all the data transmitted during a single socket + connection. + + End of stream in the middle of a packet is a protocol error. + + All bytes not part of a control word are literal bytes of a packet. + + You can create a packet socket from a POSIX stream socket or a + Windows emulation of one. + + One use of the NOP control word is to validate that the connection + is still working. You might send one periodically to detect, for + example, an unplugged TCP/IP network cable. It's probably better + to use the TCP keepalive facility for that. +============================================================================*/ +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include // mingw32 doesn't have in 12.06. +#include + +#include +#include +#if MSVCRT +# include +# include +#else +# include +# include +# include +#endif + +#include + +#include "c_util.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/girerr.hpp" +using girerr::throwf; + +#include "xmlrpc-c/packetsocket.hpp" + +using namespace std; + +#define ESC 0x1B // ASCII Escape character +#define ESC_STR "\x1B" + +class BrokenConnectionEx { +}; + +class XMLRPC_DLLEXPORT socketx { + +public: + socketx(int const sockFd); + + ~socketx(); + + void + waitForReadable() const; + + void + waitForWritable() const; + + void + read(unsigned char * const buffer, + size_t const bufferSize, + bool * const wouldblockP, + size_t * const bytesReadP) const; + + void + writeWait(const unsigned char * const data, + size_t const size) const; +private: + int fd; + bool fdIsBorrowed; +}; + + + +/* Sockets are similar, but not identical between Unix and Windows. + Some Unix socket functions appear to be available on Windows (a + Unix compatibility feature), but work only for file descriptor + numbers < 32, so we don't use those. +*/ + +socketx::socketx(int const sockFd) { +#if MSVCRT + // We don't have any way to duplicate; we'll just have to borrow. + this->fdIsBorrowed = true; + this->fd = sockFd; + u_long iMode(1); // Nonblocking mode yes + ioctlsocket(this->fd, FIONBIO, &iMode); // Make socket nonblocking +#else + this->fdIsBorrowed = false; + + int dupRc; + + dupRc = dup(sockFd); + + if (dupRc < 0) + throwf("dup() failed. errno=%d (%s)", errno, strerror(errno)); + else { + this->fd = dupRc; + fcntl(this->fd, F_SETFL, O_NONBLOCK); // Make socket nonblocking + } +#endif +} + + + +socketx::~socketx() { + + if (!this->fdIsBorrowed) { +#if MSVCRT + ::closesocket(SOCKET(this->fd)); +#else + close(this->fd); +#endif + } +} + + + +void +socketx::waitForReadable() const { + /* Return when there is something to read from the socket + (an EOF indication counts as something to read). Also + return if there is a signal (handled, of course). Rarely, + it is OK to return when there isn't anything to read. + */ +#if MSVCRT + // poll() is not available; settle for select(). + // Starting in Windows Vista, there is WSApoll() + fd_set rd_set; + FD_ZERO(&rd_set); + FD_SET(this->fd, &rd_set); + + select(this->fd + 1, &rd_set, 0, 0, 0); +#else + // poll() beats select() because higher file descriptor numbers + // work. + struct pollfd pollfds[1]; + + pollfds[0].fd = this->fd; + pollfds[0].events = POLLIN; + + poll(pollfds, ARRAY_SIZE(pollfds), -1); +#endif +} + + + +void +socketx::waitForWritable() const { + /* Return when socket is able to be written to. */ +#if MSVCRT + fd_set wr_set; + FD_ZERO(&wr_set); + FD_SET(this->fd, &wr_set); + + select(this->fd + 1, 0, &wr_set, 0, 0); +#else + struct pollfd pollfds[1]; + + pollfds[0].fd = this->fd; + pollfds[0].events = POLLOUT; + + poll(pollfds, ARRAY_SIZE(pollfds), -1); +#endif +} + + + +static bool +wouldBlock() { +/*---------------------------------------------------------------------------- + The most recently executed system socket function, which we assume failed, + failed because the situation was such that it wanted to block, but the + socket had the nonblocking option. +-----------------------------------------------------------------------------*/ +#if MSVCRT + return (WSAGetLastError() == WSAEWOULDBLOCK || + WSAGetLastError() == WSAEINPROGRESS); +#else + /* EWOULDBLOCK and EAGAIN are normally synonyms, but POSIX allows them + to be separate and allows the OS to return whichever one it wants + for the "would block" condition. + */ + return (errno == EWOULDBLOCK || errno == EAGAIN); +#endif +} + + + +static bool +lastErrorIsBrokenConn() { +/*---------------------------------------------------------------------------- + The last system call failure in this process, assuming the system call was + to read or write a steram socket, indicates the problem was that the + connection broke, e.g. because a network cable was cut, the peer powered + off, or the peer just got tired of talking to us and closed down the + connection. + + The underlying signficance of this distinction is that when a connection + has broken, the caller might reasonably respond by trying to establish a + new connection, and possibly doing so with a different network path or a + different peer. +-----------------------------------------------------------------------------*/ + bool retval; + +#if MSVCRT + // We don't know how to determine this on Windows, so we just punt + retval = false; +#else + switch (errno) { + // Some of these are probably not defined on some systems; we will + // need some build system magic to deal with that as error reports + // come in. + case EPIPE: + case ETIMEDOUT: + case ECONNRESET: + case ENOTCONN: + case ESHUTDOWN: + retval = true; + break; + default: + retval = false; + } + +#endif + + return retval; +} + + + +static string const +lastErrorDesc() { +/*---------------------------------------------------------------------------- + A description suitable for an error message of why the most recent + failed system socket function failed. +-----------------------------------------------------------------------------*/ + ostringstream msg; +#if MSVCRT + int const lastError = WSAGetLastError(); + msg << "winsock error code " << lastError << " " + << "(" << strerror(lastError) << ")"; +#else + msg << "errno = " << errno << ", (" << strerror(errno) << ")"; +#endif + return msg.str(); +} + + + + +void +socketx::read(unsigned char * const buffer, + size_t const bufferSize, + bool * const wouldblockP, + size_t * const bytesReadP) const { +/*---------------------------------------------------------------------------- + Put any bytes that are in the OS buffer waiting to be read in 'buffer', + up to 'bufferSize'. + + Return *wouldblockP == true iff the buffer is empty now, but more could + arrive later. + + Return as *bytesReadP the number of bytes put into 'buffer'. + + Throw a BrokenConnectionEx exception if the connection has been broken. +-----------------------------------------------------------------------------*/ + int rc; + + // We've seen a Windows library whose recv() expects a char * buffer + // (cf POSIX void *), so we cast. + + rc = recv(this->fd, (char *)buffer, bufferSize, 0); + + if (rc < 0) { + if (wouldBlock()) { + *wouldblockP = true; + *bytesReadP = 0; + } else if (lastErrorIsBrokenConn()) + throw BrokenConnectionEx(); + else + throwf("read() of socket failed with %s", lastErrorDesc().c_str()); + } else { + *wouldblockP = false; + *bytesReadP = rc; + } +} + + + +static void +writeFd(int const fd, + const unsigned char * const data, + size_t const size, + size_t * const bytesWrittenP) { +/*---------------------------------------------------------------------------- + Write as much of the 'size' bytes at 'data' to socket 'fd' as can be + written immediately (i.e. into the OS buffer). + + Return as *bytesWrittenP the number of bytes written. + + Throw a BrokenConnectionEx exception if the connection has been broken. +-----------------------------------------------------------------------------*/ + size_t totalBytesWritten; + bool full; // File image is "full" for now - won't take any more data + + full = false; + totalBytesWritten = 0; + + while (totalBytesWritten < size && !full) { + int rc; + + rc = send(fd, (char*)&data[totalBytesWritten], + size - totalBytesWritten, 0); + + if (rc < 0) { + if (wouldBlock()) + full = true; + else { + if (lastErrorIsBrokenConn()) + throw BrokenConnectionEx(); + else + throwf("write() of socket failed with %s", + lastErrorDesc().c_str()); + } + } else if (rc == 0) + throwf("Zero byte short write."); + else { + size_t const bytesWritten(rc); + totalBytesWritten += bytesWritten; + } + } + *bytesWrittenP = totalBytesWritten; +} + + + +void +socketx::writeWait(const unsigned char * const data, + size_t const size) const { +/*---------------------------------------------------------------------------- + Write the 'size' bytes at 'data' to the socket. Wait as long + as it takes for the file image to be able to take all the data. + + Throw a BrokenConnectionEx exception if the connection has been broken. +-----------------------------------------------------------------------------*/ + size_t totalBytesWritten; + + // We do the first one blind because it will probably just work + // and we don't want to waste the poll() call and buffer arithmetic. + + writeFd(this->fd, data, size, &totalBytesWritten); + + while (totalBytesWritten < size) { + this->waitForWritable(); + + size_t bytesWritten; + + writeFd(this->fd, &data[totalBytesWritten], size - totalBytesWritten, + &bytesWritten); + + totalBytesWritten += bytesWritten; + } +} + + + +namespace xmlrpc_c { + + +packet::packet() : + bytes(NULL), length(0), allocSize(0) {} + + + +void +packet::initialize(const unsigned char * const data, + size_t const dataLength) { + + this->bytes = reinterpret_cast(malloc(dataLength)); + + if (this->bytes == NULL) + throwf("Can't get storage for a %u-byte packet", (unsigned)dataLength); + + this->allocSize = dataLength; + + memcpy(this->bytes, data, dataLength); + + this->length = dataLength; +} + + + +packet::packet(const unsigned char * const data, + size_t const dataLength) { + + this->initialize(data, dataLength); +} + + + +packet::packet(const char * const data, + size_t const dataLength) { + + this->initialize(reinterpret_cast(data), + dataLength); +} + + + +packet::~packet() { + + if (this->bytes) + free(bytes); +} + + + +void +packet::addData(const unsigned char * const data, + size_t const dataLength) { +/*---------------------------------------------------------------------------- + Add the 'length' bytes at 'data' to the packet. + + We allocate whatever additional memory is needed to fit the new + data in. +-----------------------------------------------------------------------------*/ + size_t const neededSize(this->length + dataLength); + + if (this->allocSize < neededSize) + this->bytes = reinterpret_cast( + realloc(this->bytes, neededSize)); + + if (this->bytes == NULL) + throwf("Can't get storage for a %u-byte packet", (unsigned)neededSize); + + memcpy(this->bytes + this->length, data, dataLength); + + this->length += dataLength; +} + + + +packetPtr::packetPtr() { + // Base class constructor will construct pointer that points to nothing +} + + + +packetPtr::packetPtr(packet * const packetP) : autoObjectPtr(packetP) {} + + + +packet * +packetPtr::operator->() const { + + girmem::autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +class packetSocket_impl { + +public: + packetSocket_impl(int const sockFd); + + void + writeWait(packetPtr const& packetP) const; + + void + read(bool * const eofP, + bool * const gotPacketP, + packetPtr * const packetPP); + + void + readWait(volatile const int * const interruptP, + bool * const eofP, + bool * const gotPacketP, + packetPtr * const packetPP); + +private: + socketx sock; + // The kernel stream socket we use. + bool const mustTrace; + // We must trace our execution to Standard Error + bool eof; + // The packet socket is at end-of-file for reads. + // 'readBuffer' is empty and there won't be any more data to fill + // it because the underlying stream socket is closed. + std::queue readBuffer; + packetPtr packetAccumP; + // The receive packet we're currently accumulating; it will join + // 'readBuffer' when we've received the whole packet (and we've + // seen the END control word so we know we've received it all). + // If we're not currently accumulating a packet (haven't seen a + // PKT control word), this points to nothing. + bool inEscapeSeq; + // In our trek through the data read from the underlying stream + // socket, we are after an ESC character and before the end of the + // escape sequence. 'escAccum' shows what of the escape sequence + // we've seen so far. + bool inPacket; + // We're now receiving packet data from the underlying stream + // socket. We've seen a complete PKT control word, but have not + // seen a complete END control word since. + struct { + unsigned char bytes[3]; + size_t len; + } escAccum; + + void + takeSomeEscapeSeq(const unsigned char * const buffer, + size_t const length, + size_t * const bytesTakenP); + + void + takeSomePacket(const unsigned char * const buffer, + size_t const length, + size_t * const bytesTakenP); + + void + verifyNothingAccumulated(); + + void + processBytesRead(const unsigned char * const buffer, + size_t const bytesRead); + + void + readFromFile(); +}; + + + +packetSocket_impl::packetSocket_impl(int const sockFd) : + sock(sockFd), + mustTrace(getenv("XMLRPC_TRACE_PACKETSOCKET") != NULL) { + + this->inEscapeSeq = false; + this->inPacket = false; + this->escAccum.len = 0; + this->eof = false; + + if (this->mustTrace) + fprintf(stderr, "Tracing Xmlrpc-c packet socket\n"); +} + + + +/*---------------------------------------------------------------------------- + To complete the job, we should provide writing services analogous + to the reading services. That means a no-wait write method and + the ability to interrupt with a signal without corrupting the write + stream. + + We're a little to lazy to do that now, since we don't need it yet, + but here's a design for that: + + The packetSocket has a send queue of packets called the write + buffer. It stores packetPtr pointers to packets created by the + user. + + packetSocket::write() adds a packet to the write buffer, then calls + packetSocket::writeToFile(). If you give it a null packetPtr, + it just calls writeToFile(). + + packetSocket::writeToFile() writes from the write buffer to the + socket whatever the socket will take immediately. It writes the + start sequence, writes the packet data, then writes the end + sequence. The packetSocket keeps track of where it is in the + process of writing the current send packet (including start end + end sequences) it is. + + packetSocket::write() returns a "flushed" flag indicating that there + is nothing left in the write buffer. + + packetSocket::writeWait() just calls packetSocket::write(), then + packetSocket::flush() in a poll() loop. +-----------------------------------------------------------------------------*/ + + +static void +traceWrite(const unsigned char * const data, + size_t const size) { + + fprintf(stderr, "Sending %u-byte packet\n", (unsigned) size); + + if (size > 0) { + fprintf(stderr, "Data: "); + for (unsigned int i = 0; i < size; ++i) + fprintf(stderr, "%02x", data[i]); + + fprintf(stderr, "\n"); + } +} + + + +static const unsigned char * +escapePos(const unsigned char * const start, + const unsigned char * const end) { +/*---------------------------------------------------------------------------- + Return a pointer to the next escape character at or after 'start', but + before 'end'. If there is none, return 'end'. +-----------------------------------------------------------------------------*/ + const unsigned char * cursor; + + for (cursor = start; cursor < end; ++cursor) { + if (*cursor == ESC) + break; + } + return cursor; +} + + + +void +packetSocket_impl::writeWait(packetPtr const& packetP) const { +/*---------------------------------------------------------------------------- + Write the packet to the socket, waiting for the recipient to take it as + necessary. + + Throw a BrokenConnectionEx exception if we can't send because of a broken + connection. +-----------------------------------------------------------------------------*/ + const unsigned char * const packetStart( + reinterpret_cast(ESC_STR "PKT")); + const unsigned char * const packetEnd( + reinterpret_cast(ESC_STR "END")); + const unsigned char * const escapeChar( + reinterpret_cast(ESC_STR "ESC")); + + if (this->mustTrace) + traceWrite(packetP->getBytes(), packetP->getLength()); + + + this->sock.writeWait(packetStart, 4); + + const unsigned char * const end( + packetP->getBytes() + packetP->getLength()); + + const unsigned char * cursor; + + for (cursor = packetP->getBytes(); cursor < end; ) { + // Send up to the next escape character in the packet (or end of + // packet). + + const unsigned char * const nextEscapePos(escapePos(cursor, end)); + + this->sock.writeWait(cursor, nextEscapePos - cursor); + + cursor = nextEscapePos; + + if (cursor == end) { + // We didn't find an escape character; we sent everything + } else { + // We stopped at an escape character. Send an ESC control word. + // for that. + this->sock.writeWait(escapeChar, 4); + + cursor += 1; + } + } + this->sock.writeWait(packetEnd, 4); +} + + + +static void +traceReceivedPacket(const unsigned char * const data, + size_t const size) { + + fprintf(stderr, "%u-byte packet received\n", (unsigned) size); + + if (size > 0) { + fprintf(stderr, "Data: "); + for (unsigned int i = 0; i < size; ++i) + fprintf(stderr, "%02x", data[i]); + + fprintf(stderr, "\n"); + } +} + + + +void // private +packetSocket_impl::takeSomeEscapeSeq(const unsigned char * const buffer, + size_t const length, + size_t * const bytesTakenP) { +/*---------------------------------------------------------------------------- + Take and process some bytes from the incoming stream 'buffer', + which contains 'length' bytes, assuming they are within an escape + sequence. +-----------------------------------------------------------------------------*/ + size_t bytesTaken; + + bytesTaken = 0; + + while (this->escAccum.len < 3 && bytesTaken < length) + this->escAccum.bytes[this->escAccum.len++] = buffer[bytesTaken++]; + + assert(this->escAccum.len <= 3); + + if (this->escAccum.len == 3) { + if (0) { + } else if (xmlrpc_memeq(this->escAccum.bytes, "NOP", 3)) { + // Nothing to do + } else if (xmlrpc_memeq(this->escAccum.bytes, "PKT", 3)) { + this->packetAccumP = packetPtr(new packet); + this->inPacket = true; + } else if (xmlrpc_memeq(this->escAccum.bytes, "END", 3)) { + if (this->inPacket) { + if (this->mustTrace) + traceReceivedPacket(this->packetAccumP->getBytes(), + this->packetAccumP->getLength()); + this->readBuffer.push(this->packetAccumP); + this->inPacket = false; + this->packetAccumP = packetPtr(); + } else + throwf("END control word received without preceding PKT"); + } else if (xmlrpc_memeq(this->escAccum.bytes, "ESC", 3)) { + if (this->inPacket) + this->packetAccumP->addData((const unsigned char *)ESC_STR, 1); + else + throwf("ESC control word received outside of a packet"); + } else + throwf("Invalid escape sequence 0x%02x%02x%02x read from " + "stream socket under packet socket", + this->escAccum.bytes[0], + this->escAccum.bytes[1], + this->escAccum.bytes[2]); + + this->inEscapeSeq = false; + this->escAccum.len = 0; + } + *bytesTakenP = bytesTaken; +} + + + +void // private +packetSocket_impl::takeSomePacket(const unsigned char * const buffer, + size_t const length, + size_t * const bytesTakenP) { +/*---------------------------------------------------------------------------- + Add to the object's packet accumulator the data in 'buffer' (of which there + is 'length' bytes) up to the next escape sequence, or the whole buffer if + there isn't an escape sequence. + + Return as *bytesTakenP the number of bytes we added to the accumulator. +-----------------------------------------------------------------------------*/ + assert(!this->inEscapeSeq); + + const unsigned char * const escPos( + (const unsigned char *)memchr(buffer, ESC, length)); + + if (escPos) { + size_t const escOffset(escPos - &buffer[0]); + // move everything before the escape sequence into the + // packet accumulator. + this->packetAccumP->addData(buffer, escOffset); + + // Caller can pick up from here; we don't know nothin' 'bout + // no escape sequences. + + *bytesTakenP = escOffset; + } else { + // No complete packet yet and no substitution to do; + // just throw the whole thing into the accumulator. + this->packetAccumP->addData(buffer, length); + *bytesTakenP = length; + } +} + + + +void // private +packetSocket_impl::verifyNothingAccumulated() { +/*---------------------------------------------------------------------------- + Throw an error if there is a partial packet accumulated. +-----------------------------------------------------------------------------*/ + if (this->inEscapeSeq) + throwf("Streams socket closed in the middle of an " + "escape sequence"); + + if (this->inPacket) + throwf("Stream socket closed in the middle of a packet " + "(%u bytes of packet received; no END marker to mark " + "end of packet)", (unsigned)this->packetAccumP->getLength()); +} + + + +void // private +packetSocket_impl::processBytesRead(const unsigned char * const buffer, + size_t const bytesRead) { + + unsigned int cursor; // Cursor into buffer[] + cursor = 0; + while (cursor < bytesRead) { + size_t bytesTaken; + + if (this->inEscapeSeq) + this->takeSomeEscapeSeq(&buffer[cursor], + bytesRead - cursor, + &bytesTaken); + else if (buffer[cursor] == ESC) { + this->inEscapeSeq = true; + bytesTaken = 1; + } else if (this->inPacket) + this->takeSomePacket(&buffer[cursor], + bytesRead - cursor, + &bytesTaken); + else + throwf("Byte 0x%02x is not in a packet or escape sequence. " + "Sender is probably not using packet socket protocol", + buffer[cursor]); + + cursor += bytesTaken; + } +} + + + +static void +traceBytesRead(const unsigned char * const buffer, + size_t const bytesReadCt) { + + fprintf(stderr, "%u bytes read\n", (unsigned) bytesReadCt); + + fprintf(stderr, "Data: "); + + for (unsigned int i = 0; i < bytesReadCt; ++i) + fprintf(stderr, "%02x", buffer[i]); + + fprintf(stderr, "\n"); +} + + + +void //private +packetSocket_impl::readFromFile() { +/*---------------------------------------------------------------------------- + Read some data from the underlying stream socket. Read as much as is + available right now, up to 4K. Update *this to reflect the data read. + + E.g. if we read an entire packet, we add it to the packet buffer + (this->readBuffer). If we read the first part of a packet, we add + it to the packet accumulator (*this->packetAccumP). If we read the end + of a packet, we add the full packet to the packet buffer and empty + the packet accumulator. Etc. + + Throw a BrokenConnectionEx exception if we can't read because of a broken + connection. +-----------------------------------------------------------------------------*/ + bool wouldblock; + + wouldblock = false; + + while (this->readBuffer.empty() && !this->eof && !wouldblock) { + unsigned char buffer[4096]; + size_t bytesRead; + + this->sock.read(buffer, sizeof(buffer), &wouldblock, &bytesRead); + + if (!wouldblock) { + if (bytesRead == 0) { + if (this->mustTrace) + fprintf(stderr, "EOF on read\n"); + this->eof = true; + this->verifyNothingAccumulated(); + } else { + if (this->mustTrace) + traceBytesRead(buffer, bytesRead); + this->processBytesRead(buffer, bytesRead); + } + } + } +} + + + +void +packetSocket_impl::read(bool * const eofP, + bool * const gotPacketP, + packetPtr * const packetPP) { +/*---------------------------------------------------------------------------- + Read one packet from the socket, through the internal packet buffer. + + If there is a packet immediately available, return it as *packetPP and + return *gotPacketP true. Otherwise, return *gotPacketP false. + + Iff the socket has no more data coming (it is shut down) and there + is no complete packet in the packet buffer, return *eofP true. + + This leaves one other possibility: there is no full packet immediately + available, but there may be in the future because the socket is still + alive. In that case, we return *eofP == false and *gotPacketP == false. + + Any packet we return belongs to caller; Caller must delete it. + + Throw a BrokenConnectionEx exception if we can't read because of a broken + connection. +-----------------------------------------------------------------------------*/ + // Move any packets now waiting to be read in the underlying stream + // socket into our packet buffer (this->readBuffer). + + this->readFromFile(); + + if (this->readBuffer.empty()) { + *gotPacketP = false; + *eofP = this->eof; + } else { + *gotPacketP = true; + *eofP = false; + *packetPP = this->readBuffer.front(); + readBuffer.pop(); + } +} + + + +void +packetSocket_impl::readWait(volatile const int * const interruptP, + bool * const eofP, + bool * const gotPacketP, + packetPtr * const packetPP) { +/*---------------------------------------------------------------------------- + Read a packet from the packet socket. It may be already in the buffer. + If not, wait as long as it takes for one to arrive. + + But stop waiting and return without a packet when *interruptP is true (but + if we're in a system call, which we usually are, Caller will have to ensure + that call gets interrupted, e.g. by receiving a signal, so that we notice + *interruptP has changed). + + Also return without a packet if we reach EOF on the packet socket + (i.e. the other side disconnected). + + Return *gotPacketP true iff we return a packet. + + Return *eofP true iff we hit EOF. + + Throw a BrokenConnectionEx exception if we can't read because of a broken + connection. +-----------------------------------------------------------------------------*/ + bool gotPacket; + bool eof; + + gotPacket = false; + eof = false; + + while (!gotPacket && !eof && !*interruptP) { + + this->sock.waitForReadable(); + this->read(&eof, &gotPacket, packetPP); + } + + *gotPacketP = gotPacket; + *eofP = eof; +} + + + +packetSocket::packetSocket(int const sockFd) { + + this->implP = new packetSocket_impl(sockFd); +} + + + +packetSocket::~packetSocket() { + + delete(this->implP); +} + + + +void +packetSocket::writeWait(packetPtr const& packetP) const { + + try { + implP->writeWait(packetP); + } catch (BrokenConnectionEx) { + throwf("Recipient hung up or connection broke"); + } +} + + + +void +packetSocket::writeWait(packetPtr const& packetP, + bool * const brokenConnP) const { + + try { + implP->writeWait(packetP); + *brokenConnP = false; + } catch (BrokenConnectionEx) { + *brokenConnP = true; + } +} + + + +void +packetSocket::read(bool * const eofP, + bool * const gotPacketP, + packetPtr * const packetPP) { + + try { + this->implP->read(eofP, gotPacketP, packetPP); + } catch (BrokenConnectionEx) { + *gotPacketP = false; + *eofP = true; + } +} + + + +void +packetSocket::readWait(volatile const int * const interruptP, + bool * const eofP, + bool * const gotPacketP, + packetPtr * const packetPP) { + + try { + this->implP->readWait(interruptP, eofP, gotPacketP, packetPP); + } catch (BrokenConnectionEx) { + *gotPacketP = false; + *eofP = true; + } +} + + + +void +packetSocket::readWait(volatile const int * const interruptP, + bool * const eofP, + packetPtr * const packetPP) { + + try { + bool gotPacket; + + this->implP->readWait(interruptP, eofP, &gotPacket, packetPP); + + if (!gotPacket && !*eofP) + throwf("Packet read was interrupted"); + } catch (BrokenConnectionEx) { + *eofP = true; + } +} + + + +void +packetSocket::readWait(bool * const eofP, + packetPtr * const packetPP) { + + int const interrupt(0); // Never interrupt + + this->readWait(&interrupt, eofP, packetPP); +} + + + +} // namespace diff --git a/trunk/src/cpp/param_list.cpp b/trunk/src/cpp/param_list.cpp new file mode 100644 index 000000000..1f7ae41f0 --- /dev/null +++ b/trunk/src/cpp/param_list.cpp @@ -0,0 +1,303 @@ +#include +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base.hpp" + +using namespace std; +using namespace xmlrpc_c; + +namespace xmlrpc_c { + + +paramList::paramList(unsigned int const paramCount) { + + this->paramVector.reserve(paramCount); +} + + + +paramList& +paramList::add(xmlrpc_c::value const param) { + + // Note: Before Xmlrpc-c 1.10, the return value was void. Old programs + // using this new add() won't notice the difference. New programs + // using this new add() against an old library will, since the old + // add() will not return anything. A new program that wants to get + // a link error instead of a crash in this case can use addx() instead. + + this->paramVector.push_back(param); + + return *this; +} + + + +paramList& +paramList::addx(xmlrpc_c::value const param) { + + // See add() for an explanation of why this exists. + + return this->add(param); +} + + + +unsigned int +paramList::size() const { + return this->paramVector.size(); +} + + + +xmlrpc_c::value +paramList::operator[](unsigned int const subscript) const { + + if (subscript >= this->paramVector.size()) + throw(girerr::error( + "Subscript of xmlrpc_c::paramList out of bounds")); + + return this->paramVector[subscript]; +} + + + +int +paramList::getInt(unsigned int const paramNumber, + int const minimum, + int const maximum) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + if (this->paramVector[paramNumber].type() != value::TYPE_INT) + throw(fault("Parameter that is supposed to be integer is not", + fault::CODE_TYPE)); + + int const intvalue(static_cast( + value_int(this->paramVector[paramNumber]))); + + if (intvalue < minimum) + throw(fault("Integer parameter too low", fault::CODE_TYPE)); + + if (intvalue > maximum) + throw(fault("Integer parameter too high", fault::CODE_TYPE)); + + return intvalue; +} + + + +bool +paramList::getBoolean(unsigned int const paramNumber) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + if (this->paramVector[paramNumber].type() != value::TYPE_BOOLEAN) + throw(fault("Parameter that is supposed to be boolean is not", + fault::CODE_TYPE)); + + return static_cast(value_boolean(this->paramVector[paramNumber])); +} + + + +double +paramList::getDouble(unsigned int const paramNumber, + double const minimum, + double const maximum) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + if (this->paramVector[paramNumber].type() != value::TYPE_DOUBLE) + throw(fault("Parameter that is supposed to be floating point number " + "is not", + fault::CODE_TYPE)); + + double const doublevalue(static_cast( + value_double(this->paramVector[paramNumber]))); + + if (doublevalue < minimum) + throw(fault("Floating point number parameter too low", + fault::CODE_TYPE)); + + if (doublevalue > maximum) + throw(fault("Floating point number parameter too high", + fault::CODE_TYPE)); + + return doublevalue; +} + + + +time_t +paramList::getDatetime_sec( + unsigned int const paramNumber, + paramList::timeConstraint const constraint) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + const xmlrpc_c::value * const paramP(&this->paramVector[paramNumber]); + + if (paramP->type() != value::TYPE_DATETIME) + throw(fault("Parameter that is supposed to be a datetime is not", + fault::CODE_TYPE)); + + time_t const timeValue(static_cast(value_datetime(*paramP))); + time_t const now(time(NULL)); + + switch (constraint) { + case TC_ANY: + /* He'll take anything; no problem */ + break; + case TC_NO_FUTURE: + if (timeValue > now) + throw(fault("Datetime parameter that is not supposed to be in " + "the future is.", fault::CODE_TYPE)); + break; + case TC_NO_PAST: + if (timeValue < now) + throw(fault("Datetime parameter that is not supposed to be in " + "the past is.", fault::CODE_TYPE)); + break; + } + + return timeValue; +} + + + +string +paramList::getString(unsigned int const paramNumber) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + if (this->paramVector[paramNumber].type() != value::TYPE_STRING) + throw(fault("Parameter that is supposed to be a string is not", + fault::CODE_TYPE)); + + return static_cast(value_string(this->paramVector[paramNumber])); +} + + + +std::vector +paramList::getBytestring(unsigned int const paramNumber) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + const xmlrpc_c::value * const paramP(&this->paramVector[paramNumber]); + + if (paramP->type() != value::TYPE_BYTESTRING) + throw(fault("Parameter that is supposed to be a byte string is not", + fault::CODE_TYPE)); + + return value_bytestring(*paramP).vectorUcharValue(); +} + + +std::vector +paramList::getArray(unsigned int const paramNumber, + unsigned int const minSize, + unsigned int const maxSize) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + const xmlrpc_c::value * const paramP(&this->paramVector[paramNumber]); + + if (paramP->type() != value::TYPE_ARRAY) + throw(fault("Parameter that is supposed to be an array is not", + fault::CODE_TYPE)); + + xmlrpc_c::value_array const arrayValue(*paramP); + + if (arrayValue.size() < minSize) + throw(fault("Array parameter has too few elements", + fault::CODE_TYPE)); + + if (arrayValue.size() > maxSize) + throw(fault("Array parameter has too many elements", + fault::CODE_TYPE)); + + return value_array(*paramP).vectorValueValue(); +} + + + +std::map +paramList::getStruct(unsigned int const paramNumber) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + const xmlrpc_c::value * const paramP(&this->paramVector[paramNumber]); + + if (paramP->type() != value::TYPE_STRUCT) + throw(fault("Parameter that is supposed to be a structure is not", + fault::CODE_TYPE)); + + return static_cast >( + value_struct(*paramP)); +} + + + +void +paramList::getNil(unsigned int const paramNumber) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + if (this->paramVector[paramNumber].type() != value::TYPE_NIL) + throw(fault("Parameter that is supposed to be nil is not", + fault::CODE_TYPE)); +} + + + +xmlrpc_int64 +paramList::getI8(unsigned int const paramNumber, + xmlrpc_int64 const minimum, + xmlrpc_int64 const maximum) const { + + if (paramNumber >= this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); + + if (this->paramVector[paramNumber].type() != value::TYPE_I8) + throw(fault("Parameter that is supposed to be 64-bit integer is not", + fault::CODE_TYPE)); + + long long const longlongvalue(static_cast( + value_i8(this->paramVector[paramNumber]))); + + if (longlongvalue < minimum) + throw(fault("64-bit integer parameter too low", fault::CODE_TYPE)); + + if (longlongvalue > maximum) + throw(fault("64-bit integer parameter too high", fault::CODE_TYPE)); + + return longlongvalue; +} + + + +void +paramList::verifyEnd(unsigned int const paramNumber) const { + + if (paramNumber < this->paramVector.size()) + throw(fault("Too many parameters", fault::CODE_TYPE)); + if (paramNumber > this->paramVector.size()) + throw(fault("Not enough parameters", fault::CODE_TYPE)); +} + +} // namespace diff --git a/trunk/src/cpp/pstream.cpp b/trunk/src/cpp/pstream.cpp new file mode 100644 index 000000000..e15ac4c44 --- /dev/null +++ b/trunk/src/cpp/pstream.cpp @@ -0,0 +1,264 @@ +/*============================================================================= + pstream +=============================================================================== + + Client XML transport for Xmlrpc-c based on a very simple byte + stream. + + The protocol we use is the "packet socket" protocol, which + is an Xmlrpc-c invention. It is an almost trivial representation of + a sequence of packets on a byte stream. + + A transport object talks to exactly one server over its lifetime. + + You can create a pstream transport from any file descriptor from which + you can read and write a bidirectional character stream. Typically, + it's a TCP socket. + + This transport is synchronous only. It does not provide a working + 'start' method. You have at most one outstanding RPC and wait for + it to complete. + + By Bryan Henderson 07.05.12. + + Contributed to the public domain by its author. +=============================================================================*/ + +#include + +using namespace std; + +#include "xmlrpc-c/girerr.hpp" +using girerr::throwf; +#include "xmlrpc-c/packetsocket.hpp" + +#include "xmlrpc-c/client_transport.hpp" + +typedef xmlrpc_c::clientXmlTransport_pstream::BrokenConnectionEx + BrokenConnectionEx; + +namespace xmlrpc_c { + +struct clientXmlTransport_pstream::constrOpt_impl { + + constrOpt_impl(); + + struct { + int fd; + bool useBrokenConnEx; + } value; + struct { + bool fd; + bool useBrokenConnEx; + } present; +}; + + + +clientXmlTransport_pstream::constrOpt_impl::constrOpt_impl() { + + this->present.fd = false; + this->present.useBrokenConnEx = false; +} + + + +#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ +clientXmlTransport_pstream::constrOpt & \ +clientXmlTransport_pstream::constrOpt::OPTION_NAME(TYPE const& arg) { \ + this->implP->value.OPTION_NAME = arg; \ + this->implP->present.OPTION_NAME = true; \ + return *this; \ +} + +DEFINE_OPTION_SETTER(fd, xmlrpc_socket); +DEFINE_OPTION_SETTER(useBrokenConnEx, bool); + +#undef DEFINE_OPTION_SETTER + + + +clientXmlTransport_pstream::constrOpt::constrOpt() { + + this->implP = new clientXmlTransport_pstream::constrOpt_impl(); +} + + + +clientXmlTransport_pstream::constrOpt::~constrOpt() { + + delete(this->implP); +} + + + +clientXmlTransport_pstream::constrOpt::constrOpt(constrOpt& arg) { + + this->implP = new clientXmlTransport_pstream::constrOpt_impl(*arg.implP); +} + + + +class clientXmlTransport_pstream_impl { + +public: + clientXmlTransport_pstream_impl( + clientXmlTransport_pstream::constrOpt_impl const& opt); + + ~clientXmlTransport_pstream_impl(); + + void + call(xmlrpc_c::carriageParm * const carriageParmP, + std::string const& callXml, + std::string * const responseXmlP); + +private: + packetSocket * packetSocketP; + + bool usingBrokenConnEx; + // We're throwing a Broken Connection object when something fails + // because the connection to the server is broken. When this is false, + // we throw an ordinary error when that happens. + + void + sendCall(std::string const& callXml); + + void + recvResp(std::string * const responseXmlP); +}; + + + +clientXmlTransport_pstream_impl::clientXmlTransport_pstream_impl( + clientXmlTransport_pstream::constrOpt_impl const& opt) { + + if (!opt.present.fd) + throwf("You must provide a 'fd' constructor option."); + + auto_ptr packetSocketAP; + + try { + auto_ptr p(new packetSocket(opt.value.fd)); + packetSocketAP = p; + } catch (exception const& e) { + throwf("Unable to create packet socket out of file descriptor %d. %s", + opt.value.fd, e.what()); + } + + if (opt.present.useBrokenConnEx) + this->usingBrokenConnEx = opt.value.useBrokenConnEx; + else + this->usingBrokenConnEx = false; + + this->packetSocketP = packetSocketAP.release(); +} + + + +clientXmlTransport_pstream::clientXmlTransport_pstream( + constrOpt const& optExt) : + + implP(new clientXmlTransport_pstream_impl(*optExt.implP)) +{} + + + +clientXmlTransport_pstream_impl::~clientXmlTransport_pstream_impl() { + + delete(this->packetSocketP); +} + + + +clientXmlTransport_pstream::~clientXmlTransport_pstream() { + + delete(this->implP); +} + + + +void // private +clientXmlTransport_pstream_impl::sendCall(string const& callXml) { +/*---------------------------------------------------------------------------- + Send the text 'callXml' down the pipe as a packet which is the RPC call. +-----------------------------------------------------------------------------*/ + packetPtr const callPacketP(new packet(callXml.c_str(), callXml.length())); + + try { + bool brokenConn; + + this->packetSocketP->writeWait(callPacketP, &brokenConn); + + if (brokenConn) { + if (this->usingBrokenConnEx) + throw BrokenConnectionEx(); + else + throwf("Server hung up or connection broke"); + } + } catch (exception const& e) { + throwf("Failed to write the call to the packet socket. %s", e.what()); + } +} + + + +void +clientXmlTransport_pstream_impl::recvResp(string * const responseXmlP) { +/*---------------------------------------------------------------------------- + Receive a packet which is the RPC response and return its contents + as the text *responseXmlP. +-----------------------------------------------------------------------------*/ + packetPtr responsePacketP; + + try { + bool eof; + this->packetSocketP->readWait(&eof, &responsePacketP); + + if (eof) { + if (this->usingBrokenConnEx) + throw BrokenConnectionEx(); + else + throwf("The other end closed the socket before sending " + "the response."); + } + } catch (exception const& e) { + throwf("We sent the call, but couldn't get the response. %s", + e.what()); + } + *responseXmlP = + string(reinterpret_cast(responsePacketP->getBytes()), + responsePacketP->getLength()); +} + + + +void +clientXmlTransport_pstream_impl::call( + carriageParm * const carriageParmP, + string const& callXml, + string * const responseXmlP) { + + carriageParm_pstream * const carriageParmPstreamP( + dynamic_cast(carriageParmP)); + + if (carriageParmPstreamP == NULL) + throwf("Pstream client XML transport called with carriage " + "parameter object not of class carriageParm_pstream"); + + this->sendCall(callXml); + + this->recvResp(responseXmlP); +} + + + +void +clientXmlTransport_pstream::call( + carriageParm * const carriageParmP, + string const& callXml, + string * const responseXmlP) { + + this->implP->call(carriageParmP, callXml, responseXmlP); +} + +} // namespace diff --git a/trunk/src/cpp/registry.cpp b/trunk/src/cpp/registry.cpp new file mode 100644 index 000000000..07f795a02 --- /dev/null +++ b/trunk/src/cpp/registry.cpp @@ -0,0 +1,593 @@ +#include +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::throwf; +#include "xmlrpc-c/girmem.hpp" +using girmem::autoObject; +using girmem::autoObjectPtr; +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/env_wrap.hpp" + +#include "xmlrpc-c/registry.hpp" + +using namespace std; +using namespace xmlrpc_c; + + +callInfo::callInfo() { + + // Even though this is the builtin default default constructor, we need + // this because some compilers won't use the builtin default to construct + // a constant (e.g. "callInfo const junk;"); I don't know why. +} + + +callInfo::~callInfo() {} + + +namespace { + +void +throwIfError(env_wrap const& env) { + + if (env.env_c.fault_occurred) + throw(girerr::error(env.env_c.fault_string)); +} + + +} // namespace + +namespace xmlrpc_c { + + +method::method() : + _signature("?"), + _help("No help is available for this method") + {}; + + + +method::~method() {} + + + +methodPtr::methodPtr(method * const methodP) { + this->point(methodP); +} + + + +method * +methodPtr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +method2::method2() {} + + + +method2::~method2() {} + + +void +method2::execute(xmlrpc_c::paramList const& paramList, + xmlrpc_c::value * const resultP) { + + callInfo const nullCallInfo; + + execute(paramList, &nullCallInfo, resultP); +} + + + +defaultMethod::~defaultMethod() {} + + + +defaultMethodPtr::defaultMethodPtr() {} + + +defaultMethodPtr::defaultMethodPtr(defaultMethod * const methodP) { + this->point(methodP); +} + + + +defaultMethod * +defaultMethodPtr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +defaultMethod * +defaultMethodPtr::get() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +struct registry_impl { + + xmlrpc_registry * c_registryP; + // Pointer to the C registry object we use to implement this + // object. + + std::list managedMethodList; + // This is a list of pointers to method objects whose existence is + // managed by methodPtr shared pointers (so that the reference to + // the object by the registry keeps it in existence and if the + // registry's reference is the last reference to a method object, + // the method object disappears when the registry does). + // + // The real registry is the C registry object, so the list of methods + // in that object, not this member, is the operative list of + // registered methods. + // + // The registry may refer to method objects that are not managed by + // methodPtrs (it's the user's choice), so this member is not + // necessarily a complete list. + + xmlrpc_c::defaultMethodPtr defaultMethodP; + // Analogous to 'managedMethodList', but for the default method object. + + registry_impl(); + + ~registry_impl(); +}; + + + +registry_impl::registry_impl() { + + env_wrap env; + + this->c_registryP = xmlrpc_registry_new(&env.env_c); + + throwIfError(env); +} + + + +registry_impl::~registry_impl() { + + xmlrpc_registry_free(this->c_registryP); +} + + +registry::registry() { + + this->implP = new registry_impl(); +} + + + +registry::~registry(void) { + + delete(this->implP); +} + + + +registryPtr::registryPtr() {} + + + +registryPtr::registryPtr(registry * const registryP) { + this->point(registryP); +} + + + +registry * +registryPtr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +registry * +registryPtr::get() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +static xmlrpc_c::paramList +pListFromXmlrpcArray(xmlrpc_value * const arrayP) { +/*---------------------------------------------------------------------------- + Convert an XML-RPC array in C (not C++) form to a parameter list object + that can be passed to a method execute method. + + This is glue code to allow us to hook up C++ Xmlrpc-c code to + C Xmlrpc-c code. +-----------------------------------------------------------------------------*/ + env_wrap env; + + XMLRPC_ASSERT_ARRAY_OK(arrayP); + + unsigned int const arraySize = xmlrpc_array_size(&env.env_c, arrayP); + + assert(!env.env_c.fault_occurred); + + xmlrpc_c::paramList paramList(arraySize); + + for (unsigned int i = 0; i < arraySize; ++i) { + xmlrpc_value * arrayItemP; + + xmlrpc_array_read_item(&env.env_c, arrayP, i, &arrayItemP); + assert(!env.env_c.fault_occurred); + + paramList.add(xmlrpc_c::value(arrayItemP)); + + xmlrpc_DECREF(arrayItemP); + } + return paramList; +} + + + +static xmlrpc_value * +c_executeMethod(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const methodPtr, + void * const callInfoPtr) { +/*---------------------------------------------------------------------------- + This is a function designed to be called via a C registry to + execute an XML-RPC method, but use a C++ method object to do the + work. You register this function as the method function and a + pointer to the C++ method object as the method data in the C + registry. + + If we had a pure C++ registry, this would be unnecessary. + + Since we can't throw an error back to the C code, we catch anything + the XML-RPC method's execute() method throws, and any error we + encounter in processing the result it returns, and turn it into an + XML-RPC method failure. This will cause a leak if the execute() + method actually created a result, since it will not get destroyed. + + This function is of type 'xmlrpc_method2'. +-----------------------------------------------------------------------------*/ + method * const methodP(static_cast(methodPtr)); + paramList const paramList(pListFromXmlrpcArray(paramArrayP)); + callInfo * const callInfoP(static_cast(callInfoPtr)); + + xmlrpc_value * retval; + retval = NULL; // silence used-before-set warning + + try { + value result; + + try { + method2 * const method2P(dynamic_cast(methodP)); + if (method2P) + method2P->execute(paramList, callInfoP, &result); + else + methodP->execute(paramList, &result); + } catch (xmlrpc_c::fault const& fault) { + xmlrpc_env_set_fault(envP, fault.getCode(), + fault.getDescription().c_str()); + } + if (!envP->fault_occurred) { + if (result.isInstantiated()) + retval = result.cValue(); + else + throwf("Xmlrpc-c user's xmlrpc_c::method object's " + "'execute method' failed to set the RPC result " + "value."); + } + } catch (exception const& e) { + xmlrpc_faultf(envP, "Unexpected error executing code for " + "particular method, detected by Xmlrpc-c " + "method registry code. Method did not " + "fail; rather, it did not complete at all. %s", + e.what()); + } catch (...) { + xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, + "Unexpected error executing code for " + "particular method, detected by Xmlrpc-c " + "method registry code. Method did not " + "fail; rather, it did not complete at all."); + } + return retval; +} + + + +static xmlrpc_value * +c_executeDefaultMethod(xmlrpc_env * const envP, + const char * const , // host + const char * const methodName, + xmlrpc_value * const paramArrayP, + void * const methodPtr) { +/*---------------------------------------------------------------------------- + This is a function designed to be called via a C registry to + execute an XML-RPC method, but use a C++ method object to do the + work. You register this function as the default method function and a + pointer to the C++ default method object as the method data in the C + registry. + + If we had a pure C++ registry, this would be unnecessary. + + Since we can't throw an error back to the C code, we catch anything + the XML-RPC method's execute() method throws, and any error we + encounter in processing the result it returns, and turn it into an + XML-RPC method failure. This will cause a leak if the execute() + method actually created a result, since it will not get destroyed. +-----------------------------------------------------------------------------*/ + defaultMethod * const methodP = + static_cast(methodPtr); + paramList const paramList(pListFromXmlrpcArray(paramArrayP)); + + xmlrpc_value * retval; + retval = NULL; // silence used-before-set warning + + try { + xmlrpc_c::value result; + + try { + methodP->execute(methodName, paramList, &result); + } catch (xmlrpc_c::fault const& fault) { + xmlrpc_env_set_fault(envP, fault.getCode(), + fault.getDescription().c_str()); + } + if (!envP->fault_occurred) { + if (result.isInstantiated()) + retval = result.cValue(); + else + throwf("Xmlrpc-c user's xmlrpc_c::defaultMethod object's " + "'execute method' failed to set the RPC result " + "value."); + } + } catch (exception const& e) { + xmlrpc_faultf(envP, "Unexpected error executing default " + "method code, detected by Xmlrpc-c " + "method registry code. Method did not " + "fail; rather, it did not complete at all. %s", + e.what()); + } catch (...) { + xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, + "Unexpected error executing default " + "method code, detected by Xmlrpc-c " + "method registry code. Method did not " + "fail; rather, it did not complete at all."); + } + return retval; +} + + + +void +registry::addMethod(string const name, + method * const methodP) { +/*---------------------------------------------------------------------------- + Caller is responsible for ensuring *methodP exists as long as this + registry does. +-----------------------------------------------------------------------------*/ + struct xmlrpc_method_info3 methodInfo; + env_wrap env; + + methodInfo.methodName = name.c_str(); + methodInfo.methodFunction = &c_executeMethod; + methodInfo.serverInfo = methodP; + methodInfo.stackSize = 0; + string const signatureString(methodP->signature()); + methodInfo.signatureString = signatureString.c_str(); + string const help(methodP->help()); + methodInfo.help = help.c_str(); + + xmlrpc_registry_add_method3(&env.env_c, this->implP->c_registryP, + &methodInfo); + + throwIfError(env); +} + + + +void +registry::addMethod(string const name, + methodPtr const methodP) { + + this->addMethod(name, dynamic_cast(methodP.get())); + + this->implP->managedMethodList.push_back(methodP); +} + + + +void +registry::setDefaultMethod(defaultMethod * const methodP) { +/*---------------------------------------------------------------------------- + Caller is responsible for ensuring *methodP exists as long as this + registry does. +-----------------------------------------------------------------------------*/ + env_wrap env; + + xmlrpc_registry_set_default_method( + &env.env_c, this->implP->c_registryP, + &c_executeDefaultMethod, (void*) methodP); + + throwIfError(env); +} + + + +void +registry::setDefaultMethod(defaultMethodPtr const methodP) { + + this->setDefaultMethod(dynamic_cast(methodP.get())); + + this->implP->defaultMethodP = methodP; +} + + + +void +registry::disableIntrospection() { + + xmlrpc_registry_disable_introspection(this->implP->c_registryP); +} + + + +static xmlrpc_server_shutdown_fn shutdownServer; + +static void +shutdownServer(xmlrpc_env * const envP, + void * const context, + const char * const comment, + void * const callInfo) { + + registry::shutdown * const shutdownP( + static_cast(context)); + + assert(shutdownP != NULL); + + try { + shutdownP->doit(string(comment), callInfo); + } catch (exception const& e) { + xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, e.what()); + } +} + + + +void +registry::setShutdown(const registry::shutdown * const shutdownP) { + + void * const context(const_cast(shutdownP)); + + xmlrpc_registry_set_shutdown(this->implP->c_registryP, + &shutdownServer, + context); +} + + + +void +registry::setDialect(xmlrpc_dialect const dialect) { + + env_wrap env; + + xmlrpc_registry_set_dialect(&env.env_c, this->implP->c_registryP, dialect); + + throwIfError(env); +} + + + +void +registry::processCall(string const& callXml, + const callInfo * const callInfoP, + string * const responseXmlP) const { +/*---------------------------------------------------------------------------- + Process an XML-RPC call whose XML is 'callXml'. + + Return the response XML as *responseXmlP. + + If we are unable to execute the call, we throw an error. But if + the call executes and the method merely fails in an XML-RPC sense, we + don't. In that case, *responseXmlP indicates the failure. +-----------------------------------------------------------------------------*/ + env_wrap env; + xmlrpc_mem_block * response; + + // For the pure C++ version, this will have to parse 'callXml' + // into a method name and parameters, look up the method name in + // the registry, call the method's execute() method, then marshall + // the result into XML and return it as *responseXmlP. It will + // also have to execute system methods (e.g. introspection) + // itself. This will be more or less like what + // xmlrpc_registry_process_call() does. + + xmlrpc_registry_process_call2( + &env.env_c, this->implP->c_registryP, + callXml.c_str(), callXml.length(), + const_cast(callInfoP), + &response); + + throwIfError(env); + + *responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, response), + XMLRPC_MEMBLOCK_SIZE(char, response)); + + xmlrpc_mem_block_free(response); +} + + + +void +registry::processCall(string const& callXml, + string * const responseXmlP) const { +/*---------------------------------------------------------------------------- + Process an XML-RPC call whose XML is 'callXml'. + + Return the response XML as *responseXmlP. + + If we are unable to execute the call, we throw an error. But if + the call executes and the method merely fails in an XML-RPC sense, we + don't. In that case, *responseXmlP indicates the failure. +-----------------------------------------------------------------------------*/ + env_wrap env; + xmlrpc_mem_block * output; + + // For the pure C++ version, this will have to parse 'callXml' + // into a method name and parameters, look up the method name in + // the registry, call the method's execute() method, then marshall + // the result into XML and return it as *responseXmlP. It will + // also have to execute system methods (e.g. introspection) + // itself. This will be more or less like what + // xmlrpc_registry_process_call() does. + + output = xmlrpc_registry_process_call( + &env.env_c, this->implP->c_registryP, NULL, + callXml.c_str(), callXml.length()); + + throwIfError(env); + + *responseXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, output), + XMLRPC_MEMBLOCK_SIZE(char, output)); + + xmlrpc_mem_block_free(output); +} + + + +#define PROCESS_CALL_STACK_SIZE 256 + // This is our liberal estimate of how much stack space + // registry::processCall() needs, not counting what + // the call the to C registry uses. + + + +size_t +registry::maxStackSize() const { + + return xmlrpc_registry_max_stackSize(this->implP->c_registryP) + + PROCESS_CALL_STACK_SIZE; +} + + + +} // namespace + + +registry::shutdown::~shutdown() {} diff --git a/trunk/src/cpp/server_abyss.cpp b/trunk/src/cpp/server_abyss.cpp new file mode 100644 index 000000000..2f70516de --- /dev/null +++ b/trunk/src/cpp/server_abyss.cpp @@ -0,0 +1,1064 @@ +#include "xmlrpc_config.h" +#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ +#include +#include +#include +#include +#include +#include +#if !MSVCRT +# include +#endif + +#include "assertx.hpp" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/abyss.h" +#include "xmlrpc-c/server_abyss.h" +#include "xmlrpc-c/registry.hpp" +#include "xmlrpc-c/env_wrap.hpp" + +#include "xmlrpc-c/server_abyss.hpp" + +using namespace std; +using namespace xmlrpc_c; + +namespace xmlrpc_c { + +namespace { + + +static void +sigterm(int const signalClass) { + + cerr << "Signal of Class " << signalClass << " received. Exiting" << endl; + + exit(1); +} + + + +static void +sigchld(int const ASSERT_ONLY_ARG(signalClass)) { +/*---------------------------------------------------------------------------- + This is a signal handler for a SIGCHLD signal (which informs us that + one of our child processes has terminated). + + The only child processes we have are those that belong to the Abyss + server (and then only if the Abyss server was configured to use + forking as a threading mechanism), so we respond by passing the + signal on to the Abyss server. And reaping the dead child. +-----------------------------------------------------------------------------*/ +#ifndef _WIN32 + // Reap zombie children / report to Abyss until there aren't any more. + + bool zombiesExist; + bool error; + + assert(signalClass == SIGCHLD); + + zombiesExist = true; // initial assumption + error = false; // no error yet + while (zombiesExist && !error) { + int status; + pid_t const pid = waitpid((pid_t) -1, &status, WNOHANG); + + if (pid == 0) + zombiesExist = false; + else if (pid < 0) { + /* because of ptrace */ + if (errno == EINTR) { + // This is OK - it's a ptrace notification + } else + error = true; + } else + ServerHandleSigchld(pid); + } +#endif /* _WIN32 */ +} + + + +struct signalHandlers { +#ifndef WIN32 + struct sigaction term; + struct sigaction int_; + struct sigaction hup; + struct sigaction usr1; + struct sigaction pipe; + struct sigaction chld; +#else + int dummy; +#endif +}; + + + +void +setupSignalHandlers(struct signalHandlers * const oldHandlersP) { +#ifndef _WIN32 + struct sigaction mysigaction; + + sigemptyset(&mysigaction.sa_mask); + mysigaction.sa_flags = 0; + + /* These signals abort the program, with tracing */ + mysigaction.sa_handler = sigterm; + sigaction(SIGTERM, &mysigaction, &oldHandlersP->term); + sigaction(SIGINT, &mysigaction, &oldHandlersP->int_); + sigaction(SIGHUP, &mysigaction, &oldHandlersP->hup); + sigaction(SIGUSR1, &mysigaction, &oldHandlersP->usr1); + + /* This signal indicates connection closed in the middle */ + mysigaction.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &mysigaction, &oldHandlersP->pipe); + + /* This signal indicates a child process (request handler) has died */ + mysigaction.sa_handler = sigchld; + sigaction(SIGCHLD, &mysigaction, &oldHandlersP->chld); +#endif +} + + + +void +restoreSignalHandlers(struct signalHandlers const& oldHandlers) { + +#ifndef _WIN32 + sigaction(SIGCHLD, &oldHandlers.chld, NULL); + sigaction(SIGPIPE, &oldHandlers.pipe, NULL); + sigaction(SIGUSR1, &oldHandlers.usr1, NULL); + sigaction(SIGHUP, &oldHandlers.hup, NULL); + sigaction(SIGINT, &oldHandlers.int_, NULL); + sigaction(SIGTERM, &oldHandlers.term, NULL); +#endif +} + + + +// We need 'global' because methods of class serverAbyss call +// functions in the Abyss C library. By virtue of global's static +// storage class, the program loader will call its constructor and +// destructor and thus initialize and terminate the Abyss C library. + +class abyssGlobalState { +public: + abyssGlobalState() { + const char * error; + AbyssInit(&error); + if (error) { + string const e(error); + xmlrpc_strfree(error); + throwf("AbyssInit() failed. %s", e.c_str()); + } + } + ~abyssGlobalState() { + AbyssTerm(); + } +} const global; + +} // namespace + + + +callInfo_serverAbyss::callInfo_serverAbyss( + serverAbyss * const serverAbyssP, + TSession * const abyssSessionP) : + serverAbyssP(serverAbyssP), abyssSessionP(abyssSessionP) {} + + + +struct serverAbyss::constrOpt_impl { + + constrOpt_impl(); + + struct value { + xmlrpc_c::registryPtr registryPtr; + const xmlrpc_c::registry * registryP; + XMLRPC_SOCKET socketFd; + unsigned int portNumber; + unsigned int maxConn; + unsigned int maxConnBacklog; + size_t maxRpcMem; + unsigned int keepaliveTimeout; + unsigned int keepaliveMaxConn; + unsigned int timeout; + bool dontAdvertise; + std::string uriPath; + bool chunkResponse; + std::string allowOrigin; + unsigned int accessCtlMaxAge; + const struct sockaddr * sockAddrP; + socklen_t sockAddrLen; + std::string logFileName; + bool serverOwnsSignals; + bool expectSigchld; + } value; + struct { + bool registryPtr; + bool registryP; + bool socketFd; + bool portNumber; + bool maxConn; + bool maxConnBacklog; + bool maxRpcMem; + bool keepaliveTimeout; + bool keepaliveMaxConn; + bool timeout; + bool dontAdvertise; + bool uriPath; + bool chunkResponse; + bool allowOrigin; + bool accessCtlMaxAge; + bool sockAddrP; + bool sockAddrLen; + bool logFileName; + bool serverOwnsSignals; + bool expectSigchld; + } present; +}; + + + +serverAbyss::constrOpt_impl::constrOpt_impl() { + present.registryPtr = false; + present.registryP = false; + present.socketFd = false; + present.portNumber = false; + present.logFileName = false; + present.maxConn = false; + present.maxConnBacklog = false; + present.maxRpcMem = false; + present.keepaliveTimeout = false; + present.keepaliveMaxConn = false; + present.timeout = false; + present.dontAdvertise = false; + present.uriPath = false; + present.chunkResponse = false; + present.allowOrigin = false; + present.accessCtlMaxAge = false; + present.sockAddrP = false; + present.sockAddrLen = false; + present.serverOwnsSignals = false; + present.expectSigchld = false; + + // Set default values + value.dontAdvertise = false; + value.uriPath = string("/RPC2"); + value.chunkResponse = false; + value.serverOwnsSignals = true; + value.expectSigchld = false; +} + + + +#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ +serverAbyss::constrOpt & \ +serverAbyss::constrOpt::OPTION_NAME(TYPE const& arg) { \ + this->implP->value.OPTION_NAME = arg; \ + this->implP->present.OPTION_NAME = true; \ + return *this; \ +} + +DEFINE_OPTION_SETTER(registryPtr, xmlrpc_c::registryPtr); +DEFINE_OPTION_SETTER(registryP, const registry *); +DEFINE_OPTION_SETTER(socketFd, XMLRPC_SOCKET); +DEFINE_OPTION_SETTER(portNumber, unsigned int); +DEFINE_OPTION_SETTER(maxConn, unsigned int); +DEFINE_OPTION_SETTER(maxConnBacklog, unsigned int); +DEFINE_OPTION_SETTER(maxRpcMem, size_t); +DEFINE_OPTION_SETTER(keepaliveTimeout, unsigned int); +DEFINE_OPTION_SETTER(keepaliveMaxConn, unsigned int); +DEFINE_OPTION_SETTER(timeout, unsigned int); +DEFINE_OPTION_SETTER(dontAdvertise, bool); +DEFINE_OPTION_SETTER(uriPath, string); +DEFINE_OPTION_SETTER(chunkResponse, bool); +DEFINE_OPTION_SETTER(allowOrigin, string); +DEFINE_OPTION_SETTER(accessCtlMaxAge, unsigned int); +DEFINE_OPTION_SETTER(sockAddrP, const struct sockaddr *); +DEFINE_OPTION_SETTER(sockAddrLen, socklen_t); +DEFINE_OPTION_SETTER(logFileName, string); +DEFINE_OPTION_SETTER(serverOwnsSignals, bool); +DEFINE_OPTION_SETTER(expectSigchld, bool); + +#undef DEFINE_OPTION_SETTER + + +serverAbyss::constrOpt::constrOpt() { + + this->implP = new serverAbyss::constrOpt_impl(); +} + + + +serverAbyss::constrOpt::~constrOpt() { + + delete(this->implP); +} + + + +struct SockAddr { + + const struct sockaddr * const sockAddrP; + socklen_t const sockAddrLen; + + SockAddr(const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen) : + sockAddrP (sockAddrP), + sockAddrLen (sockAddrLen) + {} +}; + + + +struct serverAbyss_impl { + registryPtr regPtr; + // This just holds a reference to the registry so that it may + // get destroyed when the serverAbyss gets destroyed. If the + // creator of the serverAbyss is managing lifetime himself, + // this is a null pointer. 'registryP' is what you really use + // to access the registry. + + const registry * registryP; + + TServer cServer; + + TChanSwitch * chanSwitchP; + // Handle of the channel switch we created. Null if we didn't. + // When user wants us to accept connections, we create a channel + // switch and create a server based on it; otherwise, we don't. + + serverAbyss_impl(serverAbyss::constrOpt_impl const& opt, + serverAbyss * const serverAbyssP); + + ~serverAbyss_impl(); + + void + getListenName(struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP); + + void + run(); + + void + processCall(std::string const& call, + TSession * const abyssSessionP, + std::string * const responseP); + + serverAbyss * const serverAbyssP; + // The server for which we are the implementation. + + bool expectSigchld; + bool serverOwnsSignals; +}; + + + +static void +processXmlrpcCall(xmlrpc_env * const envP, + void * const arg, + const char * const callXml, + size_t const callXmlLen, + TSession * const abyssSessionP, + xmlrpc_mem_block ** const responseXmlPP) { +/*---------------------------------------------------------------------------- + This is an XML-RPC XML call processor, as called by the HTTP request + handler of the libxmlrpc_server_abyss C library. + + 'callXml'/'callXmlLen' is the XML text of a supposed XML-RPC call. + We execute the RPC and return the XML text of the XML-RPC response + as *responseXmlPP. + + 'arg' carries the information that tells us how to do that; e.g. + what XML-RPC methods are defined. +-----------------------------------------------------------------------------*/ + serverAbyss_impl * const implP( + static_cast(arg)); + + try { + string const call(callXml, callXmlLen); + + string response; + + implP->processCall(call, abyssSessionP, &response); + + xmlrpc_mem_block * responseMbP; + + responseMbP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + + if (!envP->fault_occurred) { + XMLRPC_MEMBLOCK_APPEND(char, envP, responseMbP, + response.c_str(), response.length()); + + *responseXmlPP = responseMbP; + } + } catch (exception const& e) { + xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, e.what()); + } +} + + + +static void +validateListenOptions(serverAbyss::constrOpt_impl const& opt) { + + if ((opt.present.portNumber ? 1 : 0) + + (opt.present.socketFd ? 1 : 0) + + (opt.present.sockAddrP ? 1 : 0) > 1) + throwf("You can specify at most one of portNumber, socketFd, " + "and sockAddrP options"); + + if (opt.present.sockAddrP && !opt.present.sockAddrLen) + throwf("You must specify the sockAddrLen option when you " + "specify sockAddrP"); + + if (!opt.present.sockAddrP && opt.present.sockAddrLen) + throwf("The sockAddrLen option does not make sense without " + "sockAddrP"); + + if (opt.present.portNumber) { + if (opt.value.portNumber > 0xffff) + throwf("Port number %u exceeds the maximum possible port number " + "(65535)", opt.value.portNumber); + } +} + + + +static void +createServerFromSwitch(TServer * const serverP, + TChanSwitch * const chanSwitchP) { + + const char * error; + + ServerCreateSwitch(serverP, chanSwitchP, &error); + + if (error) { + throwf("Abyss failed to create server. %s", error); + xmlrpc_strfree(error); + } +} + + + +static TChanSwitch * +newChanSwitchOsSocket(int const socketFd) { + + TChanSwitch * chanSwitchP; + const char * error; + +#ifdef WIN32 + ChanSwitchWinCreateWinsock(socketFd, &chanSwitchP, &error); +#else + ChanSwitchUnixCreateFd(socketFd, &chanSwitchP, &error); +#endif + + if (error) { + string const errorS(error); + xmlrpc_strfree(error); + + throwf("Abyss failed to create a channel switch from the " + "supplied listen socket. %s", errorS.c_str()); + } + return chanSwitchP; +} + + + +static void +chanSwitchCreateSockAddr(int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + TChanSwitch ** const chanSwitchPP) { + + const char * error; + +#ifdef WIN32 + ChanSwitchWinCreate2(protocolFamily, sockAddrP, sockAddrLen, + chanSwitchPP, &error); +#else + ChanSwitchUnixCreate2(protocolFamily, sockAddrP, sockAddrLen, + chanSwitchPP, &error); +#endif + if (error) { + string const errorS(error); + xmlrpc_strfree(error); + throwf("Unable to create Abyss channel switch from socket address. " + "%s", errorS.c_str()); + } +} + + + +static TChanSwitch * +newChanSwitchSockAddr(SockAddr const& sockAddr) { + + int protocolFamily; + + switch (sockAddr.sockAddrP->sa_family) { + case AF_INET: + protocolFamily = PF_INET; + break; + case AF_INET6: + protocolFamily = PF_INET6; + break; + default: + throwf("Unknown socket address family %d. " + "We know only AF_INET and AF_INET6.", + sockAddr.sockAddrP->sa_family); + } + + TChanSwitch * chanSwitchP; + + chanSwitchCreateSockAddr(protocolFamily, + sockAddr.sockAddrP, sockAddr.sockAddrLen, + &chanSwitchP); + + return chanSwitchP; +} + + + +static TChanSwitch * +newChanSwitchIpV4Port(unsigned int const portNumber) { + + struct sockaddr_in sockAddr; + + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons(portNumber); + sockAddr.sin_addr.s_addr = INADDR_ANY; + + TChanSwitch * chanSwitchP; + + chanSwitchCreateSockAddr(PF_INET, (const struct sockaddr *)&sockAddr, + sizeof(sockAddr), + &chanSwitchP); + + return chanSwitchP; +} + + + +static void +createServerBare(bool const logFileNameGiven, + string const& logFileName, + bool const socketFdGiven, + int const socketFd, + bool const portNumberGiven, + unsigned int const portNumber, + bool const sockAddrPGiven, + SockAddr const& sockAddr, + TServer * const serverP, + TChanSwitch ** const chanSwitchPP) { + + const char * const serverName("XmlRpcServer"); + + if (socketFdGiven || sockAddrPGiven || portNumberGiven) { + + TChanSwitch * const chanSwitchP( + socketFdGiven ? + newChanSwitchOsSocket(socketFd) : + sockAddrPGiven ? + newChanSwitchSockAddr(sockAddr) : + portNumberGiven ? + newChanSwitchIpV4Port(portNumber) : + NULL); + + assert(chanSwitchP); + + try { + createServerFromSwitch(serverP, chanSwitchP); + + try { + ServerSetName(serverP, serverName); + + if (logFileNameGiven) + ServerSetLogFileName(serverP, logFileName.c_str()); + } catch (...) { + ServerFree(serverP); + throw; + } + } catch (...) { + ChanSwitchDestroy(chanSwitchP); + throw; + } + *chanSwitchPP = chanSwitchP; + } else { + const char * const logfileArg(logFileNameGiven ? + logFileName.c_str() : NULL); + + ServerCreateNoAccept(serverP, serverName, + DEFAULT_DOCS, logfileArg); + + *chanSwitchPP = NULL; + } +} + + + +static void +setAdditionalServerParms(TServer * const serverP, + serverAbyss::constrOpt_impl const& opt) { + + if (opt.present.maxConn) + ServerSetMaxConn(serverP, opt.value.maxConn); + if (opt.present.maxConnBacklog) + ServerSetMaxConnBacklog(serverP, opt.value.maxConnBacklog); + if (opt.present.maxRpcMem) + ServerSetMaxSessionMem(serverP, opt.value.maxRpcMem); + if (opt.present.keepaliveTimeout) + ServerSetKeepaliveTimeout(serverP, opt.value.keepaliveTimeout); + if (opt.present.keepaliveMaxConn) + ServerSetKeepaliveMaxConn(serverP, opt.value.keepaliveMaxConn); + if (opt.present.timeout) + ServerSetTimeout(serverP, opt.value.timeout); + ServerSetAdvertise(serverP, !opt.value.dontAdvertise); + if (opt.value.expectSigchld) + ServerUseSigchld(serverP); +} + + + +static void +setHttpReqHandlers(TServer * const serverP, + void * const serverHandle, + size_t const maxStackSize, + string const& uriPath, + bool const chunkResponse, + bool const doHttpAccessControl, + string const& allowOrigin, + bool const accessCtlExpires, + unsigned int const accessCtlMaxAge) { + + env_wrap env; + xmlrpc_server_abyss_handler_parms parms; + + parms.xml_processor = &processXmlrpcCall; + parms.xml_processor_arg = serverHandle; + parms.xml_processor_max_stack = maxStackSize; + parms.uri_path = uriPath.c_str(); + parms.chunk_response = chunkResponse; + parms.allow_origin = doHttpAccessControl ? allowOrigin.c_str() : NULL; + parms.access_ctl_expires = accessCtlExpires; + parms.access_ctl_max_age = accessCtlMaxAge; + + xmlrpc_server_abyss_set_handler3( + &env.env_c, serverP, + &parms, XMLRPC_AHPSIZE(access_ctl_max_age)); + + if (env.env_c.fault_occurred) + throwf("Failed to register the HTTP handler for XML-RPC " + "with the underlying Abyss HTTP server. " + "xmlrpc_server_abyss_set_handler3() failed with: %s", + env.env_c.fault_string); + + xmlrpc_server_abyss_set_default_handler(serverP); +} + + + +static void +createServer(serverAbyss::constrOpt_impl const& opt, + void * const serverHandle, + size_t const maxStackSize, + TServer * const serverP, + TChanSwitch ** const chanSwitchPP) { + + validateListenOptions(opt); + + createServerBare(opt.present.logFileName, opt.value.logFileName, + opt.present.socketFd, opt.value.socketFd, + opt.present.portNumber, opt.value.portNumber, + opt.present.sockAddrP, + SockAddr(opt.value.sockAddrP, opt.value.sockAddrLen), + serverP, chanSwitchPP); + + try { + setAdditionalServerParms(serverP, opt); + + setHttpReqHandlers(serverP, + serverHandle, + maxStackSize, + opt.value.uriPath, + opt.value.chunkResponse, + opt.present.allowOrigin, + opt.value.allowOrigin, + opt.present.accessCtlMaxAge, + opt.value.accessCtlMaxAge); + + if (opt.present.portNumber || opt.present.socketFd || + opt.present.sockAddrP) + ServerInit(serverP); + } catch (...) { + ServerFree(serverP); + throw; + } +} + + + +serverAbyss_impl::serverAbyss_impl( + serverAbyss::constrOpt_impl const& opt, + serverAbyss * const serverAbyssP) : + serverAbyssP(serverAbyssP) { + + if (!opt.present.registryP && !opt.present.registryPtr) + throwf("You must specify the 'registryP' or 'registryPtr' option"); + else if (opt.present.registryP && opt.present.registryPtr) + throwf("You may not specify both the 'registryP' and " + "the 'registryPtr' options"); + else { + if (opt.present.registryP) + this->registryP = opt.value.registryP; + else { + this->regPtr = opt.value.registryPtr; + this->registryP = this->regPtr.get(); + } + } + + this->serverOwnsSignals = opt.value.serverOwnsSignals; + + if (opt.value.serverOwnsSignals && opt.value.expectSigchld) + throwf("You can't specify both expectSigchld " + "and serverOwnsSignals options"); + + DateInit(); + + createServer(opt, this, this->registryP->maxStackSize(), + &this->cServer, &this->chanSwitchP); +} + + + +serverAbyss_impl::~serverAbyss_impl() { + + ServerFree(&this->cServer); + + if (this->chanSwitchP) + ChanSwitchDestroy(this->chanSwitchP); +} + + + +void +serverAbyss_impl::getListenName(struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP) { + + if (!this->chanSwitchP) + throwf("%s", + "Server is not configured to listen for client connections"); + + const char * error; + +#ifdef WIN32 + ChanSwitchWinGetListenName(this->chanSwitchP, + sockaddrPP, sockaddrLenP, &error); +#else + ChanSwitchUnixGetListenName(this->chanSwitchP, + sockaddrPP, sockaddrLenP, &error); +#endif + + if (error) { + string const e(error); + xmlrpc_strfree(error); + throwf("%s", e.c_str()); + } +} + + + +static void +setupSignalsAndRunAbyss(TServer * const abyssServerP) { + + /* We do some pretty ugly stuff for an object method: we set signal + handlers, which are process-global. + + One example of where this can be hairy is: Caller has a child + process unrelated to the Abyss server. That child dies. We + get his death of a child signal and Caller never knows. + + We really expect to be the only thing in the process, at least + for the time we're running. If you want the Abyss Server + to behave more like an object and own the signals yourself, + use runOnce() in a loop instead of run(). + */ + signalHandlers oldHandlers; + + setupSignalHandlers(&oldHandlers); + + ServerUseSigchld(abyssServerP); + + ServerRun(abyssServerP); + + restoreSignalHandlers(oldHandlers); +} + + + +void +serverAbyss_impl::run() { + + if (this->serverOwnsSignals) + setupSignalsAndRunAbyss(&this->cServer); + else { + if (this->expectSigchld) + ServerUseSigchld(&this->cServer); + + ServerRun(&this->cServer); + } +} + + + +void +serverAbyss_impl::processCall(string const& call, + TSession * const abyssSessionP, + string * const responseP) { + + callInfo_serverAbyss const callInfo(this->serverAbyssP, abyssSessionP); + + this->registryP->processCall(call, &callInfo, responseP); +} + + + +serverAbyss::shutdown::shutdown(serverAbyss * const serverAbyssP) : + serverAbyssP(serverAbyssP) {} + + + +serverAbyss::shutdown::~shutdown() {} + + + +void +serverAbyss::shutdown::doit(string const&, + void * const) const { + + this->serverAbyssP->terminate(); +} + + + +void +serverAbyss::initialize(constrOpt const& opt) { + + this->implP = new serverAbyss_impl(*opt.implP, this); +} + + + +serverAbyss::serverAbyss(constrOpt const& opt) { + + initialize(opt); +} + + + +serverAbyss::serverAbyss( + xmlrpc_c::registry const& registry, + unsigned int const portNumber, + string const& logFileName, + unsigned int const keepaliveTimeout, + unsigned int const keepaliveMaxConn, + unsigned int const timeout, + bool const dontAdvertise, + bool const socketBound, + XMLRPC_SOCKET const socketFd) { +/*---------------------------------------------------------------------------- + This is a backward compatibility interface. This used to be the only + constructor. +-----------------------------------------------------------------------------*/ + serverAbyss::constrOpt opt; + + opt.registryP(®istry); + if (logFileName.length() > 0) + opt.logFileName(logFileName); + if (keepaliveTimeout > 0) + opt.keepaliveTimeout(keepaliveTimeout); + if (keepaliveMaxConn > 0) + opt.keepaliveMaxConn(keepaliveMaxConn); + if (timeout > 0) + opt.timeout(timeout); + opt.dontAdvertise(dontAdvertise); + if (socketBound) + opt.socketFd(socketFd); + else + opt.portNumber(portNumber); + + initialize(opt); +} + + + +serverAbyss::~serverAbyss() { + + delete(this->implP); +} + + + +void +serverAbyss::getListenName(struct sockaddr ** const sockaddrPP, + size_t * const sockaddrLenP) { + + this->implP->getListenName(sockaddrPP, sockaddrLenP); +} + + + +void +serverAbyss::run() { + + this->implP->run(); +} + + + +void +serverAbyss::runOnce() { + + ServerRunOnce(&this->implP->cServer); +} + + + +void +serverAbyss::runConn(int const socketFd) { + + ServerRunConn(&this->implP->cServer, socketFd); +} + + + +#ifndef WIN32 +void +serverAbyss::sigchld(pid_t const pid) { + + // There's a hole in the design here, because the Abyss server uses + // a process-global list of children (so there can't be more than one + // Abyss object in the process), so while this is an object method, + // it doesn't really refer to the object at all. + + // We might conceivably fix Abyss some day, then this method would do + // what you expect -- affect only its own object. But forking Abyss is + // obsolete anyway, so we just don't worry about it. + + ServerHandleSigchld(pid); +} +#endif + + + +void +serverAbyss::terminate() { + + ServerTerminate(&this->implP->cServer); +} + + + +callInfo_abyss::callInfo_abyss(TSession * const abyssSessionP) : + abyssSessionP(abyssSessionP) {} + + + +void +processXmlrpcCall2(xmlrpc_env * const envP, + void * const arg, + const char * const callXml, + size_t const callXmlLen, + TSession * const abyssSessionP, + xmlrpc_mem_block ** const responseXmlPP) { +/*---------------------------------------------------------------------------- + This is an XML-RPC XML call processor, as called by the HTTP request + handler of the libxmlrpc_server_abyss C library. + + 'callXml'/'callXmlLen' is the XML text of a supposed XML-RPC call. + We execute the RPC and return the XML text of the XML-RPC response + as *responseXmlPP. + + 'arg' carries the information that tells us how to do that; e.g. + what XML-RPC methods are defined. +-----------------------------------------------------------------------------*/ + const registry * const registryP(static_cast(arg)); + + try { + string const call(callXml, callXmlLen); + callInfo_abyss const callInfo(abyssSessionP); + + string response; + + registryP->processCall(call, &callInfo, &response); + + xmlrpc_mem_block * responseMbP; + + responseMbP = XMLRPC_MEMBLOCK_NEW(char, envP, response.length()); + + if (!envP->fault_occurred) { + XMLRPC_MEMBLOCK_APPEND(char, envP, responseMbP, + response.c_str(), response.length()); + + *responseXmlPP = responseMbP; + } + } catch (exception const& e) { + xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, e.what()); + } +} + + + +static void +setHandlers(TServer * const serverP, + string const& uriPath, + registry const& registry) { + + xmlrpc_server_abyss_set_handler2( + serverP, uriPath.c_str(), + processXmlrpcCall2, + const_cast(®istry), + registry.maxStackSize(), + false); + + xmlrpc_server_abyss_set_default_handler(serverP); +} + + + +void +server_abyss_set_handlers(TServer * const serverP, + registry const& registry, + string const& uriPath) { + + setHandlers(serverP, uriPath, registry); +} + + + +void +server_abyss_set_handlers(TServer * const serverP, + const registry * const registryP, + string const& uriPath) { + + setHandlers(serverP, uriPath, *registryP); +} + + + +void +server_abyss_set_handlers(TServer * const serverP, + registryPtr const registryPtr, + string const& uriPath) { + + setHandlers(serverP, uriPath, *registryPtr.get()); +} + + + +} // namespace diff --git a/trunk/src/cpp/server_cgi.cpp b/trunk/src/cpp/server_cgi.cpp new file mode 100644 index 000000000..7408cbaf4 --- /dev/null +++ b/trunk/src/cpp/server_cgi.cpp @@ -0,0 +1,359 @@ +/*============================================================================= + server_cgi +=============================================================================== + + This is the definition of the xmlrpc_c::server_cgi class. An object of + this class is the guts of a CGI-based XML-RPC server. It runs inside + a CGI script and gets the XML-RPC call from and delivers the XML-RPC + response to the CGI environment. + + By Bryan Henderson 08.09.17. + + Contributed to the public domain by its author. +=============================================================================*/ + +#include "xmlrpc_config.h" +#if MSVCRT +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#include +#include +#endif +#include // for getenv +#include +#include + +using namespace std; + +#include "xmlrpc-c/girerr.hpp" +using girerr::throwf; +#include "xmlrpc-c/server_cgi.hpp" + + + +namespace { + +class httpInfo { + +public: + string requestMethod; + bool contentTypePresent; + string contentType; + unsigned int contentLength; + bool contentLengthPresent; + bool authCookiePresent; + string authCookie; + + httpInfo() { + + const char * const requestMethodC = getenv("REQUEST_METHOD"); + const char * const contentTypeC = getenv("CONTENT_TYPE"); + const char * const contentLengthC = getenv("CONTENT_LENGTH"); + const char * const authCookieC = getenv("HTTP_COOKIE_AUTH"); + + if (requestMethodC) + this->requestMethod = string(requestMethodC); + else + throwf("Invalid CGI environment; environment variable " + "REQUEST_METHOD is not set"); + + if (contentTypeC) { + this->contentTypePresent = true; + this->contentType = string(contentTypeC); + } else + this->contentTypePresent = false; + + if (contentLengthC) { + this->contentLengthPresent = true; + + int const lengthAtoi(atoi(string(contentLengthC).c_str())); + + if (lengthAtoi < 0) + throwf("Content-length HTTP header value is negative"); + else if (lengthAtoi == 0) + throwf("Content-length HTTP header value is zero"); + else + this->contentLength = lengthAtoi; + } else + this->contentLengthPresent = false; + + if (authCookieC) { + this->authCookie = string(authCookieC); + this->authCookiePresent = true; + } else + this->authCookiePresent = false; + } +}; + +} // unnamed namespace + + + +namespace { + +class HttpError { + +public: + + int const code; + string const msg; + + HttpError(int const code, + string const& msg) : + code(code), + msg(msg) + {} +}; + + +} // unnamed namespace + + + +namespace xmlrpc_c { + +struct serverCgi_impl { + // 'registryP' is what we actually use; 'registryHolder' just holds a + // reference to 'registryP' so the registry doesn't disappear while + // this server exists. But note that if the creator doesn't supply + // a registryPtr, 'registryHolder' is just a placeholder variable and + // the creator is responsible for making sure the registry doesn't + // go anywhere while the server exists. + + registryPtr registryHolder; + const registry * registryP; + + serverCgi_impl(serverCgi::constrOpt const& opt); + + void + establishRegistry(serverCgi::constrOpt const& opt); + + void + tryToProcessCall(); +}; + + + +void +serverCgi_impl::establishRegistry(serverCgi::constrOpt const& opt) { + + if (!opt.present.registryP && !opt.present.registryPtr) + throwf("You must specify the 'registryP' or 'registryPtr' option"); + else if (opt.present.registryP && opt.present.registryPtr) + throwf("You may not specify both the 'registryP' and " + "the 'registryPtr' options"); + else { + if (opt.present.registryP) + this->registryP = opt.value.registryP; + else { + this->registryHolder = opt.value.registryPtr; + this->registryP = opt.value.registryPtr.get(); + } + } +} + + + +serverCgi_impl::serverCgi_impl(serverCgi::constrOpt const& opt) { + this->establishRegistry(opt); +} + + + +serverCgi::constrOpt::constrOpt() { + + present.registryP = false; + present.registryPtr = false; +} + + + +#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ +serverCgi::constrOpt & \ +serverCgi::constrOpt::OPTION_NAME(TYPE const& arg) { \ + this->value.OPTION_NAME = arg; \ + this->present.OPTION_NAME = true; \ + return *this; \ +} + +DEFINE_OPTION_SETTER(registryP, const registry *); +DEFINE_OPTION_SETTER(registryPtr, xmlrpc_c::registryPtr); + +#undef DEFINE_OPTION_SETTER + + + +serverCgi::serverCgi(constrOpt const& opt) { + + this->implP = new serverCgi_impl(opt); +} + + + +serverCgi::~serverCgi() { + + delete(this->implP); +} + + + +#if MSVCRT +#define FILEVAR fileP +#else +#define FILEVAR +#endif + +static void +setModeBinary(FILE * const FILEVAR) { + +#if MSVCRT + /* Fix from Jeff Stewart: NT opens stdin and stdout in text mode + by default, badly confusing our length calculations. So we need + to set the file handle to binary. + */ + _setmode(_fileno(FILEVAR), _O_BINARY); +#endif +} + + + +static string +getHttpBody(FILE * const fileP, + size_t const length) { + + setModeBinary(fileP); + char * const buffer(new char[length]); + auto_ptr p(buffer); // To make it go away when we leave + + size_t count; + + count = fread(buffer, sizeof(buffer[0]), length, fileP); + if (count < length) + throwf("Expected %lu bytes, received %lu", + (unsigned long) length, (unsigned long) count); + + return string(buffer, length); +} + + + +static void +writeNormalHttpResp(FILE * const fileP, + bool const sendCookie, + string const& authCookie, + string const& httpBody) { + + setModeBinary(fileP); + + // HTTP headers + + fprintf(fileP, "Status: 200 OK\n"); + + if (sendCookie) + fprintf(fileP, "Set-Cookie: auth=%s\n", authCookie.c_str()); + + fprintf(fileP, "Content-type: text/xml; charset=\"utf-8\"\n"); + fprintf(fileP, "Content-length: %u\n", (unsigned)httpBody.size()); + fprintf(fileP, "\n"); + + // HTTP body + + fwrite(httpBody.c_str(), sizeof(char), httpBody.size(), fileP); +} + + + +void +processCall2(const registry * const registryP, + FILE * const callFileP, + unsigned int const callSize, + bool const sendCookie, + string const& authCookie, + FILE * const respFileP) { + + if (callSize > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) + throw(xmlrpc_c::fault(string("XML-RPC call is too large"), + fault::CODE_LIMIT_EXCEEDED)); + else { + string const callXml(getHttpBody(callFileP, callSize)); + + string responseXml; + + try { + registryP->processCall(callXml, &responseXml); + } catch (exception const& e) { + throw(HttpError(500, e.what())); + } + + writeNormalHttpResp(respFileP, sendCookie, authCookie, responseXml); + } +} + + + + +static void +sendHttpErrorResp(FILE * const fileP, + HttpError const& e) { + + setModeBinary(fileP); + + // HTTP headers + + fprintf(fileP, "Status: %d %s\n", e.code, e.msg.c_str()); + fprintf(fileP, "Content-type: text/html\n"); + fprintf(fileP, "\n"); + + // HTTP body: HTML error message + + fprintf(fileP, "%d %s\n", e.code, e.msg.c_str()); + fprintf(fileP, "

%d %s

\n", e.code, e.msg.c_str()); + fprintf(fileP, "

The Xmlrpc-c CGI server was unable to process " + "your request. It could not process it even enough to generate " + "an XML-RPC fault response.

\n"); +} + + + +void +serverCgi_impl::tryToProcessCall() { + + httpInfo httpInfo; + + if (httpInfo.requestMethod != string("POST")) + throw(HttpError(405, "Method must be POST")); + + if (!httpInfo.contentTypePresent) + throw(HttpError(400, "Must have content-type header")); + + if (httpInfo.contentType != string("text/xml")) + throw(HttpError(400, string("ContentType must be 'text/xml', not '") + + httpInfo.contentType + string("'"))); + + if (!httpInfo.contentLengthPresent) + throw(HttpError(411, "Content-length required")); + + processCall2(this->registryP, stdin, httpInfo.contentLength, + httpInfo.authCookiePresent, httpInfo.authCookie, stdout); +} + + + +void +serverCgi::processCall() { +/*---------------------------------------------------------------------------- + Get the XML-RPC call from Standard Input and environment variables, + parse it, find the right method, call it, prepare an XML-RPC + response with the result, and write it to Standard Output. +-----------------------------------------------------------------------------*/ + try { + this->implP->tryToProcessCall(); + } catch (HttpError const& e) { + sendHttpErrorResp(stdout, e); + } +} + + + +} // namespace diff --git a/trunk/src/cpp/server_pstream.cpp b/trunk/src/cpp/server_pstream.cpp new file mode 100644 index 000000000..d66cb6209 --- /dev/null +++ b/trunk/src/cpp/server_pstream.cpp @@ -0,0 +1,278 @@ +/*============================================================================= + server_pstream +=============================================================================== + + RPC server based on a very simple byte stream and XML-RPC XML + (But this is not an XML-RPC server because it doesn't use HTTP). + + The protocol we use is the "packet socket" protocol, which + is an Xmlrpc-c invention. It is an almost trivial representation of + a sequence of packets on a byte stream. + + By Bryan Henderson 09.03.22 + + Contributed to the public domain by its author. +=============================================================================*/ + +#include "xmlrpc_config.h" +#if MSVCRT +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#include +typedef int socklen_t; +#else +#include +#endif +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::throwf; + +#include "xmlrpc-c/server_pstream.hpp" + +using namespace std; + +namespace xmlrpc_c { + + +struct serverPstream::constrOpt_impl { + + constrOpt_impl(); + + struct value { + xmlrpc_c::registryPtr registryPtr; + const xmlrpc_c::registry * registryP; + XMLRPC_SOCKET socketFd; + } value; + struct { + bool registryPtr; + bool registryP; + bool socketFd; + } present; +}; + + + +serverPstream::constrOpt_impl::constrOpt_impl() { + + this->present.socketFd = false; + this->present.registryP = false; + this->present.registryPtr = false; +} + + + +serverPstream::constrOpt::constrOpt() { + + this->implP = new serverPstream::constrOpt_impl(); +} + + + +serverPstream::constrOpt::~constrOpt() { + + delete(this->implP); +} + + + +#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ +serverPstream::constrOpt & \ +serverPstream::constrOpt::OPTION_NAME(TYPE const& arg) { \ + this->implP->value.OPTION_NAME = arg; \ + this->implP->present.OPTION_NAME = true; \ + return *this; \ +} + +DEFINE_OPTION_SETTER(socketFd, XMLRPC_SOCKET); +DEFINE_OPTION_SETTER(registryP, const registry *); +DEFINE_OPTION_SETTER(registryPtr, xmlrpc_c::registryPtr); + +#undef DEFINE_OPTION_SETTER + + + +struct serverPstream_impl { + + serverPstream_impl(serverPstream::constrOpt_impl const& opt); + + ~serverPstream_impl(); + + void + establishRegistry(serverPstream::constrOpt_impl const& opt); + + // 'registryP' is what we actually use; 'registryHolder' just holds a + // reference to 'registryP' so the registry doesn't disappear while + // this server exists. But note that if the creator doesn't supply + // a registryPtr, 'registryHolder' is just a placeholder variable and + // the creator is responsible for making sure the registry doesn't + // go anywhere while the server exists. + + registryPtr registryHolder; + const registry * registryP; + + XMLRPC_SOCKET listenSocketFd; + // The socket on which we accept connections from clients. This comes + // to us from the creator, already bound and in listen mode. That + // way, this object doesn't have to know anything about socket + // addresses or listen parameters such as the maximum connection + // backlog size. + + bool termRequested; + // User has requested that the run method return ASAP; i.e. that + // the server cease servicing RPCs. +}; + + + +serverPstream_impl::serverPstream_impl( + serverPstream::constrOpt_impl const& opt) { + + this->establishRegistry(opt); + + if (!opt.present.socketFd) + throwf("You must provide a 'socketFd' constructor option."); + + this->listenSocketFd = opt.value.socketFd; + + this->termRequested = false; +} + + + +serverPstream_impl::~serverPstream_impl() { + +} + + + +void +serverPstream_impl::establishRegistry( + serverPstream::constrOpt_impl const& opt) { + + if (!opt.present.registryP && !opt.present.registryPtr) + throwf("You must specify the 'registryP' or 'registryPtr' option"); + else if (opt.present.registryP && opt.present.registryPtr) + throwf("You may not specify both the 'registryP' and " + "the 'registryPtr' options"); + else { + if (opt.present.registryP) + this->registryP = opt.value.registryP; + else { + this->registryHolder = opt.value.registryPtr; + this->registryP = opt.value.registryPtr.get(); + } + } +} + + +/*----------------------------------------------------------------------------- + serverPstream::shutdown is a derived class of registry::shutdown. You give + it to the registry object to allow XML-RPC method 'system.shutdown' to +-----------------------------------------------------------------------------*/ + +serverPstream::shutdown::shutdown(serverPstream * const serverPstreamP) : + serverPstreamP(serverPstreamP) {} + + + +serverPstream::shutdown::~shutdown() {} + + + +void +serverPstream::shutdown::doit(string const&, + void * const) const { + + this->serverPstreamP->terminate(); +} +/*---------------------------------------------------------------------------*/ + + + +serverPstream::serverPstream(constrOpt const& opt) { + + this->implP = new serverPstream_impl(*opt.implP); +} + + + +serverPstream::~serverPstream() { + + delete(this->implP); +} + + + +void +serverPstream::runSerial(volatile const int * const interruptP) { + + while (!this->implP->termRequested && !*interruptP) { + struct sockaddr peerAddr; + socklen_t size = sizeof(peerAddr); + int rc; + + rc = accept(this->implP->listenSocketFd, &peerAddr, &size); + + if (!*interruptP) { + if (rc < 0) + if (errno == EINTR) { + // system call was interrupted, but user doesn't want + // to interrupt the server, so just keep trying + } else + throwf("Failed to accept a connection " + "on the listening socket. accept() failed " + "with errno %d (%s)", errno, strerror(errno)); + else { + int const acceptedFd = rc; + + serverPstreamConn connectionServer( + xmlrpc_c::serverPstreamConn::constrOpt() + .socketFd(acceptedFd) + .registryP(this->implP->registryP)); + + callInfo_serverPstream callInfo(this, peerAddr, size); + + connectionServer.run(&callInfo, interruptP); + } + } + } +} + + + +void +serverPstream::runSerial() { + + int const interrupt(0); // Never interrupt + + this->runSerial(&interrupt); +} + + + +void +serverPstream::terminate() { + + this->implP->termRequested = true; +} + + + +callInfo_serverPstream::callInfo_serverPstream( + serverPstream * const serverP, + struct sockaddr const clientAddr, + socklen_t const clientAddrSize) : + + serverP (serverP), + clientAddr (clientAddr), + clientAddrSize (clientAddrSize) + +{} + + + +} // namespace diff --git a/trunk/src/cpp/server_pstream_conn.cpp b/trunk/src/cpp/server_pstream_conn.cpp new file mode 100644 index 000000000..3598164b9 --- /dev/null +++ b/trunk/src/cpp/server_pstream_conn.cpp @@ -0,0 +1,364 @@ +/*============================================================================= + server_pstream +=============================================================================== + + RPC server based on a very simple byte stream and XML-RPC XML + (But this is not an XML-RPC server because it doesn't use HTTP). + + The protocol we use is the "packet socket" protocol, which + is an Xmlrpc-c invention. It is an almost trivial representation of + a sequence of packets on a byte stream. + + You can create a pstream server from any file descriptor from which + you can read and write a bidirectional character stream. Typically, + it's a TCP socket. Such a server talks to one client its entire life. + + Some day, we'll also have a version that you create from a "listening" + socket, which can talk to multiple clients serially (a client connects, + does some RPCs, and disconnects). + + By Bryan Henderson 07.05.12. + + Contributed to the public domain by its author. +=============================================================================*/ + +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::throwf; +#include "xmlrpc-c/packetsocket.hpp" + +#include "xmlrpc-c/server_pstream.hpp" + +using namespace std; + +namespace xmlrpc_c { + + +struct serverPstreamConn::constrOpt_impl { + + constrOpt_impl(); + + struct value { + xmlrpc_c::registryPtr registryPtr; + const xmlrpc_c::registry * registryP; + XMLRPC_SOCKET socketFd; + } value; + struct { + bool registryPtr; + bool registryP; + bool socketFd; + } present; +}; + + + +serverPstreamConn::constrOpt_impl::constrOpt_impl() { + + this->present.socketFd = false; + this->present.registryP = false; + this->present.registryPtr = false; +} + + + +serverPstreamConn::constrOpt::constrOpt() { + + this->implP = new constrOpt_impl(); +} + + + +serverPstreamConn::constrOpt::~constrOpt() { + + delete(this->implP); +} + + + +#define DEFINE_OPTION_SETTER(OPTION_NAME, TYPE) \ +serverPstreamConn::constrOpt & \ +serverPstreamConn::constrOpt::OPTION_NAME(TYPE const& arg) { \ + this->implP->value.OPTION_NAME = arg; \ + this->implP->present.OPTION_NAME = true; \ + return *this; \ +} + +DEFINE_OPTION_SETTER(socketFd, XMLRPC_SOCKET); +DEFINE_OPTION_SETTER(registryP, const registry *); +DEFINE_OPTION_SETTER(registryPtr, xmlrpc_c::registryPtr); + +#undef DEFINE_OPTION_SETTER + + + +struct serverPstreamConn_impl { + + serverPstreamConn_impl(serverPstreamConn::constrOpt_impl const& opt); + + ~serverPstreamConn_impl(); + + void + establishRegistry(serverPstreamConn::constrOpt_impl const& opt); + + void + establishPacketSocket(serverPstreamConn::constrOpt_impl const& opt); + + void + processRecdPacket(packetPtr const callPacketP, + callInfo * const callInfoP); + + // 'registryP' is what we actually use; 'registryHolder' just holds a + // reference to 'registryP' so the registry doesn't disappear while + // this server exists. But note that if the creator doesn't supply + // a registryPtr, 'registryHolder' is just a placeholder variable and + // the creator is responsible for making sure the registry doesn't + // go anywhere while the server exists. + + registryPtr registryHolder; + const registry * registryP; + + packetSocket * packetSocketP; + // The packet socket over which we received RPCs. + // This is permanently connected to our fixed client. +}; + + + +serverPstreamConn_impl::serverPstreamConn_impl( + serverPstreamConn::constrOpt_impl const& opt) { + + this->establishRegistry(opt); + + this->establishPacketSocket(opt); +} + + + +serverPstreamConn_impl::~serverPstreamConn_impl() { + + delete(this->packetSocketP); +} + + + +void +serverPstreamConn_impl::establishRegistry( + serverPstreamConn::constrOpt_impl const& opt) { + + if (!opt.present.registryP && !opt.present.registryPtr) + throwf("You must specify the 'registryP' or 'registryPtr' option"); + else if (opt.present.registryP && opt.present.registryPtr) + throwf("You may not specify both the 'registryP' and " + "the 'registryPtr' options"); + else { + if (opt.present.registryP) + this->registryP = opt.value.registryP; + else { + this->registryHolder = opt.value.registryPtr; + this->registryP = opt.value.registryPtr.get(); + } + } +} + + + +void +serverPstreamConn_impl::establishPacketSocket( + serverPstreamConn::constrOpt_impl const& opt) { + + if (!opt.present.socketFd) + throwf("You must provide a 'socketFd' constructor option."); + + auto_ptr packetSocketAP; + + try { + auto_ptr p(new packetSocket(opt.value.socketFd)); + packetSocketAP = p; + } catch (exception const& e) { + throwf("Unable to create packet socket out of file descriptor %d. %s", + opt.value.socketFd, e.what()); + } + this->packetSocketP = packetSocketAP.get(); + packetSocketAP.release(); +} + + + +serverPstreamConn::serverPstreamConn(constrOpt const& opt) { + + this->implP = new serverPstreamConn_impl(*opt.implP); +} + + + +serverPstreamConn::~serverPstreamConn() { + + delete(this->implP); +} + + + +static void +processCall(const registry * const registryP, + packetPtr const& callPacketP, + callInfo * const callInfoP, + packetPtr * const responsePacketPP) { + + string const callXml(reinterpret_cast(callPacketP->getBytes()), + callPacketP->getLength()); + + string responseXml; + + registryP->processCall(callXml, callInfoP, &responseXml); + + *responsePacketPP = packetPtr(new packet(responseXml.c_str(), + responseXml.length())); +} + + + +void +serverPstreamConn_impl::processRecdPacket(packetPtr const callPacketP, + callInfo * const callInfoP) { + + packetPtr responsePacketP; + try { + processCall(this->registryP, callPacketP, callInfoP, &responsePacketP); + } catch (exception const& e) { + throwf("Error executing received packet as an XML-RPC RPC. %s", + e.what()); + } + try { + this->packetSocketP->writeWait(responsePacketP); + } catch (exception const& e) { + throwf("Failed to write the response to the packet socket. %s", + e.what()); + } +} + + + +void +serverPstreamConn::runOnce(callInfo * const callInfoP, + volatile const int * const interruptP, + bool * const eofP) { +/*---------------------------------------------------------------------------- + Get and execute one RPC from the client. + + Unless *interruptP gets set nonzero first. +-----------------------------------------------------------------------------*/ + bool gotPacket; + packetPtr callPacketP; + + try { + this->implP->packetSocketP->readWait(interruptP, eofP, &gotPacket, + &callPacketP); + } catch (exception const& e) { + throwf("Error reading a packet from the packet socket. %s", + e.what()); + } + if (gotPacket) + this->implP->processRecdPacket(callPacketP, callInfoP); +} + + + +void +serverPstreamConn::runOnce(volatile const int * const interruptP, + bool * const eofP) { + + this->runOnce(NULL, interruptP, eofP); +} + + + +void +serverPstreamConn::runOnce(bool * const eofP) { +/*---------------------------------------------------------------------------- + Get and execute one RPC from the client. +-----------------------------------------------------------------------------*/ + int const interrupt(0); // Never interrupt + + this->runOnce(&interrupt, eofP); +} + + + +void +serverPstreamConn::runOnceNoWait(callInfo * const callInfoP, + bool * const eofP, + bool * const didOneP) { +/*---------------------------------------------------------------------------- + Get and execute one RPC from the client, unless none has been + received yet. Return as *didOneP whether or not one has been + received. Unless didOneP is NULL. +-----------------------------------------------------------------------------*/ + bool gotPacket; + packetPtr callPacketP; + + try { + this->implP->packetSocketP->read(eofP, &gotPacket, &callPacketP); + } catch (exception const& e) { + throwf("Error reading a packet from the packet socket. %s", + e.what()); + } + if (gotPacket) + this->implP->processRecdPacket(callPacketP, callInfoP); + + if (didOneP) + *didOneP = gotPacket; +} + + + +void +serverPstreamConn::runOnceNoWait(bool * const eofP, + bool * const didOneP) { + + this->runOnceNoWait(NULL, eofP, didOneP); +} + + + +void +serverPstreamConn::runOnceNoWait(bool * const eofP) { +/*---------------------------------------------------------------------------- + Get and execute one RPC from the client, unless none has been + received yet. +-----------------------------------------------------------------------------*/ + this->runOnceNoWait(eofP, NULL); +} + + + +void +serverPstreamConn::run(callInfo * const callInfoP, + volatile const int * const interruptP) { + + for (bool clientHasDisconnected = false; + !clientHasDisconnected && !*interruptP;) + this->runOnce(callInfoP, interruptP, &clientHasDisconnected); +} + + + +void +serverPstreamConn::run(volatile const int * const interruptP) { + + this->run(NULL, interruptP); +} + + + +void +serverPstreamConn::run() { + + int const interrupt(0); // Never interrupt + + this->run(&interrupt); +} + + + +} // namespace diff --git a/trunk/src/cpp/value.cpp b/trunk/src/cpp/value.cpp new file mode 100644 index 000000000..b319430ea --- /dev/null +++ b/trunk/src/cpp/value.cpp @@ -0,0 +1,1140 @@ +/***************************************************************************** + value.cpp +****************************************************************************** + This module provides services for dealing with XML-RPC values. Each + type of XML-RPC value is a C++ class. An object represents a + particular XML-RPC value. + + Everything is based on the C services in libxmlrpc. + + We could make things more efficient by using the internal interfaces + via xmlrpc_int.h. We could make them even more efficient by dumping + libxmlrpc altogether for some or all of these services. + + An xmlrpc_c::value object is really just a handle for a C xmlrpc_value + object. You're not supposed to make a pointer to an xmlrpc_c::value + object, but rather copy the object around. + + Because the C xmlrpc_value object does reference counting, it + disappears automatically when the last handle does. To go pure C++, + we'd have to have a C++ object for the value itself and a separate + handle object, like Boost's shared_ptr<>. + + The C++ is designed so that the user never sees the C interface at + all. Unfortunately, the user can see it if he wants because some + class members had to be declared public so that other components of + the library could see them, but the user is not supposed to access + those members. +*****************************************************************************/ + +#include +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/env_wrap.hpp" + +#include "xmlrpc-c/base.hpp" + +using namespace std; +using namespace xmlrpc_c; + +namespace { + +void +throwIfError(env_wrap const& env) { + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +class cDatetimeValueWrapper { +public: + xmlrpc_value * valueP; + + cDatetimeValueWrapper(xmlrpc_datetime const cppvalue) { + env_wrap env; + + this->valueP = xmlrpc_datetime_new(&env.env_c, cppvalue); + throwIfError(env); + } + cDatetimeValueWrapper(time_t const cppvalue) { + env_wrap env; + + this->valueP = xmlrpc_datetime_new_sec(&env.env_c, cppvalue); + throwIfError(env); + } +#if XMLRPC_HAVE_TIMEVAL + cDatetimeValueWrapper(struct timeval const cppvalue) { + env_wrap env; + + this->valueP = xmlrpc_datetime_new_timeval(&env.env_c, cppvalue); + throwIfError(env); + } +#endif +#if XMLRPC_HAVE_TIMESPEC + cDatetimeValueWrapper(struct timespec const cppvalue) { + env_wrap env; + + this->valueP = xmlrpc_datetime_new_timespec(&env.env_c, cppvalue); + throwIfError(env); + } +#endif + ~cDatetimeValueWrapper() { + xmlrpc_DECREF(this->valueP); + } +}; + + +class cStringWrapper { +public: + const char * str; + size_t length; + cStringWrapper(xmlrpc_value * valueP) { + env_wrap env; + + xmlrpc_read_string_lp(&env.env_c, valueP, &length, &str); + throwIfError(env); + } + ~cStringWrapper() { + free((char*)str); + } +}; + + + +} // namespace + + + +namespace xmlrpc_c { + +value::value() { // default constructor + this->cValueP = NULL; +} + + + +value::value(xmlrpc_value * const valueP) { + + this->instantiate(valueP); +} + + + +value::value(xmlrpc_c::value const& value) { // copy constructor + this->cValueP = value.cValue(); +} + + + +xmlrpc_c::value& +value::operator=(xmlrpc_c::value const& value) { + + if (this->cValueP != NULL) + throw(error("Assigning to already instantiated xmlrpc_c::value")); + + this->cValueP = value.cValue(); + return *this; // The result of the (a = b) expression +} + + + +value::~value() { + if (this->cValueP) { + xmlrpc_DECREF(this->cValueP); + } +} + + + +bool +value::isInstantiated() const { +/*---------------------------------------------------------------------------- + Return whether the object is actually a value, as opposed to a placeholder + variable waiting to be assigned a value. +-----------------------------------------------------------------------------*/ + return (this->cValueP != NULL); +} + + + +void +value::validateInstantiated() const { // private +/*---------------------------------------------------------------------------- + Throw an exception if the object is just a placeholder, rather than an + actual XML-RPC value. +-----------------------------------------------------------------------------*/ + if (!this->cValueP) + throw(error("Reference to xmlrpc_c::value that has not been " + "instantiated. (xmlrpc_c::value::isInstantiated may be " + "useful in diagnosing)")); +} + + + +void +value::instantiate(xmlrpc_value * const valueP) { + + xmlrpc_INCREF(valueP); + this->cValueP = valueP; +} + + + +xmlrpc_value * +value::cValue() const { + + if (this->cValueP) { + xmlrpc_INCREF(this->cValueP); // For Caller + } + return this->cValueP; +} + + + +void +value::appendToCArray(xmlrpc_value * const arrayP) const { +/*---------------------------------------------------------------------------- + Append this value to the C array 'arrayP'. +----------------------------------------------------------------------------*/ + this->validateInstantiated(); + + env_wrap env; + + xmlrpc_array_append_item(&env.env_c, arrayP, this->cValueP); + + throwIfError(env); +} + + + +void +value::addToCStruct(xmlrpc_value * const structP, + string const key) const { +/*---------------------------------------------------------------------------- + Add this value to the C array 'arrayP' with key 'key'. +----------------------------------------------------------------------------*/ + this->validateInstantiated(); + + env_wrap env; + + xmlrpc_struct_set_value_n(&env.env_c, structP, + key.c_str(), key.length(), + this->cValueP); + + throwIfError(env); +} + + + +value::type_t +value::type() const { + + this->validateInstantiated(); + + /* You'd think we could just cast from xmlrpc_type to + value::type_t, but Gcc warns if we do that. So we have to do this + even messier union nonsense. + */ + union { + xmlrpc_type x; + value::type_t y; + } u; + + u.x = xmlrpc_value_type(this->cValueP); + + return u.y; +} + + + +ostream& operator<<(ostream& out, value::type_t const& type) { + + string typeName; + + return out << string(xmlrpc_type_name((xmlrpc_type)type)); +} + + + +value_int::value_int(int const cppvalue) { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper(int const cppvalue) { + env_wrap env; + + this->valueP = xmlrpc_int_new(&env.env_c, cppvalue); + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(this->valueP); + } + }; + + cWrapper wrapper(cppvalue); + + this->instantiate(wrapper.valueP); +} + + + +value_int::value_int(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_INT) + throw(error("Not integer type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +value_int::operator int() const { + + this->validateInstantiated(); + + int retval; + env_wrap env; + + xmlrpc_read_int(&env.env_c, this->cValueP, &retval); + throwIfError(env); + + return retval; +} + + + +int +value_int::cvalue() const { + + return static_cast(*this); +} + + + +value_double::value_double(double const cppvalue) { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper(double const cppvalue) { + env_wrap env; + + this->valueP = xmlrpc_double_new(&env.env_c, cppvalue); + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(this->valueP); + } + }; + + this->instantiate(cWrapper(cppvalue).valueP); +} + + + +value_double::value_double(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_DOUBLE) + throw(error("Not double type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +value_double::operator double() const { + + this->validateInstantiated(); + + double retval; + + env_wrap env; + + xmlrpc_read_double(&env.env_c, this->cValueP, &retval); + throwIfError(env); + + return retval; +} + + + +double +value_double::cvalue() const { + + return static_cast(*this); +} + + + +value_boolean::value_boolean(bool const cppvalue) { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper(xmlrpc_bool const cppvalue) { + env_wrap env; + + this->valueP = xmlrpc_bool_new(&env.env_c, cppvalue); + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(this->valueP); + } + }; + + cWrapper wrapper(cppvalue); + + this->instantiate(wrapper.valueP); +} + + + +value_boolean::value_boolean(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_BOOLEAN) + throw(error("Not boolean type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +value_boolean::operator bool() const { + + this->validateInstantiated(); + + xmlrpc_bool retval; + + env_wrap env; + + xmlrpc_read_bool(&env.env_c, this->cValueP, &retval); + throwIfError(env); + + return (retval != false); +} + + + +bool +value_boolean::cvalue() const { + + return static_cast(*this); +} + + + +value_datetime::value_datetime(string const cppvalue) { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper(string const cppvalue) { + env_wrap env; + + this->valueP = xmlrpc_datetime_new_str(&env.env_c, + cppvalue.c_str()); + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(this->valueP); + } + }; + + cWrapper wrapper(cppvalue); + + this->instantiate(wrapper.valueP); +} + + + +value_datetime::value_datetime(xmlrpc_datetime const cppvalue) { + + cDatetimeValueWrapper wrapper(cppvalue); + + this->instantiate(wrapper.valueP); +} + + + +value_datetime::value_datetime(time_t const cppvalue) { + + cDatetimeValueWrapper wrapper(cppvalue); + + this->instantiate(wrapper.valueP); +} + + + +#if XMLRPC_HAVE_TIMEVAL +value_datetime::value_datetime(struct timeval const& cppvalue) { + + cDatetimeValueWrapper wrapper(cppvalue); + + this->instantiate(wrapper.valueP); +} +#endif + + + +#if XMLRPC_HAVE_TIMESPEC +value_datetime::value_datetime(struct timespec const& cppvalue) { + + cDatetimeValueWrapper wrapper(cppvalue); + + this->instantiate(wrapper.valueP); +} +#endif + + + +value_datetime::value_datetime(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_DATETIME) + throw(error("Not datetime type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +value_datetime::operator xmlrpc_datetime() const { + + this->validateInstantiated(); + + xmlrpc_datetime retval; + env_wrap env; + + xmlrpc_read_datetime(&env.env_c, this->cValueP, &retval); + throwIfError(env); + + return retval; +} + + + +value_datetime::operator time_t() const { + + this->validateInstantiated(); + + time_t retval; + env_wrap env; + + xmlrpc_read_datetime_sec(&env.env_c, this->cValueP, &retval); + throwIfError(env); + + return retval; +} + + + +#if XMLRPC_HAVE_TIMEVAL + +value_datetime::operator timeval() const { + + this->validateInstantiated(); + + struct timeval retval; + env_wrap env; + + xmlrpc_read_datetime_timeval(&env.env_c, this->cValueP, &retval); + throwIfError(env); + + return retval; +} +#endif + + + +#if XMLRPC_HAVE_TIMESPEC + +value_datetime::operator timespec() const { + + this->validateInstantiated(); + + struct timespec retval; + env_wrap env; + + xmlrpc_read_datetime_timespec(&env.env_c, this->cValueP, &retval); + throwIfError(env); + + return retval; +} +#endif + + + +time_t +value_datetime::cvalue() const { + + return static_cast(*this); +} + + + +string +value_datetime::iso8601Value() const { + + string retval; + + this->validateInstantiated(); + + const char * iso8601; + env_wrap env; + + xmlrpc_read_datetime_8601(&env.env_c, this->cValueP, &iso8601); + throwIfError(env); + + retval = iso8601; + + xmlrpc_strfree(iso8601); + + return retval; +} + + + +class cNewStringWrapper { +public: + xmlrpc_value * valueP; + + cNewStringWrapper(string const cppvalue, + value_string::nlCode const nlCode) { + env_wrap env; + + switch (nlCode) { + case value_string::nlCode_all: + this->valueP = xmlrpc_string_new_lp(&env.env_c, + cppvalue.length(), + cppvalue.c_str()); + break; + case value_string::nlCode_lf: + this->valueP = xmlrpc_string_new_lp_cr(&env.env_c, + cppvalue.length(), + cppvalue.c_str()); + break; + default: + throw(error("Newline encoding argument to value_string " + "constructor is not one of the defined " + "enumerations of value_string::nlCode")); + } + throwIfError(env); + } + ~cNewStringWrapper() { + xmlrpc_DECREF(this->valueP); + } +}; + + + +value_string::value_string(std::string const& cppvalue, + value_string::nlCode const nlCode) { + + cNewStringWrapper wrapper(cppvalue, nlCode); + + this->instantiate(wrapper.valueP); +} + + + +value_string::value_string(std::string const& cppvalue) { + + cNewStringWrapper wrapper(cppvalue, nlCode_all); + + this->instantiate(wrapper.valueP); +} + + + +value_string::value_string(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_STRING) + throw(error("Not string type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +std::string +value_string::crlfValue() const { + + class cWrapper { + public: + const char * str; + size_t length; + cWrapper(xmlrpc_value * valueP) { + env_wrap env; + + xmlrpc_read_string_lp_crlf(&env.env_c, valueP, &length, &str); + throwIfError(env); + } + ~cWrapper() { + free((char*)str); + } + }; + + this->validateInstantiated(); + + cWrapper wrapper(this->cValueP); + + return string(wrapper.str, wrapper.length); +} + + + +void +value_string::validate() const { +/*---------------------------------------------------------------------------- + Throw an error if the value contains non-XML characters, so that if it + were serialized into a call or response, it would not be valid XML, and + therefore not proper XML-RPC. + + Note that the object must have the ability to have this property (i.e. it + is possible to construct an object that fails this validation) because of + the poor original specification of XML-RPC. Some recipients of XML-RPC + don't mind it being invalid XML. +-----------------------------------------------------------------------------*/ + env_wrap env; + + xmlrpc_string_validate(&env.env_c, this->cValueP); + + throwIfError(env); +} + + + +value_string::operator string() const { + + this->validateInstantiated(); + + cStringWrapper adapter(this->cValueP); + + return string(adapter.str, adapter.length); +} + + + +std::string +value_string::cvalue() const { + + return static_cast(*this); +} + + + +value_bytestring::value_bytestring( + vector const& cppvalue) { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper(vector const& cppvalue) { + env_wrap env; + + this->valueP = + xmlrpc_base64_new(&env.env_c, cppvalue.size(), &cppvalue[0]); + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(this->valueP); + } + }; + + cWrapper wrapper(cppvalue); + + this->instantiate(wrapper.valueP); +} + + + +value_bytestring::value_bytestring(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_BYTESTRING) + throw(error("Not byte string type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +vector +value_bytestring::vectorUcharValue() const { + + class cWrapper { + public: + const unsigned char * contents; + size_t length; + + cWrapper(xmlrpc_value * const valueP) { + env_wrap env; + + xmlrpc_read_base64(&env.env_c, valueP, &length, &contents); + throwIfError(env); + } + ~cWrapper() { + free((void*)contents); + } + }; + + this->validateInstantiated(); + + cWrapper wrapper(this->cValueP); + + return vector(&wrapper.contents[0], + &wrapper.contents[wrapper.length]); +} + + + +vector +value_bytestring::cvalue() const { + + return this->vectorUcharValue(); +} + + + +size_t +value_bytestring::length() const { + + this->validateInstantiated(); + + env_wrap env; + size_t length; + + xmlrpc_read_base64_size(&env.env_c, this->cValueP, &length); + throwIfError(env); + + return length; +} + + + +value_array::value_array(vector const& cppvalue) { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper() { + env_wrap env; + + this->valueP = xmlrpc_array_new(&env.env_c); + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(this->valueP); + } + }; + + cWrapper wrapper; + + vector::const_iterator i; + for (i = cppvalue.begin(); i != cppvalue.end(); ++i) + i->appendToCArray(wrapper.valueP); + + this->instantiate(wrapper.valueP); +} + + + +value_array::value_array(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_ARRAY) + throw(error("Not array type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +vector +value_array::vectorValueValue() const { + + this->validateInstantiated(); + + env_wrap env; + + unsigned int arraySize; + + arraySize = xmlrpc_array_size(&env.env_c, this->cValueP); + throwIfError(env); + + vector retval(arraySize); + + for (unsigned int i = 0; i < arraySize; ++i) { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper(xmlrpc_value * const arrayP, + unsigned int const index) { + env_wrap env; + + xmlrpc_array_read_item(&env.env_c, arrayP, index, &valueP); + + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(valueP); + } + }; + + cWrapper wrapper(this->cValueP, i); + + retval[i].instantiate(wrapper.valueP); + } + + return retval; +} + + + +vector +value_array::cvalue() const { + + return this->vectorValueValue(); +} + + + +size_t +value_array::size() const { + + this->validateInstantiated(); + + env_wrap env; + unsigned int arraySize; + + arraySize = xmlrpc_array_size(&env.env_c, this->cValueP); + throwIfError(env); + + return arraySize; +} + + + +value_struct::value_struct( + map const &cppvalue) { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper() { + env_wrap env; + + this->valueP = xmlrpc_struct_new(&env.env_c); + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(this->valueP); + } + }; + + cWrapper wrapper; + + map::const_iterator i; + for (i = cppvalue.begin(); i != cppvalue.end(); ++i) { + xmlrpc_c::value mapvalue(i->second); + string mapkey(i->first); + mapvalue.addToCStruct(wrapper.valueP, mapkey); + } + + this->instantiate(wrapper.valueP); +} + + + +value_struct::value_struct(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_STRUCT) + throw(error("Not struct type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +value_struct::operator map() const { + + this->validateInstantiated(); + + env_wrap env; + unsigned int structSize; + + structSize = xmlrpc_struct_size(&env.env_c, this->cValueP); + throwIfError(env); + + map retval; + + for (unsigned int i = 0; i < structSize; ++i) { + class cMemberWrapper { + public: + xmlrpc_value * keyP; + xmlrpc_value * valueP; + + cMemberWrapper(xmlrpc_value * const structP, + unsigned int const index) { + + env_wrap env; + + xmlrpc_struct_read_member(&env.env_c, structP, index, + &keyP, &valueP); + + throwIfError(env); + } + ~cMemberWrapper() { + xmlrpc_DECREF(keyP); + xmlrpc_DECREF(valueP); + } + }; + + cMemberWrapper memberWrapper(this->cValueP, i); + + cStringWrapper keyWrapper(memberWrapper.keyP); + + string const key(keyWrapper.str, keyWrapper.length); + + retval[key] = xmlrpc_c::value(memberWrapper.valueP); + } + + return retval; +} + + + +map +value_struct::cvalue() const { + + return static_cast >(*this); +} + + + +value_nil::value_nil() { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper() { + env_wrap env; + + this->valueP = xmlrpc_nil_new(&env.env_c); + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(this->valueP); + } + }; + + cWrapper wrapper; + + this->instantiate(wrapper.valueP); +} + + + +value_nil::value_nil(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_NIL) + throw(error("Not nil type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +void * +value_nil::cvalue() const { + + return NULL; +} + + + +value_i8::value_i8(xmlrpc_int64 const cppvalue) { + + class cWrapper { + public: + xmlrpc_value * valueP; + + cWrapper(xmlrpc_int64 const cppvalue) { + env_wrap env; + + this->valueP = xmlrpc_i8_new(&env.env_c, cppvalue); + throwIfError(env); + } + ~cWrapper() { + xmlrpc_DECREF(this->valueP); + } + }; + + cWrapper wrapper(cppvalue); + + this->instantiate(wrapper.valueP); +} + + + +value_i8::value_i8(xmlrpc_c::value const baseValue) { + + if (baseValue.type() != xmlrpc_c::value::TYPE_I8) + throw(error("Not 64 bit integer type. See type() method")); + else { + this->instantiate(baseValue.cValueP); + } +} + + + +value_i8::operator xmlrpc_int64() const { + + this->validateInstantiated(); + + xmlrpc_int64 retval; + env_wrap env; + + xmlrpc_read_i8(&env.env_c, this->cValueP, &retval); + throwIfError(env); + + return retval; +} + + + +xmlrpc_int64 +value_i8::cvalue() const { + + return static_cast(*this); +} + + + +} // namespace diff --git a/trunk/src/cpp/wininet.cpp b/trunk/src/cpp/wininet.cpp new file mode 100644 index 000000000..1762968f8 --- /dev/null +++ b/trunk/src/cpp/wininet.cpp @@ -0,0 +1,166 @@ +/*============================================================================= + wininet.cpp +=============================================================================== + This is the Wininet XML transport of the C++ XML-RPC client library for + Xmlrpc-c. +=============================================================================*/ + +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/girmem.hpp" +using girmem::autoObjectPtr; +using girmem::autoObject; +#include "xmlrpc-c/env_wrap.hpp" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/transport.h" +#include "xmlrpc-c/base_int.h" + +/* transport_config.h defines MUST_BUILD_WININET_CLIENT */ +#include "transport_config.h" + +#include "xmlrpc-c/client_transport.hpp" + + +using namespace std; +using namespace xmlrpc_c; + + +namespace { + +class globalConstant { +public: + globalConstant(); + ~globalConstant(); +}; + + + +globalConstant::globalConstant() { + + // Not thread safe + + xmlrpc_transport_setup setupFn; + +#if MUST_BUILD_WININET_CLIENT + setupFn = xmlrpc_wininet_transport_ops.setup_global_const; +#else + setupFn = NULL; +#endif + if (setupFn) { + env_wrap env; + + setupFn(&env.env_c); // Not thread safe + + if (env.env_c.fault_occurred) + throwf("Failed to do global initialization " + "of Wininet transport code. %s", env.env_c.fault_string); + } +} + + + +globalConstant::~globalConstant() { + + // Not thread safe + + xmlrpc_transport_teardown teardownFn; + +#if MUST_BUILD_WININET_CLIENT + teardownFn = xmlrpc_wininet_transport_ops.teardown_global_const; +#else + teardownFn = NULL; +#endif + if (teardownFn) + teardownFn(); // not thread safe +} + + + +globalConstant globalConst; + // This object is never accessed. Its whole purpose to to be born and + // to die, which it does automatically as part of C++ program + // program initialization and termination. + +} // namespace + + +namespace xmlrpc_c { + +carriageParm_wininet0::carriageParm_wininet0( + string const serverUrl + ) { + + this->instantiate(serverUrl); +} + + + +carriageParm_wininet0Ptr::carriageParm_wininet0Ptr() { + // Base class constructor will construct pointer that points to nothing +} + + + +carriageParm_wininet0Ptr::carriageParm_wininet0Ptr( + carriageParm_wininet0 * const carriageParmP) { + this->point(carriageParmP); +} + + + +carriageParm_wininet0 * +carriageParm_wininet0Ptr::operator->() const { + + autoObject * const p(this->objectP); + return dynamic_cast(p); +} + + + +#if MUST_BUILD_WININET_CLIENT + +clientXmlTransport_wininet::clientXmlTransport_wininet( + bool const allowInvalidSslCerts + ) { + + struct xmlrpc_wininet_xportparms transportParms; + + transportParms.allowInvalidSSLCerts = allowInvalidSslCerts; + + this->c_transportOpsP = &xmlrpc_wininet_transport_ops; + + env_wrap env; + + xmlrpc_wininet_transport_ops.create( + &env.env_c, 0, "", "", + &transportParms, XMLRPC_WXPSIZE(allowInvalidSSLCerts), + &this->c_transportP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + +#else // MUST_BUILD_WININET_CLIENT + +clientXmlTransport_wininet::clientXmlTransport_wininet(bool const) { + + throw(error("There is no Wininet client XML transport " + "in this XML-RPC client library")); +} + +#endif + + + +clientXmlTransport_wininet::~clientXmlTransport_wininet() { + + this->c_transportOpsP->destroy(this->c_transportP); +} + +} // namespace diff --git a/trunk/src/cpp/xml.cpp b/trunk/src/cpp/xml.cpp new file mode 100644 index 000000000..90ab2a4e9 --- /dev/null +++ b/trunk/src/cpp/xml.cpp @@ -0,0 +1,312 @@ +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/env_wrap.hpp" + +#include "xmlrpc-c/xml.hpp" + +using namespace std; +using namespace xmlrpc_c; + + +namespace { + +class cValueWrapper { +/*---------------------------------------------------------------------------- + Use an object of this class to set up to remove a reference to an + xmlrpc_value object (a C object with manual reference management) + at the end of a scope -- even if the scope ends with a throw. +-----------------------------------------------------------------------------*/ +public: + xmlrpc_value * const valueP; + cValueWrapper(xmlrpc_value * valueP) : valueP(valueP) {} + ~cValueWrapper() { xmlrpc_DECREF(valueP); } +}; + + + +class cStringWrapper { +public: + const char * const cString; + cStringWrapper(const char * const cString) : cString(cString) {} + ~cStringWrapper() { xmlrpc_strfree(cString); } +}; + + + +class memblockWrapper { + xmlrpc_mem_block * const memblockP; +public: + memblockWrapper(xmlrpc_mem_block * const memblockP) : + memblockP(memblockP) {} + + ~memblockWrapper() { + XMLRPC_MEMBLOCK_FREE(char, memblockP); + } +}; + + + +xmlrpc_value * +cArrayFromParamList(paramList const& paramList) { + + env_wrap env; + + xmlrpc_value * paramArrayP; + + paramArrayP = xmlrpc_array_new(&env.env_c); + if (!env.env_c.fault_occurred) { + for (unsigned int i = 0; + i < paramList.size() && !env.env_c.fault_occurred; + ++i) { + cValueWrapper const param(paramList[i].cValue()); + + xmlrpc_array_append_item(&env.env_c, paramArrayP, param.valueP); + } + } + if (env.env_c.fault_occurred) { + xmlrpc_DECREF(paramArrayP); + throw(error(env.env_c.fault_string)); + } + return paramArrayP; +} + + + +paramList const +paramListFromCArray(xmlrpc_value * const cArrayP) { + + paramList retval; + env_wrap env; + + unsigned int const nParam(xmlrpc_array_size(&env.env_c, cArrayP)); + + if (!env.env_c.fault_occurred) { + for (unsigned int i = 0; + i < nParam && !env.env_c.fault_occurred; + ++i) { + + xmlrpc_value * cParamP; + + xmlrpc_array_read_item(&env.env_c, cArrayP, i, &cParamP); + + if (!env.env_c.fault_occurred) { + + cValueWrapper const paramAuto(cParamP); + // Causes xmlrpc_DECREF(cParamP) at end of scope + + retval.add(cParamP); + } + } + } + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); + + return retval; +} + + + +} // namespace + + +namespace xmlrpc_c { +namespace xml { + + +void +generateCall(string const& methodName, + paramList const& paramList, + xmlrpc_dialect const dialect, + string * const callXmlP) { +/*---------------------------------------------------------------------------- + Generate the XML for an XML-RPC call, given a method name and parameter + list. + + Use dialect 'dialect' of XML-RPC. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * callXmlMP; + env_wrap env; + + callXmlMP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); + if (!env.env_c.fault_occurred) { + memblockWrapper callXmlHolder(callXmlMP); + // Makes callXmlMP get freed at end of scope + + xmlrpc_value * const paramArrayP(cArrayFromParamList(paramList)); + + xmlrpc_serialize_call2(&env.env_c, callXmlMP, methodName.c_str(), + paramArrayP, dialect); + + *callXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, callXmlMP), + XMLRPC_MEMBLOCK_SIZE(char, callXmlMP)); + + xmlrpc_DECREF(paramArrayP); + } + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +generateCall(string const& methodName, + paramList const& paramList, + string * const callXmlP) { + + generateCall(methodName, paramList, xmlrpc_dialect_i8, callXmlP); + +} + + + +void +parseCall(string const& callXml, + string * const methodNameP, + paramList * const paramListP) { + + env_wrap env; + const char * c_methodName; + xmlrpc_value * c_paramArrayP; + + xmlrpc_parse_call(&env.env_c, callXml.c_str(), callXml.size(), + &c_methodName, &c_paramArrayP); + + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); + else { + cValueWrapper const paramListAuto(c_paramArrayP); + // Causes XMLRPC_decref(c_paramArrayP) at end of scope + cStringWrapper const methodNameAuto(c_methodName); + // Causes xmlrpc_strfree(c_methodName) at end of scope + + *paramListP = paramListFromCArray(c_paramArrayP); + *methodNameP = string(c_methodName); + } +} + + + +void +generateResponse(rpcOutcome const& outcome, + xmlrpc_dialect const dialect, + string * const respXmlP) { +/*---------------------------------------------------------------------------- + Generate the XML for an XML-RPC resp, given the RPC outcome. + + Use dialect 'dialect' of XML-RPC. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * respXmlMP; + env_wrap env; + + respXmlMP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0); + if (!env.env_c.fault_occurred) { + memblockWrapper respXmlAuto(respXmlMP); + // Makes respXmlMP get freed at end of scope + + if (outcome.succeeded()) { + cValueWrapper cResult(outcome.getResult().cValue()); + + xmlrpc_serialize_response2(&env.env_c, respXmlMP, + cResult.valueP, dialect); + + *respXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, respXmlMP), + XMLRPC_MEMBLOCK_SIZE(char, respXmlMP)); + } else { + env_wrap cFault; + + xmlrpc_env_set_fault(&cFault.env_c, outcome.getFault().getCode(), + outcome.getFault().getDescription().c_str()); + + xmlrpc_serialize_fault(&env.env_c, respXmlMP, &cFault.env_c); + + *respXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, respXmlMP), + XMLRPC_MEMBLOCK_SIZE(char, respXmlMP)); + } + } + if (env.env_c.fault_occurred) + throw(error(env.env_c.fault_string)); +} + + + +void +generateResponse(rpcOutcome const& outcome, + string * const respXmlP) { + + generateResponse(outcome, xmlrpc_dialect_i8, respXmlP); + +} + + + +void +parseResponse(string const& responseXml, + rpcOutcome * const outcomeP) { +/*---------------------------------------------------------------------------- + Parse the XML for an XML-RPC response into an XML-RPC result value. +-----------------------------------------------------------------------------*/ + env_wrap env; + + xmlrpc_value * c_resultP; + int faultCode; + const char * faultString; + + xmlrpc_parse_response2(&env.env_c, responseXml.c_str(), responseXml.size(), + &c_resultP, &faultCode, &faultString); + + if (env.env_c.fault_occurred) + throwf("Unable to find XML-RPC response in what server sent back. %s", + env.env_c.fault_string); + else { + if (faultString) { + *outcomeP = + rpcOutcome(fault(faultString, + static_cast(faultCode))); + xmlrpc_strfree(faultString); + } else { + XMLRPC_ASSERT_VALUE_OK(c_resultP); + *outcomeP = rpcOutcome(value(c_resultP)); + xmlrpc_DECREF(c_resultP); + } + } +} + + + +void +parseSuccessfulResponse(string const& responseXml, + value * const resultP) { +/*---------------------------------------------------------------------------- + Same as parseResponse(), but expects the response to indicate success; + throws an error if it doesn't. +-----------------------------------------------------------------------------*/ + rpcOutcome outcome; + + parseResponse(responseXml, &outcome); + + if (!outcome.succeeded()) + throwf("RPC response indicates it failed. %s", + outcome.getFault().getDescription().c_str()); + + *resultP = outcome.getResult(); +} + + + +void +trace(string const& label, + string const& xml) { + + xmlrpc_traceXml(label.c_str(), xml.c_str(), xml.size()); + +} + + +}} // namespace diff --git a/trunk/src/double.c b/trunk/src/double.c new file mode 100644 index 000000000..58f8f0056 --- /dev/null +++ b/trunk/src/double.c @@ -0,0 +1,285 @@ +#include "xmlrpc_config.h" + +#include +#include +#include +#include + +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/util_int.h" + +#include "double.h" + +typedef struct { + char * bytes; + /* NULL means there has been a memory allocation failure. + bufferConcat() still works in this case, because we dont' want + callers to have to deal with the out-of-memory possibility; + it's just a no-op. + */ + char * next; + char * end; +} buffer; + + +static void +bufferInit(buffer * const bufferP) { + + unsigned int const initialSize = 64; + + bufferP->bytes = malloc(initialSize); + + if (bufferP->bytes) { + bufferP->next = bufferP->bytes; + bufferP->end = bufferP->bytes + initialSize; + } +} + + + +static void +bufferConcat(buffer * const bufferP, + char const newChar) { + + if (bufferP->bytes) { + if (bufferP->next >= bufferP->end) { + size_t const oldSize = bufferP->end - bufferP->bytes; + size_t const newSize = oldSize + 64; + bufferP->bytes = realloc(bufferP->bytes, newSize); + bufferP->next = bufferP->bytes + oldSize; + bufferP->end = bufferP->bytes + newSize; + } + + if (bufferP->bytes) + *(bufferP->next++) = newChar; + } +} + + + +static char +digitChar(unsigned int const digitValue) { + + assert(digitValue < 10); + + return '0' + digitValue; +} + + + +static unsigned int +leadDigit(double const arg, + double const precision) { +/*---------------------------------------------------------------------------- + Assuming 'arg' has one digit before the decimal point (which may be zero), + return that digit. + + We assume the precision of 'arg' is plus or minus 'precision', and bias our + estimation of the first digit up. We do that bias in order to bias toward + shorter decimal ciphers: It's cleaner to consider 2.9999999 to be 3 than to + consider 3 to be 2.999999. +-----------------------------------------------------------------------------*/ + return MIN(9, (unsigned int)(arg + precision)); +} + + + +static void +floatWhole(double const value, + buffer * const formattedP, + double * const formattedAmountP, + double * const precisionP) { +/*---------------------------------------------------------------------------- + Format into *formattedP the whole part of 'value', i.e. the part before the + decimal point. + + 'value' is a finite number. + + Return as *formattedAmountP the whole amount; e.g. if 'value' is 35.2, + we return *formattedAmountP = 35. + + As there is imprecision involved in our calculations, return as *precisionP + the maximum difference there may be be between 'double' and what we + formatted. +-----------------------------------------------------------------------------*/ + if (value < 1.0) { + /* No digits to add to the whole part */ + *formattedAmountP = 0; + *precisionP = DBL_EPSILON; + } else { + double nonLeastAmount; + double nonLeastPrecision; + unsigned int leastValue; + + /* Add all digits but the least significant to *formattedP */ + + floatWhole(value/10.0, formattedP, &nonLeastAmount, + &nonLeastPrecision); + + /* Add the least significant digit to *formattedP */ + + if (nonLeastPrecision > 0.1) { + /* We're down in the noise now; no point in showing any more + significant digits (and we couldn't if we wanted to, because + nonLeastPrecision * 10 might be more than 10 less than + 'value'). + */ + leastValue = 0; + } else + leastValue = leadDigit(value - nonLeastAmount * 10, + nonLeastPrecision * 10); + + bufferConcat(formattedP, digitChar(leastValue)); + + *formattedAmountP = nonLeastAmount * 10 + leastValue; + *precisionP = nonLeastPrecision * 10; + } +} + + + +static void +floatFractionPart(double const value, + double const wholePrecision, + buffer * const formattedP) { +/*---------------------------------------------------------------------------- + Serialize the part that comes after the decimal point, assuming there + is something (nonzero) before the decimal point that uses up all but + 'wholePrecision' of the available precision. +-----------------------------------------------------------------------------*/ + double precision; + double d; + + assert(value < 1.0); + + for (d = value, precision = wholePrecision; + d > precision; + precision *= 10) { + + unsigned int digitValue; + + d *= 10; + digitValue = leadDigit(d, precision); + + d -= digitValue; + + assert(d < 1.0); + + bufferConcat(formattedP, digitChar(digitValue)); + } +} + + + +static void +floatFraction(double const value, + buffer * const formattedP) { +/*---------------------------------------------------------------------------- + Serialize the part that comes after the decimal point, assuming there + is nothing before the decimal point. +-----------------------------------------------------------------------------*/ + double precision; + double d; + + assert(0.0 < value && value < 1.0); + + /* Do the leading zeroes, which eat no precision */ + + for (d = value * 10; d < 1.0; d *= 10) + bufferConcat(formattedP, '0'); + + /* Now the significant digits */ + + precision = DBL_EPSILON; + + while (d > precision) { + unsigned int const digitValue = leadDigit(d, precision); + + bufferConcat(formattedP, digitChar(digitValue)); + + d -= digitValue; + + assert(d < 1.0); + + d *= 10; + precision *= 10; + } +} + + + +static void +floatUnsigned(double const value, + buffer * const formattedP) { +/*---------------------------------------------------------------------------- + Serialize 'value', assuming it is positive, and append it to *formattedP, + without a sign. +-----------------------------------------------------------------------------*/ + assert(value >= 0.0); + + if (value >= 1.0) { + double wholePart; + double wholePrecision; + + floatWhole(value, formattedP, &wholePart, &wholePrecision); + + if (wholePrecision >= 1.0) { + /* We ran out of precision before we got to the decimal + point + */ + } else { + double const fractionPart = value - wholePart; + + if (fractionPart > wholePrecision) { + bufferConcat(formattedP, '.'); + + floatFractionPart(fractionPart, wholePrecision, + formattedP); + } + } + } else { + bufferConcat(formattedP, '0'); + + if (value > 0.0) { + bufferConcat(formattedP, '.'); + floatFraction(value, formattedP); + } + } +} + + + +void +xmlrpc_formatFloat(xmlrpc_env * const envP, + double const value, + const char ** const formattedP) { +/*---------------------------------------------------------------------------- + Format the value 'value' in XML-RPC - just the characters that represent + the numbers - none of the XML markup. E.g. "1.234". + + Assume 'value' is finite, as there is no such thing as an infinite or + NaN value in XML-RPC. +-----------------------------------------------------------------------------*/ + double absvalue; + buffer formatted; + + assert(XMLRPC_FINITE(value)); + + bufferInit(&formatted); + + if (value < 0.0) { + bufferConcat(&formatted, '-'); + absvalue = - value; + } else + absvalue = value; + + floatUnsigned(absvalue, &formatted); + + bufferConcat(&formatted, '\0'); + + if (formatted.bytes == NULL) + xmlrpc_faultf(envP, "Couldn't allocate memory to format %g", + value); + else + *formattedP = formatted.bytes; +} diff --git a/trunk/src/double.h b/trunk/src/double.h new file mode 100644 index 000000000..dc563c2cd --- /dev/null +++ b/trunk/src/double.h @@ -0,0 +1,11 @@ +#ifndef DOUBLE_H_INCLUDED +#define DOUBLE_H_INCLUDED + +#include "xmlrpc-c/util.h" + +void +xmlrpc_formatFloat(xmlrpc_env * const envP, + double const value, + const char ** const formattedP); + +#endif diff --git a/trunk/src/json.c b/trunk/src/json.c new file mode 100644 index 000000000..be0257722 --- /dev/null +++ b/trunk/src/json.c @@ -0,0 +1,1485 @@ +/*============================================================================= + json.c +=============================================================================== + + Bo Lorentsen (bl@lue.dk) had the idea to do XML-RPC values in JSON + and wrote the original version of this code in February and March + 2010. + + Bryan Henderson restructured the code and improved diagnostic information + (made it tell you where the JSON is screwed up) before its first release + in XML-RPC for C and C++ in Release 1.22. + + JSON: RFC-4627 +=============================================================================*/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "xmlrpc-c/json.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/string_number.h" + + + +/*============================================================================= + Tokenizer for the json parser +=============================================================================*/ +enum ttype { + typeNone, + typeOpenBrace, + typeCloseBrace, + typeOpenBracket, + typeCloseBracket, + typeColon, + typeComma, + typeString, + typeInteger, + typeFloat, + typeNull, + typeUndefined, + typeTrue, + typeFalse, + typeEof, +} ; + +static const char * +tokTypeName(enum ttype const type) { + + switch (type) { + case typeNone: return "None"; + case typeOpenBrace: return "Open brace"; + case typeCloseBrace: return "Close brace"; + case typeOpenBracket: return "Open bracket"; + case typeCloseBracket: return "Close bracket"; + case typeColon: return "Colon"; + case typeComma: return "Comma"; + case typeString: return "String"; + case typeInteger: return "Integer"; + case typeFloat: return "Float"; + case typeNull: return "Null"; + case typeUndefined: return "Undefined"; + case typeTrue: return "True"; + case typeFalse: return "False"; + case typeEof: return "Eof"; + default: return "???"; + } +} + + + +typedef struct { + const char * original; + size_t size; + const char * begin; + const char * end; + enum ttype type; +} Tokenizer; + + + +static void +initializeTokenizer(Tokenizer * const tokP, + const char * const str) { + + tokP->original = str; + tokP->end = str; /* end of the "previous" token */ + tokP->type = typeNone; +} + + + +static void +terminateTokenizer(Tokenizer * const tokP ATTR_UNUSED ) { + +} + + + +struct docPosition { + /* A position in the document, as meaningful to the user */ + unsigned int lineNum; /* First line is 1 */ + unsigned int colNum; /* First column is 1 */ +}; + + + +static struct docPosition +currentDocumentPosition(Tokenizer * const tokP) { +/*---------------------------------------------------------------------------- + Return the document position (line & column) of the start of the current + token +-----------------------------------------------------------------------------*/ + struct docPosition retval; + + unsigned int curLine; + unsigned int curCol; + const char * cursor; + + curLine = 0; + curCol = 0; + + for (cursor = tokP->original; cursor < tokP->begin; ++cursor) { + ++curCol; + + if (*cursor == '\n') { + ++curLine; + curCol = 0; + } + } + retval.lineNum = curLine + 1; + retval.colNum = curCol + 1; + + return retval; +} + + + +static void +setParseErr(xmlrpc_env * const envP, + Tokenizer * const tokP, + const char * const format, + ...) { + + struct docPosition const pos = currentDocumentPosition(tokP); + + va_list args; + const char * msg; + + XMLRPC_ASSERT(envP != NULL); + XMLRPC_ASSERT(format != NULL); + + va_start(args, format); + + xmlrpc_vasprintf(&msg, format, args); + + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "JSON parse error at Line %u, Column %u: %s", + pos.lineNum, pos.colNum, msg); + + xmlrpc_strfree(msg); + + va_end(args); +} + + + +static void +finishStringToken(xmlrpc_env * const envP, + Tokenizer * const tokP) { + + ++tokP->end; + + while (*tokP->end != '"' && *tokP->end != '\0' && !envP->fault_occurred) { + if (*tokP->end == '\\') { + ++tokP->end; + switch (*tokP->end) { + case '"': + case '\\': + case '/': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + ++tokP->end; + break; + case 'u': { + const char * cur; + + ++tokP->end; + + cur = tokP->end; + + while (isxdigit(*cur) && cur - tokP->end < 4) + ++cur; + + if (cur - tokP->end < 4) + setParseErr(envP, tokP, + "hex unicode must contain 4 digits. " + "There are only %u here", cur - tokP->end); + else + tokP->end = cur; + } break; + case '\0': + setParseErr(envP, tokP, "JSON document ends in the middle " + "of a backslash escape sequence"); + break; + default: + setParseErr(envP, tokP, "unknown escape character " + "after backslash: '%c'", *tokP->end); + } + } else + ++tokP->end; + } + if (!envP->fault_occurred) { + if (*tokP->end == '\0') + setParseErr(envP, tokP, "JSON document ends in the middle " + "of a string literal"); + else { + ++tokP->end; + tokP->size = (tokP->end - tokP->begin) - 1; + } + } +} + + + +static bool +isInteger(const char * const token, + unsigned int const tokSize) { + + if (tokSize < 1) + return false; + else { + unsigned int i; + + i = 0; + + if (token[0] == '-') + ++i; + + while (i < tokSize) { + if (!isdigit(token[i])) + return false; + ++i; + } + return true; + } +} + + + +static bool +isFloat(const char * const token, + unsigned int const tokSize) { +/*---------------------------------------------------------------------------- + The token 'token', of size 'tokSize' is a syntactically valid floating + point number. + + N.B. This is true of any integer. + + We don't accept plus signs. + + Examples of valid floating point: 0, 32, 32.5, , 32.500, + 32.5E4 -5, 32.5E-4, 005. +-----------------------------------------------------------------------------*/ + unsigned int i; + bool seenPeriod; + bool seenDigit; + + seenPeriod = false; + seenDigit = false; + i = 0; + + if (tokSize >= 1 && token[0] == '-') + ++i; + + while (i < tokSize) { + char const c = token[i]; + + if (c == 'e') + return isInteger(&token[i], tokSize - i); + else if (c == '.') { + if (seenPeriod) { + /* It's a second period */ + return false; + } else { + seenPeriod = true; + } + } else if (isdigit(c)) + seenDigit = true; + else + return false; + ++i; + } + if (seenDigit) + return true; + else + return false; +} + + + +static bool +isWordChar(char const candidate) { +/*---------------------------------------------------------------------------- + Return true iff 'candidate' is a character that can be in a "word" token. + A word token is a multi-character token that is either a JSON keyword or a + number. +-----------------------------------------------------------------------------*/ + return (isalnum(candidate) || candidate == '.' || candidate == '-'); +} + + + +static void +finishAlphanumericWordToken(Tokenizer * const tokP) { + + ++tokP->end; + + while (isWordChar(*tokP->end)) + ++tokP->end; + + tokP->size = tokP->end - tokP->begin; +} + + + +static void +finishDelimiterToken(Tokenizer * const tokP) { + + ++tokP->end; + tokP->size = tokP->end - tokP->begin; +} + + + +static bool +atComment(Tokenizer * const tokP) { + + return (*tokP->begin == '/' && *(tokP->begin + 1) == '/'); +} + + + +static void +advancePastWhiteSpace(Tokenizer * const tokP) { + + while (isspace(*tokP->begin)) + ++tokP->begin; +} + + + +static void +advancePastComments(Tokenizer * const tokP) { +/*---------------------------------------------------------------------------- + Advance the pointer over any comments. +-----------------------------------------------------------------------------*/ + while (atComment(tokP)) { + /* A comment ends at a newline or end of document */ + while (*tokP->begin != '\n' && *tokP->begin != '\0') + ++tokP->begin; + } +} + + + +static void +advanceToNextToken(Tokenizer * const tokP) { +/*---------------------------------------------------------------------------- + Advance the pointer over any white space and comments to the next + token, or end of document, whichever comes first. +-----------------------------------------------------------------------------*/ + + while (*tokP->begin != '\0' && + (isspace(*tokP->begin) || atComment(tokP))) { + + advancePastWhiteSpace(tokP); + + advancePastComments(tokP); + } +} + + + +static void +getToken(xmlrpc_env * const envP, + Tokenizer * const tokP) { + + /* The token starts where the last one left off */ + tokP->begin = tokP->end; + + advanceToNextToken(tokP); + + if (*tokP->begin == '\0') { + /* End of document */ + tokP->end = tokP->begin; + tokP->type = typeEof; + tokP->size = tokP->end - tokP->begin; + } else { + tokP->end = tokP->begin; /* initial value */ + + if (*tokP->begin == '{') { + finishDelimiterToken(tokP); + tokP->type = typeOpenBrace; + } else if (*tokP->begin == '}') { + finishDelimiterToken(tokP); + tokP->type = typeCloseBrace; + } else if (*tokP->begin == '[') { + finishDelimiterToken(tokP); + tokP->type = typeOpenBracket; + } else if (*tokP->begin == ']') { + finishDelimiterToken(tokP); + tokP->type = typeCloseBracket; + } else if (*tokP->begin == ':') { + finishDelimiterToken(tokP); + tokP->type = typeColon; + } else if (*tokP->begin == ',') { + finishDelimiterToken(tokP); + tokP->type = typeComma; + } else if (*tokP->begin == '"') { + finishStringToken(envP, tokP); + + if (!envP->fault_occurred) + tokP->type = typeString; + } else { + if (isWordChar(*tokP->begin)) { + finishAlphanumericWordToken(tokP); + + if (isInteger(tokP->begin, tokP->size)) + tokP->type = typeInteger; + else if (isFloat(tokP->begin, tokP->size)) + tokP->type = typeFloat; + else if (xmlrpc_strneq(tokP->begin, "null", tokP->size)) + tokP->type = typeNull; + else if (xmlrpc_strneq(tokP->begin, "undefined", tokP->size)) + tokP->type = typeUndefined; + else if(xmlrpc_strneq(tokP->begin, "false", tokP->size)) + tokP->type = typeFalse; + else if(xmlrpc_strneq(tokP->begin, "true", tokP->size)) + tokP->type = typeTrue; + else + setParseErr(envP, tokP, "Invalid word token -- " + "Not a valid integer, floating point " + "number, 'null', 'true', or 'false'"); + } else { + setParseErr(envP, tokP, + "Not a valid token -- starts with '%c'; " + "a valid token starts with " + "one of []{}:,\"-. or digit or letter", + *tokP->begin); + } + } + } +} + + + +/*===========================================================================*/ + + + +static int +utf8Decode(uint32_t const c, + char * const out) { +/*--------------------------------------------------------------------------- + convert a unicode char to a utf8 char +---------------------------------------------------------------------------*/ + if (c <= 0x7F) { /* 0XXX XXXX one byte */ + out[0] = (char) c; + return 1; + } else if (c <= 0x7FF) { /* 110X XXXX two bytes */ + out[0] = (char)( 0xC0 | (c >> 6) ); + out[1] = (char)( 0x80 | (c & 0x3F) ); + return 2; + } else if (c <= 0xFFFF) { /* 1110 XXXX three bytes */ + out[0] = (char) (0xE0 | (c >> 12)); + out[1] = (char) (0x80 | ((c >> 6) & 0x3F)); + out[2] = (char) (0x80 | (c & 0x3F)); + return 3; + } else if (c <= 0x1FFFFF) { /* 1111 0XXX four bytes */ + out[0] = (char) (0xF0 | (c >> 18)); + out[1] = (char) (0x80 | ((c >> 12) & 0x3F)); + out[2] = (char) (0x80 | ((c >> 6) & 0x3F)); + out[3] = (char) (0x80 | (c & 0x3F)); + return 4; + } else + return 0; +} + + + +static void +getBackslashSequence(xmlrpc_env * const envP, + const char * const cur, + xmlrpc_mem_block * const memBlockP, + unsigned int * const nBytesConsumedP) { + + char buffer[5]; + unsigned int tsize; + + switch (*cur) { + case '"': + buffer[0] = '"'; + tsize = 1; + *nBytesConsumedP = 1; + break; + case '/': + buffer[0] = '/'; + tsize = 1; + *nBytesConsumedP = 1; + break; + case '\\': + buffer[0] = '\\'; + tsize = 1; + *nBytesConsumedP = 1; + break; + case 'b': + buffer[0] = '\b'; + tsize = 1; + *nBytesConsumedP = 1; + break; + case 'f': + buffer[0] = '\f'; + tsize = 1; + *nBytesConsumedP = 1; + break; + case 'n': + buffer[0] = '\n'; + tsize = 1; + *nBytesConsumedP = 1; + break; + case 'r': + buffer[0] = '\r'; + tsize = 1; + *nBytesConsumedP = 1; + break; + case 't': + buffer[0] = '\t'; + tsize = 1; + *nBytesConsumedP = 1; + break; + case 'u': { + long digit; + strncpy(buffer, cur + 1, 4); + digit = strtol(buffer, NULL, 16); + tsize = utf8Decode(digit, buffer); + *nBytesConsumedP = 5; /* uXXXX */ + break; + } + default: + xmlrpc_faultf(envP, "Invalid character after backslash " + "escape: '%c'", *cur); + *nBytesConsumedP = 0; /* quiet compiler warning */ + tsize = 0; /* quiet compiler warning */ + } + if (!envP->fault_occurred) + XMLRPC_MEMBLOCK_APPEND(char, envP, memBlockP, buffer, tsize ); +} + + + +static void +unescapeString(xmlrpc_env * const envP, + const char * const begin, + const char * const end, + xmlrpc_mem_block ** const memBlockPP) { + + xmlrpc_mem_block * memBlockP; + + memBlockP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + + if (!envP->fault_occurred) { + const char * cur; + const char * last; + + cur = begin; + last = cur; + + while (cur != end && !envP->fault_occurred) { + if (*cur == '\\') { + if (cur != last) { + XMLRPC_MEMBLOCK_APPEND( + char, envP, memBlockP, last, cur - last ); + if (!envP->fault_occurred) + last = cur; + } + if (!envP->fault_occurred) { + unsigned int nBytesConsumed; + + cur += 1; /* consume slash */ + + getBackslashSequence(envP, cur, memBlockP, + &nBytesConsumed); + + if (!envP->fault_occurred) { + cur += nBytesConsumed; + last = cur; + } + } + } else + ++cur; + } + if (!envP->fault_occurred) { + if (cur != last) { + XMLRPC_MEMBLOCK_APPEND(char, envP, + memBlockP, last, cur - last ); + } + } + if (!envP->fault_occurred) { + /* Append terminating NUL */ + XMLRPC_MEMBLOCK_APPEND(char, envP, memBlockP, "", 1); + } + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, memBlockP); + } + *memBlockPP = memBlockP; +} + + + +static xmlrpc_value * +makeUtf8String(xmlrpc_env * const envP, + const char * const begin, + const char * const end) { +/*---------------------------------------------------------------------------- + Copy a json string directly into a string value, and convert any json + escaping (\uXXXX) to something acceptable to the internal string handling. + + Try to do this in as few chunks as possible ! +-----------------------------------------------------------------------------*/ + xmlrpc_value * valP; + + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_STRING; + valP->_wcs_block = NULL; + + if (!envP->fault_occurred) + unescapeString(envP, begin, end, &valP->blockP); + + if (envP->fault_occurred) + xmlrpc_DECREF(valP); + } + return valP; +} + + + +static xmlrpc_value * +stringTokenValue(xmlrpc_env * const envP, + Tokenizer * const tokP) { + + xmlrpc_env env; + xmlrpc_value * valP; + + xmlrpc_env_init(&env); + + assert(tokP->end >= tokP->begin + 2); + assert(*tokP->begin == '"'); + assert(*(tokP->end-1) == '"'); + + valP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); + + if (env.fault_occurred) { + setParseErr(envP, tokP, "Error in string token: %s", + env.fault_string); + } + xmlrpc_env_clean(&env); + + return valP; +} + + + +static xmlrpc_value * +integerTokenValue(xmlrpc_env * const envP, + Tokenizer * const tokP) { + + xmlrpc_env env; + char valueString[tokP->size + 1]; + xmlrpc_int64 value; + xmlrpc_value * valP; + + xmlrpc_env_init(&env); + + memcpy(valueString, tokP->begin, tokP->size); + valueString[tokP->size] = '\0'; + + xmlrpc_parse_int64(&env, valueString, &value); + + if (env.fault_occurred) + setParseErr(envP, tokP, "Error in integer token value '%s': %s", + tokP->begin, env.fault_string); + else + valP = xmlrpc_i8_new(envP, value); + + xmlrpc_env_clean(&env); + + return valP; +} + + + +/* Forward declarations for recursion: */ + +static xmlrpc_value * +parseValue(xmlrpc_env * const envP, + Tokenizer * const tokP); + +static xmlrpc_value * +parseList(xmlrpc_env * const envP, + Tokenizer * const tokP); + +static xmlrpc_value * +parseObject(xmlrpc_env * const envP, + Tokenizer * const tokP); + + + +static void +parseListElement(xmlrpc_env * const envP, + Tokenizer * const tokP, + xmlrpc_value * const listArrayP, + bool * const endOfListP) { + + xmlrpc_value * itemP; + + itemP = parseValue(envP, tokP); + + if (!envP->fault_occurred) { + xmlrpc_array_append_item(envP, listArrayP, itemP); + + if (!envP->fault_occurred) { + getToken(envP, tokP); + if (!envP->fault_occurred) { + if (tokP->type == typeComma) { + *endOfListP = false; + } else if (tokP->type == typeCloseBracket) + *endOfListP = true; + else + setParseErr(envP, tokP, + "Need comma or close bracket " + "after array item. Instead we have %s", + tokTypeName(tokP->type)); + } + } + xmlrpc_DECREF(itemP); + } +} + + + +static xmlrpc_value * +parseList(xmlrpc_env * const envP, + Tokenizer * const tokP) { + + xmlrpc_value * retval; + + XMLRPC_ASSERT_ENV_OK(envP); + + retval = xmlrpc_array_new(envP); + + if (!envP->fault_occurred) { + bool endOfList; + for (endOfList = false; !endOfList && !envP->fault_occurred; ) { + getToken(envP,tokP); + + if (!envP->fault_occurred) { + if (tokP->type == typeEof) + endOfList = true; + else if (tokP->type == typeCloseBracket) + endOfList = true; + else + parseListElement(envP, tokP, retval, &endOfList); + } + } + if (envP->fault_occurred) + xmlrpc_DECREF(retval); + } + return retval; +} + + + +static void +parseObjectMemberValue(xmlrpc_env * const envP, + Tokenizer * const tokP, + xmlrpc_value * const keyP, + xmlrpc_value * const objectP) { + + xmlrpc_value * valP; + + getToken(envP,tokP); + + if (!envP->fault_occurred) { + valP = parseValue(envP, tokP); + + if (!envP->fault_occurred) { + xmlrpc_struct_set_value_v(envP, objectP, keyP, valP); + + xmlrpc_DECREF(valP); + } + } +} + + + +static void +parseObjectMember(xmlrpc_env * const envP, + Tokenizer * const tokP, + xmlrpc_value * const objectP) { + + xmlrpc_env env; + xmlrpc_value * keyP; + + xmlrpc_env_init(&env); + + /* The current token is the string which is the member name: */ + assert(tokP->type = typeString); + assert(tokP->end >= tokP->begin + 2); + assert(*tokP->begin == '"'); + assert(*(tokP->end-1) == '"'); + + keyP = makeUtf8String(&env, tokP->begin + 1, tokP->end - 1); + + if (env.fault_occurred) + setParseErr(envP, tokP, "Error in what is supposed to be " + "the key of a member of an object: %s", + env.fault_string); + else { + getToken(envP, tokP); + + if (!envP->fault_occurred) { + if (tokP->type == typeColon) + parseObjectMemberValue(envP, tokP, keyP, objectP); + else + setParseErr(envP, tokP, + "Need a colon after member key " + "in object. Instead we have %s", + tokTypeName(tokP->type)); + } + xmlrpc_DECREF(keyP); + } + xmlrpc_env_clean(&env); +} + + + +static xmlrpc_value * +parseObject(xmlrpc_env * const envP, + Tokenizer * const tokP) { + + xmlrpc_value * retval; + + XMLRPC_ASSERT_ENV_OK(envP); + + retval = xmlrpc_struct_new(envP); + + if (!envP->fault_occurred) { + bool objectDone; + + objectDone = false; + while (!objectDone && !envP->fault_occurred) { + getToken(envP, tokP); + + if (!envP->fault_occurred) { + if (tokP->type == typeCloseBrace) { + objectDone = true; + } else if (tokP->type == typeString) { + parseObjectMember(envP, tokP, retval); + + if (!envP->fault_occurred) { + getToken(envP, tokP); + + if (!envP->fault_occurred) { + if (tokP->type == typeComma) { + /* member separator; keep going */ + } else if (tokP->type == typeCloseBrace) { + /* No more members in this object */ + objectDone = true; + } else + setParseErr( + envP, tokP, + "Need a comma or close brace after object " + "member. Instead we have %s", + tokTypeName(tokP->type)); + } + } + } else { + setParseErr(envP, tokP, + "Need a string (i.e. starting with " + "a quotation mark) as member key " + "in object, or closing brace to end the " + "object. Instead we have %s", + tokTypeName(tokP->type)); + } + } + } + if (envP->fault_occurred) + xmlrpc_DECREF(retval); + } + return retval; +} + + + + + +static xmlrpc_value * +parseValue(xmlrpc_env * const envP, + Tokenizer * const tokP) { + + xmlrpc_value * retval; + + XMLRPC_ASSERT_ENV_OK(envP); + + switch (tokP->type) { + + case typeOpenBracket: + retval = parseList(envP, tokP); + break; + + case typeOpenBrace: + retval = parseObject(envP, tokP); + break; + + case typeNull: + retval = xmlrpc_nil_new(envP); + break; + + case typeUndefined: + retval = xmlrpc_nil_new(envP); + break; + + case typeFalse: + retval = xmlrpc_bool_new(envP, (xmlrpc_bool)false); + break; + + case typeTrue: + retval = xmlrpc_bool_new(envP, (xmlrpc_bool)true); + break; + + case typeInteger: + retval = integerTokenValue(envP, tokP); + break; + + case typeFloat: + retval = xmlrpc_double_new(envP, strtod(tokP->begin, NULL)); + break; + + case typeString: + retval = stringTokenValue(envP, tokP); + break; + + default: + retval = NULL; + setParseErr(envP, tokP, "Invalid token " + "where a value is supposed to begin: %s. " + "Should be an open bracket, open brace, " + "'null', 'false', 'true', a number, or a string", + tokTypeName(tokP->type)); + } + return retval; +} + + + +xmlrpc_value * +xmlrpc_parse_json(xmlrpc_env * const envP, + const char * const str) { + + xmlrpc_value * retval = retval; + Tokenizer tok; + + XMLRPC_ASSERT_ENV_OK(envP); + + initializeTokenizer(&tok, str); + + getToken(envP, &tok); + + if (!envP->fault_occurred) { + retval = parseValue(envP, &tok); + + if (!envP->fault_occurred) { + getToken(envP, &tok); + + if (!envP->fault_occurred) { + if (tok.type != typeEof) + setParseErr(envP, &tok, "There is junk after the end of " + "the JSON value, to wit a %s token", + tokTypeName(tok.type)); + } + if (envP->fault_occurred) + xmlrpc_DECREF(retval); + } + } + + terminateTokenizer(&tok); + + return retval; +} + + + +/*============================================================================ + Serialize value to JSON +============================================================================*/ + +/* Borrowed from xmlrpc_serialize */ + +static void +formatOut(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + const char * const formatString, ... ) { + + va_list args; + char buffer[1024]; + int rc; + + XMLRPC_ASSERT_ENV_OK(envP); + + va_start(args, formatString); + + rc = XMLRPC_VSNPRINTF(buffer, sizeof(buffer), formatString, args); + + /* Old vsnprintf() (and Windows) fails with return value -1 if the full + string doesn't fit in the buffer. New vsnprintf() puts whatever will + fit in the buffer, and returns the length of the full string + regardless. For us, this truncation is a failure. + */ + + if (rc < 0) + xmlrpc_faultf(envP, "formatOut() overflowed internal buffer"); + else { + unsigned int const formattedLen = rc; + + if (formattedLen + 1 >= (sizeof(buffer))) + xmlrpc_faultf(envP, "formatOut() overflowed internal buffer"); + else + XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, buffer, formattedLen); + } + va_end(args); +} + + + +static void +indent(xmlrpc_env * const envP, + unsigned int const level, + xmlrpc_mem_block * const outP) { + + unsigned int i; + + for (i = 0; i < level * 2 && !envP->fault_occurred; ++i) + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, " ", 1); +} + + + +/* Forward declaration for recursion */ + +static void +serializeValue(xmlrpc_env * const envP, + xmlrpc_value * const valP, + unsigned int const level, + xmlrpc_mem_block * const outP); + + + +static void +appendEscapeSeq(xmlrpc_env * const envP, + xmlrpc_mem_block * const outP, + unsigned char const c) { +/*---------------------------------------------------------------------------- + Append to *outP the escaped representation of 'c'. + + This is e.g. "\t" for tab, or "\u001C" for something exotic. +-----------------------------------------------------------------------------*/ + unsigned int size; + char buffer[6+1]; + char slashChar; + /* Character that goes after the backslash, including 'u' for \uHHHH */ + + switch (c) { + case '"' : slashChar = '"'; break; /* U+0022 */ + case '\\': slashChar = '\\'; break; /* U+005C */ + case '\b': slashChar = 'b'; break; /* U+0008 */ + case '\f': slashChar = 'f'; break; /* U+000C */ + case '\n': slashChar = 'n'; break; /* U+000A */ + case '\r': slashChar = 'r'; break; /* U+000D */ + case '\t': slashChar = 't'; break; /* U+0009 */ + default: + slashChar = 'u'; + }; + + buffer[0] = '\\'; + buffer[1] = slashChar; + + if (slashChar == 'u') { + sprintf(&buffer[2], "%04x", c); + size = 6; /* \u1234 */ + } else + size = 2; + + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, buffer, size); +} + + + +static void +makeJsonString(xmlrpc_env * const envP, + const char * const value, + size_t const length, + xmlrpc_mem_block * const outP) { +/*---------------------------------------------------------------------------- + Create a JSON representation of a string, appended to *outP. +-----------------------------------------------------------------------------*/ + const char * const begin = &value[0]; + const char * const end = begin + length; + + const char * cur; + const char * last; + + last = cur = begin; + + while (cur != end && !envP->fault_occurred) { + unsigned char const c = *cur; + + if (c < 0x1F || c == '"' || c == '\\') { + /* This characters needs to be escaped. Put a backslash escape + sequence in the output for this character, after copying all + the characters before it to the output. + */ + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, last, cur - last); + + if (!envP->fault_occurred) { + appendEscapeSeq(envP, outP, c); + + ++cur; + last = cur; + } + } else + ++cur; + } + + /* Copy all characters since the last escaped character to the output */ + if (cur != last) + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, last, cur - last); +} + + + +static void +makeJsonStringFromXmlRpc(xmlrpc_env * const envP, + const xmlrpc_value * const valP, + xmlrpc_mem_block * const outP) { +/*---------------------------------------------------------------------------- + Convert a string XML-RPC value to JSON, appended to *outP. +-----------------------------------------------------------------------------*/ + const char * value; + size_t length; + + xmlrpc_read_string_lp(envP, valP, &length, &value); + if (!envP->fault_occurred) { + makeJsonString(envP, value, length, outP); + + xmlrpc_strfree(value); + } +} + + + +static void +serializeInt(xmlrpc_env * const envP, + xmlrpc_value * const valP, + xmlrpc_mem_block * const outP) { + + xmlrpc_int value; + + xmlrpc_read_int(envP, valP, &value); + + formatOut(envP, outP, "%d", value); +} + + + +static void +serializeI8(xmlrpc_env * const envP, + xmlrpc_value * const valP, + xmlrpc_mem_block * const outP) { + + xmlrpc_int64 value; + + xmlrpc_read_i8(envP, valP, &value); + + formatOut(envP, outP, "%" XMLRPC_PRId64, value); +} + + + +static void +serializeBool(xmlrpc_env * const envP, + xmlrpc_value * const valP, + xmlrpc_mem_block * const outP) { + + xmlrpc_bool value; + xmlrpc_read_bool(envP, valP, &value); + + formatOut(envP, outP, "%s", value ? "true" : "false"); +} + + + +static void +serializeDouble(xmlrpc_env * const envP, + xmlrpc_value * const valP, + xmlrpc_mem_block * const outP) { + + xmlrpc_double value; + xmlrpc_read_double(envP, valP, &value); + + formatOut(envP, outP, "%e", value); +} + + + +static void +serializeDatetime(xmlrpc_env * const envP, + xmlrpc_value * const valP, + xmlrpc_mem_block * const outP) { + + /* ISO 8601 time string as JSON does not have a datetime type */ + + formatOut(envP, outP, "\"%u%02u%02uT%02u:%02u:%02u\"", + valP->_value.dt.Y, + valP->_value.dt.M, + valP->_value.dt.D, + valP->_value.dt.h, + valP->_value.dt.m, + valP->_value.dt.s); +} + + + +static void +serializeString(xmlrpc_env * const envP, + xmlrpc_value * const valP, + xmlrpc_mem_block * const outP) { + + formatOut(envP, outP, "\""); + + makeJsonStringFromXmlRpc(envP, valP, outP); + + formatOut(envP, outP, "\""); +} + + + +static void +serializeBitstring(xmlrpc_env * const envP, + xmlrpc_value * const valP, + xmlrpc_mem_block * const outP) { +/*---------------------------------------------------------------------------- + Append to *outP a JSON string whose value is the bit string *valP in + base64 ASCII. +-----------------------------------------------------------------------------*/ + const unsigned char * bytes; + size_t size; + + xmlrpc_read_base64(envP, valP, &size, &bytes); + + if (!envP->fault_occurred) { + xmlrpc_mem_block * const base64P = + xmlrpc_base64_encode(envP, bytes, size); + + if (!envP->fault_occurred) { + + formatOut(envP, outP, "\""); + + XMLRPC_MEMBLOCK_APPEND( + char, envP, outP, + XMLRPC_MEMBLOCK_CONTENTS(char, base64P), + XMLRPC_MEMBLOCK_SIZE(char, base64P)); + + if (!envP->fault_occurred) + formatOut(envP, outP, "\""); + + XMLRPC_MEMBLOCK_FREE(char, base64P); + } + free((unsigned char*)bytes); + } +} + + + +static void +serializeArray(xmlrpc_env * const envP, + xmlrpc_value * const valP, + unsigned int const level, + xmlrpc_mem_block * const outP) { + + unsigned int const size = xmlrpc_array_size(envP, valP); + + if (!envP->fault_occurred) { + unsigned int i; + + formatOut(envP, outP, "[\n"); + + for (i = 0; i < size && !envP->fault_occurred; ++i) { + xmlrpc_value * const itemP = + xmlrpc_array_get_item(envP, valP, i); + + if (!envP->fault_occurred) { + if (!envP->fault_occurred) { + serializeValue(envP, itemP, level + 1, outP); + + if (i < size - 1) + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, ",\n", 2); + } + } + } + if (!envP->fault_occurred) { + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, "\n", 1); + indent(envP, level, outP); + if (!envP->fault_occurred) { + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, "]", 1); + } + } + } +} + + + +static void +serializeStructMember(xmlrpc_env * const envP, + xmlrpc_value * const memberKeyP, + xmlrpc_value * const memberValueP, + unsigned int const level, + xmlrpc_mem_block * const outP) { + + serializeValue(envP, memberKeyP, level, outP); + + if (!envP->fault_occurred) { + formatOut(envP, outP, ":"); + + if (!envP->fault_occurred) + serializeValue(envP, memberValueP, level, outP); + } +} + + + +static void +serializeStruct(xmlrpc_env * const envP, + xmlrpc_value * const valP, + unsigned int const level, + xmlrpc_mem_block * const outP) { + + if (!envP->fault_occurred) { + formatOut(envP, outP, "{\n"); + if (!envP->fault_occurred) { + unsigned int const size = xmlrpc_struct_size(envP, valP); + + if (!envP->fault_occurred) { + unsigned int i; + for (i = 0; i < size && !envP->fault_occurred; ++i) { + xmlrpc_value * memberKeyP; + xmlrpc_value * memberValueP; + + xmlrpc_struct_get_key_and_value(envP, valP, i, + &memberKeyP, + &memberValueP); + if (!envP->fault_occurred) { + serializeStructMember(envP, memberKeyP, memberValueP, + level + 1, outP); + + if (!envP->fault_occurred && i < size - 1) + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, ",\n", 2); + } + } + if (!envP->fault_occurred) { + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, "\n", 1); + indent(envP, level, outP); + XMLRPC_MEMBLOCK_APPEND(char, envP, outP, "}", 1); + } + } + } + } +} + + + +static void +serializeValue(xmlrpc_env * const envP, + xmlrpc_value * const valP, + unsigned int const level, + xmlrpc_mem_block * const outP) { +/*---------------------------------------------------------------------------- + Generate JSON to represent the value *valP. Append it to *outP. + + The JSON consists of lines of text. Indent them 'level' levels. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + + indent(envP, level, outP); + + switch (xmlrpc_value_type(valP)) { + case XMLRPC_TYPE_INT: + serializeInt(envP, valP, outP); + break; + + case XMLRPC_TYPE_I8: + serializeI8(envP, valP, outP); + break; + + case XMLRPC_TYPE_BOOL: + serializeBool(envP, valP, outP); + break; + + case XMLRPC_TYPE_DOUBLE: + serializeDouble(envP, valP, outP); + break; + + case XMLRPC_TYPE_DATETIME: + serializeDatetime(envP, valP, outP); + break; + + case XMLRPC_TYPE_STRING: + serializeString(envP, valP, outP); + break; + + case XMLRPC_TYPE_BASE64: + serializeBitstring(envP, valP, outP); + break; + + case XMLRPC_TYPE_ARRAY: + serializeArray(envP, valP, level, outP); + break; + + case XMLRPC_TYPE_STRUCT: + serializeStruct(envP, valP, level, outP); + break; + + case XMLRPC_TYPE_C_PTR: + xmlrpc_faultf(envP, "Tried to serialize a C pointer value."); + break; + + case XMLRPC_TYPE_NIL: + formatOut(envP, outP, "null"); + break; + + case XMLRPC_TYPE_DEAD: + xmlrpc_faultf(envP, "Tried to serialize a dead value."); + break; + + default: + xmlrpc_faultf(envP, "Invalid xmlrpc_value type: 0x%x", + xmlrpc_value_type(valP)); + } +} + + + +void +xmlrpc_serialize_json(xmlrpc_env * const envP, + xmlrpc_value * const valP, + xmlrpc_mem_block * const outP) { +/*---------------------------------------------------------------------------- + Generate JSON to represent the value *valP. Append it to *outP. +-----------------------------------------------------------------------------*/ + serializeValue(envP, valP, 0, outP); +} diff --git a/trunk/src/method.c b/trunk/src/method.c new file mode 100644 index 000000000..cd7961e2d --- /dev/null +++ b/trunk/src/method.c @@ -0,0 +1,455 @@ +/*========================================================================= + XML-RPC server method registry + Method services +=========================================================================== + These are the functions that implement the method objects that + the XML-RPC method registry uses. + + By Bryan Henderson, December 2006. + + Contributed to the public domain by its author. +=========================================================================*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include "xmlrpc_config.h" + +#include +#include +#include + +#include "bool.h" +#include "mallocvar.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/base.h" +#include "registry.h" + +#include "method.h" + + +static void +signatureDestroy(struct xmlrpc_signature * const signatureP) { + + if (signatureP->argList) + free((void*)signatureP->argList); + + free(signatureP); +} + + + +static void +translateTypeSpecifierToName(xmlrpc_env * const envP, + char const typeSpecifier, + const char ** const typeNameP) { + + switch (typeSpecifier) { + case 'i': *typeNameP = "int"; break; + case 'b': *typeNameP = "boolean"; break; + case 'd': *typeNameP = "double"; break; + case 's': *typeNameP = "string"; break; + case '8': *typeNameP = "dateTime.iso8601"; break; + case '6': *typeNameP = "base64"; break; + case 'S': *typeNameP = "struct"; break; + case 'A': *typeNameP = "array"; break; + case 'n': *typeNameP = "nil"; break; + case 'I': *typeNameP = "i8"; break; + default: + xmlrpc_faultf(envP, + "Method registry contains invalid signature " + "data. It contains the type specifier '%c'", + typeSpecifier); + *typeNameP = NULL; /* quiet compiler warning */ + } +} + + + +/* MSVC 8 complains that const char ** is incompatible with void * in the + REALLOCARRAY. It's not. +*/ +#pragma warning(push) +#pragma warning(disable:4090) + +static void +makeRoomInArgList(xmlrpc_env * const envP, + struct xmlrpc_signature * const signatureP, + unsigned int const minArgCount) { + + if (signatureP->argListSpace < minArgCount) { + REALLOCARRAY(signatureP->argList, minArgCount); + if (signatureP->argList == NULL) { + xmlrpc_faultf(envP, "Couldn't get memory for a argument list for " + "a method signature with %u arguments", minArgCount); + signatureP->argListSpace = 0; + } + } +} + +#pragma warning(pop) + + + +static void +parseArgumentTypeSpecifiers(xmlrpc_env * const envP, + const char * const startP, + struct xmlrpc_signature * const signatureP, + const char ** const nextPP) { + const char * cursorP; + + cursorP = startP; /* start at the beginning */ + + while (!envP->fault_occurred && *cursorP != ',' && *cursorP != '\0') { + const char * typeName; + + translateTypeSpecifierToName(envP, *cursorP, &typeName); + + if (!envP->fault_occurred) { + ++cursorP; + + makeRoomInArgList(envP, signatureP, signatureP->argCount + 1); + + signatureP->argList[signatureP->argCount++] = typeName; + } + } + if (!envP->fault_occurred) { + if (*cursorP) { + XMLRPC_ASSERT(*cursorP == ','); + ++cursorP; /* Move past the signature and comma */ + } + } + if (envP->fault_occurred) + free((void*)signatureP->argList); + + *nextPP = cursorP; +} + + + +static void +parseOneSignature(xmlrpc_env * const envP, + const char * const startP, + struct xmlrpc_signature ** const signaturePP, + const char ** const nextPP) { +/*---------------------------------------------------------------------------- + Parse one signature from the signature string that starts at 'startP'. + + Return that signature as a signature object *signaturePP. + + Return as *nextP the location in the signature string of the next + signature (i.e. right after the next comma). If there is no next + signature (the string ends before any comma), make it point to the + terminating NUL. +-----------------------------------------------------------------------------*/ + struct xmlrpc_signature * signatureP; + + MALLOCVAR(signatureP); + if (signatureP == NULL) + xmlrpc_faultf(envP, "Couldn't get memory for signature"); + else { + const char * cursorP; + + signatureP->argListSpace = 0; /* Start with no argument space */ + signatureP->argList = NULL; /* Nothing allocated yet */ + signatureP->argCount = 0; /* Start with no arguments */ + + cursorP = startP; /* start at the beginning */ + + if (*cursorP == ',' || *cursorP == '\0') + xmlrpc_faultf(envP, "empty signature (a signature " + "must have at least return value type)"); + else { + translateTypeSpecifierToName(envP, *cursorP, &signatureP->retType); + + ++cursorP; + + if (*cursorP != ':') + xmlrpc_faultf(envP, "No colon (':') after " + "the result type specifier"); + else { + ++cursorP; + + parseArgumentTypeSpecifiers(envP, cursorP, signatureP, nextPP); + } + } + if (envP->fault_occurred) + free(signatureP); + } + *signaturePP = signatureP; +} + + + +static void +destroySignatures(struct xmlrpc_signature * const firstSignatureP) { + + struct xmlrpc_signature * p; + struct xmlrpc_signature * nextP; + + for (p = firstSignatureP; p; p = nextP) { + nextP = p->nextP; + signatureDestroy(p); + } +} + + + +static void +listSignatures(xmlrpc_env * const envP, + const char * const sigListString, + struct xmlrpc_signature ** const firstSignaturePP) { + + struct xmlrpc_signature ** p; + const char * cursorP; + + *firstSignaturePP = NULL; /* Start with empty list */ + + p = firstSignaturePP; + cursorP = &sigListString[0]; + + while (!envP->fault_occurred && *cursorP != '\0') { + struct xmlrpc_signature * signatureP; + + parseOneSignature(envP, cursorP, &signatureP, &cursorP); + + /* cursorP now points at next signature in the list or the + terminating NUL. + */ + + if (!envP->fault_occurred) { + signatureP->nextP = NULL; + *p = signatureP; + p = &signatureP->nextP; + } + } + if (envP->fault_occurred) + destroySignatures(*firstSignaturePP); +} + + + +static void +signatureListCreate(xmlrpc_env * const envP, + const char * const sigListString, + xmlrpc_signatureList ** const signatureListPP) { + + xmlrpc_signatureList * signatureListP; + + XMLRPC_ASSERT_ENV_OK(envP); + + MALLOCVAR(signatureListP); + + if (signatureListP == NULL) + xmlrpc_faultf(envP, "Could not allocate memory for signature list"); + else { + signatureListP->firstSignatureP = NULL; + + if (sigListString == NULL || xmlrpc_streq(sigListString, "?")) { + /* No signatures -- leave the list empty */ + } else { + listSignatures(envP, sigListString, + &signatureListP->firstSignatureP); + + if (!envP->fault_occurred) { + if (!signatureListP->firstSignatureP) + xmlrpc_faultf(envP, "Signature string is empty."); + + if (envP->fault_occurred) + destroySignatures(signatureListP->firstSignatureP); + } + } + if (envP->fault_occurred) + free(signatureListP); + + *signatureListPP = signatureListP; + } +} + + + +static void +signatureListDestroy(xmlrpc_signatureList * const signatureListP) { + + destroySignatures(signatureListP->firstSignatureP); + + free(signatureListP); +} + + + +static void +makeSignatureList(xmlrpc_env * const envP, + const char * const signatureString, + xmlrpc_signatureList ** const signatureListPP) { + + xmlrpc_env env; + + xmlrpc_env_init(&env); + + signatureListCreate(&env, signatureString, signatureListPP); + + if (env.fault_occurred) + xmlrpc_faultf(envP, "Can't interpret signature string '%s'. %s", + signatureString, env.fault_string); + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_methodCreate(xmlrpc_env * const envP, + xmlrpc_method1 methodFnType1, + xmlrpc_method2 methodFnType2, + void * const userData, + const char * const signatureString, + const char * const helpText, + size_t const stackSize, + xmlrpc_methodInfo ** const methodPP) { + + xmlrpc_methodInfo * methodP; + + XMLRPC_ASSERT_ENV_OK(envP); + + MALLOCVAR(methodP); + + if (methodP == NULL) + xmlrpc_faultf(envP, "Unable to allocate storage for a method " + "descriptor"); + else { + methodP->methodFnType1 = methodFnType1; + methodP->methodFnType2 = methodFnType2; + methodP->userData = userData; + methodP->helpText = xmlrpc_strdupsol(helpText); + methodP->stackSize = stackSize; + + makeSignatureList(envP, signatureString, &methodP->signatureListP); + + if (envP->fault_occurred) { + xmlrpc_strfree(methodP->helpText); + free(methodP); + } + + *methodPP = methodP; + } +} + + + +void +xmlrpc_methodDestroy(xmlrpc_methodInfo * const methodP) { + + signatureListDestroy(methodP->signatureListP); + + xmlrpc_strfree(methodP->helpText); + + free(methodP); +} + + + +void +xmlrpc_methodListCreate(xmlrpc_env * const envP, + xmlrpc_methodList ** const methodListPP) { + + xmlrpc_methodList * methodListP; + + XMLRPC_ASSERT_ENV_OK(envP); + + MALLOCVAR(methodListP); + + if (methodListP == NULL) + xmlrpc_faultf(envP, "Couldn't allocate method list descriptor"); + else { + methodListP->firstMethodP = NULL; + methodListP->lastMethodP = NULL; + + *methodListPP = methodListP; + } +} + + + +void +xmlrpc_methodListDestroy(xmlrpc_methodList * methodListP) { + + xmlrpc_methodNode * p; + xmlrpc_methodNode * nextP; + + for (p = methodListP->firstMethodP; p; p = nextP) { + nextP = p->nextP; + + xmlrpc_methodDestroy(p->methodP); + xmlrpc_strfree(p->methodName); + free(p); + } + + free(methodListP); +} + + + +void +xmlrpc_methodListLookupByName(xmlrpc_methodList * const methodListP, + const char * const methodName, + xmlrpc_methodInfo ** const methodPP) { + + + /* We do a simple linear lookup along a linked list. + If speed is important, we can make this a binary tree instead. + */ + + xmlrpc_methodNode * p; + xmlrpc_methodInfo * methodP; + + for (p = methodListP->firstMethodP, methodP = NULL; + p && !methodP; + p = p->nextP) { + + if (xmlrpc_streq(p->methodName, methodName)) + methodP = p->methodP; + } + *methodPP = methodP; +} + + + +void +xmlrpc_methodListAdd(xmlrpc_env * const envP, + xmlrpc_methodList * const methodListP, + const char * const methodName, + xmlrpc_methodInfo * const methodP) { + + xmlrpc_methodInfo * existingMethodP; + + XMLRPC_ASSERT_ENV_OK(envP); + + xmlrpc_methodListLookupByName(methodListP, methodName, &existingMethodP); + + if (existingMethodP) + xmlrpc_faultf(envP, "Method named '%s' already registered", + methodName); + else { + xmlrpc_methodNode * methodNodeP; + + MALLOCVAR(methodNodeP); + + if (methodNodeP == NULL) + xmlrpc_faultf(envP, "Couldn't allocate method node"); + else { + methodNodeP->methodName = strdup(methodName); + methodNodeP->methodP = methodP; + methodNodeP->nextP = NULL; + + if (!methodListP->firstMethodP) + methodListP->firstMethodP = methodNodeP; + + if (methodListP->lastMethodP) + methodListP->lastMethodP->nextP = methodNodeP; + + methodListP->lastMethodP = methodNodeP; + } + } +} + diff --git a/trunk/src/method.h b/trunk/src/method.h new file mode 100644 index 000000000..f1d56cb12 --- /dev/null +++ b/trunk/src/method.h @@ -0,0 +1,125 @@ +#ifndef METHOD_H_INCLUDED +#define METHOD_H_INCLUDED + +#include "xmlrpc-c/base.h" + +struct xmlrpc_signature { + struct xmlrpc_signature * nextP; + const char * retType; + /* Name of the XML-RPC element that represents the return value + type, e.g. "int" or "dateTime.iso8601" + */ + unsigned int argCount; + /* Number of arguments method takes */ + unsigned int argListSpace; + /* Number of slots that exist in the argList[] (i.e. memory is + allocated) + */ + const char ** argList; + /* Array of size 'argCount'. argList[i] is the name of the type + of argument i. Like 'retType', e.g. "string". + + The strings are constants, not malloc'ed. + */ +}; + +typedef struct xmlrpc_signatureList { + /* A list of signatures for a method. Each signature describes one + alternative form of invoking the method (a + single method might have multiple forms, e.g. one takes two integer + arguments; another takes a single string). + */ + struct xmlrpc_signature * firstSignatureP; +} xmlrpc_signatureList; + +struct xmlrpc_registry { + bool introspectionEnabled; + struct xmlrpc_methodList * methodListP; + xmlrpc_default_method defaultMethodFunction; + void * defaultMethodUserData; + xmlrpc_preinvoke_method preinvokeFunction; + void * preinvokeUserData; + xmlrpc_server_shutdown_fn * shutdownServerFn; + /* Function that can be called to shut down the server that is + using this registry. NULL if none. + */ + void * shutdownContext; + /* Context for _shutdown_server_fn -- understood only by + that function, passed to it as argument. + */ + xmlrpc_dialect dialect; +}; + +typedef struct { +/*---------------------------------------------------------------------------- + Everything a registry knows about one XML-RPC method +-----------------------------------------------------------------------------*/ + /* One of the methodTypeX fields is NULL and the other isn't. + (The reason there are two is backward compatibility. Old + programs set up the registry with Type 1; modern ones set it up + with Type 2. + */ + xmlrpc_method1 methodFnType1; + /* The method function, if it's type 1. Null if it's not */ + xmlrpc_method2 methodFnType2; + /* The method function, if it's type 2. Null if it's not */ + void * userData; + /* Passed to method function */ + size_t stackSize; + /* Amount of stack space 'methodFnType1' or 'methodFnType2' uses. + Zero means unspecified. + */ + struct xmlrpc_signatureList * signatureListP; + /* Stuff returned by system method system.methodSignature. + Empty list doesn't mean there are no valid forms of calling the + method -- just that the registry declines to state. + */ + const char * helpText; + /* Stuff returned by system method system.methodHelp */ +} xmlrpc_methodInfo; + +typedef struct xmlrpc_methodNode { + struct xmlrpc_methodNode * nextP; + const char * methodName; + xmlrpc_methodInfo * methodP; +} xmlrpc_methodNode; + +typedef struct xmlrpc_methodList { + xmlrpc_methodNode * firstMethodP; + xmlrpc_methodNode * lastMethodP; +} xmlrpc_methodList; + +void +xmlrpc_methodCreate(xmlrpc_env * const envP, + xmlrpc_method1 methodFnType1, + xmlrpc_method2 methodFnType2, + void * const userData, + const char * const signatureString, + const char * const helpText, + size_t const stackSize, + xmlrpc_methodInfo ** const methodPP); + +void +xmlrpc_methodDestroy(xmlrpc_methodInfo * const methodP); + +void +xmlrpc_methodListCreate(xmlrpc_env * const envP, + xmlrpc_methodList ** const methodListPP); + +void +xmlrpc_methodListDestroy(xmlrpc_methodList * methodListP); + +void +xmlrpc_methodListLookupByName(xmlrpc_methodList * const methodListP, + const char * const methodName, + xmlrpc_methodInfo ** const methodPP); + +void +xmlrpc_methodListAdd(xmlrpc_env * const envP, + xmlrpc_methodList * const methodListP, + const char * const methodName, + xmlrpc_methodInfo * const methodP); + + + +#endif diff --git a/trunk/src/parse_datetime.c b/trunk/src/parse_datetime.c new file mode 100644 index 000000000..bedf67165 --- /dev/null +++ b/trunk/src/parse_datetime.c @@ -0,0 +1,467 @@ +#include "xmlrpc_config.h" + +#include +#include +#include +#include + +#if HAVE_REGEX +#include /* Missing from regex.h in GNU libc */ +#include +#endif + +#include "bool.h" +#include "c_util.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" + +#include "parse_datetime.h" + + + +#if HAVE_REGEX + +static unsigned int +digitStringValue(const char * const string, + regmatch_t const match) { +/*---------------------------------------------------------------------------- + Return the numerical value of the decimal whole number substring of + 'string' identified by 'match'. E.g. if 'string' is 'abc34d' and + 'match' says start at 3 and end at 5, we return 34. +-----------------------------------------------------------------------------*/ + unsigned int i; + unsigned int accum; + + assert(match.rm_so >= 0); + assert(match.rm_eo >= 0); + + for (i = match.rm_so, accum = 0; i < (unsigned)match.rm_eo; ++i) { + accum *= 10; + assert(isdigit(string[i])); + accum += string[i] - '0'; + } + return accum; +} +#endif /* HAVE_REGEX */ + + + +#if HAVE_REGEX + +static unsigned int +digitStringMillionths(const char * const string, + regmatch_t const match) { +/*---------------------------------------------------------------------------- + Return the number of millionths represented by the digits after the + decimal point in a decimal string, where thse digits are the substring + of 'string' identified by 'match'. E.g. if the substring is + 34, we return 340,000. +-----------------------------------------------------------------------------*/ + unsigned int i; + unsigned int accum; + + assert(match.rm_so >= 0); + assert(match.rm_eo >= 0); + + for (i = match.rm_so, accum = 0; i < (unsigned)match.rm_so+6; ++i) { + accum *= 10; + if (i < (unsigned)match.rm_eo) { + assert(isdigit(string[i])); + accum += string[i] - '0'; + } + } + return accum; +} +#endif /* HAVE_REGEX */ + + +#if HAVE_REGEX + +static void +subParseDtRegex_standard(regmatch_t * const matches, + const char * const datetimeString, + xmlrpc_datetime * const dtP) { + + dtP->Y = digitStringValue(datetimeString, matches[1]); + dtP->M = digitStringValue(datetimeString, matches[2]); + dtP->D = digitStringValue(datetimeString, matches[3]); + dtP->h = digitStringValue(datetimeString, matches[4]); + dtP->m = digitStringValue(datetimeString, matches[5]); + dtP->s = digitStringValue(datetimeString, matches[6]); + + if (matches[7].rm_so == -1) + dtP->u = 0; + else + dtP->u = digitStringMillionths(datetimeString, matches[7]); +} + + + +static void +subParseDtRegex_standardtzd(regmatch_t * const matches, + const char * const datetimeString, + xmlrpc_datetime * const dtP) { + + dtP->Y = digitStringValue(datetimeString, matches[1]); + dtP->M = digitStringValue(datetimeString, matches[2]); + dtP->D = digitStringValue(datetimeString, matches[3]); + dtP->h = digitStringValue(datetimeString, matches[4]); + dtP->m = digitStringValue(datetimeString, matches[5]); + dtP->s = digitStringValue(datetimeString, matches[6]); + dtP->u = 0; +} + +#endif /* HAVE_REGEX */ + + +#if HAVE_REGEX + +typedef void (*regparsefunc_t)(regmatch_t * const matches, + const char * const datetimeString, + xmlrpc_datetime * const dtP); + + +struct regexParser { + const char * const regex; + regparsefunc_t func; +}; + +static const struct regexParser iso8601Regex[] + + /* Each entry of this table is instructions for recognizing and parsing + some form of a "dateTime.iso8601" XML element. + + (Note that we recognize far more than just the XML-RPC standard + dateTime.iso8601). + */ + + = { + { + /* Examples: + YYYYMMDD[T]HHMMSS + YYYY-MM-DD[T]HH:MM:SS + YYYY-MM-DD[T]HH:MM:SS.ssss + */ + + "^([0-9]{4})\\-?([0-9]{2})\\-?([0-9]{2})T" + "([0-9]{2}):?([0-9]{2}):?([0-9]{2})\\.?([0-9]+)?$", + subParseDtRegex_standard + }, + + { + /* Examples: + YYYYMMDD[T]HHMMSS[Z] + YYYYMMDD[T]HHMMSS[+-]hh + YYYYMMDD[T]HHMMSS[+-]hhmm + */ + + "^([0-9]{4})\\-?([0-9]{2})\\-?([0-9]{2})T" + "([0-9]{2}):?([0-9]{2}):?([0-9]{2})[Z\\+\\-]([0-9]{2,4})?$", + subParseDtRegex_standardtzd + }, + { NULL, NULL } + }; +#endif /* HAVE_REGEX */ + + + +#if HAVE_REGEX +static void +parseDtRegex(xmlrpc_env * const envP, + const char * const datetimeString, + xmlrpc_datetime * const dtP) { + + unsigned int i; + const struct regexParser * parserP; + /* The parser that matches 'datetimeString'. Null if no match yet + found. + */ + regmatch_t matches[1024]; + + for (i = 0, parserP = NULL; iso8601Regex[i].regex && !parserP; ++i) { + const struct regexParser * const thisParserP = &iso8601Regex[i]; + + regex_t re; + int status; + + status = regcomp(&re, thisParserP->regex, REG_ICASE | REG_EXTENDED); + + /* Our regex is valid, so it must have compiled: */ + assert(status == 0); if (status){}; /* quiet compiler warning */ + { + int status; + + status = regexec(&re, datetimeString, ARRAY_SIZE(matches), + matches, 0); + + if (status == 0) { + assert(matches[0].rm_so != -1); /* Match of whole regex */ + + parserP = thisParserP; + } + } + regfree(&re); + } + + if (parserP) { + parserP->func(matches, datetimeString, dtP); + } else { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "value '%s' is not of any form we recognize " + "for a element", + datetimeString); + } + +} +#endif /* HAVE_REGEX */ + + + +static __inline__ void +parseDtNoRegex(xmlrpc_env * const envP, + const char * const datetimeString, + xmlrpc_datetime * const dtP) { + + unsigned int const dtStrlen = strlen(datetimeString); + + char year[4+1]; + char month[2+1]; + char day[2+1]; + char hour[2+1]; + char minute[2+1]; + char second[2+1]; + + if (dtStrlen < 17 || dtStrlen == 18 || dtStrlen > 24) + xmlrpc_faultf(envP, "could not parse date, size incompatible: '%d'", + dtStrlen); + else { + year[0] = datetimeString[ 0]; + year[1] = datetimeString[ 1]; + year[2] = datetimeString[ 2]; + year[3] = datetimeString[ 3]; + year[4] = '\0'; + + month[0] = datetimeString[ 4]; + month[1] = datetimeString[ 5]; + month[2] = '\0'; + + day[0] = datetimeString[ 6]; + day[1] = datetimeString[ 7]; + day[2] = '\0'; + + assert(datetimeString[ 8] == 'T'); + + hour[0] = datetimeString[ 9]; + hour[1] = datetimeString[10]; + hour[2] = '\0'; + + assert(datetimeString[11] == ':'); + + minute[0] = datetimeString[12]; + minute[1] = datetimeString[13]; + minute[2] = '\0'; + + assert(datetimeString[14] == ':'); + + second[0] = datetimeString[15]; + second[1] = datetimeString[16]; + second[2] = '\0'; + + if (dtStrlen > 17) { + unsigned int const pad = 24 - dtStrlen; + unsigned int i; + + dtP->u = atoi(&datetimeString[18]); + for (i = 0; i < pad; ++i) + dtP->u *= 10; + } else + dtP->u = 0; + + dtP->Y = atoi(year); + dtP->M = atoi(month); + dtP->D = atoi(day); + dtP->h = atoi(hour); + dtP->m = atoi(minute); + dtP->s = atoi(second); + } +} + + + +static void +validateFirst17(xmlrpc_env * const envP, + const char * const dt) { +/*---------------------------------------------------------------------------- + Assuming 'dt' is at least 17 characters long, validate that the first + 17 characters are a valid XML-RPC datetime, e.g. + "20080628T16:35:02" +-----------------------------------------------------------------------------*/ + unsigned int i; + + for (i = 0; i < 8 && !envP->fault_occurred; ++i) + if (!isdigit(dt[i])) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[i]); + + if (dt[8] != 'T') + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "9th character is '%c', not 'T'", + dt[8]); + if (!isdigit(dt[9])) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[9]); + if (!isdigit(dt[10])) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[10]); + if (dt[11] != ':') + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Not a colon: '%c'", dt[11]); + if (!isdigit(dt[12])) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[12]); + if (!isdigit(dt[13])) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[13]); + if (dt[14] != ':') + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Not a colon: '%c'", dt[14]); + if (!isdigit(dt[15])) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[15]); + if (!isdigit(dt[16])) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Not a digit: '%c'", dt[16]); +} + + + +static void +validateFractionalSeconds(xmlrpc_env * const envP, + const char * const dt) { +/*---------------------------------------------------------------------------- + Validate the fractional seconds part of the XML-RPC datetime string + 'dt', if any. That's the decimal point and everything following + it. +-----------------------------------------------------------------------------*/ + if (strlen(dt) > 17) { + if (dt[17] != '.') { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "'%c' where only a period is valid", dt[17]); + } else { + if (dt[18] == '\0') + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, "Nothing after decimal point"); + else { + unsigned int i; + for (i = 18; dt[i] != '\0' && !envP->fault_occurred; ++i) { + if (!isdigit(dt[i])) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Non-digit in fractional seconds: '%c'", dt[i]); + } + } + } + } +} + + + +static __inline__ void +validateFormatNoRegex(xmlrpc_env * const envP, + const char * const dt) { + + if (strlen(dt) < 17) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Invalid length of %u of datetime. " + "Must be at least 17 characters", + (unsigned)strlen(dt)); + else { + validateFirst17(envP, dt); + + validateFractionalSeconds(envP, dt); + } +} + + + +static void +validateXmlrpcDatetimeSome(xmlrpc_env * const envP, + xmlrpc_datetime const dt) { +/*---------------------------------------------------------------------------- + Type xmlrpc_datetime is defined such that it can represent a nonexistent + datetime such as February 30. + + Validate that 'dt' doesn't have glaring invalidities such as Hour 25. + We leave the possibility of more subtle invalidity such as February 30. +-----------------------------------------------------------------------------*/ + + if (dt.M < 1 || dt.M > 12) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Month of year value %u is not in the range 1-12", dt.M); + else if (dt.D < 1 || dt.D > 31) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Day of month value %u is not in the range 1-31", dt.D); + else if (dt.h > 23) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Hour of day value %u is not in the range 0-23", dt.h); + else if (dt.m > 59) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Minute of hour value %u is not in the range 0-59", dt.m); + else if (dt.s > 59) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Second of minute value %u is not in the range 0-59", dt.s); + else if (dt.u > 999999) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Microsecond of second value %u is not in the range 0-1M", dt.u); +} + + + +void +xmlrpc_parseDatetime(xmlrpc_env * const envP, + const char * const datetimeString, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Parse the content of a XML-RPC XML element, e.g. + "20000301T00:00:00". + + 'str' is that content. + + Example of the format we parse: "19980717T14:08:55" + Note that this is not quite ISO 8601. It's a bizarre combination of + two ISO 8601 formats. + + Note that Xmlrpc-c recognizes various extensions of the XML-RPC + element type. + + 'str' may not be valid XML-RPC (with extensions). In that case we fail + with fault code XMLRPC_PARSE_ERROR. +-----------------------------------------------------------------------------*/ + xmlrpc_datetime dt; + +#if HAVE_REGEX + parseDtRegex(envP, datetimeString, &dt); +#else + /* Note: validation is not as strong without regex */ + validateFormatNoRegex(envP, datetimeString); + if (!envP->fault_occurred) + parseDtNoRegex(envP, datetimeString, &dt); +#endif + + if (!envP->fault_occurred) { + validateXmlrpcDatetimeSome(envP, dt); + + if (!envP->fault_occurred) + *valuePP = xmlrpc_datetime_new(envP, dt); + } +} diff --git a/trunk/src/parse_datetime.h b/trunk/src/parse_datetime.h new file mode 100644 index 000000000..85207b7e5 --- /dev/null +++ b/trunk/src/parse_datetime.h @@ -0,0 +1,12 @@ +#ifndef PARSE_DATETIME_H_INCLUDED +#define PARSE_DATETIME_H_INCLUDED + +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/base.h" + +void +xmlrpc_parseDatetime(xmlrpc_env * const envP, + const char * const str, + xmlrpc_value ** const valuePP); + +#endif diff --git a/trunk/src/parse_value.c b/trunk/src/parse_value.c new file mode 100644 index 000000000..7886c7d9d --- /dev/null +++ b/trunk/src/parse_value.c @@ -0,0 +1,744 @@ +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "bool.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/string_number.h" +#include "xmlrpc-c/util.h" +#include "xmlparser.h" +#include "parse_datetime.h" + +#include "parse_value.h" + + + +static void +setParseFault(xmlrpc_env * const envP, + const char * const format, + ...) { + + va_list args; + va_start(args, format); + xmlrpc_set_fault_formatted_v(envP, XMLRPC_PARSE_ERROR, format, args); + va_end(args); +} + + + +static void +parseArrayDataChild(xmlrpc_env * const envP, + xml_element * const childP, + unsigned int const maxRecursion, + xmlrpc_value * const arrayP) { + + const char * const elemName = xml_element_name(childP); + + if (!xmlrpc_streq(elemName, "value")) + setParseFault(envP, " element has <%s> child. " + "Only makes sense.", elemName); + else { + xmlrpc_value * itemP; + + xmlrpc_parseValue(envP, maxRecursion-1, childP, &itemP); + + if (!envP->fault_occurred) { + xmlrpc_array_append_item(envP, arrayP, itemP); + + xmlrpc_DECREF(itemP); + } + } +} + + + +static void +parseArray(xmlrpc_env * const envP, + unsigned int const maxRecursion, + xml_element * const arrayElemP, + xmlrpc_value ** const arrayPP) { + + xmlrpc_value * arrayP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(arrayElemP != NULL); + + arrayP = xmlrpc_array_new(envP); + if (!envP->fault_occurred) { + size_t const childCount = xml_element_children_size(arrayElemP); + + if (childCount != 1) + setParseFault(envP, + " element has %u children. Only one " + "makes sense.", (unsigned int)childCount); + else { + xml_element * const dataElemP = + xml_element_children(arrayElemP)[0]; + const char * const elemName = xml_element_name(dataElemP); + + if (!xmlrpc_streq(elemName, "data")) + setParseFault(envP, + " element has <%s> child. Only " + "makes sense.", elemName); + else { + xml_element ** const values = xml_element_children(dataElemP); + unsigned int const size = xml_element_children_size(dataElemP); + + unsigned int i; + + for (i = 0; i < size && !envP->fault_occurred; ++i) + parseArrayDataChild(envP, values[i], maxRecursion, arrayP); + } + } + if (envP->fault_occurred) + xmlrpc_DECREF(arrayP); + else + *arrayPP = arrayP; + } +} + + + +static void +parseName(xmlrpc_env * const envP, + xml_element * const nameElemP, + xmlrpc_value ** const valuePP) { + + size_t const childCount = xml_element_children_size(nameElemP); + + if (childCount > 0) + setParseFault(envP, " element has %u children. " + "Should have none.", (unsigned int)childCount); + else { + const char * const cdata = xml_element_cdata(nameElemP); + size_t const cdataSize = xml_element_cdata_size(nameElemP); + + *valuePP = xmlrpc_string_new_lp(envP, cdataSize, cdata); + } +} + + + +static void +getNameChild(xmlrpc_env * const envP, + xml_element * const parentP, + xml_element * * const childPP) { + + xml_element ** const children = xml_element_children(parentP); + size_t const childCount = xml_element_children_size(parentP); + + xml_element * childP; + unsigned int i; + + for (i = 0, childP = NULL; i < childCount && !childP; ++i) { + if (xmlrpc_streq(xml_element_name(children[i]), "name")) + childP = children[i]; + } + if (!childP) + xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, + " has no child"); + else + *childPP = childP; +} + + + +static void +getValueChild(xmlrpc_env * const envP, + xml_element * const parentP, + xml_element * * const childPP) { + + xml_element ** const children = xml_element_children(parentP); + size_t const childCount = xml_element_children_size(parentP); + + xml_element * childP; + unsigned int i; + + for (i = 0, childP = NULL; i < childCount && !childP; ++i) { + if (xmlrpc_streq(xml_element_name(children[i]), "value")) + childP = children[i]; + } + if (!childP) + xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, + " has no child"); + else + *childPP = childP; +} + + + +static void +parseMember(xmlrpc_env * const envP, + xml_element * const memberP, + unsigned int const maxRecursion, + xmlrpc_value ** const keyPP, + xmlrpc_value ** const valuePP) { + + size_t const childCount = xml_element_children_size(memberP); + + if (childCount != 2) + setParseFault(envP, + " element has %u children. Only one and " + "one make sense.", (unsigned int)childCount); + else { + xml_element * nameElemP; + + getNameChild(envP, memberP, &nameElemP); + + if (!envP->fault_occurred) { + parseName(envP, nameElemP, keyPP); + + if (!envP->fault_occurred) { + xml_element * valueElemP; + + getValueChild(envP, memberP, &valueElemP); + + if (!envP->fault_occurred) + xmlrpc_parseValue(envP, maxRecursion-1, valueElemP, + valuePP); + + if (envP->fault_occurred) + xmlrpc_DECREF(*keyPP); + } + } + } +} + + + +static void +parseStruct(xmlrpc_env * const envP, + unsigned int const maxRecursion, + xml_element * const elemP, + xmlrpc_value ** const structPP) { +/*---------------------------------------------------------------------------- + Parse the element 'elemP'. +-----------------------------------------------------------------------------*/ + xmlrpc_value * structP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(elemP != NULL); + + structP = xmlrpc_struct_new(envP); + if (!envP->fault_occurred) { + /* Iterate over our children, extracting key/value pairs. */ + + xml_element ** const members = xml_element_children(elemP); + unsigned int const size = xml_element_children_size(elemP); + + unsigned int i; + + for (i = 0; i < size && !envP->fault_occurred; ++i) { + const char * const elemName = xml_element_name(members[i]); + + if (!xmlrpc_streq(elemName, "member")) + setParseFault(envP, "<%s> element found where only " + "makes sense", elemName); + else { + xmlrpc_value * keyP; + xmlrpc_value * valueP; + + parseMember(envP, members[i], maxRecursion, &keyP, &valueP); + + if (!envP->fault_occurred) { + xmlrpc_struct_set_value_v(envP, structP, keyP, valueP); + + xmlrpc_DECREF(keyP); + xmlrpc_DECREF(valueP); + } + } + } + if (envP->fault_occurred) + xmlrpc_DECREF(structP); + else + *structPP = structP; + } +} + + + +static void +parseInt(xmlrpc_env * const envP, + const char * const str, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Parse the content of a XML-RPC XML element, e.g. "34". + + 'str' is that content. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(str); + + if (str[0] == '\0') + setParseFault(envP, " XML element content is empty"); + else if (isspace(str[0])) + setParseFault(envP, " content '%s' starts with white space", + str); + else { + long i; + char * tail; + + errno = 0; + i = strtol(str, &tail, 10); + + /* Look for ERANGE. */ + if (errno == ERANGE) + setParseFault(envP, " XML element value '%s' represents a " + "number beyond the range that " + "XML-RPC allows (%d - %d)", str, + XMLRPC_INT32_MIN, XMLRPC_INT32_MAX); + else if (errno != 0) + setParseFault(envP, "unexpected error parsing XML element " + "value '%s'. strtol() failed with errno %d (%s)", + str, errno, strerror(errno)); + else { + /* Look for out-of-range errors which didn't produce ERANGE. */ + if (i < XMLRPC_INT32_MIN) + setParseFault(envP, + " value %ld is below the range allowed " + "by XML-RPC (minimum is %d)", + i, XMLRPC_INT32_MIN); + else if (i > XMLRPC_INT32_MAX) + setParseFault(envP, + " value %ld is above the range allowed " + "by XML-RPC (maximum is %d)", + i, XMLRPC_INT32_MAX); + else { + if (tail[0] != '\0') + setParseFault(envP, + " value '%s' contains non-numerical " + "junk: '%s'", str, tail); + else + *valuePP = xmlrpc_int_new(envP, i); + } + } + } +} + + + +static void +parseBoolean(xmlrpc_env * const envP, + const char * const str, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Parse the content of a XML-RPC XML element, e.g. "1". + + 'str' is that content. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(str); + + if (xmlrpc_streq(str, "0") || xmlrpc_streq(str, "1")) + *valuePP = xmlrpc_bool_new(envP, xmlrpc_streq(str, "1") ? 1 : 0); + else + setParseFault(envP, " XML element content must be either " + "'0' or '1' according to XML-RPC. This one has '%s'", + str); +} + + + +static void +scanAndValidateDoubleString(xmlrpc_env * const envP, + const char * const string, + const char ** const mantissaP, + const char ** const mantissaEndP, + const char ** const fractionP, + const char ** const fractionEndP) { + + const char * mantissa; + const char * dp; + const char * p; + + if (string[0] == '-' || string[0] == '+') + mantissa = &string[1]; + else + mantissa = &string[0]; + + for (p = mantissa, dp = NULL; *p; ++p) { + char const c = *p; + if (c == '.') { + if (dp) { + setParseFault(envP, "Two decimal points"); + return; + } else + dp = p; + } else if (c < '0' || c > '9') { + setParseFault(envP, "Garbage (not sign, digit, or period) " + "starting at '%s'", p); + return; + } + } + *mantissaP = mantissa; + if (dp) { + *mantissaEndP = dp; + *fractionP = dp+1; + *fractionEndP = p; + } else { + *mantissaEndP = p; + *fractionP = p; + *fractionEndP = p; + } +} + + + +static bool +isInfinite(double const value) { + + return value > DBL_MAX; +} + + + +static void +parseDoubleString(xmlrpc_env * const envP, + const char * const string, + double * const valueP) { +/*---------------------------------------------------------------------------- + Turn e.g. "4.3" into 4.3 . +-----------------------------------------------------------------------------*/ + /* strtod() is no good for this because it is designed for human + interfaces; it parses according to locale. As a practical + matter that sometimes means that it does not recognize "." as a + decimal point. In XML-RPC, "." is a decimal point. + + Design note: in my experiments, using strtod() was 10 times + slower than using this function. + */ + const char * mantissa; + const char * mantissaEnd; + const char * fraction; + const char * fractionEnd; + + scanAndValidateDoubleString(envP, string, &mantissa, &mantissaEnd, + &fraction, &fractionEnd); + + if (!envP->fault_occurred) { + double accum; + + accum = 0.0; + + if (mantissa == mantissaEnd && fraction == fractionEnd) { + setParseFault(envP, "No digits"); + return; + } + { + /* Add in the whole part */ + const char * p; + + for (p = mantissa; p < mantissaEnd; ++p) { + accum *= 10; + accum += (*p - '0'); + } + } + { + /* Add in the fractional part */ + double significance; + const char * p; + for (significance = 0.1, p = fraction; + p < fractionEnd; + ++p, significance *= 0.1) { + + accum += (*p - '0') * significance; + } + } + if (isInfinite(accum)) + setParseFault(envP, "Value exceeds the size allowed by XML-RPC"); + else + *valueP = string[0] == '-' ? (- accum) : accum; + } +} + + + +static void +parseDoubleStringStrtod(const char * const str, + bool * const failedP, + double * const valueP) { + + if (strlen(str) == 0) { + /* strtod() happily interprets empty string as 0.0. We don't think + the user will appreciate that XML-RPC extension. + */ + *failedP = true; + } else { + char * tail; + + errno = 0; + + *valueP = strtod(str, &tail); + + if (errno != 0) + *failedP = true; + else { + if (tail[0] != '\0') + *failedP = true; + else + *failedP = false; + } + } +} + + + +static void +parseDouble(xmlrpc_env * const envP, + const char * const str, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Parse the content of a XML-RPC XML element, e.g. "34.5". + + 'str' is that content. +-----------------------------------------------------------------------------*/ + xmlrpc_env parseEnv; + double valueDouble; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(str); + + xmlrpc_env_init(&parseEnv); + + parseDoubleString(&parseEnv, str, &valueDouble); + + if (parseEnv.fault_occurred) { + /* As an alternative, try a strtod() parsing. strtod() + accepts other forms, e.g. "3.4E6"; "3,4"; " 3.4". These + are not permitted by XML-RPC, but an almost-XML-RPC partner + might use one. In fact, for many years, Xmlrpc-c generated + such alternatives (by mistake). + */ + bool failed; + parseDoubleStringStrtod(str, &failed, &valueDouble); + if (failed) + setParseFault(envP, " element value '%s' is not a valid " + "floating point number. %s", + str, parseEnv.fault_string); + } + + if (!envP->fault_occurred) + *valuePP = xmlrpc_double_new(envP, valueDouble); + + xmlrpc_env_clean(&parseEnv); +} + + + +static void +parseBase64(xmlrpc_env * const envP, + const char * const str, + size_t const strLength, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Parse the content of a XML-RPC XML element, e.g. "FD32YY". + + 'str' is that content. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * decoded; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(str); + + decoded = xmlrpc_base64_decode(envP, str, strLength); + if (!envP->fault_occurred) { + unsigned char * const bytes = + XMLRPC_MEMBLOCK_CONTENTS(unsigned char, decoded); + size_t const byteCount = + XMLRPC_MEMBLOCK_SIZE(unsigned char, decoded); + + *valuePP = xmlrpc_base64_new(envP, byteCount, bytes); + + XMLRPC_MEMBLOCK_FREE(unsigned char, decoded); + } +} + + + +static void +parseI8(xmlrpc_env * const envP, + const char * const str, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Parse the content of a XML-RPC XML element, e.g. "34". + + 'str' is that content. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(str); + + if (str[0] == '\0') + setParseFault(envP, " XML element content is empty"); + else if (isspace(str[0])) + setParseFault(envP, + " content '%s' starts with white space", str); + else { + xmlrpc_int64 i; + xmlrpc_env env; + + xmlrpc_env_init(&env); + + xmlrpc_parse_int64(&env, str, &i); + + if (env.fault_occurred) + setParseFault(envP, " XML element value '%s' is invalid " + "because it does not represent " + "a 64 bit integer. %s", env.fault_string); + else + *valuePP = xmlrpc_i8_new(envP, i); + + xmlrpc_env_clean(&env); + } +} + + + +static void +parseSimpleValueCdata(xmlrpc_env * const envP, + const char * const elementName, + const char * const cdata, + size_t const cdataLength, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Parse an XML element that is supposedly a data type element such as + . Its name is 'elementName', and it has no children, but + contains cdata 'cdata', which is 'dataLength' characters long. +-----------------------------------------------------------------------------*/ + /* We need to straighten out the whole character set / encoding thing + some day. What is 'cdata', and what should it be? Does it have + embedded NUL? Some of the code here assumes it doesn't. Is it + text? + + The parser assumes it's UTF 8 with embedded NULs. + But the parser will get terribly confused if there are any + UTF-8 multibyte sequences or NUL characters. So will most of the + others. + + The "ex:XXX" element names are what the Apache XML-RPC facility + uses: http://ws.apache.org/xmlrpc/types.html. (Technically, it + isn't "ex" but an arbitrary prefix that identifies a namespace + declared earlier in the XML document -- this is an XML thing. + But we aren't nearly sophisticated enough to use real XML + namespaces, so we exploit the fact that XML-RPC actually uses + "ex"). + + "i1" and "i2" are just from my imagination. + */ + + if (xmlrpc_streq(elementName, "int") || + xmlrpc_streq(elementName, "i4") || + xmlrpc_streq(elementName, "i1") || + xmlrpc_streq(elementName, "i2") || + xmlrpc_streq(elementName, "ex:i1") || + xmlrpc_streq(elementName, "ex:i2")) + parseInt(envP, cdata, valuePP); + else if (xmlrpc_streq(elementName, "boolean")) + parseBoolean(envP, cdata, valuePP); + else if (xmlrpc_streq(elementName, "double")) + parseDouble(envP, cdata, valuePP); + else if (xmlrpc_streq(elementName, "dateTime.iso8601")) + xmlrpc_parseDatetime(envP, cdata, valuePP); + else if (xmlrpc_streq(elementName, "string")) + *valuePP = xmlrpc_string_new_lp(envP, cdataLength, cdata); + else if (xmlrpc_streq(elementName, "base64")) + parseBase64(envP, cdata, cdataLength, valuePP); + else if (xmlrpc_streq(elementName, "nil") || + xmlrpc_streq(elementName, "ex:nil")) + *valuePP = xmlrpc_nil_new(envP); + else if (xmlrpc_streq(elementName, "i8") || + xmlrpc_streq(elementName, "ex:i8")) + parseI8(envP, cdata, valuePP); + else + setParseFault(envP, "Unknown value type -- XML element is named " + "<%s>", elementName); +} + + + +static void +parseSimpleValue(xmlrpc_env * const envP, + xml_element * const elemP, + xmlrpc_value ** const valuePP) { + + size_t const childCount = xml_element_children_size(elemP); + + if (childCount > 0) + setParseFault(envP, "The child of a element " + "is neither nor , " + "but has %u child elements of its own.", + (unsigned int)childCount); + else { + const char * const elemName = xml_element_name(elemP); + const char * const cdata = xml_element_cdata(elemP); + size_t const cdataSize = xml_element_cdata_size(elemP); + + parseSimpleValueCdata(envP, elemName, cdata, cdataSize, valuePP); + } +} + + + +void +xmlrpc_parseValue(xmlrpc_env * const envP, + unsigned int const maxRecursion, + xml_element * const elemP, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Compute the xmlrpc_value represented by the XML element 'elem'. + Return that xmlrpc_value. + + We call convert_array() and convert_struct(), which may ultimately + call us recursively. Don't recurse any more than 'maxRecursion' + times. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(elemP != NULL); + + /* Assume we'll need to recurse, make sure we're allowed */ + if (maxRecursion < 1) + xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, + "Nested data structure too deep."); + else { + if (!xmlrpc_streq(xml_element_name(elemP), "value")) + setParseFault(envP, + "<%s> element where expected", + xml_element_name(elemP)); + else { + size_t const childCount = xml_element_children_size(elemP); + + if (childCount == 0) { + /* We have no type element, so treat the value as a string. */ + const char * const cdata = xml_element_cdata(elemP); + size_t const cdata_size = xml_element_cdata_size(elemP); + *valuePP = xmlrpc_string_new_lp(envP, cdata_size, cdata); + } else if (childCount > 1) + setParseFault(envP, " has %u child elements. " + "Only zero or one make sense.", + (unsigned int)childCount); + else { + /* We should have a type tag inside our value tag. */ + xml_element * const childP = xml_element_children(elemP)[0]; + const char * const childName = xml_element_name(childP); + + if (xmlrpc_streq(childName, "struct")) + parseStruct(envP, maxRecursion, childP, valuePP); + else if (xmlrpc_streq(childName, "array")) + parseArray(envP, maxRecursion, childP, valuePP); + else + parseSimpleValue(envP, childP, valuePP); + } + } + } +} + + + diff --git a/trunk/src/parse_value.h b/trunk/src/parse_value.h new file mode 100644 index 000000000..bca801113 --- /dev/null +++ b/trunk/src/parse_value.h @@ -0,0 +1,13 @@ +#ifndef PARSE_VALUE_H_INCLUDED +#define PARSE_VALUE_H_INCLUDED + +#include "xmlrpc-c/base.h" +#include "xmlparser.h" + +void +xmlrpc_parseValue(xmlrpc_env * const envP, + unsigned int const maxRecursion, + xml_element * const elemP, + xmlrpc_value ** const valuePP); + +#endif diff --git a/trunk/src/parse_xml.c b/trunk/src/parse_xml.c new file mode 100644 index 000000000..2618a72df --- /dev/null +++ b/trunk/src/parse_xml.c @@ -0,0 +1,103 @@ +/*============================================================================= + parse_xml +=============================================================================== + This is an example of using the XML parsing facilities of + XML-RPC For C/C++, in particular its libxmlrpc_xmlparse library. + + Feed XML (any XML - doesn't have to be XML-RPC) to this program as + standard input. It parses it and tells you what it sees. + + Example: + + $ ./gen_sample_add_xml | ./parse_xml + +=============================================================================*/ +#include +#include +#include + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/xmlparser.h" + + + +static const char * +getStdin(void) { + + size_t const maxInputSize = 64 * 1024; + char * retval; + + retval = malloc(maxInputSize + 1); + + if (retval == NULL) { + fprintf(stderr, "malloc failed."); + exit(100); + } else { + size_t rc; + + rc = fread(retval, 1, maxInputSize, stdin); + + if (rc < 0) + fprintf(stderr, "Failed to read Standard Input"); + else { + size_t const bytesRead = rc; + retval[bytesRead] = '\0'; + } + } + return retval; +} + + + +static void +describeXmlElement(const xml_element * const elemP, + const char * const prefix) { + + unsigned int i; + + printf("%sXML element type: '%s'\n", + prefix, xml_element_name(elemP)); + + printf("%sCdata: '%s'\n", + prefix, xml_element_cdata(elemP)); + + printf("%sNumber of child elements: %u\n", + prefix, xml_element_children_size(elemP)); + + if (xml_element_children_size(elemP) == 0) + printf("\n"); + + for (i = 0; i < xml_element_children_size(elemP); ++i) { + char * const newPrefix = malloc(strlen(prefix) + 2); + sprintf(newPrefix, "%s ", prefix); + describeXmlElement(xml_element_children(elemP)[i], newPrefix); + free(newPrefix); + } +} + + + +int +main(int argc, const char ** argv) { + + const char * xml; + xmlrpc_env env; + xml_element * elemP; + + xmlrpc_env_init(&env); + + xml = getStdin(); + + xml_parse(&env, xml, strlen(xml), &elemP); + + if (env.fault_occurred) + printf("xml_parse failed. %s\n", env.fault_string); + else { + printf("Parsed successfully.\n"); + + describeXmlElement(elemP, ""); + } + xmlrpc_env_clean(&env); + + return 0; +} diff --git a/trunk/src/registry.c b/trunk/src/registry.c new file mode 100644 index 000000000..4dae56515 --- /dev/null +++ b/trunk/src/registry.c @@ -0,0 +1,499 @@ +/*========================================================================= + XML-RPC Server Method Registry +=========================================================================== + These are the functions that implement the XML-RPC method registry. + + A method registry is a list of XML-RPC methods for a server to + implement, along with the details of how to implement each -- most + notably a function pointer for a function that executes the method. + + To build an XML-RPC server, just add a communication facility. + + Copyright information is at end of file + +=========================================================================*/ + +#include +#include +#include + +#include "xmlrpc_config.h" +#include "bool.h" +#include "mallocvar.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "method.h" +#include "system_method.h" +#include "version.h" + +#include "registry.h" + + +unsigned int const xmlrpc_server_version_major = XMLRPC_VERSION_MAJOR; +unsigned int const xmlrpc_server_version_minor = XMLRPC_VERSION_MINOR; +unsigned int const xmlrpc_server_version_point = XMLRPC_VERSION_POINT; + + + +void +xmlrpc_server_version(unsigned int * const majorP, + unsigned int * const minorP, + unsigned int * const pointP) { + + *majorP = XMLRPC_VERSION_MAJOR; + *minorP = XMLRPC_VERSION_MINOR; + *pointP = XMLRPC_VERSION_POINT; +} + + + +xmlrpc_registry * +xmlrpc_registry_new(xmlrpc_env * const envP) { + + xmlrpc_registry * registryP; + + XMLRPC_ASSERT_ENV_OK(envP); + + MALLOCVAR(registryP); + + if (registryP == NULL) + xmlrpc_faultf(envP, "Could not allocate memory for registry"); + else { + registryP->introspectionEnabled = true; + registryP->defaultMethodFunction = NULL; + registryP->preinvokeFunction = NULL; + registryP->shutdownServerFn = NULL; + registryP->dialect = xmlrpc_dialect_i8; + + xmlrpc_methodListCreate(envP, ®istryP->methodListP); + if (!envP->fault_occurred) + xmlrpc_installSystemMethods(envP, registryP); + + if (envP->fault_occurred) + free(registryP); + } + return registryP; +} + + + +void +xmlrpc_registry_free(xmlrpc_registry * const registryP) { + + XMLRPC_ASSERT_PTR_OK(registryP); + + xmlrpc_methodListDestroy(registryP->methodListP); + + free(registryP); +} + + + +static void +registryAddMethod(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const char * const methodName, + xmlrpc_method1 method1, + xmlrpc_method2 method2, + const char * const signatureString, + const char * const help, + void * const userData, + size_t const stackSize) { + + const char * const helpString = + help ? help : "No help is available for this method."; + + xmlrpc_methodInfo * methodP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(registryP); + XMLRPC_ASSERT_PTR_OK(methodName); + XMLRPC_ASSERT(method1 != NULL || method2 != NULL); + + xmlrpc_methodCreate(envP, method1, method2, userData, + signatureString, helpString, stackSize, &methodP); + + if (!envP->fault_occurred) { + xmlrpc_methodListAdd(envP, registryP->methodListP, methodName, + methodP); + + if (envP->fault_occurred) + xmlrpc_methodDestroy(methodP); + } +} + + + +void +xmlrpc_registry_add_method_w_doc( + xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const char * const host ATTR_UNUSED, + const char * const methodName, + xmlrpc_method1 const method, + void * const serverInfo, + const char * const signatureString, + const char * const help) { + + XMLRPC_ASSERT(host == NULL); + + registryAddMethod(envP, registryP, methodName, method, NULL, + signatureString, help, serverInfo, 0); +} + + + +void +xmlrpc_registry_add_method(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const char * const host, + const char * const methodName, + xmlrpc_method1 const method, + void * const serverInfoP) { + + xmlrpc_registry_add_method_w_doc( + envP, registryP, host, methodName, + method, serverInfoP, "?", "No help is available for this method."); +} + + + +void +xmlrpc_registry_add_method2(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const char * const methodName, + xmlrpc_method2 method, + const char * const signatureString, + const char * const help, + void * const serverInfo) { + + registryAddMethod(envP, registryP, methodName, NULL, method, + signatureString, help, serverInfo, 0); +} + + + +void +xmlrpc_registry_add_method3( + xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const struct xmlrpc_method_info3 * const infoP) { + + registryAddMethod(envP, registryP, infoP->methodName, NULL, + infoP->methodFunction, + infoP->signatureString, infoP->help, infoP->serverInfo, + infoP->stackSize); +} + + + +void +xmlrpc_registry_set_default_method( + xmlrpc_env * const envP ATTR_UNUSED, + xmlrpc_registry * const registryP ATTR_UNUSED, + xmlrpc_default_method const function, + void * const userData) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(registryP); + XMLRPC_ASSERT_PTR_OK(function); + + /* Note: this may be the first default method, or it may be a replacement + of the current one. + */ + + registryP->defaultMethodFunction = function; + registryP->defaultMethodUserData = userData; +} + + + +/* This is our guess at what a method function requires when the user + doesn't say. +*/ +#define METHOD_FUNCTION_STACK 128*1024 + + + +static size_t +methodStackSize(const xmlrpc_methodInfo * const methodP) { + + return methodP->stackSize == + 0 ? METHOD_FUNCTION_STACK : methodP->stackSize; +} + + + +size_t +xmlrpc_registry_max_stackSize(xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Return the maximum amount of stack required by the methods in registry + *registryP. + + If there are no methods, return 0. +-----------------------------------------------------------------------------*/ + xmlrpc_methodNode * p; + size_t stackSize; + + for (p = registryP->methodListP->firstMethodP, stackSize = 0; + p; + p = p->nextP) { + + stackSize = MAX(stackSize, methodStackSize(p->methodP)); + } + return stackSize; +} + + + +void +xmlrpc_registry_set_preinvoke_method( + xmlrpc_env * const envP ATTR_UNUSED, + xmlrpc_registry * const registryP ATTR_UNUSED, + xmlrpc_preinvoke_method const function, + void * const userData) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(registryP); + XMLRPC_ASSERT_PTR_OK(function); + + registryP->preinvokeFunction = function; + registryP->preinvokeUserData = userData; +} + + + +void +xmlrpc_registry_set_shutdown(xmlrpc_registry * const registryP, + xmlrpc_server_shutdown_fn * const shutdownFn, + void * const context) { + + XMLRPC_ASSERT_PTR_OK(registryP); + XMLRPC_ASSERT_PTR_OK(shutdownFn); + + registryP->shutdownServerFn = shutdownFn; + + registryP->shutdownContext = context; +} + + + +void +xmlrpc_registry_set_dialect(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + xmlrpc_dialect const dialect) { + + if (dialect != xmlrpc_dialect_i8 && + dialect != xmlrpc_dialect_apache) + xmlrpc_faultf(envP, "Invalid dialect argument -- not of type " + "xmlrpc_dialect. Numerical value is %u", dialect); + else + registryP->dialect = dialect; +} + + + +static void +callNamedMethod(xmlrpc_env * const envP, + xmlrpc_methodInfo * const methodP, + xmlrpc_value * const paramArrayP, + void * const callInfoP, + xmlrpc_value ** const resultPP) { + + if (methodP->methodFnType2) + *resultPP = + methodP->methodFnType2(envP, paramArrayP, + methodP->userData, callInfoP); + else { + assert(methodP->methodFnType1); + *resultPP = + methodP->methodFnType1(envP, paramArrayP, methodP->userData); + } +} + + + +void +xmlrpc_dispatchCall(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const char * const methodName, + xmlrpc_value * const paramArrayP, + void * const callInfoP, + xmlrpc_value ** const resultPP) { + + if (registryP->preinvokeFunction) + registryP->preinvokeFunction(envP, methodName, paramArrayP, + registryP->preinvokeUserData); + + if (!envP->fault_occurred) { + xmlrpc_methodInfo * methodP; + + xmlrpc_methodListLookupByName(registryP->methodListP, methodName, + &methodP); + + if (methodP) + callNamedMethod(envP, methodP, paramArrayP, callInfoP, resultPP); + else { + if (registryP->defaultMethodFunction) + *resultPP = registryP->defaultMethodFunction( + envP, callInfoP, methodName, paramArrayP, + registryP->defaultMethodUserData); + else { + /* No matching method, and no default. */ + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_NO_SUCH_METHOD_ERROR, + "Method '%s' not defined", methodName); + } + } + } + /* For backward compatibility, for sloppy users: */ + if (envP->fault_occurred) + *resultPP = NULL; +} + + + +/*========================================================================= +** xmlrpc_registry_process_call +**========================================================================= +** +*/ + +static void +serializeFault(xmlrpc_env * const envP, + xmlrpc_env const fault, + xmlrpc_mem_block * const responseXmlP) { + + xmlrpc_env env; + + xmlrpc_env_init(&env); + + xmlrpc_serialize_fault(&env, responseXmlP, &fault); + + if (env.fault_occurred) + xmlrpc_faultf(envP, + "Executed XML-RPC method completely and it " + "generated a fault response, but we failed " + "to encode that fault response as XML-RPC " + "so we could send it to the client. %s", + env.fault_string); + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_registry_process_call2(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const char * const callXml, + size_t const callXmlLen, + void * const callInfo, + xmlrpc_mem_block ** const responseXmlPP) { + + xmlrpc_mem_block * responseXmlP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(callXml); + + xmlrpc_traceXml("XML-RPC CALL", callXml, callXmlLen); + + /* Allocate our output buffer. + ** If this fails, we need to die in a special fashion. */ + responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + if (!envP->fault_occurred) { + const char * methodName; + xmlrpc_value * paramArrayP; + xmlrpc_env fault; + xmlrpc_env parseEnv; + + xmlrpc_env_init(&fault); + xmlrpc_env_init(&parseEnv); + + xmlrpc_parse_call(&parseEnv, callXml, callXmlLen, + &methodName, ¶mArrayP); + + if (parseEnv.fault_occurred) + xmlrpc_env_set_fault_formatted( + &fault, XMLRPC_PARSE_ERROR, + "Call XML not a proper XML-RPC call. %s", + parseEnv.fault_string); + else { + xmlrpc_value * resultP; + + xmlrpc_dispatchCall(&fault, registryP, methodName, paramArrayP, + callInfo, &resultP); + + if (!fault.fault_occurred) { + xmlrpc_serialize_response2(envP, responseXmlP, + resultP, registryP->dialect); + + xmlrpc_DECREF(resultP); + } + xmlrpc_strfree(methodName); + xmlrpc_DECREF(paramArrayP); + } + if (!envP->fault_occurred && fault.fault_occurred) + serializeFault(envP, fault, responseXmlP); + + xmlrpc_env_clean(&parseEnv); + xmlrpc_env_clean(&fault); + + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, responseXmlP); + else { + *responseXmlPP = responseXmlP; + xmlrpc_traceXml("XML-RPC RESPONSE", + XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlP), + XMLRPC_MEMBLOCK_SIZE(char, responseXmlP)); + } + } +} + + + +xmlrpc_mem_block * +xmlrpc_registry_process_call(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const char * const host ATTR_UNUSED, + const char * const callXml, + size_t const callXmlLen) { + + xmlrpc_mem_block * responseXmlP; + + xmlrpc_registry_process_call2(envP, registryP, callXml, callXmlLen, NULL, + &responseXmlP); + + return responseXmlP; +} + + + +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** Copyright (C) 2001 by Eric Kidd. All rights reserved. +** Copyright (C) 2001 by Luke Howard. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ diff --git a/trunk/src/registry.h b/trunk/src/registry.h new file mode 100644 index 000000000..509d57886 --- /dev/null +++ b/trunk/src/registry.h @@ -0,0 +1,15 @@ +#ifndef REGISTRY_H_INCLUDED +#define REGISTRY_H_INCLUDED + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" + +void +xmlrpc_dispatchCall(struct _xmlrpc_env * const envP, + struct xmlrpc_registry * const registryP, + const char * const methodName, + struct _xmlrpc_value * const paramArrayP, + void * const callInfoP, + struct _xmlrpc_value ** const resultPP); + +#endif diff --git a/trunk/src/resource.c b/trunk/src/resource.c new file mode 100644 index 000000000..bed48a060 --- /dev/null +++ b/trunk/src/resource.c @@ -0,0 +1,31 @@ +#include "xmlrpc_config.h" + +#include "xmlrpc-c/base.h" + + +/*========================================================================= +** Resource Limits +**========================================================================= +*/ + +static size_t limits[XMLRPC_LAST_LIMIT_ID + 1] = { + XMLRPC_NESTING_LIMIT_DEFAULT, + XMLRPC_XML_SIZE_LIMIT_DEFAULT +}; + +void +xmlrpc_limit_set (int const limit_id, + size_t const value) { + + XMLRPC_ASSERT(0 <= limit_id && limit_id <= XMLRPC_LAST_LIMIT_ID); + limits[limit_id] = value; +} + + + +size_t +xmlrpc_limit_get(int const limit_id) { + + XMLRPC_ASSERT(0 <= limit_id && limit_id <= XMLRPC_LAST_LIMIT_ID); + return limits[limit_id]; +} diff --git a/trunk/src/system_method.c b/trunk/src/system_method.c new file mode 100644 index 000000000..bc6cf4999 --- /dev/null +++ b/trunk/src/system_method.c @@ -0,0 +1,886 @@ +/* Copyright information is at end of file */ + +#include "xmlrpc_config.h" + +#include +#include +#include + +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "version.h" +#include "registry.h" +#include "method.h" + +#include "system_method.h" + + +struct systemMethodReg { +/*---------------------------------------------------------------------------- + Information needed to register a system method +-----------------------------------------------------------------------------*/ + const char * const methodName; + xmlrpc_method2 const methodFunction; + const char * const signatureString; + const char * const helpText; +}; + + + +void +xmlrpc_registry_disable_introspection(xmlrpc_registry * const registryP) { + + XMLRPC_ASSERT_PTR_OK(registryP); + + registryP->introspectionEnabled = false; +} + + + +/*========================================================================= + system.multicall +=========================================================================*/ + +static void +callOneMethod(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + xmlrpc_value * const rpcDescP, + void * const callInfo, + xmlrpc_value ** const resultPP) { + + const char * methodName; + xmlrpc_value * paramArrayP; + + XMLRPC_ASSERT_ENV_OK(envP); + + if (xmlrpc_value_type(rpcDescP) != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, + "An element of the multicall array is type %u, but should " + "be a struct (with members 'methodName' and 'params')", + xmlrpc_value_type(rpcDescP)); + else { + xmlrpc_decompose_value(envP, rpcDescP, "{s:s,s:A,*}", + "methodName", &methodName, + "params", ¶mArrayP); + if (!envP->fault_occurred) { + /* Watch out for a deep recursion attack. */ + if (xmlrpc_streq(methodName, "system.multicall")) + xmlrpc_env_set_fault_formatted( + envP, + XMLRPC_REQUEST_REFUSED_ERROR, + "Recursive system.multicall forbidden"); + else { + xmlrpc_env env; + xmlrpc_value * resultValP; + + xmlrpc_env_init(&env); + xmlrpc_dispatchCall(&env, registryP, methodName, paramArrayP, + callInfo, + &resultValP); + if (env.fault_occurred) { + /* Method failed, so result is a fault structure */ + *resultPP = + xmlrpc_build_value( + envP, "{s:i,s:s}", + "faultCode", (xmlrpc_int32) env.fault_code, + "faultString", env.fault_string); + } else { + *resultPP = xmlrpc_build_value(envP, "(V)", resultValP); + + xmlrpc_DECREF(resultValP); + } + xmlrpc_env_clean(&env); + } + xmlrpc_DECREF(paramArrayP); + xmlrpc_strfree(methodName); + } + } +} + + + +static void +getMethListFromMulticallPlist(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + xmlrpc_value ** const methlistPP) { + + if (xmlrpc_array_size(envP, paramArrayP) != 1) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "system.multicall takes one parameter, which is an " + "array, each element describing one RPC. You " + "supplied %u arguments", + xmlrpc_array_size(envP, paramArrayP)); + else { + xmlrpc_value * methlistP; + + xmlrpc_array_read_item(envP, paramArrayP, 0, &methlistP); + + XMLRPC_ASSERT_ENV_OK(envP); + + if (xmlrpc_value_type(methlistP) != XMLRPC_TYPE_ARRAY) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, + "system.multicall's parameter should be an array, " + "each element describing one RPC. But it is type " + "%u instead.", xmlrpc_value_type(methlistP)); + else + *methlistPP = methlistP; + + if (envP->fault_occurred) + xmlrpc_DECREF(methlistP); + } +} + + + +static xmlrpc_value * +system_multicall(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo) { + + xmlrpc_registry * registryP; + xmlrpc_value * resultsP; + xmlrpc_value * methlistP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_ARRAY_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(serverInfo); + + resultsP = NULL; /* defeat compiler warning */ + + /* Turn our arguments into something more useful. */ + registryP = (xmlrpc_registry*) serverInfo; + + getMethListFromMulticallPlist(envP, paramArrayP, &methlistP); + if (!envP->fault_occurred) { + /* Create an initially empty result list. */ + resultsP = xmlrpc_array_new(envP); + if (!envP->fault_occurred) { + /* Loop over our input list, calling each method in turn. */ + unsigned int const methodCount = + xmlrpc_array_size(envP, methlistP); + unsigned int i; + for (i = 0; i < methodCount && !envP->fault_occurred; ++i) { + xmlrpc_value * const methinfoP = + xmlrpc_array_get_item(envP, methlistP, i); + + xmlrpc_value * resultP; + + XMLRPC_ASSERT_ENV_OK(envP); + + callOneMethod(envP, registryP, methinfoP, callInfo, &resultP); + + if (!envP->fault_occurred) { + /* Append this method result to our master array. */ + xmlrpc_array_append_item(envP, resultsP, resultP); + xmlrpc_DECREF(resultP); + } + } + if (envP->fault_occurred) + xmlrpc_DECREF(resultsP); + xmlrpc_DECREF(methlistP); + } + } + return resultsP; +} + + + +static struct systemMethodReg const methodMulticall = { + "system.multicall", + &system_multicall, + "A:A", + "Process an array of calls, and return an array of results. Calls should " + "be structs of the form {'methodName': string, 'params': array}. Each " + "result will either be a single-item array containg the result value, or " + "a struct of the form {'faultCode': int, 'faultString': string}. This " + "is useful when you need to make lots of small calls without lots of " + "round trips.", +}; + + +/*========================================================================= + system.listMethods +=========================================================================*/ + + +static void +createMethodListArray(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + xmlrpc_value ** const methodListPP) { +/*---------------------------------------------------------------------------- + Create as an XML-RPC array value a list of names of methods registered + in registry 'registryP'. + + This is the type of value that the system.listMethods method is supposed + to return. +-----------------------------------------------------------------------------*/ + xmlrpc_value * methodListP; + + methodListP = xmlrpc_array_new(envP); + + if (!envP->fault_occurred) { + xmlrpc_methodNode * methodNodeP; + for (methodNodeP = registryP->methodListP->firstMethodP; + methodNodeP && !envP->fault_occurred; + methodNodeP = methodNodeP->nextP) { + + xmlrpc_value * methodNameVP; + + methodNameVP = xmlrpc_string_new(envP, methodNodeP->methodName); + + if (!envP->fault_occurred) { + xmlrpc_array_append_item(envP, methodListP, methodNameVP); + + xmlrpc_DECREF(methodNameVP); + } + } + if (envP->fault_occurred) + xmlrpc_DECREF(methodListP); + } + *methodListPP = methodListP; +} + + + +static xmlrpc_value * +system_listMethods(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo ATTR_UNUSED) { + + xmlrpc_registry * const registryP = serverInfo; + + xmlrpc_value * retvalP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(serverInfo); + + xmlrpc_decompose_value(envP, paramArrayP, "()"); + if (!envP->fault_occurred) { + if (!registryP->introspectionEnabled) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INTROSPECTION_DISABLED_ERROR, + "Introspection is disabled in this server " + "for security reasons"); + else + createMethodListArray(envP, registryP, &retvalP); + } + return retvalP; +} + + + +static struct systemMethodReg const methodListMethods = { + "system.listMethods", + &system_listMethods, + "A:", + "Return an array of all available XML-RPC methods on this server.", +}; + + + +/*========================================================================= + system.methodExist +==========================================================================*/ + +static void +determineMethodExistence(xmlrpc_env * const envP, + const char * const methodName, + xmlrpc_registry * const registryP, + xmlrpc_value ** const existsPP) { + + xmlrpc_methodInfo * methodP; + + xmlrpc_methodListLookupByName(registryP->methodListP, methodName, + &methodP); + + *existsPP = xmlrpc_bool_new(envP, !!methodP); +} + + + +static xmlrpc_value * +system_methodExist(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo ATTR_UNUSED) { + + xmlrpc_registry * const registryP = serverInfo; + + xmlrpc_value * retvalP; + + const char * methodName; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(serverInfo); + + xmlrpc_decompose_value(envP, paramArrayP, "(s)", &methodName); + + if (!envP->fault_occurred) { + determineMethodExistence(envP, methodName, registryP, &retvalP); + + xmlrpc_strfree(methodName); + } + + return retvalP; +} + + + +static struct systemMethodReg const methodMethodExist = { + "system.methodExist", + &system_methodExist, + "s:b", + "Tell whether a method by a specified name exists on this server", +}; + + + +/*========================================================================= + system.methodHelp +=========================================================================*/ + + +static void +getHelpString(xmlrpc_env * const envP, + const char * const methodName, + xmlrpc_registry * const registryP, + xmlrpc_value ** const helpStringPP) { + + xmlrpc_methodInfo * methodP; + + xmlrpc_methodListLookupByName(registryP->methodListP, methodName, + &methodP); + + if (!methodP) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_NO_SUCH_METHOD_ERROR, + "Method '%s' does not exist", methodName); + else + *helpStringPP = xmlrpc_string_new(envP, methodP->helpText); +} + + + +static xmlrpc_value * +system_methodHelp(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo ATTR_UNUSED) { + + xmlrpc_registry * const registryP = serverInfo; + + xmlrpc_value * retvalP; + + const char * methodName; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(serverInfo); + + xmlrpc_decompose_value(envP, paramArrayP, "(s)", &methodName); + + if (!envP->fault_occurred) { + if (!registryP->introspectionEnabled) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INTROSPECTION_DISABLED_ERROR, + "Introspection is disabled in this server " + "for security reasons"); + else + getHelpString(envP, methodName, registryP, &retvalP); + + xmlrpc_strfree(methodName); + } + + return retvalP; +} + + +static struct systemMethodReg const methodMethodHelp = { + "system.methodHelp", + &system_methodHelp, + "s:s", + "Given the name of a method, return a help string.", +}; + + + +/*========================================================================= + system.methodSignature +==========================================================================*/ + +static void +buildNoSigSuppliedResult(xmlrpc_env * const envP, + xmlrpc_value ** const resultPP) { + + xmlrpc_env env; + + xmlrpc_env_init(&env); + + *resultPP = xmlrpc_string_new(&env, "undef"); + if (env.fault_occurred) + xmlrpc_faultf(envP, "Unable to construct 'undef'. %s", + env.fault_string); + + xmlrpc_env_clean(&env); +} + + + +static void +buildSignatureValue(xmlrpc_env * const envP, + struct xmlrpc_signature * const signatureP, + xmlrpc_value ** const sigValuePP) { + + xmlrpc_value * sigValueP; + unsigned int i; + + sigValueP = xmlrpc_array_new(envP); + + { + xmlrpc_value * retTypeVP; + + retTypeVP = xmlrpc_string_new(envP, signatureP->retType); + + xmlrpc_array_append_item(envP, sigValueP, retTypeVP); + + xmlrpc_DECREF(retTypeVP); + } + for (i = 0; i < signatureP->argCount && !envP->fault_occurred; ++i) { + xmlrpc_value * argTypeVP; + + argTypeVP = xmlrpc_string_new(envP, signatureP->argList[i]); + if (!envP->fault_occurred) { + xmlrpc_array_append_item(envP, sigValueP, argTypeVP); + + xmlrpc_DECREF(argTypeVP); + } + } + + if (envP->fault_occurred) + xmlrpc_DECREF(sigValueP); + + *sigValuePP = sigValueP; +} + + + +static void +getSignatureList(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const char * const methodName, + xmlrpc_value ** const signatureListPP) { +/*---------------------------------------------------------------------------- + Get the signature list array for method named 'methodName' from registry + 'registryP'. + + If there is no signature information for the method in the registry, + return *signatureListPP == NULL. + + Nonexistent method is considered a failure. +-----------------------------------------------------------------------------*/ + xmlrpc_methodInfo * methodP; + + xmlrpc_methodListLookupByName(registryP->methodListP, methodName, + &methodP); + + if (!methodP) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_NO_SUCH_METHOD_ERROR, + "Method '%s' does not exist", methodName); + else { + if (!methodP->signatureListP->firstSignatureP) + *signatureListPP = NULL; + else { + xmlrpc_value * signatureListP; + + signatureListP = xmlrpc_array_new(envP); + + if (!envP->fault_occurred) { + struct xmlrpc_signature * signatureP; + for (signatureP = methodP->signatureListP->firstSignatureP; + signatureP && !envP->fault_occurred; + signatureP = signatureP->nextP) { + + xmlrpc_value * signatureVP; + + buildSignatureValue(envP, signatureP, &signatureVP); + + xmlrpc_array_append_item(envP, + signatureListP, signatureVP); + + xmlrpc_DECREF(signatureVP); + } + if (envP->fault_occurred) + xmlrpc_DECREF(signatureListP); + } + *signatureListPP = signatureListP; + } + } +} + + + +/* Microsoft Visual C in debug mode produces code that complains about + returning an undefined value from system_methodSignature(). It's a bogus + complaint, because this function is defined to return nothing meaningful + those cases. So we disable the check. +*/ +#pragma runtime_checks("u", off) + + + +static xmlrpc_value * +system_methodSignature(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo ATTR_UNUSED) { + + xmlrpc_registry * const registryP = (xmlrpc_registry *) serverInfo; + + xmlrpc_value * retvalP; + const char * methodName; + xmlrpc_env env; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(serverInfo); + + xmlrpc_env_init(&env); + + /* Turn our arguments into something more useful. */ + xmlrpc_decompose_value(&env, paramArrayP, "(s)", &methodName); + if (env.fault_occurred) + xmlrpc_env_set_fault_formatted( + envP, env.fault_code, + "Invalid parameter list. %s", env.fault_string); + else { + if (!registryP->introspectionEnabled) + xmlrpc_env_set_fault(envP, XMLRPC_INTROSPECTION_DISABLED_ERROR, + "Introspection disabled on this server"); + else { + xmlrpc_value * signatureListP; + + getSignatureList(envP, registryP, methodName, &signatureListP); + + if (!envP->fault_occurred) { + if (signatureListP) + retvalP = signatureListP; + else + buildNoSigSuppliedResult(envP, &retvalP); + } + } + xmlrpc_strfree(methodName); + } + xmlrpc_env_clean(&env); + + return retvalP; +} + + + +#pragma runtime_checks("u", restore) + + + +static struct systemMethodReg const methodMethodSignature = { + "system.methodSignature", + &system_methodSignature, + "A:s", + "Given the name of a method, return an array of legal signatures. " + "Each signature is an array of strings. The first item of each signature " + "is the return type, and any others items are parameter types.", +}; + + + + +/*========================================================================= + system.shutdown +==========================================================================*/ + +static xmlrpc_value * +system_shutdown(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo) { + + xmlrpc_registry * const registryP = (xmlrpc_registry *) serverInfo; + + xmlrpc_value * retvalP; + const char * comment; + xmlrpc_env env; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(serverInfo); + + xmlrpc_env_init(&env); + + /* Turn our arguments into something more useful. */ + xmlrpc_decompose_value(&env, paramArrayP, "(s)", &comment); + if (env.fault_occurred) + xmlrpc_env_set_fault_formatted( + envP, env.fault_code, + "Invalid parameter list. %s", env.fault_string); + else { + if (!registryP->shutdownServerFn) + xmlrpc_env_set_fault( + envP, 0, "This server program is not capable of " + "shutting down"); + else { + registryP->shutdownServerFn( + &env, registryP->shutdownContext, comment, callInfo); + + if (env.fault_occurred) + xmlrpc_env_set_fault(envP, env.fault_code, env.fault_string); + else { + retvalP = xmlrpc_int_new(&env, 0); + + if (env.fault_occurred) + xmlrpc_faultf(envP, + "Failed to construct return value. %s", + env.fault_string); + } + } + xmlrpc_strfree(comment); + } + xmlrpc_env_clean(&env); + + return retvalP; +} + + + +static struct systemMethodReg const methodShutdown = { + "system.shutdown", + &system_shutdown, + "i:s", + "Shut down the server. Return code is always zero.", +}; + + + +/*========================================================================= + system.capabilities +=========================================================================*/ + +static void +constructCapabilities(xmlrpc_env * const envP, + xmlrpc_registry * const registryP ATTR_UNUSED, + xmlrpc_value ** const capabilitiesPP) { + + *capabilitiesPP = + xmlrpc_build_value( + envP, "{s:s,s:i,s:i,s:i,s:i}", + "facility", "xmlrpc-c", + "version_major", XMLRPC_VERSION_MAJOR, + "version_minor", XMLRPC_VERSION_MINOR, + "version_point", XMLRPC_VERSION_POINT, + "protocol_version", 2 + ); + +} + + + +static xmlrpc_value * +system_capabilities(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo ATTR_UNUSED) { + + xmlrpc_registry * const registryP = serverInfo; + + xmlrpc_value * retvalP; + + unsigned int paramCount; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(serverInfo); + + paramCount = xmlrpc_array_size(envP, paramArrayP); + + if (paramCount > 0) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, + "There are no parameters. You supplied %u", paramCount); + else + constructCapabilities(envP, registryP, &retvalP); + + return retvalP; +} + + + +static struct systemMethodReg const methodCapabilities = { + "system.capabilities", + &system_capabilities, + "S:", + "Return the capabilities of XML-RPC server. This includes the " + "version number of the XML-RPC For C/C++ software" +}; + + + +/*========================================================================= + system.getCapabilities +=========================================================================*/ + +/* This implements a standard. + See http://tech.groups.yahoo.com/group/xml-rpc/message/2897 . +*/ + +static void +listCapabilities(xmlrpc_env * const envP, + xmlrpc_registry * const registryP ATTR_UNUSED, + xmlrpc_value ** const capabilitiesPP) { + + *capabilitiesPP = + xmlrpc_build_value( + envP, "{s:{s:s,s:i}}", + "introspect", + "specUrl", + "http://xmlrpc-c.sourceforge.net/xmlrpc-c/introspection.html", + "specVersion", + 1 + ); +} + + + +static xmlrpc_value * +system_getCapabilities(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo ATTR_UNUSED) { + + xmlrpc_registry * const registryP = serverInfo; + + xmlrpc_value * retvalP; + + unsigned int paramCount; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(serverInfo); + + paramCount = xmlrpc_array_size(envP, paramArrayP); + + if (paramCount > 0) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, + "There are no parameters. You supplied %u", paramCount); + else + listCapabilities(envP, registryP, &retvalP); + + return retvalP; +} + + + +static struct systemMethodReg const methodGetCapabilities = { + "system.getCapabilities", + &system_getCapabilities, + "S:", + "Return the list of standard capabilities of XML-RPC server. " + "See http://tech.groups.yahoo.com/group/xml-rpc/message/2897" +}; + + + +/*============================================================================ + Installer of system methods +============================================================================*/ + +static void +registerSystemMethod(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + struct systemMethodReg const methodReg) { + + xmlrpc_env env; + xmlrpc_env_init(&env); + + xmlrpc_registry_add_method2( + &env, registryP, methodReg.methodName, + methodReg.methodFunction, + methodReg.signatureString, methodReg.helpText, registryP); + + if (env.fault_occurred) + xmlrpc_faultf(envP, "Failed to register '%s' system method. %s", + methodReg.methodName, env.fault_string); + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_installSystemMethods(xmlrpc_env * const envP, + xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Install the built-in methods (system.*) into registry 'registryP'. +-----------------------------------------------------------------------------*/ + if (!envP->fault_occurred) + registerSystemMethod(envP, registryP, methodListMethods); + + if (!envP->fault_occurred) + registerSystemMethod(envP, registryP, methodMethodExist); + + if (!envP->fault_occurred) + registerSystemMethod(envP, registryP, methodMethodHelp); + + if (!envP->fault_occurred) + registerSystemMethod(envP, registryP, methodMethodSignature); + + if (!envP->fault_occurred) + registerSystemMethod(envP, registryP, methodMulticall); + + if (!envP->fault_occurred) + registerSystemMethod(envP, registryP, methodShutdown); + + if (!envP->fault_occurred) + registerSystemMethod(envP, registryP, methodCapabilities); + + if (!envP->fault_occurred) + registerSystemMethod(envP, registryP, methodGetCapabilities); +} + + + +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** Copyright (C) 2001 by Eric Kidd. All rights reserved. +** Copyright (C) 2001 by Luke Howard. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ + diff --git a/trunk/src/system_method.h b/trunk/src/system_method.h new file mode 100644 index 000000000..cf2df3858 --- /dev/null +++ b/trunk/src/system_method.h @@ -0,0 +1,14 @@ +#ifndef SYSTEM_METHOD_H_INCLUDED +#define SYSTEM_METHOD_H_INCLUDED + + +void +xmlrpc_installSystemMethods(struct _xmlrpc_env * const envP, + struct xmlrpc_registry * const registryP); + +void +xmlrpc_buildSignatureArray(xmlrpc_env * const envP, + const char * const sigListString, + xmlrpc_value ** const resultPP); + +#endif diff --git a/trunk/src/trace.c b/trunk/src/trace.c new file mode 100644 index 000000000..bb6594539 --- /dev/null +++ b/trunk/src/trace.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include + +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" + + +static size_t +nextLineSize(const char * const string, + size_t const startPos, + size_t const stringSize) { +/*---------------------------------------------------------------------------- + Return the length of the line that starts at offset 'startPos' in the + string 'string', which is 'stringSize' characters long. + + 'string' in not NUL-terminated. + + A line begins at beginning of string or after a newline character and + runs through the next newline character or end of string. The line + includes the newline character at the end, if any. +-----------------------------------------------------------------------------*/ + size_t i; + + for (i = startPos; i < stringSize && string[i] != '\n'; ++i); + + if (i < stringSize) + ++i; /* Include the newline */ + + return i - startPos; +} + + + +void +xmlrpc_traceXml(const char * const label, + const char * const xml, + size_t const xmlLength) { + + if (getenv("XMLRPC_TRACE_XML")) { + size_t cursor; /* Index into xml[] */ + + fprintf(stderr, "%s:\n\n", label); + + for (cursor = 0; cursor < xmlLength; ) { + /* Print one line of XML */ + + size_t const lineSize = nextLineSize(xml, cursor, xmlLength); + const char * const xmlPrintableLine = + xmlrpc_makePrintable_lp(&xml[cursor], lineSize); + + fprintf(stderr, "%s\n", xmlPrintableLine); + + cursor += lineSize; + + xmlrpc_strfree(xmlPrintableLine); + } + fprintf(stderr, "\n"); + } +} + + diff --git a/trunk/src/version.c b/trunk/src/version.c new file mode 100644 index 000000000..07a2d4334 --- /dev/null +++ b/trunk/src/version.c @@ -0,0 +1,18 @@ +#include "version.h" + +#include "xmlrpc-c/base.h" + +unsigned int const xmlrpc_version_major = XMLRPC_VERSION_MAJOR; +unsigned int const xmlrpc_version_minor = XMLRPC_VERSION_MINOR; +unsigned int const xmlrpc_version_point = XMLRPC_VERSION_POINT; + +void +xmlrpc_version(unsigned int * const majorP, + unsigned int * const minorP, + unsigned int * const pointP) { + + *majorP = XMLRPC_VERSION_MAJOR; + *minorP = XMLRPC_VERSION_MINOR; + *pointP = XMLRPC_VERSION_POINT; +} + diff --git a/trunk/src/xmlparser.h b/trunk/src/xmlparser.h new file mode 100644 index 000000000..3dc17d69f --- /dev/null +++ b/trunk/src/xmlparser.h @@ -0,0 +1,131 @@ +/* Copyright and license information is at the end of the file */ + +#ifndef XMLRPC_XMLPARSER_H_INCLUDED +#define XMLRPC_XMLPARSER_H_INCLUDED + +#include "xmlrpc-c/util_int.h" +/*============================================================================= + Abstract XML Parser Interface +=============================================================================== + This file provides an abstract interface to the XML parser, so we can + use multiple XML parsers with the main XML-RPC code not having to know + their specific interfaces. + + It works like this: When you need to parse some XML (we don't care what the + XML is as long as it is one valid XML element, but in practice it is going + to be an XML-RPC call or response), you call our 'xml_init' with the XML + text as argument. That generates an object of type 'xml_element' to + represent the XML element. + + You then call methods of that object to parse the XML element, e.g. to + find out its name or its children. +=============================================================================*/ + + +typedef struct _xml_element xml_element; + /* An object that represents an XML element */ + +void +xml_element_free(xml_element * const elemP); + /* Destroy the element */ + +const char * +xml_element_name(const xml_element * const elemP); + /* The XML element name. UTF-8. + + This points to memory owned by *elemP. + */ + +size_t +xml_element_cdata_size(const xml_element * const elemP); + /* The size of the element's cdata */ + +const char * +xml_element_cdata(const xml_element * const elemP); + /* The XML element's CDATA. UTF-8. + + This is a pointer to the cdata. + + There is a NUL character appended to the CDATA, but it is not part of + the CDATA, so is not included in the value returned by + xml_element_cdata_size(). + + This is memory owned by *elemP. + + 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. + */ + +unsigned int +xml_element_children_size(const xml_element * const elemP); + /* Number of children the XML element has */ + +xml_element ** +xml_element_children(const xml_element * const elemP); + /* All the child elements of the element. + + Each pointer points to an object owned by *elemP. + */ + +void +xml_parse(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xml_element ** const resultPP); + /* + Create an xml_elemnt object to represent it. + + Caller must ultimately destroy this object. + + Parse the XML text 'xmlData', of length 'xmlDataLen'. Return the + description of the element that the XML text contains as *resultPP. + Normally, the element has children, so that *resultPP is just the + root of a tree of elements. + + Use *memPoolP for some memory allocations. It is primarily for memory + uses whose size we cannot bound right now, like because it depends on + what the XML looks like - *memPoolP has bounds, so this prevents us + from using more than our share of system memory. If 'memPoolP' is + null, just use the default system pool (which is unbounded). + */ + + +/* Initialize and terminate static global parser state. This should be done + once per run of a program, and while the program is just one thread. +*/ +void +xml_init(xmlrpc_env * const envP); + +void +xml_term(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. */ + +#endif diff --git a/trunk/src/xmlrpc_array.c b/trunk/src/xmlrpc_array.c new file mode 100644 index 000000000..45f15c3d7 --- /dev/null +++ b/trunk/src/xmlrpc_array.c @@ -0,0 +1,278 @@ +/* Copyright information is at the end of the file */ + +/*========================================================================= +** XML-RPC Array Functions +**========================================================================= +*/ + +#include "xmlrpc_config.h" + +#include +#include +#include + +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" + + + +void +xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP) { + + if (arrayP == NULL) + abort(); + else if (arrayP->_type != XMLRPC_TYPE_ARRAY) + abort(); + else { + size_t const arraySize = + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); + xmlrpc_value ** const contents = + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); + + if (contents == NULL) + abort(); + else { + size_t index; + + for (index = 0; index < arraySize; ++index) { + xmlrpc_value * const itemP = contents[index]; + if (itemP == NULL) + abort(); + else if (itemP->refcount < 1) + abort(); + } + } + } +} + + + +void +xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP) { +/*---------------------------------------------------------------------------- + Dispose of the contents of an array (but not the array value itself). + The value is not valid after this. +-----------------------------------------------------------------------------*/ + size_t const arraySize = + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); + xmlrpc_value ** const contents = + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); + + size_t index; + + XMLRPC_ASSERT_ARRAY_OK(arrayP); + + /* Release our reference to each item in the array */ + for (index = 0; index < arraySize; ++index) { + xmlrpc_value * const itemP = contents[index]; + xmlrpc_DECREF(itemP); + } + XMLRPC_MEMBLOCK_FREE(xmlrpc_value *, arrayP->blockP); +} + + + +int +xmlrpc_array_size(xmlrpc_env * const envP, + const xmlrpc_value * const arrayP) { + + int retval; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(arrayP); + + if (arrayP->_type != XMLRPC_TYPE_ARRAY) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value is not an array"); + retval = -1; + } else { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); + + assert((size_t)(int)(size) == size); + + retval = (int)size; + } + return retval; +} + + + +void +xmlrpc_array_append_item(xmlrpc_env * const envP, + xmlrpc_value * const arrayP, + xmlrpc_value * const valueP) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(arrayP); + + if (xmlrpc_value_type(arrayP) != XMLRPC_TYPE_ARRAY) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value is not an array"); + else { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); + + XMLRPC_MEMBLOCK_RESIZE(xmlrpc_value *, envP, arrayP->blockP, size+1); + + if (!envP->fault_occurred) { + xmlrpc_value ** const contents = + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); + xmlrpc_INCREF(valueP); + contents[size] = valueP; + } + } +} + + + +void +xmlrpc_array_read_item(xmlrpc_env * const envP, + const xmlrpc_value * const arrayP, + unsigned int const index, + xmlrpc_value ** const valuePP) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(arrayP); + XMLRPC_ASSERT_PTR_OK(valuePP); + + if (arrayP->_type != XMLRPC_TYPE_ARRAY) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Attempt to read array item from " + "a value that is not an array"); + else { + xmlrpc_value ** const contents = + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, arrayP->blockP); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, arrayP->blockP); + + if (index >= size) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, "Array index %u is beyond end " + "of %u-item array", index, (unsigned int)size); + else { + *valuePP = contents[index]; + xmlrpc_INCREF(*valuePP); + } + } +} + + + +xmlrpc_value * +xmlrpc_array_get_item(xmlrpc_env * const envP, + const xmlrpc_value * const arrayP, + int const index) { + + xmlrpc_value * valueP; + + if (index < 0) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, "Index %d is negative.", index); + else { + xmlrpc_array_read_item(envP, arrayP, index, &valueP); + + if (!envP->fault_occurred) + xmlrpc_DECREF(valueP); + } + if (envP->fault_occurred) + valueP = NULL; + + return valueP; +} + + + +xmlrpc_value * +xmlrpc_array_new(xmlrpc_env * const envP) { +/*---------------------------------------------------------------------------- + Create an empty array xmlrpc_value. +-----------------------------------------------------------------------------*/ + xmlrpc_value * arrayP; + + xmlrpc_createXmlrpcValue(envP, &arrayP); + if (!envP->fault_occurred) { + arrayP->_type = XMLRPC_TYPE_ARRAY; + arrayP->blockP = XMLRPC_MEMBLOCK_NEW(xmlrpc_value *, envP, 0); + if (envP->fault_occurred) + free(arrayP); + } + return arrayP; +} + + + +xmlrpc_value * +xmlrpc_array_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * arrayP; + + if (valueP->_type != XMLRPC_TYPE_ARRAY) { + xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, + "Value is not an array. " + "It is type #%d", valueP->_type); + arrayP = NULL; + } else { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, valueP->blockP); + + xmlrpc_createXmlrpcValue(envP, &arrayP); + if (!envP->fault_occurred) { + arrayP->_type = XMLRPC_TYPE_ARRAY; + + arrayP->blockP = XMLRPC_MEMBLOCK_NEW(xmlrpc_value *, envP, 0); + + if (envP->fault_occurred) + free(arrayP); + else { + xmlrpc_value ** const srcValuePList = + XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, valueP->blockP); + + unsigned int i; + + for (i = 0; i < size && !envP->fault_occurred; ++i) { + xmlrpc_value * const newEltP = + xmlrpc_value_new(envP, srcValuePList[i]); + if (!envP->fault_occurred) + xmlrpc_array_append_item(envP, arrayP, newEltP); + } + if (envP->fault_occurred) + xmlrpc_destroyArrayContents(arrayP); + } + + if (envP->fault_occurred) + free(arrayP); + } + } + return arrayP; +} + + + +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** Copyright (C) 2001 by Eric Kidd. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ diff --git a/trunk/src/xmlrpc_authcookie.c b/trunk/src/xmlrpc_authcookie.c new file mode 100644 index 000000000..c0f19eb8d --- /dev/null +++ b/trunk/src/xmlrpc_authcookie.c @@ -0,0 +1,86 @@ +/* Copyright (C) 2002 by jeff@ourexchange.net. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ + +#include "xmlrpc_config.h" + +#include +#include +#include + +#include "mallocvar.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/util_int.h" + +/***************************************************************************** + I don't see how these were expected to be used. And I probably + broke it somehow at some point by removing code from somewhere else. + But I doubt that, whatever it's supposed to do, environment + variables are the right tool. + + Note that on a platform that doesn't have SETENV, + xmlrpc_authcookie_set() is just a no-op. + + -Bryan 2005.06.10 +****************************************************************************/ + +void +xmlrpc_authcookie_set(xmlrpc_env * const envP, + const char * const username, + const char * const password) { + + char * unencoded; + xmlrpc_mem_block * token; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(username); + XMLRPC_ASSERT_PTR_OK(password); + + /* Create unencoded string/hash. */ + + MALLOCARRAY(unencoded,(strlen(username) + strlen(password) + 1 + 1)); + sprintf(unencoded, "%s:%s", username, password); + + /* Create encoded string. */ + token = xmlrpc_base64_encode_without_newlines( + envP, (unsigned char *)unencoded, strlen(unencoded)); + if (!envP->fault_occurred) { + /* Set HTTP_COOKIE_AUTH to the character representation of the + encoded string. + */ +#if HAVE_SETENV + setenv("HTTP_COOKIE_AUTH", + XMLRPC_MEMBLOCK_CONTENTS(char, token), + 1); +#endif + xmlrpc_mem_block_free(token); + } + free(unencoded); +} + + + +char *xmlrpc_authcookie ( void ) { + return getenv("HTTP_COOKIE_AUTH"); +} diff --git a/trunk/src/xmlrpc_build.c b/trunk/src/xmlrpc_build.c new file mode 100644 index 000000000..b44f4716d --- /dev/null +++ b/trunk/src/xmlrpc_build.c @@ -0,0 +1,430 @@ +/* Copyright information is at end of file */ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include + +#include "bool.h" +#include "c_util.h" +#include "mallocvar.h" +#include "stdargx.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" + + + +static void +getString(xmlrpc_env * const envP, + const char ** const formatP, + va_listx * const argsP, + xmlrpc_value ** const valPP) { + + const char * str; + size_t len; + + str = (const char*) va_arg(argsP->v, char*); + if (*(*formatP) == '#') { + ++(*formatP); + len = (size_t) va_arg(argsP->v, size_t); + } else + len = strlen(str); + + *valPP = xmlrpc_string_new_lp(envP, len, str); +} + + + +static void +getWideString(xmlrpc_env * const envP ATTR_UNUSED, + const char ** const formatP ATTR_UNUSED, + va_listx * const argsP ATTR_UNUSED, + xmlrpc_value ** const valPP ATTR_UNUSED) { + +#if HAVE_UNICODE_WCHAR + wchar_t *wcs; + size_t len; + + wcs = (wchar_t*) va_arg(argsP->v, wchar_t*); + if (**formatP == '#') { + (*formatP)++; + len = (size_t) va_arg(argsP->v, size_t); + } else + len = wcslen(wcs); + + *valPP = xmlrpc_string_w_new_lp(envP, len, wcs); + +#endif /* HAVE_UNICODE_WCHAR */ +} + + + +static void +getBase64(xmlrpc_env * const envP, + va_listx * const argsP, + xmlrpc_value ** const valPP) { + + unsigned char * value; + size_t length; + + value = (unsigned char*) va_arg(argsP->v, unsigned char*); + length = (size_t) va_arg(argsP->v, size_t); + + *valPP = xmlrpc_base64_new(envP, length, value); +} + + + +static void +getValue(xmlrpc_env * const envP, + const char** const format, + va_listx * const argsP, + xmlrpc_value ** const valPP); + + + +static void +getArray(xmlrpc_env * const envP, + const char ** const formatP, + char const delimiter, + va_listx * const argsP, + xmlrpc_value ** const arrayPP) { + + xmlrpc_value * arrayP; + + arrayP = xmlrpc_array_new(envP); + + /* Add items to the array until we hit our delimiter. */ + + while (**formatP != delimiter && !envP->fault_occurred) { + + xmlrpc_value * itemP; + + if (**formatP == '\0') + xmlrpc_env_set_fault( + envP, XMLRPC_INTERNAL_ERROR, + "format string ended before closing ')'."); + else { + getValue(envP, formatP, argsP, &itemP); + if (!envP->fault_occurred) { + xmlrpc_array_append_item(envP, arrayP, itemP); + xmlrpc_DECREF(itemP); + } + } + } + if (envP->fault_occurred) + xmlrpc_DECREF(arrayP); + + *arrayPP = arrayP; +} + + + +static void +getStructMember(xmlrpc_env * const envP, + const char ** const formatP, + va_listx * const argsP, + xmlrpc_value ** const keyPP, + xmlrpc_value ** const valuePP) { + + + /* Get the key */ + getValue(envP, formatP, argsP, keyPP); + if (!envP->fault_occurred) { + if (**formatP != ':') + xmlrpc_env_set_fault( + envP, XMLRPC_INTERNAL_ERROR, + "format string does not have ':' after a " + "structure member key."); + else { + /* Skip over colon that separates key from value */ + (*formatP)++; + + /* Get the value */ + getValue(envP, formatP, argsP, valuePP); + } + if (envP->fault_occurred) + xmlrpc_DECREF(*keyPP); + } +} + + + +static void +getStruct(xmlrpc_env * const envP, + const char ** const formatP, + char const delimiter, + va_listx * const argsP, + xmlrpc_value ** const structPP) { + + xmlrpc_value * structP; + + structP = xmlrpc_struct_new(envP); + if (!envP->fault_occurred) { + while (**formatP != delimiter && !envP->fault_occurred) { + xmlrpc_value * keyP; + xmlrpc_value * valueP; + + getStructMember(envP, formatP, argsP, &keyP, &valueP); + + if (!envP->fault_occurred) { + if (**formatP == ',') + (*formatP)++; /* Skip over the comma */ + else if (**formatP == delimiter) { + /* End of the line */ + } else + xmlrpc_env_set_fault( + envP, XMLRPC_INTERNAL_ERROR, + "format string does not have ',' or ')' after " + "a structure member"); + + if (!envP->fault_occurred) + /* Add the new member to the struct. */ + xmlrpc_struct_set_value_v(envP, structP, keyP, valueP); + + xmlrpc_DECREF(valueP); + xmlrpc_DECREF(keyP); + } + } + if (envP->fault_occurred) + xmlrpc_DECREF(structP); + } + *structPP = structP; +} + + + +static void +mkArrayFromVal(xmlrpc_env * const envP, + xmlrpc_value * const value, + xmlrpc_value ** const valPP) { + + if (xmlrpc_value_type(value) != XMLRPC_TYPE_ARRAY) + xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, + "Array format ('A'), non-array xmlrpc_value"); + else + xmlrpc_INCREF(value); + + *valPP = value; +} + + + +static void +mkStructFromVal(xmlrpc_env * const envP, + xmlrpc_value * const value, + xmlrpc_value ** const valPP) { + + if (xmlrpc_value_type(value) != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, + "Struct format ('S'), non-struct xmlrpc_value"); + else + xmlrpc_INCREF(value); + + *valPP = value; +} + + + +static void +getValue(xmlrpc_env * const envP, + const char** const formatP, + va_listx * const argsP, + xmlrpc_value ** const valPP) { +/*---------------------------------------------------------------------------- + Get the next value from the list. *formatP points to the specifier + for the next value in the format string (i.e. to the type code + character) and we move *formatP past the whole specifier for the + next value. We read the required arguments from 'argsP'. We return + the value as *valPP with a reference to it. + + For example, if *formatP points to the "i" in the string "sis", + we read one argument from 'argsP' and return as *valP an integer whose + value is the argument we read. We advance *formatP to point to the + last 's' and advance 'argsP' to point to the argument that belongs to + that 's'. +-----------------------------------------------------------------------------*/ + char const formatChar = *(*formatP)++; + + switch (formatChar) { + case 'i': + *valPP = + xmlrpc_int_new(envP, (xmlrpc_int32) va_arg(argsP->v, + xmlrpc_int32)); + break; + + case 'b': + *valPP = + xmlrpc_bool_new(envP, (xmlrpc_bool) va_arg(argsP->v, xmlrpc_bool)); + break; + + case 'd': + *valPP = + xmlrpc_double_new(envP, (double) va_arg(argsP->v, double)); + break; + + case 's': + getString(envP, formatP, argsP, valPP); + break; + + case 'w': + getWideString(envP, formatP, argsP, valPP); + break; + + case 't': + *valPP = xmlrpc_datetime_new_sec(envP, va_arg(argsP->v, time_t)); + break; + + case '8': + *valPP = xmlrpc_datetime_new_str(envP, va_arg(argsP->v, char*)); + break; + + case '6': + getBase64(envP, argsP, valPP); + break; + + case 'n': + *valPP = + xmlrpc_nil_new(envP); + break; + + case 'I': + *valPP = + xmlrpc_i8_new(envP, (xmlrpc_int64) va_arg(argsP->v, xmlrpc_int64)); + break; + + case 'p': + *valPP = + xmlrpc_cptr_new(envP, (void*) va_arg(argsP->v, void*)); + break; + + case 'A': + mkArrayFromVal(envP, (xmlrpc_value*) va_arg(argsP->v, xmlrpc_value*), + valPP); + break; + + case 'S': + mkStructFromVal(envP, (xmlrpc_value*) va_arg(argsP->v, xmlrpc_value*), + valPP); + break; + + case 'V': + *valPP = (xmlrpc_value*) va_arg(argsP->v, xmlrpc_value*); + xmlrpc_INCREF(*valPP); + break; + + case '(': + getArray(envP, formatP, ')', argsP, valPP); + if (!envP->fault_occurred) { + XMLRPC_ASSERT(**formatP == ')'); + (*formatP)++; /* Skip over closing parenthesis */ + } + break; + + case '{': + getStruct(envP, formatP, '}', argsP, valPP); + if (!envP->fault_occurred) { + XMLRPC_ASSERT(**formatP == '}'); + (*formatP)++; /* Skip over closing brace */ + } + break; + + default: { + const char * const badCharacter = xmlrpc_makePrintableChar(formatChar); + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INTERNAL_ERROR, + "Unexpected character '%s' in format string", badCharacter); + xmlrpc_strfree(badCharacter); + } + } +} + + + +void +xmlrpc_build_value_va(xmlrpc_env * const envP, + const char * const format, + va_list const args, + xmlrpc_value ** const valPP, + const char ** const tailP) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(format != NULL); + + if (strlen(format) == 0) + xmlrpc_faultf(envP, "Format string is empty."); + else { + va_listx currentArgs; + const char * formatCursor; + + init_va_listx(¤tArgs, args); + formatCursor = &format[0]; + getValue(envP, &formatCursor, ¤tArgs, valPP); + + if (!envP->fault_occurred) + XMLRPC_ASSERT_VALUE_OK(*valPP); + + *tailP = formatCursor; + } +} + + + +xmlrpc_value * +xmlrpc_build_value(xmlrpc_env * const envP, + const char * const format, + ...) { + + va_list args; + xmlrpc_value * retval; + const char * suffix; + + va_start(args, format); + xmlrpc_build_value_va(envP, format, args, &retval, &suffix); + va_end(args); + + if (!envP->fault_occurred) { + if (*suffix != '\0') + xmlrpc_faultf(envP, "Junk after the format specifier: '%s'. " + "The format string must describe exactly " + "one XML-RPC value " + "(but it might be a compound value " + "such as an array)", + suffix); + + if (envP->fault_occurred) + xmlrpc_DECREF(retval); + } + return retval; +} + + +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** Copyright (C) 2001 by Eric Kidd. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ diff --git a/trunk/src/xmlrpc_client.c b/trunk/src/xmlrpc_client.c new file mode 100644 index 000000000..9466b5b5d --- /dev/null +++ b/trunk/src/xmlrpc_client.c @@ -0,0 +1,1201 @@ +/* Copyright information is at end of file */ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include "xmlrpc_config.h" + +#undef PACKAGE +#undef VERSION + +#include +#include +#include +#include +#include +#include +#include + +#include "bool.h" +#include "mallocvar.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/client_int.h" +/* transport_config.h defines XMLRPC_DEFAULT_TRANSPORT, + MUST_BUILD_WININET_CLIENT, MUST_BUILD_CURL_CLIENT, + MUST_BUILD_LIBWWW_CLIENT +*/ +#include "transport_config.h" +#include "version.h" + +struct xmlrpc_client { +/*---------------------------------------------------------------------------- + This represents a client object. +-----------------------------------------------------------------------------*/ + bool myTransport; + /* The transport described below was created by this object; + No one else knows it exists and this object is responsible + for destroying it. + */ + struct xmlrpc_client_transport * transportP; + struct xmlrpc_client_transport_ops transportOps; + xmlrpc_dialect dialect; + xmlrpc_progress_fn * progressFn; +}; + + + +struct xmlrpc_call_info { + /* This is all the information needed to finish executing a started + RPC. + + You don't need this for an RPC the user executes synchronously, + because then you can just use the storage in which the user passed + his arguments. But for asynchronous, the user will take back his + storage, and we need to keep this info in our own. + */ + + void * userHandle; + /* This is a handle for this call that is meaningful to our + user. + */ + xmlrpc_progress_fn * progressFn; + struct { + /* These are arguments to pass to the completion function. It + doesn't make sense to use them for anything else. In fact, it + really doesn't make sense for them to be arguments to the + completion function, but they are historically. */ + const char * serverUrl; + const char * methodName; + xmlrpc_value * paramArrayP; + } completionArgs; + xmlrpc_response_handler * completionFn; + + + /* The serialized XML data passed to this call. We keep this around + ** for use by our source_anchor field. */ + xmlrpc_mem_block *serialized_xml; +}; + + + +/*========================================================================= + Global Constant Setup/Teardown +=========================================================================*/ + +static void +callTransportSetup(xmlrpc_env * const envP, + xmlrpc_transport_setup setupFn) { + + if (setupFn) + setupFn(envP); +} + + + +int xmlrpc_trace_transport; + + + +static void +setupTransportGlobalConst(xmlrpc_env * const envP) { + + xmlrpc_trace_transport = getenv("XMLRPC_TRACE_TRANSPORT") ? 1 : 0; + +#if MUST_BUILD_WININET_CLIENT + if (!envP->fault_occurred) + callTransportSetup(envP, + xmlrpc_wininet_transport_ops.setup_global_const); +#endif +#if MUST_BUILD_CURL_CLIENT + if (!envP->fault_occurred) + callTransportSetup(envP, + xmlrpc_curl_transport_ops.setup_global_const); +#endif +#if MUST_BUILD_LIBWWW_CLIENT + if (!envP->fault_occurred) + callTransportSetup(envP, + xmlrpc_libwww_transport_ops.setup_global_const); +#endif +} + + + +static void +callTransportTeardown(xmlrpc_transport_teardown teardownFn) { + + if (teardownFn) + teardownFn(); +} + + + +static void +teardownTransportGlobalConst(void) { + +#if MUST_BUILD_WININET_CLIENT + callTransportTeardown( + xmlrpc_wininet_transport_ops.teardown_global_const); +#endif +#if MUST_BUILD_CURL_CLIENT + callTransportTeardown( + xmlrpc_curl_transport_ops.teardown_global_const); +#endif +#if MUST_BUILD_LIBWWW_CLIENT + callTransportTeardown( + xmlrpc_libwww_transport_ops.teardown_global_const); +#endif +} + + + +/*========================================================================= + Global stuff (except the global client) +=========================================================================*/ + +static unsigned int constSetupCount = 0; + + +void +xmlrpc_client_setup_global_const(xmlrpc_env * const envP) { +/*---------------------------------------------------------------------------- + Set up pseudo-constant global variables (they'd be constant, except that + the library loader doesn't set them. An explicit call from the loaded + program does). + + This function is not thread-safe. The user is supposed to call it + (perhaps cascaded down from a multitude of higher level libraries) + as part of early program setup, when the program is only one thread. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + + if (constSetupCount == 0) + setupTransportGlobalConst(envP); + + ++constSetupCount; +} + + + +void +xmlrpc_client_teardown_global_const(void) { +/*---------------------------------------------------------------------------- + Complement to xmlrpc_client_setup_global_const(). + + This function is not thread-safe. The user is supposed to call it + (perhaps cascaded down from a multitude of higher level libraries) + as part of final program cleanup, when the program is only one thread. +-----------------------------------------------------------------------------*/ + assert(constSetupCount > 0); + + --constSetupCount; + + if (constSetupCount == 0) + teardownTransportGlobalConst(); +} + + + +unsigned int const xmlrpc_client_version_major = XMLRPC_VERSION_MAJOR; +unsigned int const xmlrpc_client_version_minor = XMLRPC_VERSION_MINOR; +unsigned int const xmlrpc_client_version_point = XMLRPC_VERSION_POINT; + +void +xmlrpc_client_version(unsigned int * const majorP, + unsigned int * const minorP, + unsigned int * const pointP) { + + *majorP = XMLRPC_VERSION_MAJOR; + *minorP = XMLRPC_VERSION_MINOR; + *pointP = XMLRPC_VERSION_POINT; +} + + + +/*========================================================================= + Client Create/Destroy +=========================================================================*/ + +static void +getTransportOps( + xmlrpc_env * const envP, + const char * const transportName, + const struct xmlrpc_client_transport_ops ** const opsPP) { + + if (false) { + } +#if MUST_BUILD_WININET_CLIENT + else if (xmlrpc_streq(transportName, "wininet")) + *opsPP = &xmlrpc_wininet_transport_ops; +#endif +#if MUST_BUILD_CURL_CLIENT + else if (xmlrpc_streq(transportName, "curl")) + *opsPP = &xmlrpc_curl_transport_ops; +#endif +#if MUST_BUILD_LIBWWW_CLIENT + else if (xmlrpc_streq(transportName, "libwww")) + *opsPP = &xmlrpc_libwww_transport_ops; +#endif + else + xmlrpc_faultf(envP, "Unrecognized XML transport name '%s'", + transportName); +} + + + +struct xportParms { + const void * parmsP; + size_t size; +}; + + + +static void +getTransportParmsFromClientParms( + xmlrpc_env * const envP, + const struct xmlrpc_clientparms * const clientparmsP, + unsigned int const parmSize, + struct xportParms * const xportParmsP) { + + if (parmSize < XMLRPC_CPSIZE(transportparmsP) || + clientparmsP->transportparmsP == NULL) { + + xportParmsP->parmsP = NULL; + xportParmsP->size = 0; + } else { + xportParmsP->parmsP = clientparmsP->transportparmsP; + if (parmSize < XMLRPC_CPSIZE(transportparm_size)) + xmlrpc_faultf(envP, "Your 'clientparms' argument contains the " + "transportparmsP member, " + "but no transportparms_size member"); + else + xportParmsP->size = clientparmsP->transportparm_size; + } +} + + + +static void +getTransportInfo( + xmlrpc_env * const envP, + const struct xmlrpc_clientparms * const clientparmsP, + unsigned int const parmSize, + const char ** const transportNameP, + struct xportParms * const transportParmsP, + const struct xmlrpc_client_transport_ops ** const transportOpsPP, + xmlrpc_client_transport ** const transportPP) { + + const char * transportNameParm; + xmlrpc_client_transport * transportP; + const struct xmlrpc_client_transport_ops * transportOpsP; + + if (parmSize < XMLRPC_CPSIZE(transport)) + transportNameParm = NULL; + else + transportNameParm = clientparmsP->transport; + + if (parmSize < XMLRPC_CPSIZE(transportP)) + transportP = NULL; + else + transportP = clientparmsP->transportP; + + if (parmSize < XMLRPC_CPSIZE(transportOpsP)) + transportOpsP = NULL; + else + transportOpsP = clientparmsP->transportOpsP; + + if ((transportOpsP && !transportP) || (transportP && ! transportOpsP)) + xmlrpc_faultf(envP, "'transportOpsP' and 'transportP' go together. " + "You must specify both or neither"); + else if (transportNameParm && transportP) + xmlrpc_faultf(envP, "You cannot specify both 'transport' and " + "'transportP' transport parameters."); + else if (transportP) + *transportNameP = NULL; + else if (transportNameParm) + *transportNameP = transportNameParm; + else + *transportNameP = xmlrpc_client_get_default_transport(envP); + + *transportOpsPP = transportOpsP; + *transportPP = transportP; + + if (!envP->fault_occurred) { + getTransportParmsFromClientParms( + envP, clientparmsP, parmSize, transportParmsP); + + if (!envP->fault_occurred) { + if (transportParmsP->parmsP && !transportNameParm) + xmlrpc_faultf( + envP, + "You specified transport parameters, but did not " + "specify a transport type. Parameters are specific " + "to a particular type."); + } + } +} + + + +static void +getDialectFromClientParms( + const struct xmlrpc_clientparms * const clientparmsP, + unsigned int const parmSize, + xmlrpc_dialect * const dialectP) { + + if (parmSize < XMLRPC_CPSIZE(dialect)) + *dialectP = xmlrpc_dialect_i8; + else + *dialectP = clientparmsP->dialect; +} + + + +static void +clientCreate( + xmlrpc_env * const envP, + bool const myTransport, + const struct xmlrpc_client_transport_ops * const transportOpsP, + struct xmlrpc_client_transport * const transportP, + xmlrpc_dialect const dialect, + xmlrpc_progress_fn * const progressFn, + xmlrpc_client ** const clientPP) { + + XMLRPC_ASSERT_PTR_OK(transportOpsP); + XMLRPC_ASSERT_PTR_OK(transportP); + XMLRPC_ASSERT_PTR_OK(clientPP); + + if (constSetupCount == 0) { + xmlrpc_faultf(envP, + "You have not called " + "xmlrpc_client_setup_global_const()."); + /* Impl note: We can't just call it now because it isn't + thread-safe. + */ + } else { + xmlrpc_client * clientP; + + MALLOCVAR(clientP); + + if (clientP == NULL) + xmlrpc_faultf(envP, "Unable to allocate memory for " + "client descriptor."); + else { + clientP->myTransport = myTransport; + clientP->transportOps = *transportOpsP; + clientP->transportP = transportP; + clientP->dialect = dialect; + clientP->progressFn = progressFn; + + *clientPP = clientP; + } + } +} + + + +static void +createTransportAndClient( + xmlrpc_env * const envP, + const char * const transportName, + const void * const transportparmsP, + size_t const transportparmSize, + int const flags, + const char * const appname, + const char * const appversion, + xmlrpc_dialect const dialect, + xmlrpc_progress_fn * const progressFn, + xmlrpc_client ** const clientPP) { + + const struct xmlrpc_client_transport_ops * transportOpsP; + + getTransportOps(envP, transportName, &transportOpsP); + if (!envP->fault_occurred) { + xmlrpc_client_transport * transportP; + + /* The following call is not thread-safe */ + transportOpsP->create( + envP, flags, appname, appversion, + transportparmsP, transportparmSize, + &transportP); + if (!envP->fault_occurred) { + bool const myTransportTrue = true; + + clientCreate(envP, myTransportTrue, transportOpsP, transportP, + dialect, progressFn, clientPP); + + if (envP->fault_occurred) + transportOpsP->destroy(transportP); + } + } +} + + + +void +xmlrpc_client_create(xmlrpc_env * const envP, + int const flags, + const char * const appname, + const char * const appversion, + const struct xmlrpc_clientparms * const clientparmsP, + unsigned int const parmSize, + xmlrpc_client ** const clientPP) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(clientPP); + + if (constSetupCount == 0) { + xmlrpc_faultf(envP, + "You have not called " + "xmlrpc_client_setup_global_const()."); + /* Impl note: We can't just call it now because it isn't + thread-safe. + */ + } else { + const char * transportName; + struct xportParms transportparms; + const struct xmlrpc_client_transport_ops * transportOpsP; + xmlrpc_client_transport * transportP; + xmlrpc_dialect dialect; + xmlrpc_progress_fn * progressFn; + + getTransportInfo(envP, clientparmsP, parmSize, &transportName, + &transportparms, &transportOpsP, &transportP); + + getDialectFromClientParms(clientparmsP, parmSize, &dialect); + + progressFn = parmSize >= XMLRPC_CPSIZE(progressFn) ? + clientparmsP->progressFn : NULL; + + if (!envP->fault_occurred) { + if (transportName) + createTransportAndClient(envP, transportName, + transportparms.parmsP, + transportparms.size, + flags, appname, appversion, dialect, + progressFn, + clientPP); + else { + bool myTransportFalse = false; + clientCreate(envP, myTransportFalse, + transportOpsP, transportP, dialect, progressFn, + clientPP); + } + } + } +} + + + +void +xmlrpc_client_destroy(xmlrpc_client * const clientP) { + + XMLRPC_ASSERT_PTR_OK(clientP); + + if (clientP->myTransport) + clientP->transportOps.destroy(clientP->transportP); + + free(clientP); +} + + + +/*========================================================================= + Call/Response Utilities +=========================================================================*/ + +static void +makeCallXml(xmlrpc_env * const envP, + const char * const methodName, + xmlrpc_value * const paramArrayP, + xmlrpc_dialect const dialect, + xmlrpc_mem_block ** const callXmlPP) { +/*---------------------------------------------------------------------------- + Make the XML for an XML-RPC call of method named 'methodName', with + parameters *paramArrayP, in XML-RPC dialect 'dialect'. + + Return the XML in a newly created xmlrpc_memblock and return a pointer to + it as *callXmlPP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(callXmlPP); + + if (methodName == NULL) + xmlrpc_faultf(envP, "method name argument is NULL pointer"); + else { + xmlrpc_mem_block * callXmlP; + + callXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + if (!envP->fault_occurred) { + xmlrpc_serialize_call2(envP, callXmlP, methodName, paramArrayP, + dialect); + + *callXmlPP = callXmlP; + + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, callXmlP); + } + } +} + + + +/*========================================================================= + Synchronous Call +=========================================================================*/ + +void +xmlrpc_client_transport_call2( + xmlrpc_env * const envP, + xmlrpc_client * const clientP, + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block ** const respXmlPP) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(clientP); + XMLRPC_ASSERT_PTR_OK(serverP); + XMLRPC_ASSERT_PTR_OK(callXmlP); + XMLRPC_ASSERT_PTR_OK(respXmlPP); + + clientP->transportOps.call( + envP, clientP->transportP, serverP, callXmlP, + respXmlPP); +} + + + +static void +parseResponse(xmlrpc_env * const envP, + xmlrpc_mem_block * const respXmlP, + xmlrpc_value ** const resultPP, + int * const faultCodeP, + const char ** const faultStringP) { + + xmlrpc_env respEnv; + + XMLRPC_ASSERT_ENV_OK(envP); + + xmlrpc_env_init(&respEnv); + + xmlrpc_parse_response2( + &respEnv, + XMLRPC_MEMBLOCK_CONTENTS(char, respXmlP), + XMLRPC_MEMBLOCK_SIZE(char, respXmlP), + resultPP, faultCodeP, faultStringP); + + if (respEnv.fault_occurred) + xmlrpc_env_set_fault_formatted( + envP, respEnv.fault_code, + "Unable to make sense of XML-RPC response from server. " + "%s. Use XMLRPC_TRACE_XML to see for yourself", + respEnv.fault_string); + + xmlrpc_env_clean(&respEnv); +} + + + +void +xmlrpc_client_call2(xmlrpc_env * const envP, + struct xmlrpc_client * const clientP, + const xmlrpc_server_info * const serverInfoP, + const char * const methodName, + xmlrpc_value * const paramArrayP, + xmlrpc_value ** const resultPP) { + + xmlrpc_mem_block * callXmlP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(clientP); + XMLRPC_ASSERT_PTR_OK(serverInfoP); + XMLRPC_ASSERT_PTR_OK(paramArrayP); + + makeCallXml(envP, methodName, paramArrayP, clientP->dialect, &callXmlP); + + if (!envP->fault_occurred) { + xmlrpc_mem_block * respXmlP; + + xmlrpc_traceXml("XML-RPC CALL", + XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP), + XMLRPC_MEMBLOCK_SIZE(char, callXmlP)); + + clientP->transportOps.call( + envP, clientP->transportP, serverInfoP, callXmlP, &respXmlP); + if (!envP->fault_occurred) { + int faultCode; + const char * faultString; + + xmlrpc_traceXml("XML-RPC RESPONSE", + XMLRPC_MEMBLOCK_CONTENTS(char, respXmlP), + XMLRPC_MEMBLOCK_SIZE(char, respXmlP)); + + parseResponse(envP, respXmlP, resultPP, &faultCode, &faultString); + + if (!envP->fault_occurred) { + if (faultString) { + xmlrpc_env_set_fault_formatted( + envP, faultCode, + "RPC failed at server. %s", faultString); + xmlrpc_strfree(faultString); + } else + XMLRPC_ASSERT_VALUE_OK(*resultPP); + } + XMLRPC_MEMBLOCK_FREE(char, respXmlP); + } + XMLRPC_MEMBLOCK_FREE(char, callXmlP); + } +} + + + +static void +computeParamArray(xmlrpc_env * const envP, + const char * const format, + va_list args, + xmlrpc_value ** const paramArrayPP) { +/*---------------------------------------------------------------------------- + 'format' and 'args' specify the parameter list of an RPC, in the form + of an XML-RPC array value, with one element per RPC parameter. + + 'format' is an XML-RPC value format string, e.g. "(ii{s:i,s:i})". + 'args' is the list of substitution values for that string + (6 values in this example, 4 integers and 2 strings). + + We return the XML-RPC value 'format' and 'args' represent, but throw an + error if they don't validly specify a single array. + + Note that it is a common user error to specify the format string as a + single or string of argument types, instead of as an array of argument + types. E.g. "i" or "ii" instead of "(i)" and "(ii)". So we try + especially hard to give an informative message for that case. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xmlrpc_value * paramArrayP; + const char * suffix; + /* Stuff left over in format string after parameter array + specification. + */ + + xmlrpc_env_init(&env); + xmlrpc_build_value_va(&env, format, args, ¶mArrayP, &suffix); + if (env.fault_occurred) + xmlrpc_env_set_fault_formatted( + envP, env.fault_code, "Invalid RPC arguments. " + "The format argument must indicate a single array (each element " + "of which is one argument to the XML-RPC call), and the " + "following arguments must correspond to that format argument. " + "The failure is: %s", + env.fault_string); + else { + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + + if (*suffix != '\0') + xmlrpc_faultf(envP, + "Junk after the parameter array specifier: '%s'. " + "The format string must specify exactly one value: " + "an array of RPC parameters", + suffix); + else { + if (xmlrpc_value_type(paramArrayP) != XMLRPC_TYPE_ARRAY) + xmlrpc_faultf( + envP, + "You must specify the parameter list as an " + "XML-RPC array value, " + "each element of which is a parameter of the RPC. " + "But your format string specifies an XML-RPC %s, not " + "an array", + xmlrpc_type_name(xmlrpc_value_type(paramArrayP))); + } + if (env.fault_occurred) + xmlrpc_DECREF(paramArrayP); + else + *paramArrayPP = paramArrayP; + } + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_client_call_server2_va(xmlrpc_env * const envP, + struct xmlrpc_client * const clientP, + const xmlrpc_server_info * const serverInfoP, + const char * const methodName, + const char * const format, + va_list args, + xmlrpc_value ** const resultPP) { + + /* This function exists only for use by the global client function + xmlrpc_client_call_server(). + */ + + xmlrpc_value * paramArrayP; + /* The XML-RPC parameter list array */ + + XMLRPC_ASSERT_ENV_OK(envP); + + computeParamArray(envP, format, args, ¶mArrayP); + + if (!envP->fault_occurred) { + xmlrpc_client_call2(envP, clientP, + serverInfoP, methodName, paramArrayP, + resultPP); + + xmlrpc_DECREF(paramArrayP); + } +} + + + +void +xmlrpc_client_call2f_va(xmlrpc_env * const envP, + xmlrpc_client * const clientP, + const char * const serverUrl, + const char * const methodName, + const char * const format, + xmlrpc_value ** const resultPP, + va_list args) { + + xmlrpc_value * paramArrayP; + /* The XML-RPC parameter list array */ + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(clientP); + XMLRPC_ASSERT_PTR_OK(serverUrl); + XMLRPC_ASSERT_PTR_OK(methodName); + XMLRPC_ASSERT_PTR_OK(format); + XMLRPC_ASSERT_PTR_OK(resultPP); + + computeParamArray(envP, format, args, ¶mArrayP); + + if (!envP->fault_occurred) { + xmlrpc_server_info * serverInfoP; + + serverInfoP = xmlrpc_server_info_new(envP, serverUrl); + + if (!envP->fault_occurred) { + /* Perform the actual XML-RPC call. */ + xmlrpc_client_call2(envP, clientP, + serverInfoP, methodName, paramArrayP, + resultPP); + if (!envP->fault_occurred) + XMLRPC_ASSERT_VALUE_OK(*resultPP); + xmlrpc_server_info_free(serverInfoP); + } + xmlrpc_DECREF(paramArrayP); + } +} + + + +void +xmlrpc_client_call2f(xmlrpc_env * const envP, + xmlrpc_client * const clientP, + const char * const serverUrl, + const char * const methodName, + xmlrpc_value ** const resultPP, + const char * const format, + ...) { + + va_list args; + + XMLRPC_ASSERT_PTR_OK(format); + + va_start(args, format); + xmlrpc_client_call2f_va(envP, clientP, serverUrl, + methodName, format, resultPP, args); + va_end(args); +} + + + +/*========================================================================= + Asynchronous Call +=========================================================================*/ + +static void +callInfoSetCompletion(xmlrpc_env * const envP, + struct xmlrpc_call_info * const callInfoP, + const char * const serverUrl, + const char * const methodName, + xmlrpc_value * const paramArrayP, + xmlrpc_response_handler completionFn, + xmlrpc_progress_fn progressFn, + void * const userHandle) { +/*---------------------------------------------------------------------------- + Set the members of callinfo structure *callInfoP that are used for + the completion and progress calls from the transport to us. +-----------------------------------------------------------------------------*/ + callInfoP->completionFn = completionFn; + callInfoP->progressFn = progressFn; + callInfoP->userHandle = userHandle; + callInfoP->completionArgs.serverUrl = strdup(serverUrl); + if (callInfoP->completionArgs.serverUrl == NULL) + xmlrpc_faultf(envP, "Couldn't get memory to store server URL"); + else { + callInfoP->completionArgs.methodName = strdup(methodName); + if (callInfoP->completionArgs.methodName == NULL) + xmlrpc_faultf(envP, "Couldn't get memory to store method name"); + else { + callInfoP->completionArgs.paramArrayP = paramArrayP; + xmlrpc_INCREF(paramArrayP); + } + if (envP->fault_occurred) + xmlrpc_strfree(callInfoP->completionArgs.serverUrl); + } +} + + + +static void +callInfoCreate(xmlrpc_env * const envP, + const char * const methodName, + xmlrpc_value * const paramArrayP, + xmlrpc_dialect const dialect, + const char * const serverUrl, + xmlrpc_response_handler completionFn, + xmlrpc_progress_fn progressFn, + void * const userHandle, + struct xmlrpc_call_info ** const callInfoPP) { +/*---------------------------------------------------------------------------- + Create a call_info object. A call_info object represents an XML-RPC + call. +-----------------------------------------------------------------------------*/ + struct xmlrpc_call_info * callInfoP; + + XMLRPC_ASSERT_PTR_OK(serverUrl); + XMLRPC_ASSERT_PTR_OK(methodName); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + XMLRPC_ASSERT_PTR_OK(callInfoPP); + + MALLOCVAR(callInfoP); + if (callInfoP == NULL) + xmlrpc_faultf(envP, "Couldn't allocate memory for xmlrpc_call_info"); + else { + xmlrpc_mem_block * callXmlP; + + makeCallXml(envP, methodName, paramArrayP, dialect, &callXmlP); + + if (!envP->fault_occurred) { + callInfoP->serialized_xml = callXmlP; + + callInfoSetCompletion(envP, callInfoP, serverUrl, methodName, + paramArrayP, + completionFn, progressFn, userHandle); + + if (envP->fault_occurred) + free(callInfoP); + } + } + *callInfoPP = callInfoP; +} + + + +static void +callInfoDestroy(struct xmlrpc_call_info * const callInfoP) { + + XMLRPC_ASSERT_PTR_OK(callInfoP); + + if (callInfoP->completionFn) { + xmlrpc_DECREF(callInfoP->completionArgs.paramArrayP); + xmlrpc_strfree(callInfoP->completionArgs.methodName); + xmlrpc_strfree(callInfoP->completionArgs.serverUrl); + } + if (callInfoP->serialized_xml) + xmlrpc_mem_block_free(callInfoP->serialized_xml); + + free(callInfoP); +} + + + +void +xmlrpc_client_event_loop_finish(xmlrpc_client * const clientP) { + + XMLRPC_ASSERT_PTR_OK(clientP); + + clientP->transportOps.finish_asynch( + clientP->transportP, timeout_no, 0); +} + + + +void +xmlrpc_client_event_loop_finish_timeout(xmlrpc_client * const clientP, + xmlrpc_timeout const timeout) { + + XMLRPC_ASSERT_PTR_OK(clientP); + + clientP->transportOps.finish_asynch( + clientP->transportP, timeout_yes, timeout); +} + + + +/* Microsoft Visual C in debug mode produces code that complains about + passing an undefined value of 'resultP' to xmlrpc_parse_response2(). + It's a bogus complaint, because this function knows in those cases + that the value of 'resultP' is meaningless. So we disable the check. +*/ +#pragma runtime_checks("u", off) + + + +static void +asynchComplete(struct xmlrpc_call_info * const callInfoP, + xmlrpc_mem_block * const responseXmlP, + xmlrpc_env const transportEnv) { +/*---------------------------------------------------------------------------- + Complete an asynchronous XML-RPC call request. + + This includes calling the user's RPC completion routine. + + 'transportEnv' describes an error that the transport + encountered in processing the call. If the transport successfully + sent the call to the server and processed the response but the + server failed the call, 'transportEnv' indicates no error, and the + response in *responseXmlP might very well indicate that the server + failed the request. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xmlrpc_value * resultP; + + xmlrpc_env_init(&env); + + if (transportEnv.fault_occurred) + xmlrpc_env_set_fault_formatted( + &env, transportEnv.fault_code, + "Client transport failed to execute the RPC. %s", + transportEnv.fault_string); + + if (!env.fault_occurred) { + int faultCode; + const char * faultString; + + xmlrpc_parse_response2(&env, + XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlP), + XMLRPC_MEMBLOCK_SIZE(char, responseXmlP), + &resultP, &faultCode, &faultString); + + if (!env.fault_occurred) { + if (faultString) { + xmlrpc_env_set_fault_formatted( + &env, faultCode, + "RPC failed at server. %s", faultString); + xmlrpc_strfree(faultString); + } + } + } + /* Call the user's completion function with the RPC result */ + (*callInfoP->completionFn)(callInfoP->completionArgs.serverUrl, + callInfoP->completionArgs.methodName, + callInfoP->completionArgs.paramArrayP, + callInfoP->userHandle, + &env, resultP); + + if (!env.fault_occurred) + xmlrpc_DECREF(resultP); + + callInfoDestroy(callInfoP); + + xmlrpc_env_clean(&env); +} + + + +#pragma runtime_checks("u", restore) + + + +static void +progress(struct xmlrpc_call_info * const callInfoP, + struct xmlrpc_progress_data const progressData) { + + /* We wouldn't have asked the transport to call our progress + function if we didn't have a user progress function to call: + */ + assert(callInfoP->progressFn); + + callInfoP->progressFn(callInfoP->userHandle, progressData); +} + + + +void +xmlrpc_client_start_rpc(xmlrpc_env * const envP, + struct xmlrpc_client * const clientP, + const xmlrpc_server_info * const serverInfoP, + const char * const methodName, + xmlrpc_value * const paramArrayP, + xmlrpc_response_handler completionFn, + void * const userHandle) { + + struct xmlrpc_call_info * callInfoP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(clientP); + XMLRPC_ASSERT_PTR_OK(serverInfoP); + XMLRPC_ASSERT_PTR_OK(methodName); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + + callInfoCreate(envP, methodName, paramArrayP, clientP->dialect, + serverInfoP->serverUrl, + completionFn, clientP->progressFn, userHandle, + &callInfoP); + + if (!envP->fault_occurred) { + xmlrpc_traceXml( + "XML-RPC CALL", + XMLRPC_MEMBLOCK_CONTENTS(char, callInfoP->serialized_xml), + XMLRPC_MEMBLOCK_SIZE(char, callInfoP->serialized_xml)); + + clientP->transportOps.send_request( + envP, clientP->transportP, serverInfoP, + callInfoP->serialized_xml, + &asynchComplete, clientP->progressFn ? &progress : NULL, + callInfoP); + } + if (envP->fault_occurred) + callInfoDestroy(callInfoP); + else { + /* asynchComplete() will destroy *callInfoP */ + } +} + + + +void +xmlrpc_client_start_rpcf_server_va( + xmlrpc_env * const envP, + xmlrpc_client * const clientP, + const xmlrpc_server_info * const serverInfoP, + const char * const methodName, + xmlrpc_response_handler responseHandler, + void * const userHandle, + const char * const format, + va_list args) { + + xmlrpc_value * paramArrayP; + /* The XML-RPC parameter list array */ + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(clientP); + XMLRPC_ASSERT_PTR_OK(serverInfoP); + XMLRPC_ASSERT_PTR_OK(methodName); + XMLRPC_ASSERT_PTR_OK(format); + + computeParamArray(envP, format, args, ¶mArrayP); + + if (!envP->fault_occurred) { + xmlrpc_client_start_rpc(envP, clientP, + serverInfoP, methodName, paramArrayP, + responseHandler, userHandle); + + xmlrpc_DECREF(paramArrayP); + } +} + + + +void +xmlrpc_client_start_rpcf_va(xmlrpc_env * const envP, + xmlrpc_client * const clientP, + const char * const serverUrl, + const char * const methodName, + xmlrpc_response_handler responseHandler, + void * const userHandle, + const char * const format, + va_list args) { + + xmlrpc_server_info * serverInfoP; + + XMLRPC_ASSERT_ENV_OK(envP); + + serverInfoP = xmlrpc_server_info_new(envP, serverUrl); + if (!envP->fault_occurred) { + xmlrpc_client_start_rpcf_server_va( + envP, clientP, + serverInfoP, methodName, + responseHandler, userHandle, + format, args); + + xmlrpc_server_info_free(serverInfoP); + } +} + + + +void +xmlrpc_client_start_rpcf(xmlrpc_env * const envP, + xmlrpc_client * const clientP, + const char * const serverUrl, + const char * const methodName, + xmlrpc_response_handler responseHandler, + void * const userHandle, + const char * const format, + ...) { + + va_list args; + + XMLRPC_ASSERT_PTR_OK(format); + + va_start(args, format); + xmlrpc_client_start_rpcf_va(envP, clientP, serverUrl, methodName, + responseHandler, + userHandle, format, args); + va_end(args); +} + + + +/*========================================================================= + Miscellaneous +=========================================================================*/ + +const char * +xmlrpc_client_get_default_transport(xmlrpc_env * const envP ATTR_UNUSED) { + + return XMLRPC_DEFAULT_TRANSPORT; +} + + + +void +xmlrpc_client_set_interrupt(xmlrpc_client * const clientP, + int * const interruptP) { + + if (clientP->transportOps.set_interrupt) + clientP->transportOps.set_interrupt(clientP->transportP, interruptP); +} + + + +/* 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. +*/ diff --git a/trunk/src/xmlrpc_client_global.c b/trunk/src/xmlrpc_client_global.c new file mode 100644 index 000000000..362b99f5c --- /dev/null +++ b/trunk/src/xmlrpc_client_global.c @@ -0,0 +1,370 @@ +#include + +#include "xmlrpc_config.h" + +#include "bool.h" + +#include +#include +#include +#include + +/*========================================================================= + Global Client +=========================================================================*/ + +static struct xmlrpc_client * globalClientP; +static bool globalClientExists = false; + + +void +xmlrpc_client_init2(xmlrpc_env * const envP, + int const flags, + const char * const appname, + const char * const appversion, + const struct xmlrpc_clientparms * const clientparmsP, + unsigned int const parmSize) { +/*---------------------------------------------------------------------------- + This function is not thread-safe. +-----------------------------------------------------------------------------*/ + if (globalClientExists) + xmlrpc_faultf( + envP, + "Xmlrpc-c global client instance has already been created " + "(need to call xmlrpc_client_cleanup() before you can " + "reinitialize)."); + else { + /* The following call is not thread-safe */ + xmlrpc_client_setup_global_const(envP); + if (!envP->fault_occurred) { + xmlrpc_client_create(envP, flags, appname, appversion, + clientparmsP, parmSize, &globalClientP); + if (!envP->fault_occurred) + globalClientExists = true; + + if (envP->fault_occurred) + xmlrpc_client_teardown_global_const(); + } + } +} + + + +void +xmlrpc_client_init(int const flags, + const char * const appname, + const char * const appversion) { +/*---------------------------------------------------------------------------- + This function is not thread-safe. +-----------------------------------------------------------------------------*/ + struct xmlrpc_clientparms clientparms; + + /* As our interface does not allow for failure, we just fail silently ! */ + + xmlrpc_env env; + xmlrpc_env_init(&env); + + clientparms.transport = NULL; + + /* The following call is not thread-safe */ + xmlrpc_client_init2(&env, flags, + appname, appversion, + &clientparms, XMLRPC_CPSIZE(transport)); + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_client_cleanup() { +/*---------------------------------------------------------------------------- + This function is not thread-safe +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT(globalClientExists); + + xmlrpc_client_destroy(globalClientP); + + globalClientExists = false; + + /* The following call is not thread-safe */ + xmlrpc_client_teardown_global_const(); +} + + + +static void +validateGlobalClientExists(xmlrpc_env * const envP) { + + if (!globalClientExists) + xmlrpc_faultf(envP, + "Xmlrpc-c global client instance " + "has not been created " + "(need to call xmlrpc_client_init2())."); +} + + + +void +xmlrpc_client_transport_call( + xmlrpc_env * const envP, + void * const reserved ATTR_UNUSED, + /* for client handle */ + const xmlrpc_server_info * const serverP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block ** const respXmlPP) { + + validateGlobalClientExists(envP); + if (!envP->fault_occurred) + xmlrpc_client_transport_call2(envP, globalClientP, serverP, + callXmlP, respXmlPP); +} + + + +xmlrpc_value * +xmlrpc_client_call(xmlrpc_env * const envP, + const char * const serverUrl, + const char * const methodName, + const char * const format, + ...) { + + xmlrpc_value * resultP; + + validateGlobalClientExists(envP); + + if (!envP->fault_occurred) { + va_list args; + + va_start(args, format); + + xmlrpc_client_call2f_va(envP, globalClientP, serverUrl, + methodName, format, &resultP, args); + + va_end(args); + } + return resultP; +} + + + +xmlrpc_value * +xmlrpc_client_call_server(xmlrpc_env * const envP, + const xmlrpc_server_info * const serverInfoP, + const char * const methodName, + const char * const format, + ...) { + + xmlrpc_value * resultP; + + validateGlobalClientExists(envP); + + if (!envP->fault_occurred) { + va_list args; + + va_start(args, format); + + xmlrpc_client_call_server2_va(envP, globalClientP, serverInfoP, + methodName, format, args, &resultP); + va_end(args); + } + return resultP; +} + + + +xmlrpc_value * +xmlrpc_client_call_server_params( + xmlrpc_env * const envP, + const xmlrpc_server_info * const serverInfoP, + const char * const methodName, + xmlrpc_value * const paramArrayP) { + + xmlrpc_value * resultP; + + validateGlobalClientExists(envP); + + if (!envP->fault_occurred) + xmlrpc_client_call2(envP, globalClientP, + serverInfoP, methodName, paramArrayP, + &resultP); + + return resultP; +} + + + +xmlrpc_value * +xmlrpc_client_call_params(xmlrpc_env * const envP, + const char * const serverUrl, + const char * const methodName, + xmlrpc_value * const paramArrayP) { + + xmlrpc_value * resultP; + + validateGlobalClientExists(envP); + + if (!envP->fault_occurred) { + xmlrpc_server_info * serverInfoP; + + serverInfoP = xmlrpc_server_info_new(envP, serverUrl); + + if (!envP->fault_occurred) { + xmlrpc_client_call2(envP, globalClientP, + serverInfoP, methodName, paramArrayP, + &resultP); + + xmlrpc_server_info_free(serverInfoP); + } + } + return resultP; +} + + + +void +xmlrpc_client_call_server_asynch_params( + xmlrpc_server_info * const serverInfoP, + const char * const methodName, + xmlrpc_response_handler responseHandler, + void * const userData, + xmlrpc_value * const paramArrayP) { + + xmlrpc_env env; + + xmlrpc_env_init(&env); + + validateGlobalClientExists(&env); + + if (!env.fault_occurred) + xmlrpc_client_start_rpc(&env, globalClientP, + serverInfoP, methodName, paramArrayP, + responseHandler, userData); + + if (env.fault_occurred) { + /* Unfortunately, we have no way to return an error and the + regular callback for a failed RPC is designed to have the + parameter array passed to it. This was probably an oversight + of the original asynch design, but now we have to be as + backward compatible as possible, so we do this: + */ + (*responseHandler)(serverInfoP->serverUrl, + methodName, paramArrayP, userData, + &env, NULL); + } + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_client_call_asynch(const char * const serverUrl, + const char * const methodName, + xmlrpc_response_handler responseHandler, + void * const userData, + const char * const format, + ...) { + + xmlrpc_env env; + + xmlrpc_env_init(&env); + + validateGlobalClientExists(&env); + + if (!env.fault_occurred) { + va_list args; + + va_start(args, format); + + xmlrpc_client_start_rpcf_va(&env, globalClientP, + serverUrl, methodName, + responseHandler, userData, + format, args); + + va_end(args); + } + if (env.fault_occurred) + (*responseHandler)(serverUrl, methodName, NULL, userData, &env, NULL); + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_client_call_asynch_params(const char * const serverUrl, + const char * const methodName, + xmlrpc_response_handler responseHandler, + void * const userData, + xmlrpc_value * const paramArrayP) { + xmlrpc_env env; + xmlrpc_server_info * serverInfoP; + + xmlrpc_env_init(&env); + + serverInfoP = xmlrpc_server_info_new(&env, serverUrl); + + if (!env.fault_occurred) { + xmlrpc_client_call_server_asynch_params( + serverInfoP, methodName, responseHandler, userData, paramArrayP); + + xmlrpc_server_info_free(serverInfoP); + } + if (env.fault_occurred) + (*responseHandler)(serverUrl, methodName, paramArrayP, userData, + &env, NULL); + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_client_call_server_asynch(xmlrpc_server_info * const serverInfoP, + const char * const methodName, + xmlrpc_response_handler responseHandler, + void * const userData, + const char * const format, + ...) { + + xmlrpc_env env; + + validateGlobalClientExists(&env); + + if (!env.fault_occurred) { + va_list args; + + xmlrpc_env_init(&env); + + va_start(args, format); + + xmlrpc_client_start_rpcf_server_va( + &env, globalClientP, serverInfoP, methodName, + responseHandler, userData, format, args); + + va_end(args); + } + if (env.fault_occurred) + (*responseHandler)(serverInfoP->serverUrl, methodName, NULL, + userData, &env, NULL); + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_client_event_loop_finish_asynch(void) { + + XMLRPC_ASSERT(globalClientExists); + xmlrpc_client_event_loop_finish(globalClientP); +} + + + +void +xmlrpc_client_event_loop_finish_asynch_timeout( + unsigned long const milliseconds) { + + XMLRPC_ASSERT(globalClientExists); + xmlrpc_client_event_loop_finish_timeout(globalClientP, milliseconds); +} diff --git a/trunk/src/xmlrpc_data.c b/trunk/src/xmlrpc_data.c new file mode 100644 index 000000000..605cac1eb --- /dev/null +++ b/trunk/src/xmlrpc_data.c @@ -0,0 +1,721 @@ +/* Copyright information is at end of file */ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include + +#include "bool.h" +#include "mallocvar.h" + +#include "xmlrpc-c/lock.h" +#include "xmlrpc-c/lock_platform.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" + + +/*============================================================================= + + xmlrpc_value is designed to enable cheap copies by sharing pointers and + maintaining reference counts. Multiple threads can use an xmlrpc_value + simultaneously because there is locking around the reference count + manipulation (but only since Xmlrpc-c 1.33). But there is no copy on + write, so the scheme depends upon the user not modifying an xmlrpc_value + after building it, and not copying it while building it. Another reason + to observe this sequence is that there is no locking around modifications, + so a reader could see a half-updated xmlrpc_value. + + We could enforce a prohibition against modifying an xmlrpc_value that has + references other than the one by the party doing the modifying, but we + don't because we allowed it for a long time before we noticed the problem + adn we're afraid of breaking an existing program that does these updates in + such a way that it actually works. + +=============================================================================*/ + + + +static void +destroyCptr(xmlrpc_value * const valueP) { + + if (valueP->_value.cptr.dtor) + valueP->_value.cptr.dtor(valueP->_value.cptr.dtorContext, + valueP->_value.cptr.objectP); +} + + + +static void +destroyValue(xmlrpc_value * const valueP) { + + /* First, we need to destroy this value's contents, if any. */ + switch (valueP->_type) { + case XMLRPC_TYPE_INT: + break; + + case XMLRPC_TYPE_BOOL: + break; + + case XMLRPC_TYPE_DOUBLE: + break; + + case XMLRPC_TYPE_DATETIME: + xmlrpc_destroyDatetime(valueP); + break; + + case XMLRPC_TYPE_STRING: + xmlrpc_destroyString(valueP); + break; + + case XMLRPC_TYPE_BASE64: + xmlrpc_mem_block_free(valueP->blockP); + break; + + case XMLRPC_TYPE_ARRAY: + xmlrpc_destroyArrayContents(valueP); + break; + + case XMLRPC_TYPE_STRUCT: + xmlrpc_destroyStruct(valueP); + break; + + case XMLRPC_TYPE_C_PTR: + destroyCptr(valueP); + break; + + case XMLRPC_TYPE_NIL: + break; + + case XMLRPC_TYPE_I8: + break; + + case XMLRPC_TYPE_DEAD: + XMLRPC_ASSERT(false); /* Can't happen, per entry conditions */ + + default: + XMLRPC_ASSERT(false); /* There are no other possible values */ + } + + valueP->lockP->destroy(valueP->lockP); + + /* Next, we mark this value as invalid, to help catch refcount errors. + */ + valueP->_type = XMLRPC_TYPE_DEAD; + + /* Finally, we destroy the value itself. */ + free(valueP); +} + + + +/*=========================================================================== + Reference Counting +============================================================================= + Some simple reference-counting code. The xmlrpc_DECREF routine is in + charge of destroying values when their reference count reaches zero. +============================================================================*/ + +void +xmlrpc_INCREF (xmlrpc_value * const valueP) { + + XMLRPC_ASSERT_VALUE_OK(valueP); + + valueP->lockP->acquire(valueP->lockP); + + XMLRPC_ASSERT(valueP->refcount > 0); + + ++valueP->refcount; + + valueP->lockP->release(valueP->lockP); +} + + + +void +xmlrpc_DECREF (xmlrpc_value * const valueP) { + + bool died; + + XMLRPC_ASSERT_VALUE_OK(valueP); + + valueP->lockP->acquire(valueP->lockP); + + XMLRPC_ASSERT(valueP->refcount > 0); + XMLRPC_ASSERT(valueP->_type != XMLRPC_TYPE_DEAD); + + --valueP->refcount; + + died = (valueP->refcount == 0); + + valueP->lockP->release(valueP->lockP); + + if (died) + destroyValue(valueP); +} + + + +/*========================================================================= + Utiltiies +=========================================================================*/ + +const char * +xmlrpc_type_name(xmlrpc_type const type) { + + switch (type) { + + case XMLRPC_TYPE_INT: return "INT"; + case XMLRPC_TYPE_BOOL: return "BOOL"; + case XMLRPC_TYPE_DOUBLE: return "DOUBLE"; + case XMLRPC_TYPE_DATETIME: return "DATETIME"; + case XMLRPC_TYPE_STRING: return "STRING"; + case XMLRPC_TYPE_BASE64: return "BASE64"; + case XMLRPC_TYPE_ARRAY: return "ARRAY"; + case XMLRPC_TYPE_STRUCT: return "STRUCT"; + case XMLRPC_TYPE_C_PTR: return "C_PTR"; + case XMLRPC_TYPE_NIL: return "NIL"; + case XMLRPC_TYPE_I8: return "I8"; + case XMLRPC_TYPE_DEAD: return "DEAD"; + default: return "???"; + + } +} + + + +static void +validateType(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + xmlrpc_type const expectedType) { + + if (valueP->_type != expectedType) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " + "type %s was expected.", + xmlrpc_type_name(valueP->_type), xmlrpc_type_name(expectedType)); + } +} + + + +/*========================================================================= + Extracting XML-RPC value +=========================================================================== + These routines extract XML-RPC values into ordinary C data types. + + For array and struct values, see the separates files xmlrpc_array.c + and xmlrpc_struct.c. +=========================================================================*/ + +void +xmlrpc_read_int(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + xmlrpc_int32 * const intValueP) { + + validateType(envP, valueP, XMLRPC_TYPE_INT); + if (!envP->fault_occurred) + *intValueP = valueP->_value.i; +} + + + +void +xmlrpc_read_bool(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + xmlrpc_bool * const boolValueP) { + + validateType(envP, valueP, XMLRPC_TYPE_BOOL); + if (!envP->fault_occurred) + *boolValueP = valueP->_value.b; +} + + + +void +xmlrpc_read_double(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + xmlrpc_double * const doubleValueP) { + + validateType(envP, valueP, XMLRPC_TYPE_DOUBLE); + if (!envP->fault_occurred) + *doubleValueP = valueP->_value.d; + +} + + + +/* datetime stuff is in xmlrpc_datetime.c */ + +/* string stuff is in xmlrpc_string.c */ + + + +void +xmlrpc_read_base64(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + size_t * const lengthP, + const unsigned char ** const byteStringValueP) { + + validateType(envP, valueP, XMLRPC_TYPE_BASE64); + if (!envP->fault_occurred) { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); + + char * byteStringValue; + + byteStringValue = malloc(size); + if (byteStringValue == NULL) + xmlrpc_faultf(envP, + "Unable to allocate %u bytes for byte string.", + (unsigned)size); + else { + memcpy(byteStringValue, contents, size); + *byteStringValueP = (const unsigned char *)byteStringValue; + *lengthP = size; + } + } +} + + + +void +xmlrpc_read_base64_old(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + size_t * const lengthP, + const unsigned char ** const byteStringValueP) { + + validateType(envP, valueP, XMLRPC_TYPE_BASE64); + if (!envP->fault_occurred) { + *lengthP = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); + *byteStringValueP = (const unsigned char *) + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); + } +} + + + +void +xmlrpc_read_base64_size(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + size_t * const lengthP) { + + validateType(envP, valueP, XMLRPC_TYPE_BASE64); + if (!envP->fault_occurred) + *lengthP = XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); +} + + + +void +xmlrpc_read_cptr(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + void ** const ptrValueP) { + + validateType(envP, valueP, XMLRPC_TYPE_C_PTR); + if (!envP->fault_occurred) + *ptrValueP = valueP->_value.cptr.objectP; +} + + + +void +xmlrpc_read_nil(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { +/*---------------------------------------------------------------------------- + Read out the value of a nil value. It doesn't have one, of course, so + this is essentially a no-op. But it does validate the type and is + necessary to match all the other types. +-----------------------------------------------------------------------------*/ + validateType(envP, valueP, XMLRPC_TYPE_NIL); +} + + + +void +xmlrpc_read_i8(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + xmlrpc_int64 * const intValueP) { + + validateType(envP, valueP, XMLRPC_TYPE_I8); + if (!envP->fault_occurred) + *intValueP = valueP->_value.i8; +} + + + +xmlrpc_type xmlrpc_value_type (xmlrpc_value* const value) +{ + XMLRPC_ASSERT_VALUE_OK(value); + return value->_type; +} + + + +void +xmlrpc_createXmlrpcValue(xmlrpc_env * const envP, + xmlrpc_value ** const valPP) { +/*---------------------------------------------------------------------------- + Create a blank xmlrpc_value to be filled in. + + Set the reference count to 1. +-----------------------------------------------------------------------------*/ + xmlrpc_value * valP; + + MALLOCVAR(valP); + if (!valP) + xmlrpc_faultf(envP, "Could not allocate memory for xmlrpc_value"); + else { + valP->lockP = xmlrpc_lock_create(); + + if (!valP->lockP) + xmlrpc_faultf(envP, "Could not allocate memory for lock for " + "xmlrpc_value"); + else + valP->refcount = 1; + + if (envP->fault_occurred) { + free(valP); + valP = NULL; + } + } + *valPP = valP; +} + + + +xmlrpc_value * +xmlrpc_value_new(xmlrpc_env * const envP, + xmlrpc_value * const sourceValP) { + + switch (sourceValP->_type) { + case XMLRPC_TYPE_INT: + return xmlrpc_int_new_value(envP, sourceValP); + case XMLRPC_TYPE_I8: + return xmlrpc_i8_new_value(envP, sourceValP); + case XMLRPC_TYPE_BOOL: + return xmlrpc_bool_new_value(envP, sourceValP); + case XMLRPC_TYPE_DOUBLE: + return xmlrpc_double_new_value(envP, sourceValP); + case XMLRPC_TYPE_DATETIME: + return xmlrpc_datetime_new_value(envP, sourceValP); + case XMLRPC_TYPE_STRING: + return xmlrpc_string_new_value(envP, sourceValP); + case XMLRPC_TYPE_BASE64: + return xmlrpc_base64_new_value(envP, sourceValP); + case XMLRPC_TYPE_ARRAY: + return xmlrpc_array_new_value(envP, sourceValP); + case XMLRPC_TYPE_STRUCT: + return xmlrpc_struct_new_value(envP, sourceValP); + case XMLRPC_TYPE_C_PTR: + return xmlrpc_cptr_new_value(envP, sourceValP); + case XMLRPC_TYPE_NIL: + return xmlrpc_nil_new(envP); + case XMLRPC_TYPE_DEAD: + xmlrpc_faultf(envP, "Attempt to copy a dead xmlrpc_value"); + return NULL; + } + assert(false); /* All cases are handled above */ + + return NULL; /* Quiet compiler warning */ +} + + + +xmlrpc_value * +xmlrpc_int_new(xmlrpc_env * const envP, + xmlrpc_int32 const value) { + + xmlrpc_value * valP; + + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_INT; + valP->_value.i = value; + } + return valP; +} + + + +xmlrpc_value * +xmlrpc_int_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * retval; + + if (valueP->_type != XMLRPC_TYPE_INT) { + xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, + "Value is not an integer. " + "It is type #%d", valueP->_type); + retval = NULL; + } else + retval = xmlrpc_int_new(envP, valueP->_value.i); + + return retval; +} + + + +xmlrpc_value * +xmlrpc_i8_new(xmlrpc_env * const envP, + xmlrpc_int64 const value) { + + xmlrpc_value * valP; + + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_I8; + valP->_value.i8 = value; + } + return valP; +} + + + +xmlrpc_value * +xmlrpc_i8_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * retval; + + if (valueP->_type != XMLRPC_TYPE_I8) { + xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, + "Value is not a 64-bit integer. " + "It is type #%d", valueP->_type); + retval = NULL; + } else + retval = xmlrpc_i8_new(envP, valueP->_value.i8); + + return retval; +} + + + +xmlrpc_value * +xmlrpc_bool_new(xmlrpc_env * const envP, + xmlrpc_bool const value) { + + xmlrpc_value * valP; + + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_BOOL; + valP->_value.b = value; + } + return valP; +} + + + +xmlrpc_value * +xmlrpc_bool_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * retval; + + if (valueP->_type != XMLRPC_TYPE_BOOL) { + xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, + "Value is not a boolean. " + "It is type #%d", valueP->_type); + retval = NULL; + } else + retval = xmlrpc_bool_new(envP, valueP->_value.b); + + return retval; +} + + + +xmlrpc_value * +xmlrpc_double_new(xmlrpc_env * const envP, + double const value) { + + xmlrpc_value * valP; + + if (!XMLRPC_FINITE(value)) { + xmlrpc_faultf(envP, "Value is not a finite number, " + "so cannot be represented in XML-RPC"); + valP = NULL; + } else { + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_DOUBLE; + valP->_value.d = value; + } + } + return valP; +} + + + +xmlrpc_value * +xmlrpc_double_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * retval; + + if (valueP->_type != XMLRPC_TYPE_DOUBLE) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, + "Value is not a floating point number. " + "It is type #%d", valueP->_type); + retval = NULL; + } else + retval = xmlrpc_double_new(envP, valueP->_value.d); + + return retval; +} + + + +xmlrpc_value * +xmlrpc_base64_new(xmlrpc_env * const envP, + size_t const length, + const unsigned char * const value) { + + xmlrpc_value * valP; + + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_BASE64; + + valP->blockP = xmlrpc_mem_block_new(envP, length); + if (!envP->fault_occurred) { + char * const contents = + xmlrpc_mem_block_contents(valP->blockP); + memcpy(contents, value, length); + } + if (envP->fault_occurred) + free(valP); + } + return valP; +} + + + +xmlrpc_value * +xmlrpc_base64_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * retval; + + if (valueP->_type != XMLRPC_TYPE_BASE64) { + xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, + "Value is not a datetime. " + "It is type #%d", valueP->_type); + retval = NULL; + } else + retval = xmlrpc_base64_new(envP, + xmlrpc_mem_block_size(valueP->blockP), + xmlrpc_mem_block_contents(valueP->blockP)); + + return retval; +} + + + +/* array stuff is in xmlrpc_array.c */ + + + +xmlrpc_value * +xmlrpc_cptr_new(xmlrpc_env * const envP, + void * const value) { + + return xmlrpc_cptr_new_dtor(envP, value, NULL, NULL); +} + + + +xmlrpc_value * +xmlrpc_cptr_new_dtor(xmlrpc_env * const envP, + void * const value, + xmlrpc_cptr_dtor_fn const dtor, + void * const dtorContext) { + + xmlrpc_value * valP; + + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_C_PTR; + valP->_value.cptr.objectP = value; + valP->_value.cptr.dtor = dtor; + valP->_value.cptr.dtorContext = dtorContext; + } + return valP; +} + + + +xmlrpc_value * +xmlrpc_cptr_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * retval; + + if (valueP->_type != XMLRPC_TYPE_C_PTR) { + xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, + "Value is not a C poitner. " + "It is type #%d", valueP->_type); + retval = NULL; + } else + retval = xmlrpc_cptr_new_dtor(envP, + valueP->_value.cptr.objectP, + valueP->_value.cptr.dtor, + valueP->_value.cptr.dtorContext); + return retval; +} + + + +xmlrpc_value * +xmlrpc_nil_new(xmlrpc_env * const envP) { + xmlrpc_value * valP; + + xmlrpc_createXmlrpcValue(envP, &valP); + if (!envP->fault_occurred) + valP->_type = XMLRPC_TYPE_NIL; + + return valP; +} + + + +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** Copyright (C) 2001 by Eric Kidd. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ diff --git a/trunk/src/xmlrpc_datetime.c b/trunk/src/xmlrpc_datetime.c new file mode 100644 index 000000000..117f5297c --- /dev/null +++ b/trunk/src/xmlrpc_datetime.c @@ -0,0 +1,672 @@ +#include "xmlrpc_config.h" + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include +#include +#include +#include +#if MSVCRT +# define WIN32_LEAN_AND_MEAN +# include +#endif + +#include "bool.h" +#include "mallocvar.h" + +#include "xmlrpc-c/c_util.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/time_int.h" + + +#if HAVE_REGEX +#include +#endif + +#if MSVCRT + +static const __int64 SECS_BETWEEN_EPOCHS = 11644473600; +static const __int64 SECS_TO_100NS = 10000000; /* 10^7 */ + + +void +UnixTimeToFileTime(time_t const t, + LPFILETIME const pft) { + + int64_t const ll = + Int32x32To64(t, SECS_TO_100NS) + SECS_BETWEEN_EPOCHS * SECS_TO_100NS; + + pft->dwLowDateTime = (DWORD)ll; + pft->dwHighDateTime = (DWORD)(ll >> 32); +} + + + +void +UnixTimeToSystemTime(time_t const t, + LPSYSTEMTIME const pst) { + FILETIME ft; + + UnixTimeToFileTime(t, &ft); + FileTimeToSystemTime(&ft, pst); +} + + + +static void +UnixTimeFromFileTime(xmlrpc_env * const envP, + LPFILETIME const pft, + time_t * const timeValueP) { + + int64_t const WinEpoch100Ns = + ((int64_t)pft->dwHighDateTime << 32) + pft->dwLowDateTime; + int64_t const unixEpoch100Ns = + WinEpoch100Ns - (SECS_BETWEEN_EPOCHS * SECS_TO_100NS); + int64_t const unixEpochSeconds = + unixEpoch100Ns / SECS_TO_100NS; + + if ((time_t)unixEpochSeconds != unixEpochSeconds) { + /* Value is too big for a time_t; fail. */ + xmlrpc_faultf(envP, "Does not indicate a valid date"); + *timeValueP = (time_t)(-1); + } else + *timeValueP = (time_t)unixEpochSeconds; +} + + + +static void +UnixTimeFromSystemTime(xmlrpc_env * const envP, + LPSYSTEMTIME const pst, + time_t * const timeValueP) { + FILETIME filetime; + + SystemTimeToFileTime(pst, &filetime); + UnixTimeFromFileTime(envP, &filetime, timeValueP); +} + +#endif /* MSVCRT */ + + + +static void +validateDatetimeType(xmlrpc_env * const envP, + const xmlrpc_value * const valueP) { + + if (valueP->_type != XMLRPC_TYPE_DATETIME) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " + "type %s was expected.", + xmlrpc_type_name(valueP->_type), + xmlrpc_type_name(XMLRPC_TYPE_DATETIME)); + } +} + + + +void +xmlrpc_read_datetime(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + xmlrpc_datetime * const dtP) { + + validateDatetimeType(envP, valueP); + if (!envP->fault_occurred) { + *dtP = valueP->_value.dt; + } +} + + + +void +xmlrpc_read_datetime_str(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + const char ** const stringValueP) { +/*---------------------------------------------------------------------------- + This exists for backward compatibility. No normal modern program would + want to see a datetime value in this format. Note that the format isn't + even ISO 8601 -- it's a bizarre hybrid of two ISO 8601 formats. + + Do not extend this. + + This exists because Xmlrpc-c was at one time lazy and this was the only way + to extract the value. An xmlrpc_value in those days represented a datetime + with the actual XML-RPC wire format of a datetime, and this function simply + returned a copy of it. +-----------------------------------------------------------------------------*/ + validateDatetimeType(envP, valueP); + if (!envP->fault_occurred) { + time_t secs; + unsigned int usecs; + + xmlrpc_read_datetime_usec(envP, valueP, &secs, &usecs); + + if (!envP->fault_occurred) { + struct tm brokenTime; + char dtString[64]; + + xmlrpc_gmtime(secs, &brokenTime); + + /* Note that this format is NOT ISO 8601 -- it's a bizarre + hybrid of two ISO 8601 formats. + */ + strftime(dtString, sizeof(dtString), "%Y%m%dT%H:%M:%S", + &brokenTime); + + if (usecs != 0) { + char usecString[64]; + assert(usecs < 1000000); + XMLRPC_SNPRINTF(usecString, sizeof(usecString), + ".%06u", usecs); + STRSCAT(dtString, usecString); + } + + *stringValueP = strdup(dtString); + if (*stringValueP == NULL) + xmlrpc_faultf(envP, + "Unable to allocate memory for datetime string"); + } + } +} + + + +void +xmlrpc_read_datetime_str_old(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + const char ** const stringValueP) { + + assert(valueP->_cache); + + validateDatetimeType(envP, valueP); + if (!envP->fault_occurred) { + const char ** const readBufferP = valueP->_cache; + + if (!*readBufferP) + /* Nobody's asked for the internal buffer before. Set it up. */ + xmlrpc_read_datetime_str(envP, valueP, readBufferP); + + *stringValueP = *readBufferP; + } +} + + + +void +xmlrpc_read_datetime_usec(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + time_t * const secsP, + unsigned int * const usecsP) { + + validateDatetimeType(envP, valueP); + + if (!envP->fault_occurred) { + if (valueP->_value.dt.Y < 1970) + xmlrpc_faultf(envP, "Year (%u) is too early to represent as " + "a standard Unix time", + valueP->_value.dt.Y); + else { + struct tm brokenTime; + const char * error; + + brokenTime.tm_sec = valueP->_value.dt.s; + brokenTime.tm_min = valueP->_value.dt.m; + brokenTime.tm_hour = valueP->_value.dt.h; + brokenTime.tm_mday = valueP->_value.dt.D; + brokenTime.tm_mon = valueP->_value.dt.M - 1; + brokenTime.tm_year = valueP->_value.dt.Y - 1900; + + xmlrpc_timegm(&brokenTime, secsP, &error); + + if (error) { + /* Ideally, this wouldn't be possible - it wouldn't be + possible to create an xmlrpc_value that doesn't actually + represent a real datetime. But today, we're lazy and + don't fully validate incoming XML-RPC + elements, and we also have the legacy + xmlrpc_datetime_new_str() constructor to which the user + may feed garbage. + + We should tighten that up and then simply assert here that + xmlrpc_timegm() succeeded. + */ + xmlrpc_env_set_fault_formatted(envP, XMLRPC_PARSE_ERROR, + "A datetime received in an XML-RPC message " + "or generated with legacy Xmlrpc-c facilities " + "does not validly describe a datetime. %s", + error); + xmlrpc_strfree(error); + } else + *usecsP = valueP->_value.dt.u; + } + } +} + + + +void +xmlrpc_read_datetime_sec(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + time_t * const timeValueP) { + + unsigned int usecs; + + xmlrpc_read_datetime_usec(envP, valueP, timeValueP, &usecs); +} + + + +#if XMLRPC_HAVE_TIMEVAL + +void +xmlrpc_read_datetime_timeval(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + struct timeval * const timeValueP) { + + time_t secs; + unsigned int usecs; + + xmlrpc_read_datetime_usec(envP, valueP, &secs, &usecs); + + timeValueP->tv_sec = secs; + timeValueP->tv_usec = usecs; +} +#endif + + + +#if XMLRPC_HAVE_TIMESPEC + +void +xmlrpc_read_datetime_timespec(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + struct timespec * const timeValueP) { + + time_t secs; + unsigned int usecs; + + xmlrpc_read_datetime_usec(envP, valueP, &secs, &usecs); + + timeValueP->tv_sec = secs; + timeValueP->tv_nsec = usecs * 1000; +} +#endif + + + +void +xmlrpc_read_datetime_8601(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + const char ** const iso8601ValueP) { +/*---------------------------------------------------------------------------- + Get the datetime in ISO 8601 format. + + ISO 8601 allows a variety of representations for each datetime. + The particular one we return is as in the following example. + + 19930214T131030,250000Z + + (13:10:30.25 on February 14, 1993) + + There are always 4 digits for the year. There are always 6 digits after the + comma (microseconds). Midnight is hour 0, not 24. +-----------------------------------------------------------------------------*/ + validateDatetimeType(envP, valueP); + if (!envP->fault_occurred) { + xmlrpc_datetime dt; + + xmlrpc_read_datetime(envP, valueP, &dt); + + if (!envP->fault_occurred) { + if (dt.Y > 9999) + xmlrpc_faultf(envP, "Too far in future (year %u). " + "ISO 8601 cannot " + "represent years after AD 9999", dt.Y); + else { + xmlrpc_asprintf(iso8601ValueP, + "%04u%02u%02uT%02u%02u%02u,%06uZ", + dt.Y, dt.M, dt.D, dt.h, dt.m, dt.s, dt.u); + + if (xmlrpc_strnomem(*iso8601ValueP)) + xmlrpc_faultf(envP, + "Unable to allocate memory " + "for datetime string"); + + if (envP->fault_occurred) + xmlrpc_strfree(*iso8601ValueP); + } + } + } +} + + + +xmlrpc_value * +xmlrpc_datetime_new(xmlrpc_env * const envP, + xmlrpc_datetime const dt) { + + xmlrpc_value * valP; + + const char ** readBufferP; + + MALLOCVAR(readBufferP); + + if (!readBufferP) + xmlrpc_faultf(envP, "Couldn't get memory for the cache part of the " + "XML-RPC datetime value object"); + + else { + *readBufferP = NULL; + + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_DATETIME; + + valP->_value.dt = dt; + + valP->_cache = readBufferP; + } + if (envP->fault_occurred) + free(readBufferP); + } + return valP; +} + + + +static void +parseDatetimeString(const char * const datetimeString, + xmlrpc_datetime * const dtP) { + + size_t const dtStrlen = strlen(datetimeString); + + char year[4+1]; + char month[2+1]; + char day[2+1]; + char hour[2+1]; + char minute[2+1]; + char second[2+1]; + + /* Because we require input to be valid: */ + assert(dtStrlen >= 17 && dtStrlen != 18 && dtStrlen <= 24); + + year[0] = datetimeString[ 0]; + year[1] = datetimeString[ 1]; + year[2] = datetimeString[ 2]; + year[3] = datetimeString[ 3]; + year[4] = '\0'; + + month[0] = datetimeString[ 4]; + month[1] = datetimeString[ 5]; + month[2] = '\0'; + + day[0] = datetimeString[ 6]; + day[1] = datetimeString[ 7]; + day[2] = '\0'; + + assert(datetimeString[ 8] == 'T'); + + hour[0] = datetimeString[ 9]; + hour[1] = datetimeString[10]; + hour[2] = '\0'; + + assert(datetimeString[11] == ':'); + + minute[0] = datetimeString[12]; + minute[1] = datetimeString[13]; + minute[2] = '\0'; + + assert(datetimeString[14] == ':'); + + second[0] = datetimeString[15]; + second[1] = datetimeString[16]; + second[2] = '\0'; + + if (dtStrlen > 17) { + size_t const pad = 24 - dtStrlen; + size_t i; + + dtP->u = atoi(&datetimeString[18]); + for (i = 0; i < pad; ++i) + dtP->u *= 10; + } else + dtP->u = 0; + + dtP->Y = atoi(year); + dtP->M = atoi(month); + dtP->D = atoi(day); + dtP->h = atoi(hour); + dtP->m = atoi(minute); + dtP->s = atoi(second); +} + + + +static void +validateFirst17(xmlrpc_env * const envP, + const char * const dt) { +/*---------------------------------------------------------------------------- + Assuming 'dt' is at least 17 characters long, validate that the first + 17 characters are a valid XML-RPC datetime, e.g. + "20080628T16:35:02" +-----------------------------------------------------------------------------*/ + unsigned int i; + + for (i = 0; i < 8 && !envP->fault_occurred; ++i) + if (!isdigit(dt[i])) + xmlrpc_faultf(envP, "Not a digit: '%c'", dt[i]); + + if (dt[8] != 'T') + xmlrpc_faultf(envP, "9th character is '%c', not 'T'", dt[8]); + if (!isdigit(dt[9])) + xmlrpc_faultf(envP, "Not a digit: '%c'", dt[9]); + if (!isdigit(dt[10])) + xmlrpc_faultf(envP, "Not a digit: '%c'", dt[10]); + if (dt[11] != ':') + xmlrpc_faultf(envP, "Not a colon: '%c'", dt[11]); + if (!isdigit(dt[12])) + xmlrpc_faultf(envP, "Not a digit: '%c'", dt[12]); + if (!isdigit(dt[13])) + xmlrpc_faultf(envP, "Not a digit: '%c'", dt[13]); + if (dt[14] != ':') + xmlrpc_faultf(envP, "Not a colon: '%c'", dt[14]); + if (!isdigit(dt[15])) + xmlrpc_faultf(envP, "Not a digit: '%c'", dt[15]); + if (!isdigit(dt[16])) + xmlrpc_faultf(envP, "Not a digit: '%c'", dt[16]); +} + + + +static void +validateFractionalSeconds(xmlrpc_env * const envP, + const char * const dt) { +/*---------------------------------------------------------------------------- + Validate the fractional seconds part of the XML-RPC datetime string + 'dt', if any. That's the decimal point and everything following + it. +-----------------------------------------------------------------------------*/ + if (strlen(dt) > 17) { + if (dt[17] != '.') { + xmlrpc_faultf(envP, "'%c' where only a period is valid", dt[17]); + } else { + if (dt[18] == '\0') + xmlrpc_faultf(envP, "Nothing after decimal point"); + else { + unsigned int i; + for (i = 18; dt[i] != '\0' && !envP->fault_occurred; ++i) { + if (!isdigit(dt[i])) + xmlrpc_faultf(envP, + "Non-digit in fractional seconds: '%c'", + dt[i]); + } + } + } + } +} + + + +static void +validateFormat(xmlrpc_env * const envP, + const char * const dt) { + + if (strlen(dt) < 17) + xmlrpc_faultf(envP, + "Invalid length of %u of datetime string. " + "Must be at least 17 characters", + (unsigned)strlen(dt)); + else { + validateFirst17(envP, dt); + + if (!envP->fault_occurred) + validateFractionalSeconds(envP, dt); + } +} + + + +/* Microsoft Visual C in debug mode produces code that complains about + returning an undefined value from xmlrpc_datetime_new_str(). It's a bogus + complaint, because this function is defined to return nothing meaningful + those cases. So we disable the check. +*/ +#pragma runtime_checks("u", off) + + + +xmlrpc_value * +xmlrpc_datetime_new_str(xmlrpc_env * const envP, + const char * const datetimeString) { +/*---------------------------------------------------------------------------- + This exists only for backward compatibility. Originally, this was the + only way to create a datetime XML-RPC value, because we had a really + lazy implementation of XML-RPC serialization and parsing (basically, the + user did it!). + + Do not extend this. The user should use more normal C representations + of datetimes. +-----------------------------------------------------------------------------*/ + xmlrpc_value * retval; + + validateFormat(envP, datetimeString); + if (!envP->fault_occurred) { + xmlrpc_datetime dt; + + parseDatetimeString(datetimeString, &dt); + + /* Note that parseDatetimeString() can generate an invalid datetime + value, e.g. Hour 25 or February 30. Ideally, we would catch that + here, but because of laziness, we simply accept the possibility of + invalid xmlrpc_datetime in xmlrpc_value and whoever uses the the + xmlrpc_value has to deal with it. + */ + retval = xmlrpc_datetime_new(envP, dt); + } + + return retval; +} + + + +#pragma runtime_checks("u", restore) + + + +xmlrpc_value * +xmlrpc_datetime_new_usec(xmlrpc_env * const envP, + time_t const secs, + unsigned int const usecs) { + + xmlrpc_value * valueP; + + if (usecs >= 1000000) + xmlrpc_faultf(envP, "Number of fractional microseconds must be less " + "than one million. You specified %u", usecs); + else { + struct tm brokenTime; + xmlrpc_datetime dt; + + xmlrpc_gmtime(secs, &brokenTime); + + dt.s = brokenTime.tm_sec; + dt.m = brokenTime.tm_min; + dt.h = brokenTime.tm_hour; + dt.D = brokenTime.tm_mday; + dt.M = brokenTime.tm_mon + 1; + dt.Y = 1900 + brokenTime.tm_year; + dt.u = usecs; + + valueP = xmlrpc_datetime_new(envP, dt); + } + return valueP; +} + + + +xmlrpc_value * +xmlrpc_datetime_new_sec(xmlrpc_env * const envP, + time_t const value) { + + return xmlrpc_datetime_new_usec(envP, value, 0); +} + + + +#if XMLRPC_HAVE_TIMEVAL + +xmlrpc_value * +xmlrpc_datetime_new_timeval(xmlrpc_env * const envP, + struct timeval const value) { + + return xmlrpc_datetime_new_usec(envP, value.tv_sec, value.tv_usec); +} +#endif + + + +#if XMLRPC_HAVE_TIMESPEC + +xmlrpc_value * +xmlrpc_datetime_new_timespec(xmlrpc_env * const envP, + struct timespec const value) { + + return xmlrpc_datetime_new_usec(envP, value.tv_sec, value.tv_nsec/1000); +} +#endif + + + +xmlrpc_value * +xmlrpc_datetime_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * retval; + + if (valueP->_type != XMLRPC_TYPE_DATETIME) { + xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, + "Value is not a datetime. " + "It is type #%d", valueP->_type); + retval = NULL; + } else + retval = xmlrpc_datetime_new(envP, valueP->_value.dt); + + return retval; +} + + + +void +xmlrpc_destroyDatetime(xmlrpc_value * const datetimeP) { + + const char ** const readBufferP = datetimeP->_cache; + + if (*readBufferP) + xmlrpc_strfree(*readBufferP); + + free(datetimeP->_cache); +} diff --git a/trunk/src/xmlrpc_decompose.c b/trunk/src/xmlrpc_decompose.c new file mode 100644 index 000000000..86727121a --- /dev/null +++ b/trunk/src/xmlrpc_decompose.c @@ -0,0 +1,1153 @@ +/* By Bryan Henderson July 2006. + + Contributed to the public domain. +*/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include + +#include "bool.h" +#include "c_util.h" +#include "mallocvar.h" +#include "stdargx.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" + + +/* THE DECOMPOSITION TREE + + We execute xmlrpc_decompose_value() in two steps: + + 1) Create a "decomposition tree" that tells how Caller wants the XML-RPC + value decomposed. + + 2) Using that tree, decompose the value. I.e. store stuff in the variables + in which Caller wants it stored. + + The decomposition tree is composed of information from the format + string and the variable arguments that the format string describes. + Nothing in the tree is derived from the actual XML-RPC value being + decomposed, and the tree may in fact be invalid for the particular + XML-RPC value it's meant for. + + If the XML-RPC value is a simple value such as an integer, the + decomposition tree is trivial -- it's a single node that says + "store the value of an integer via pointer P". + + Where it gets interesting is where the XML-RPC value to be decomposed + is a complex value (array or struct). Then, the root node of the tree + says, e.g., "decompose a 5-item array according to the following + 5 decomposition trees" and it points to 5 additional nodes. Each of + those nodes is the root of another decomposition tree (which can also + be called a branch in this context). Each of those branches tells + how to decompose one of the items of the array. + + Roots, interior nodes, and leaves are all essentially the same data + type. +*/ + +struct integerDecomp { + xmlrpc_int32 * valueP; +}; + +struct boolDecomp { + xmlrpc_bool * valueP; +}; + +struct doubleDecomp { + double * valueP; +}; + +struct datetimeTDecomp { + time_t * valueP; +}; + +struct datetime8Decomp { + const char ** valueP; +}; + +struct stringDecomp { + const char ** valueP; + size_t * sizeP; + /* NULL means don't store a size */ +}; + +struct wideStringDecomp { +#if HAVE_UNICODE_WCHAR + const wchar_t ** valueP; +#endif + size_t * sizeP; + /* NULL means don't store a size */ +}; + +struct bitStringDecomp { + const unsigned char ** valueP; + size_t * sizeP; +}; + +struct cptrDecomp { + void ** valueP; +}; + +struct i8Decomp { + xmlrpc_int64 * valueP; +}; + +struct valueDecomp { + xmlrpc_value ** valueP; +}; + +struct arrayValDecomp { + xmlrpc_value ** valueP; +}; + +struct structValDecomp { + xmlrpc_value ** valueP; +}; + +struct arrayDecomp { + unsigned int itemCnt; + bool ignoreExcess; + /* If there are more than 'itemCnt' items in the array, just + extract the first 'itemCnt' and ignore the rest, rather than + fail the decomposition. + */ + struct decompTreeNode * itemArray[16]; + /* Only first 'itemCnt' elements of this array are defined */ +}; + +struct mbrDecomp { + const char * key; + /* The key for the member whose value client wants to extract */ + struct decompTreeNode * decompTreeP; + /* Instructions on how to decompose (extract) member's value */ +}; + +struct structDecomp { + unsigned int mbrCnt; + struct mbrDecomp mbrArray[16]; +}; + + +struct decompTreeNode { + char formatSpecChar; + /* e.g. 'i', 'b', '8', 'A'. '(' means array; '{' means struct */ + union { + /*------------------------------------------------------------------------ + 'formatSpecChar' selects among these members. + -------------------------------------------------------------------------*/ + struct integerDecomp Tinteger; + struct boolDecomp Tbool; + struct doubleDecomp Tdouble; + struct datetimeTDecomp TdatetimeT; + struct datetime8Decomp Tdatetime8; + struct stringDecomp Tstring; + struct wideStringDecomp TwideString; + struct bitStringDecomp TbitString; + struct cptrDecomp Tcptr; + struct i8Decomp Ti8; + struct valueDecomp Tvalue; + struct arrayValDecomp TarrayVal; + struct structValDecomp TstructVal; + struct arrayDecomp Tarray; + struct structDecomp Tstruct; + } store; + +}; + + + +/* prototype for recursive calls */ +static void +releaseDecomposition(const struct decompTreeNode * const decompRootP); + + +static void +releaseDecompArray(struct arrayDecomp const arrayDecomp) { + + unsigned int i; + for (i = 0; i < arrayDecomp.itemCnt; ++i) { + releaseDecomposition(arrayDecomp.itemArray[i]); + } +} + + + +static void +releaseDecompStruct(struct structDecomp const structDecomp) { + + unsigned int i; + for (i = 0; i < structDecomp.mbrCnt; ++i) { + releaseDecomposition(structDecomp.mbrArray[i].decompTreeP); + } +} + + + +static void +releaseDecomposition(const struct decompTreeNode * const decompRootP) { +/*---------------------------------------------------------------------------- + Assuming that Caller has decomposed something according to 'decompRootP', + release whatever resources the decomposed information occupies. + + E.g. if it's an XML-RPC string, Caller would have allocated memory + for the C string that represents the decomposed value of XML-RPC string, + and we release that memory. +-----------------------------------------------------------------------------*/ + switch (decompRootP->formatSpecChar) { + case 'i': + case 'b': + case 'd': + case 'n': + case 'I': + case 't': + case 'p': + /* Nothing was allocated; nothing to release */ + break; + case '8': + xmlrpc_strfree(*decompRootP->store.Tdatetime8.valueP); + break; + case 's': + xmlrpc_strfree(*decompRootP->store.Tstring.valueP); + break; + case 'w': +#if HAVE_UNICODE_WCHAR + free((void*)*decompRootP->store.TwideString.valueP); +#else + XMLRPC_ASSERT(false); +#endif + break; + case '6': + free((void*)*decompRootP->store.TbitString.valueP); + break; + case 'V': + xmlrpc_DECREF(*decompRootP->store.Tvalue.valueP); + break; + case 'A': + xmlrpc_DECREF(*decompRootP->store.TarrayVal.valueP); + break; + case 'S': + xmlrpc_DECREF(*decompRootP->store.TstructVal.valueP); + break; + case '(': + releaseDecompArray(decompRootP->store.Tarray); + break; + case '{': + releaseDecompStruct(decompRootP->store.Tstruct); + break; + } +} + + + +/* Prototype for recursive invocation: */ + +static void +decomposeValueWithTree(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + bool const oldstyleMemMgmt, + const struct decompTreeNode * const decompRootP); + + + +static void +validateArraySize(xmlrpc_env * const envP, + const xmlrpc_value * const arrayP, + struct arrayDecomp const arrayDecomp) { + + unsigned int size; + + size = xmlrpc_array_size(envP, arrayP); + if (!envP->fault_occurred) { + if (arrayDecomp.itemCnt > size) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, + "Format string requests %u items from array, but array " + "has only %u items.", arrayDecomp.itemCnt, size); + else if (arrayDecomp.itemCnt < size && !arrayDecomp.ignoreExcess) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, + "Format string requests exactly %u items from array, " + "but array has %u items. (A '*' at the end would avoid " + "this failure)", arrayDecomp.itemCnt, size); + } +} + + + +static void +parsearray(xmlrpc_env * const envP, + const xmlrpc_value * const arrayP, + struct arrayDecomp const arrayDecomp, + bool const oldstyleMemMgmt) { + + validateArraySize(envP, arrayP, arrayDecomp); + + if (!envP->fault_occurred) { + unsigned int doneCnt; + + doneCnt = 0; + while(doneCnt < arrayDecomp.itemCnt && !envP->fault_occurred) { + xmlrpc_value * itemP; + + xmlrpc_array_read_item(envP, arrayP, doneCnt, &itemP); + + if (!envP->fault_occurred) { + XMLRPC_ASSERT(doneCnt < ARRAY_SIZE(arrayDecomp.itemArray)); + decomposeValueWithTree(envP, itemP, oldstyleMemMgmt, + arrayDecomp.itemArray[doneCnt]); + + if (!envP->fault_occurred) + ++doneCnt; + + xmlrpc_DECREF(itemP); + } + } + if (envP->fault_occurred) { + if (!oldstyleMemMgmt) { + /* Release the items we completed before we failed. */ + unsigned int i; + for (i = 0; i < doneCnt; ++i) + releaseDecomposition(arrayDecomp.itemArray[i]); + } + } + } +} + + + +static void +parsestruct(xmlrpc_env * const envP, + xmlrpc_value * const structP, + struct structDecomp const structDecomp, + bool const oldstyleMemMgmt) { + + unsigned int doneCount; + + doneCount = 0; /* No members done yet */ + + while (doneCount < structDecomp.mbrCnt && !envP->fault_occurred) { + const char * const key = structDecomp.mbrArray[doneCount].key; + + xmlrpc_value * valueP; + + xmlrpc_struct_read_value(envP, structP, key, &valueP); + + if (!envP->fault_occurred) { + decomposeValueWithTree( + envP, valueP, oldstyleMemMgmt, + structDecomp.mbrArray[doneCount].decompTreeP); + + if (!envP->fault_occurred) + ++doneCount; + + xmlrpc_DECREF(valueP); + } + } + + if (envP->fault_occurred) { + if (!oldstyleMemMgmt) { + /* Release the items we completed before we failed. */ + unsigned int i; + for (i = 0; i < doneCount; ++i) + releaseDecomposition(structDecomp.mbrArray[i].decompTreeP); + } + } +} + + + +static void +readString(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + const char ** const stringValueP, + bool const oldstyleMemMgmt) { + + if (oldstyleMemMgmt) { + xmlrpc_read_string_old(envP, valueP, stringValueP); + } else + xmlrpc_read_string(envP, valueP, stringValueP); +} + + + +static void +readStringLp(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + size_t * const lengthP, + const char ** const stringValueP, + bool const oldstyleMemMgmt) { + + if (oldstyleMemMgmt) { + xmlrpc_read_string_lp_old(envP, valueP, lengthP, stringValueP); + } else + xmlrpc_read_string_lp(envP, valueP, lengthP, stringValueP); +} + + + +#if HAVE_UNICODE_WCHAR +static void +readStringW(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + const wchar_t ** const stringValueP, + bool const oldstyleMemMgmt) { + + if (oldstyleMemMgmt) { + xmlrpc_read_string_w_old(envP, valueP, stringValueP); + } else + xmlrpc_read_string_w(envP, valueP, stringValueP); +} + + + +static void +readStringWLp(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + size_t * const lengthP, + const wchar_t ** const stringValueP, + bool const oldstyleMemMgmt) { + + if (oldstyleMemMgmt) { + xmlrpc_read_string_w_lp_old(envP, valueP, lengthP, stringValueP); + } else + xmlrpc_read_string_w_lp(envP, valueP, lengthP, stringValueP); +} +#endif + + +static void +readDatetime8Str(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + const char ** const stringValueP, + bool const oldstyleMemMgmt) { + + if (oldstyleMemMgmt) + xmlrpc_read_datetime_str_old(envP, valueP, stringValueP); + else + xmlrpc_read_datetime_str(envP, valueP, stringValueP); +} + + + +static void +readBase64(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + size_t * const lengthP, + const unsigned char ** const byteStringValueP, + bool const oldstyleMemMgmt) { + + if (oldstyleMemMgmt) + xmlrpc_read_base64_old(envP, valueP, lengthP, byteStringValueP); + else + xmlrpc_read_base64(envP, valueP, lengthP, byteStringValueP); +} + + +static void +decomposeValueWithTree(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + bool const oldstyleMemMgmt, + const struct decompTreeNode * const decompRootP) { +/*---------------------------------------------------------------------------- + Decompose XML-RPC value *valueP, given the decomposition tree + *decompRootP. The decomposition tree tells what structure *valueP + is expected to have and where to put the various components of it + (e.g. it says "it's an array of 3 integers. Put their values at + locations x, y, and z") +-----------------------------------------------------------------------------*/ + switch (decompRootP->formatSpecChar) { + case '-': + /* There's nothing to validate or return */ + break; + case 'i': + xmlrpc_read_int(envP, valueP, decompRootP->store.Tinteger.valueP); + break; + + case 'b': + xmlrpc_read_bool(envP, valueP, decompRootP->store.Tbool.valueP); + break; + + case 'd': + xmlrpc_read_double(envP, valueP, decompRootP->store.Tdouble.valueP); + break; + + case 't': + xmlrpc_read_datetime_sec(envP, valueP, + decompRootP->store.TdatetimeT.valueP); + break; + + case '8': + readDatetime8Str(envP, valueP, decompRootP->store.Tdatetime8.valueP, + oldstyleMemMgmt); + break; + + case 's': + if (decompRootP->store.Tstring.sizeP) + readStringLp(envP, valueP, + decompRootP->store.Tstring.sizeP, + decompRootP->store.Tstring.valueP, + oldstyleMemMgmt); + else + readString(envP, valueP, decompRootP->store.Tstring.valueP, + oldstyleMemMgmt); + break; + + case 'w': +#if HAVE_UNICODE_WCHAR + if (decompRootP->store.Tstring.sizeP) + readStringWLp(envP, valueP, + decompRootP->store.TwideString.sizeP, + decompRootP->store.TwideString.valueP, + oldstyleMemMgmt); + else + readStringW(envP, valueP, decompRootP->store.TwideString.valueP, + oldstyleMemMgmt); +#else + XMLRPC_ASSERT(false); +#endif /* HAVE_UNICODE_WCHAR */ + break; + + case '6': + readBase64(envP, valueP, + decompRootP->store.TbitString.sizeP, + decompRootP->store.TbitString.valueP, + oldstyleMemMgmt); + break; + + case 'n': + xmlrpc_read_nil(envP, valueP); + break; + + case 'I': + xmlrpc_read_i8(envP, valueP, decompRootP->store.Ti8.valueP); + break; + + case 'p': + xmlrpc_read_cptr(envP, valueP, decompRootP->store.Tcptr.valueP); + break; + + case 'V': + *decompRootP->store.Tvalue.valueP = valueP; + if (!oldstyleMemMgmt) + xmlrpc_INCREF(valueP); + break; + + case 'A': + if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type " + "%s, but the 'A' specifier requires type ARRAY", + xmlrpc_type_name(xmlrpc_value_type(valueP))); + else { + *decompRootP->store.TarrayVal.valueP = valueP; + if (!oldstyleMemMgmt) + xmlrpc_INCREF(valueP); + } + break; + + case 'S': + if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type " + "%s, but the 'S' specifier requires type STRUCT.", + xmlrpc_type_name(xmlrpc_value_type(valueP))); + else { + *decompRootP->store.TstructVal.valueP = valueP; + if (!oldstyleMemMgmt) + xmlrpc_INCREF(valueP); + } + break; + + case '(': + if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type " + "%s, but the '(...)' specifier requires type ARRAY", + xmlrpc_type_name(xmlrpc_value_type(valueP))); + else + parsearray(envP, valueP, decompRootP->store.Tarray, + oldstyleMemMgmt); + break; + + case '{': + if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type " + "%s, but the '{...}' specifier requires type STRUCT", + xmlrpc_type_name(xmlrpc_value_type(valueP))); + else + parsestruct(envP, valueP, decompRootP->store.Tstruct, + oldstyleMemMgmt); + break; + + default: + /* Every format character that is allowed in a decomposition tree + node is handled above. + */ + XMLRPC_ASSERT(false); + } +} + + +/* Forward declaration for recursive calls */ + +static void +createDecompTreeNext(xmlrpc_env * const envP, + const char ** const formatP, + va_listx * const argsP, + struct decompTreeNode ** const decompNodePP); + + + +static void +buildWideStringNode(xmlrpc_env * const envP ATTR_UNUSED, + const char ** const formatP, + va_listx * const argsP, + struct decompTreeNode * const decompNodeP) { + +#if HAVE_UNICODE_WCHAR + decompNodeP->store.TwideString.valueP = + (const wchar_t**) va_arg(argsP->v, wchar_t**); + if (**formatP == '#') { + decompNodeP->store.TwideString.sizeP = + (size_t*) va_arg(argsP->v, size_t**); + (*formatP)++; + } else + decompNodeP->store.TwideString.sizeP = NULL; +#else + xmlrpc_faultf(envP, + "This XML-RPC For C/C++ library was built without Unicode " + "wide character capability. 'w' isn't available."); +#endif /* HAVE_UNICODE_WCHAR */ +} + + + +static void +destroyDecompTree(struct decompTreeNode * const decompRootP) { + + switch (decompRootP->formatSpecChar) { + case '(': { + unsigned int i; + for (i = 0; i < decompRootP->store.Tarray.itemCnt; ++i) + destroyDecompTree(decompRootP->store.Tarray.itemArray[i]); + } break; + case '{': { + unsigned int i; + for (i = 0; i < decompRootP->store.Tstruct.mbrCnt; ++i) + destroyDecompTree( + decompRootP->store.Tstruct.mbrArray[i].decompTreeP); + } break; + } + + free(decompRootP); +} + + + +static void +processArraySpecTail(xmlrpc_env * const envP, + const char ** const formatP, + bool * const hasTrailingAsteriskP, + char const delim) { + + if (**formatP == '*') { + *hasTrailingAsteriskP = true; + + ++*formatP; + + if (!**formatP) + xmlrpc_faultf(envP, "missing closing delimiter ('%c')", delim); + else if (**formatP != delim) + xmlrpc_faultf(envP, "character following '*' in array " + "specification should be the closing delimiter " + "'%c', but is '%c'", delim, **formatP); + } else { + *hasTrailingAsteriskP = false; + + if (!**formatP) + xmlrpc_faultf(envP, "missing closing delimiter ('%c')", delim); + } + if (!envP->fault_occurred) + XMLRPC_ASSERT(**formatP == delim); +} + + + +static void +buildArrayDecompBranch(xmlrpc_env * const envP, + const char ** const formatP, + char const delim, + va_listx * const argsP, + struct decompTreeNode * const decompNodeP) { +/*---------------------------------------------------------------------------- + Fill in the decomposition tree node *decompNodeP to cover an array + whose items are described by *formatP. To wit, they are the values + described by successive format specifiers in *formatP up to but not + including the next 'delim' character. + + Plus, the last character before the delimiter might be a '*', which + means "ignore any additional items in the array." + + We create a node (and whole branch if required) to describe each array + item. + + The pointers to where those items are to be stored are given by + 'argsP'. + + We advance *formatP to the delimiter character, and advance 'argsP' + past whatever arguments we use. +-----------------------------------------------------------------------------*/ + unsigned int itemCnt; + /* Number of array items in the branch so far */ + + itemCnt = 0; /* Branch is empty so far */ + + while (**formatP && **formatP != delim && **formatP != '*' && + !envP->fault_occurred) { + if (itemCnt >= ARRAY_SIZE(decompNodeP->store.Tarray.itemArray)) + xmlrpc_faultf(envP, "Too many array items in format string. " + "The most items you can have for an array in " + "a format string is %u.", (unsigned) + ARRAY_SIZE(decompNodeP->store.Tarray.itemArray)); + else { + struct decompTreeNode * itemNodeP; + + createDecompTreeNext(envP, formatP, argsP, &itemNodeP); + + if (!envP->fault_occurred) + decompNodeP->store.Tarray.itemArray[itemCnt++] = itemNodeP; + } + } + if (!envP->fault_occurred) { + decompNodeP->store.Tarray.itemCnt = itemCnt; + processArraySpecTail(envP, formatP, + &decompNodeP->store.Tarray.ignoreExcess, + delim); + } + if (envP->fault_occurred) { + unsigned int i; + for (i = 0; i < itemCnt; ++i) + destroyDecompTree(decompNodeP->store.Tarray.itemArray[i]); + } +} + + + +static void +doStructValue(xmlrpc_env * const envP, + const char ** const formatP, + va_listx * const argsP, + struct mbrDecomp * const mbrP) { + + struct decompTreeNode * valueNodeP; + + mbrP->key = (const char*) va_arg(argsP->v, char*); + + createDecompTreeNext(envP, formatP, argsP, &valueNodeP); + + if (!envP->fault_occurred) + mbrP->decompTreeP = valueNodeP; +} + + + +static void +skipAsterisk(xmlrpc_env * const envP, + const char ** const formatP, + char const delim) { + + if (**formatP == '*') { + ++*formatP; + + if (!**formatP) + xmlrpc_faultf(envP, "missing closing delimiter ('%c')", delim); + else if (**formatP != delim) + xmlrpc_faultf(envP, "junk after '*' in the specifier of an " + "array. First character='%c'", **formatP); + } else + /* Conceptually, one can make it an error to leave some struct + members behind, but we have never had code that knows how to + recognize that case. + */ + xmlrpc_faultf(envP, + "You must put a trailing '*' in the specifiers for " + "struct members to signify it's OK if there are " + "additional members you didn't get."); +} + + + +static void +skipColon(xmlrpc_env * const envP, + const char ** const formatP, + char const delim) { + + if (**formatP == '\0') + xmlrpc_faultf(envP, "format string ends in the middle of a struct " + "member specifier"); + else if (**formatP == delim) + xmlrpc_faultf(envP, "member list ends in the middle of a member"); + else if (**formatP != ':') + xmlrpc_faultf(envP, "In a struct specifier, '%c' found " + "where a colon (':') separating key and " + "value was expected.", **formatP); +} + + + +static void +skipComma(xmlrpc_env * const envP, + const char ** const formatP, + char const delim) { + + if (**formatP && **formatP != delim) { + if (**formatP == ',') + ++*formatP; /* skip over comma */ + else + xmlrpc_faultf(envP, "'%c' where we expected a ',' " + "to separate struct members", **formatP); + } +} + + + +static void +buildStructDecompBranch(xmlrpc_env * const envP, + const char ** const formatP, + char const delim, + va_listx * const argsP, + struct decompTreeNode * const decompNodeP) { +/*---------------------------------------------------------------------------- + Fill in the decomposition tree node *decompNodeP to cover a struct + whose members are described by *formatP. To wit, they are the values + described by successive format specifiers in *formatP up to but not + including the next 'delim' character. + + We create a node (and whole branch if required) to describe each + struct member value. + + The pointers to where those values are to be stored are given by + 'argsP'. + + The names of the members to be extracted are also given by 'argsP'. + + We advance *formatP to the delimiter character, and advance 'argsP' + past whatever arguments we use. +-----------------------------------------------------------------------------*/ + unsigned int memberCnt; + /* Number of struct members in the branch so far */ + + memberCnt = 0; /* Branch is empty so far */ + + while (**formatP && **formatP != delim && **formatP != '*' && + !envP->fault_occurred) { + if (memberCnt >= ARRAY_SIZE(decompNodeP->store.Tstruct.mbrArray)) + xmlrpc_faultf(envP, + "Too many structure members in format string. " + "The most members you can specify in " + "a format string is %u.", (unsigned) + ARRAY_SIZE(decompNodeP->store.Tstruct.mbrArray)); + else { + struct mbrDecomp * const mbrP = + &decompNodeP->store.Tstruct.mbrArray[memberCnt]; + + if (**formatP != 's') + xmlrpc_faultf(envP, "In a struct specifier, the specifier " + "for the key is '%c', but it must be 's'.", + **formatP); + else { + ++*formatP; + + skipColon(envP, formatP, delim); + + if (!envP->fault_occurred) { + ++*formatP; + + doStructValue(envP, formatP, argsP, mbrP); + + if (!envP->fault_occurred) + ++memberCnt; + + skipComma(envP, formatP, delim); + } + } + } + } + decompNodeP->store.Tstruct.mbrCnt = memberCnt; + + if (!envP->fault_occurred) { + skipAsterisk(envP, formatP, delim); + if (!envP->fault_occurred) + XMLRPC_ASSERT(**formatP == delim); + } + + if (envP->fault_occurred) { + unsigned int i; + for (i = 0; i < memberCnt; ++i) + destroyDecompTree( + decompNodeP->store.Tstruct.mbrArray[i].decompTreeP); + } +} + + + +static void +createDecompTreeNext(xmlrpc_env * const envP, + const char ** const formatP, + va_listx * const argsP, + struct decompTreeNode ** const decompNodePP) { +/*---------------------------------------------------------------------------- + Create a branch of a decomposition tree that applies to the first + value described by '*formatP', and advance *formatP past the description + of that first value. E.g.: + + - If *formatP is "isb", we create a branch consisting of one + node -- for an integer. We advance *formatP by one character, so + it points to the "s". + + - If *formatP is "(isb)s", we create a branch that represents the + array (isb) and advance *formatP past the closing parenthesis to + point to the final "s". We return as *decompNodePP a pointer to + a node for the array, and that array in turn points to nodes for + each of the 3 array items: one for an integer, one for a string, + and one for a boolean. + + The locations at which the components of that value are to be + stored (which is the main contents of the branch we create) are + given by 'argsP'. + + Return as *decompNodeP a pointer to the root node of the branch we + generate. +-----------------------------------------------------------------------------*/ + struct decompTreeNode * decompNodeP; + + MALLOCVAR(decompNodeP); + + if (decompNodeP == NULL) + xmlrpc_faultf(envP, "Could not allocate space for a decomposition " + "tree node"); + else { + decompNodeP->formatSpecChar = *(*formatP)++; + + switch (decompNodeP->formatSpecChar) { + case '-': + /* There's nothing to store */ + break; + case 'i': + decompNodeP->store.Tinteger.valueP = + (xmlrpc_int32*) va_arg(argsP->v, xmlrpc_int32*); + break; + + case 'b': + decompNodeP->store.Tbool.valueP = + (xmlrpc_bool*) va_arg(argsP->v, xmlrpc_bool*); + break; + + case 'd': + decompNodeP->store.Tdouble.valueP = + (double*) va_arg(argsP->v, double*); + break; + + case 't': + decompNodeP->store.TdatetimeT.valueP = + va_arg(argsP->v, time_t*); + break; + + case '8': + decompNodeP->store.Tdatetime8.valueP = + (const char**) va_arg(argsP->v, char**); + break; + + case 's': + decompNodeP->store.Tstring.valueP = + (const char**) va_arg(argsP->v, char**); + if (**formatP == '#') { + decompNodeP->store.Tstring.sizeP = + (size_t*) va_arg(argsP->v, size_t**); + ++*formatP; + } else + decompNodeP->store.Tstring.sizeP = NULL; + break; + + case 'w': + buildWideStringNode(envP, formatP, argsP, decompNodeP); + break; + + case '6': + decompNodeP->store.TbitString.valueP = + (const unsigned char**) va_arg(argsP->v, unsigned char**); + decompNodeP->store.TbitString.sizeP = + (size_t*) va_arg(argsP->v, size_t**); + break; + + case 'n': + /* There's no value to store */ + break; + + case 'I': + decompNodeP->store.Ti8.valueP = + (xmlrpc_int64 *) va_arg(argsP->v, xmlrpc_int64 *); + break; + + case 'p': + decompNodeP->store.Tcptr.valueP = + (void**) va_arg(argsP->v, void**); + break; + + case 'V': + decompNodeP->store.Tvalue.valueP = + (xmlrpc_value**) va_arg(argsP->v, xmlrpc_value**); + break; + + case 'A': + decompNodeP->store.TarrayVal.valueP = + (xmlrpc_value**) va_arg(argsP->v, xmlrpc_value**); + break; + + case 'S': + decompNodeP->store.TstructVal.valueP = + (xmlrpc_value**) va_arg(argsP->v, xmlrpc_value**); + break; + + case '(': + buildArrayDecompBranch(envP, formatP, ')', argsP, decompNodeP); + ++(*formatP); /* skip past closing ')' */ + break; + + case '{': + buildStructDecompBranch(envP, formatP, '}', argsP, decompNodeP); + ++(*formatP); /* skip past closing '}' */ + break; + + default: + xmlrpc_faultf(envP, "Invalid format character '%c'", + decompNodeP->formatSpecChar); + } + if (envP->fault_occurred) + free(decompNodeP); + else + *decompNodePP = decompNodeP; + } +} + + + +static void +createDecompTree(xmlrpc_env * const envP, + const char * const format, + va_listx const args, + struct decompTreeNode ** const decompRootPP) { + + const char * formatCursor; + struct decompTreeNode * decompRootP; + va_listx currentArgs; + + currentArgs = args; + formatCursor = &format[0]; + createDecompTreeNext(envP, &formatCursor, ¤tArgs, &decompRootP); + if (!envP->fault_occurred) { + if (*formatCursor != '\0') + xmlrpc_faultf(envP, "format string '%s' has garbage at the end: " + "'%s'. It should be a specifier of a single value " + "(but that might be a complex value, such as an " + "array)", format, formatCursor); + + if (envP->fault_occurred) + destroyDecompTree(decompRootP); + } + *decompRootPP = decompRootP; +} + + + +static void +decomposeValue(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + bool const oldstyleMemMgmt, + const char * const format, + va_listx const args) { + + struct decompTreeNode * decompRootP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(valueP); + XMLRPC_ASSERT(format != NULL); + + createDecompTree(envP, format, args, &decompRootP); + + if (!envP->fault_occurred) { + decomposeValueWithTree(envP, valueP, oldstyleMemMgmt, decompRootP); + + destroyDecompTree(decompRootP); + } +} + + + +void +xmlrpc_decompose_value_va(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + const char * const format, + va_list const args) { + + bool const oldstyleMemMgtFalse = false; + va_listx argsx; + + init_va_listx(&argsx, args); + + decomposeValue(envP, valueP, oldstyleMemMgtFalse, format, argsx); +} + + + +void +xmlrpc_decompose_value(xmlrpc_env * const envP, + xmlrpc_value * const value, + const char * const format, + ...) { + + va_list args; + + va_start(args, format); + xmlrpc_decompose_value_va(envP, value, format, args); + va_end(args); +} + + + +void +xmlrpc_parse_value_va(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + const char * const format, + va_list const args) { + + bool const oldstyleMemMgmtTrue = true; + va_listx argsx; + + init_va_listx(&argsx, args); + + decomposeValue(envP, valueP, oldstyleMemMgmtTrue, format, argsx); +} + + + +void +xmlrpc_parse_value(xmlrpc_env * const envP, + xmlrpc_value * const value, + const char * const format, + ...) { + + va_list args; + + va_start(args, format); + xmlrpc_parse_value_va(envP, value, format, args); + va_end(args); +} diff --git a/trunk/src/xmlrpc_expat.c b/trunk/src/xmlrpc_expat.c new file mode 100644 index 000000000..30fae15c7 --- /dev/null +++ b/trunk/src/xmlrpc_expat.c @@ -0,0 +1,546 @@ +/* Copyright information is at end of file */ + +#include "xmlrpc_config.h" + +#include +#include +#include + +#include /* Expat */ + +#include "bool.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" + +#include "xmlparser.h" + +struct _xml_element { +/*---------------------------------------------------------------------------- + Information about an XML element +-----------------------------------------------------------------------------*/ + struct _xml_element * parentP; + const char * name; + xmlrpc_mem_block * cdataP; /* char */ + xmlrpc_mem_block * childrenP; /* xml_element* */ +}; + +/* Check that we're using expat in UTF-8 mode, not wchar_t mode. +** If you need to use expat in wchar_t mode, write a subroutine to +** copy a wchar_t string to a char string & return an error for +** any non-ASCII characters. Then call this subroutine on all +** XML_Char strings passed to our event handlers before using the +** data. */ +/* #if sizeof(char) != sizeof(XML_Char) +** #error expat must define XML_Char to be a regular char. +** #endif +*/ + +#define XMLRPC_ASSERT_ELEM_OK(elem) \ + XMLRPC_ASSERT((elem) != NULL && (elem)->name != XMLRPC_BAD_POINTER) + + +void +xml_init(xmlrpc_env * const envP) { + + XMLRPC_ASSERT_ENV_OK(envP); +} + + + +void +xml_term(void) { + +} + + + +static xml_element * +xmlElementNew(xmlrpc_env * const envP, + const char * const name) { +/*---------------------------------------------------------------------------- + A new skeleton element object - ready to be filled in to represent an + actual element. +-----------------------------------------------------------------------------*/ + xml_element * retval; + int name_valid, cdata_valid, children_valid; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(name != NULL); + + /* Set up our error-handling preconditions. */ + retval = NULL; + name_valid = cdata_valid = children_valid = 0; + + /* Allocate our xml_element structure. */ + retval = (xml_element*) malloc(sizeof(xml_element)); + XMLRPC_FAIL_IF_NULL(retval, envP, XMLRPC_INTERNAL_ERROR, + "Couldn't allocate memory for XML element"); + + /* Set our parent field to NULL. */ + retval->parentP = NULL; + + /* Copy over the element name. */ + retval->name = xmlrpc_strdupnull(name); + XMLRPC_FAIL_IF_NULL(retval->name, envP, XMLRPC_INTERNAL_ERROR, + "Couldn't allocate memory for XML element"); + name_valid = 1; + + retval->cdataP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + XMLRPC_FAIL_IF_FAULT(envP); + cdata_valid = 1; + + retval->childrenP = XMLRPC_MEMBLOCK_NEW(xml_element *, envP, 0); + XMLRPC_FAIL_IF_FAULT(envP); + children_valid = 1; + + cleanup: + if (envP->fault_occurred) { + if (retval) { + if (name_valid) + xmlrpc_strfree(retval->name); + if (cdata_valid) + XMLRPC_MEMBLOCK_FREE(char, retval->cdataP); + if (children_valid) + XMLRPC_MEMBLOCK_FREE(xml_element *, retval->childrenP); + free(retval); + } + return NULL; + } else { + return retval; + } +} + + +/*========================================================================= +** xml_element_free +**========================================================================= +** Blow away an existing element & all of its child elements. +*/ +void +xml_element_free(xml_element * const elemP) { + + xmlrpc_mem_block * childrenP; + size_t size, i; + xml_element ** contents; + + XMLRPC_ASSERT_ELEM_OK(elemP); + + xmlrpc_strfree(elemP->name); + elemP->name = XMLRPC_BAD_POINTER; + + XMLRPC_MEMBLOCK_FREE(char, elemP->cdataP); + + /* Deallocate all of our children recursively. */ + childrenP = elemP->childrenP; + contents = XMLRPC_MEMBLOCK_CONTENTS(xml_element *, childrenP); + size = XMLRPC_MEMBLOCK_SIZE(xml_element *, childrenP); + for (i = 0; i < size; ++i) + xml_element_free(contents[i]); + + XMLRPC_MEMBLOCK_FREE(xml_element *, elemP->childrenP); + + free(elemP); +} + + +/*========================================================================= +** Miscellaneous Accessors +**========================================================================= +** Return the fields of the xml_element. See the header for more +** documentation on each function works. +*/ + + + +const char * +xml_element_name(const xml_element * const elemP) { + + XMLRPC_ASSERT_ELEM_OK(elemP); + + return elemP->name; +} + + + +size_t +xml_element_cdata_size (const xml_element * const elemP) { +/*---------------------------------------------------------------------------- + The result of this function is NOT VALID until the end_element handler + has been called! +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ELEM_OK(elemP); + + return XMLRPC_MEMBLOCK_SIZE(char, elemP->cdataP) - 1; +} + + + +const char * +xml_element_cdata(const xml_element * const elemP) { + + XMLRPC_ASSERT_ELEM_OK(elemP); + + return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(const char, elemP->cdataP); +} + + + +unsigned int +xml_element_children_size(const xml_element * const elemP) { + + XMLRPC_ASSERT_ELEM_OK(elemP); + + return XMLRPC_MEMBLOCK_SIZE(xml_element *, elemP->childrenP); +} + + + +xml_element ** +xml_element_children(const xml_element * const elemP) { + XMLRPC_ASSERT_ELEM_OK(elemP); + return XMLRPC_MEMBLOCK_CONTENTS(xml_element *, elemP->childrenP); +} + + + +/*============================================================================= + Internal xml_element Utility Functions +=============================================================================*/ + +static void +xml_element_append_cdata(xmlrpc_env * const envP, + xml_element * const elemP, + const char * const cdata, + size_t const size) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_ELEM_OK(elemP); + + XMLRPC_MEMBLOCK_APPEND(char, envP, elemP->cdataP, cdata, size); +} + + + +static void +xml_element_append_child(xmlrpc_env * const envP, + xml_element * const elemP, + xml_element * const childP) { +/*---------------------------------------------------------------------------- + Whether or not this function succeeds, it takes ownership of *childP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_ELEM_OK(elemP); + XMLRPC_ASSERT_ELEM_OK(childP); + XMLRPC_ASSERT(childP->parentP == NULL); + + XMLRPC_MEMBLOCK_APPEND(xml_element *, envP, elemP->childrenP, &childP, 1); + if (!envP->fault_occurred) + childP->parentP = elemP; + else + xml_element_free(childP); +} + + + +typedef struct { +/*---------------------------------------------------------------------------- + Our parse context. We pass this around as expat user data. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xml_element * rootP; + xml_element * currentP; + xmlrpc_mem_pool * memPoolP; + /* The memory pool we use for as much memory allocation as we can; + It's purpose is that it is of limited size, so especially use it + for things that need to be limited, like to prevent an XML-RPC + client from using up all the memory by sending a cleverly crafted + XML document. + */ +} ParseContext; + + + +static void +initParseContext(ParseContext * const contextP, + xmlrpc_mem_pool * const memPoolP) { + + xmlrpc_env_init(&contextP->env); + + contextP->rootP = NULL; + contextP->currentP = NULL; + contextP->memPoolP = memPoolP; +} + + + +static void +termParseContext(ParseContext * const contextP) { + + xmlrpc_env_clean(&contextP->env); +} + + +/*============================================================================= + Expat Event Handler Functions +=============================================================================*/ + +static void +startElement(void * const userData, + XML_Char * const name, + XML_Char ** const atts ATTR_UNUSED) { + + ParseContext * const contextP = userData; + + XMLRPC_ASSERT(contextP != NULL); + XMLRPC_ASSERT(name != NULL); + + if (!contextP->env.fault_occurred) { + xml_element * elemP; + + elemP = xmlElementNew(&contextP->env, name); + if (!contextP->env.fault_occurred) { + XMLRPC_ASSERT(elemP != NULL); + + /* Insert the new element in the appropriate place. */ + if (!contextP->rootP) { + /* No root yet, so this element must be the root. */ + contextP->rootP = elemP; + contextP->currentP = elemP; + } else { + XMLRPC_ASSERT(contextP->currentP != NULL); + + /* (We need to watch our error handling invariants + very carefully here. Read the docs for + xml_element_append_child. + */ + xml_element_append_child(&contextP->env, contextP->currentP, + elemP); + if (!contextP->env.fault_occurred) + contextP->currentP = elemP; + } + if (contextP->env.fault_occurred) + xml_element_free(elemP); + } + if (contextP->env.fault_occurred) { + /* Having changed *contextP to reflect failure, we are responsible + for undoing everything that has been done so far in this + context. + */ + if (contextP->rootP) + xml_element_free(contextP->rootP); + } + } +} + + + +static void +endElement(void * const userData, + XML_Char * const name ATTR_UNUSED) { + + ParseContext * const contextP = userData; + + XMLRPC_ASSERT(contextP != NULL); + XMLRPC_ASSERT(name != NULL); + + if (!contextP->env.fault_occurred) { + /* I think Expat enforces these facts: */ + XMLRPC_ASSERT(xmlrpc_streq(name, contextP->currentP->name)); + XMLRPC_ASSERT(contextP->currentP->parentP != NULL || + contextP->currentP == contextP->rootP); + + /* Add a trailing NUL to our cdata. */ + xml_element_append_cdata(&contextP->env, contextP->currentP, "\0", 1); + if (!contextP->env.fault_occurred) + /* Pop our "stack" of elements. */ + contextP->currentP = contextP->currentP->parentP; + + if (contextP->env.fault_occurred) { + /* Having changed *contextP to reflect failure, we are responsible + for undoing everything that has been done so far in this + context. + */ + if (contextP->rootP) + xml_element_free(contextP->rootP); + } + } +} + + + +static void +characterData(void * const userData, + XML_Char * const s, + int const len) { +/*---------------------------------------------------------------------------- + This is an Expat character data (cdata) handler. When an Expat + parser comes across cdata, he calls one of these with the cdata as + argument. He can call it multiple times for consecutive cdata. + + We simply append the cdata to the cdata buffer for whatever XML + element the parser is presently parsing. +-----------------------------------------------------------------------------*/ + ParseContext * const contextP = userData; + + XMLRPC_ASSERT(contextP != NULL); + XMLRPC_ASSERT(s != NULL); + XMLRPC_ASSERT(len >= 0); + + if (!contextP->env.fault_occurred) { + XMLRPC_ASSERT(contextP->currentP != NULL); + + xml_element_append_cdata(&contextP->env, contextP->currentP, s, len); + } +} + + + +static void +createParser(xmlrpc_env * const envP, + xmlrpc_mem_pool * const memPoolP, + ParseContext * const contextP, + XML_Parser * const parserP) { +/*---------------------------------------------------------------------------- + Create an Expat parser to parse our XML. + + Return the parser handle as *parserP. + + Set up *contextP as a context specific to this module for Expat to + associate with the parser. The XML element handlers in this module get a + pointer to *contextP to use for context. + + Use memory pool *memPoolP for certain memory allocations needed to parse + the document. Especially allocations for which we cannot predict a bound + until we see the XML. +-----------------------------------------------------------------------------*/ + XML_Parser parser; + + parser = xmlrpc_XML_ParserCreate(NULL); + if (parser == NULL) + xmlrpc_faultf(envP, "Could not create expat parser"); + else { + initParseContext(contextP, memPoolP); + + xmlrpc_XML_SetUserData(parser, contextP); + xmlrpc_XML_SetElementHandler( + parser, + (XML_StartElementHandler) startElement, + (XML_EndElementHandler) endElement); + xmlrpc_XML_SetCharacterDataHandler( + parser, + (XML_CharacterDataHandler) characterData); + } + *parserP = parser; +} + + + +static void +destroyParser(XML_Parser const parser, + ParseContext * const contextP) { + + termParseContext(contextP); + + xmlrpc_XML_ParserFree(parser); +} + + + +void +xml_parse(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xml_element ** const resultPP) { +/*---------------------------------------------------------------------------- + This is an implementation of the interface declared in xmlparser.h. This + implementation uses Xmlrpc-c's private fork of Expat. +-----------------------------------------------------------------------------*/ + /* + This is an Expat driver. + + We set up event-based parser handlers for Expat and set Expat loose + on the XML. Expat walks through the XML, calling our handlers along + the way. Our handlers build up the element description in our + 'context' variable, so that when Expat is finished, our results are + in 'context' and we just have to pluck them out. + + We should allow the user to specify the encoding in 'xmlData', but + we don't. + */ + XML_Parser parser; + ParseContext context; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(xmlData != NULL); + + createParser(envP, memPoolP, &context, &parser); + + if (!envP->fault_occurred) { + bool ok; + + ok = xmlrpc_XML_Parse(parser, xmlData, xmlDataLen, 1); + /* sets 'context', *envP */ + if (!ok) { + /* Expat failed on its own to parse it -- this is not an error + that our handlers detected. + */ + xmlrpc_env_set_fault( + envP, XMLRPC_PARSE_ERROR, + xmlrpc_XML_GetErrorString(parser)); + if (!context.env.fault_occurred) { + /* Have to clean up what our handlers built before Expat + barfed. + */ + if (context.rootP) + xml_element_free(context.rootP); + } + } else { + /* Expat got through the XML OK, but when it called our handlers, + they might have detected a problem. They would have noted + such a problem in *contextP. + */ + if (context.env.fault_occurred) + xmlrpc_env_set_fault_formatted( + envP, context.env.fault_code, + "XML doesn't parse. %s", context.env.fault_string); + else { + XMLRPC_ASSERT(context.rootP != NULL); + XMLRPC_ASSERT(context.currentP == NULL); + + *resultPP = context.rootP; + } + } + destroyParser(parser, &context); + } +} + + +/* 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. */ diff --git a/trunk/src/xmlrpc_libxml2.c b/trunk/src/xmlrpc_libxml2.c new file mode 100644 index 000000000..207036ffb --- /dev/null +++ b/trunk/src/xmlrpc_libxml2.c @@ -0,0 +1,533 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** Copyright (C) 2002 Ximian, Inc. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +/* There was code here from 2006-2013 that included + instead of when compiling for Windows. It was probably + compiled rarely if ever (this file is an optional part of the build). + In Feburary 2013, a Mingw user found was necessary, + and that makes more sense, so we changed it. +*/ +#include + +#include "mallocvar.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" + +#include "xmlparser.h" + +struct _xml_element { + xml_element * parentP; + const char * name; + xmlrpc_mem_block cdata; /* char */ + xmlrpc_mem_block children; /* xml_element* */ +}; + +#define XMLRPC_ASSERT_ELEM_OK(elem) \ + XMLRPC_ASSERT((elem) != NULL && (elem)->name != XMLRPC_BAD_POINTER) + + + +void +xml_init(xmlrpc_env * const envP) { + + XMLRPC_ASSERT_ENV_OK(envP); + + /* N.B. xmlInitParser() does not stack. Calling it twice is the + same as calling it once. Consequently, the same is true + of xml_init(). + + N.B. xmlInitParser() is necessary for form only, because every + libxml2 subroutine that needs it to be called just calls it itself. + */ + xmlInitParser(); +} + + + +void +xml_term(void) { + + /* N.B xmlCleanupParser() doesn't know how many times you called + xmlInitParser(). Calling it twice is the same as calling it once. + This means you must not call xml_term() while anything else in + the process is still using libxml2. + */ + xmlCleanupParser(); +} + + + +static xml_element * +xmlElementNew(xmlrpc_env * const envP, + const char * const name) { +/*---------------------------------------------------------------------------- + Create a new xml_element. This routine isn't exported, because the + arguments are implementation-dependent. +-----------------------------------------------------------------------------*/ + + xml_element * retval; + bool nameIsValid; + bool cdataIsValid; + bool childrenAreValid; + + XMLRPC_ASSERT_ENV_OK(envP); + assert(name != NULL); + + /* Set up our error-handling preconditions. */ + retval = NULL; + nameIsValid = cdataIsValid = childrenAreValid = false; + + MALLOCVAR(retval); + XMLRPC_FAIL_IF_NULL(retval, envP, XMLRPC_INTERNAL_ERROR, + "Couldn't allocate memory for XML element"); + + retval->parentP = NULL; + + /* Copy over the element name. */ + retval->name = strdup(name); + XMLRPC_FAIL_IF_NULL(retval->name, envP, XMLRPC_INTERNAL_ERROR, + "Couldn't allocate memory for XML element"); + nameIsValid = true; + + /* Initialize a block to hold our CDATA. */ + XMLRPC_TYPED_MEM_BLOCK_INIT(char, envP, &retval->cdata, 0); + XMLRPC_FAIL_IF_FAULT(envP); + cdataIsValid = true; + + /* Initialize a block to hold our child elements. */ + XMLRPC_TYPED_MEM_BLOCK_INIT(xml_element *, envP, &retval->children, 0); + XMLRPC_FAIL_IF_FAULT(envP); + childrenAreValid = true; + +cleanup: + if (envP->fault_occurred) { + if (retval) { + if (nameIsValid) + xmlrpc_strfree(retval->name); + if (cdataIsValid) + xmlrpc_mem_block_clean(&retval->cdata); + if (childrenAreValid) + xmlrpc_mem_block_clean(&retval->children); + free(retval); + } + retval = NULL; + } + return retval; +} + + + +void +xml_element_free(xml_element * const elemP) { +/*---------------------------------------------------------------------------- + Blow away an existing element & all of its child elements. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * children; + unsigned int size; + unsigned int i; + xml_element ** contents; + + XMLRPC_ASSERT_ELEM_OK(elemP); + + xmlrpc_strfree(elemP->name); + elemP->name = XMLRPC_BAD_POINTER; + xmlrpc_mem_block_clean(&elemP->cdata); + + /* Deallocate all of our children recursively. */ + children = &elemP->children; + contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element *, children); + size = XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, children); + for (i = 0; i < size; ++i) + xml_element_free(contents[i]); + + xmlrpc_mem_block_clean(&elemP->children); + + free(elemP); +} + + + +/*========================================================================= +** Miscellaneous Accessors +**========================================================================= +** Return the fields of the xml_element. See the header for more +** documentation on each function works. +*/ + +const char * +xml_element_name(const xml_element * const elemP) { + + XMLRPC_ASSERT_ELEM_OK(elemP); + return elemP->name; +} + +size_t +xml_element_cdata_size(const xml_element * const elemP) { + /* The result of this function is NOT VALID until the end_element handler + has been called! + */ + XMLRPC_ASSERT_ELEM_OK(elemP); + return XMLRPC_TYPED_MEM_BLOCK_SIZE(char, &elemP->cdata) - 1; +} + + + +const char * +xml_element_cdata(const xml_element * const elemP) { + XMLRPC_ASSERT_ELEM_OK(elemP); + return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &elemP->cdata); +} + + + +unsigned int +xml_element_children_size(const xml_element * const elemP) { + XMLRPC_ASSERT_ELEM_OK(elemP); + return XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, &elemP->children); +} + + + +xml_element ** +xml_element_children(const xml_element * const elemP) { + XMLRPC_ASSERT_ELEM_OK(elemP); + return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element *, &elemP->children); +} + + + +/*========================================================================= +** Internal xml_element Utility Functions +**========================================================================= +*/ + +static void +xmlElementAppendCdata(xmlrpc_env * const envP, + xml_element * const elemP, + const char * const cdata, + size_t const size) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_ELEM_OK(elemP); + + XMLRPC_TYPED_MEM_BLOCK_APPEND(char, envP, &elemP->cdata, cdata, size); +} + + + +static void +xmlElementAppendChild(xmlrpc_env * const envP, + xml_element * const elemP, + xml_element * const childP) { + + /* Whether or not this function succeeds, it takes ownership of the 'child' + argument. + WARNING - This is the exact opposite of the usual memory ownership + rules for xmlrpc_value! So please pay attention. + */ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_ELEM_OK(elemP); + XMLRPC_ASSERT_ELEM_OK(childP); + assert(childP->parentP == NULL); + + XMLRPC_TYPED_MEM_BLOCK_APPEND(xml_element *, envP, &elemP->children, + &childP, 1); + if (!envP->fault_occurred) + childP->parentP = elemP; + else + xml_element_free(childP); +} + + + +typedef struct { +/*---------------------------------------------------------------------------- + Our parse context. We pass this around as libxml user data. +-----------------------------------------------------------------------------*/ + + xmlrpc_env env; + xml_element * rootP; + xml_element * currentP; +} ParseContext; + + + +/*========================================================================= +** LibXML Event Handler Functions +**========================================================================= +*/ + +static void +startElement_(void * const userData, + const xmlChar * const name, + const xmlChar ** const attrs ATTR_UNUSED) { + + ParseContext * contextP; + xml_element * elemP; + xml_element * newCurrentP; + + assert(userData != NULL && name != NULL); + + /* Get our context and see if an error has already occured. */ + contextP = (ParseContext*) userData; + if (!contextP->env.fault_occurred) { + /* Build a new element. */ + elemP = xmlElementNew(&contextP->env, (char *) name); + XMLRPC_FAIL_IF_FAULT(&contextP->env); + + /* Insert it in the appropriate place. */ + if (!contextP->rootP) { + contextP->rootP = elemP; + contextP->currentP = elemP; + elemP = NULL; + } else { + assert(contextP->currentP != NULL); + + /* (We need to watch our error handling invariants very carefully + ** here. Read the docs for xml_elementAppendChild. */ + newCurrentP = elemP; + xmlElementAppendChild(&contextP->env, contextP->currentP, elemP); + elemP = NULL; + XMLRPC_FAIL_IF_FAULT(&contextP->env); + contextP->currentP = newCurrentP; + } + + cleanup: + if (elemP) + xml_element_free(elemP); + } +} + + + +static void +endElement_(void * const userData, + const xmlChar * const name ATTR_UNUSED) { + + ParseContext * contextP; + + assert(userData != NULL && name != NULL); + + /* Get our context and see if an error has already occured. */ + contextP = (ParseContext*) userData; + if (!contextP->env.fault_occurred) { + assert(xmlrpc_streq((const char *)name, + contextP->currentP->name)); + assert(contextP->currentP->parentP != NULL || + contextP->currentP == contextP->rootP); + + /* Add a trailing '\0' to our cdata. */ + xmlElementAppendCdata(&contextP->env, contextP->currentP, "\0", 1); + if (!contextP->env.fault_occurred) { + /* Pop our "stack" of elements. */ + contextP->currentP = contextP->currentP->parentP; + } + } +} + + + +static void +characterData(void * const userData, + const xmlChar * const s, + int const len) { + + ParseContext * contextP; + + assert(userData != NULL && s != NULL); + + /* Get our context and see if an error has already occured. */ + contextP = (ParseContext*)userData; + if (!contextP->env.fault_occurred) { + assert(contextP->currentP != NULL); + + xmlElementAppendCdata(&contextP->env, + contextP->currentP, + (char *)s, + len); + } +} + + + +/*========================================================================= +** LibXML Driver +**========================================================================= +** XXX - We should allow the user to specify the encoding of our xml_data. +*/ + +static xmlSAXHandler const saxHandler = { + NULL, /* internalSubset */ + NULL, /* isStandalone */ + NULL, /* hasInternalSubset */ + NULL, /* hasExternalSubset */ + NULL, /* resolveEntity */ + NULL, /* getEntity */ + NULL, /* entityDecl */ + NULL, /* notationDecl */ + NULL, /* attributeDecl */ + NULL, /* elementDecl */ + NULL, /* unparsedEntityDecl */ + NULL, /* setDocumentLocator */ + NULL, /* startDocument */ + NULL, /* endDocument */ + startElement_, /* startElement */ + endElement_, /* endElement */ + NULL, /* reference */ + characterData, /* characters */ + NULL, /* ignorableWhitespace */ + NULL, /* processingInstruction */ + NULL, /* comment */ + NULL, /* warning */ + NULL, /* error */ + NULL, /* fatalError */ + NULL, /* getParameterEntity */ + NULL, /* cdataBlock */ + NULL, /* externalSubset */ + 1 /* initialized */ + + /* Following are SAX2 fields. Any ifdef here? */ + + ,NULL, /* _private */ + NULL, /* startElementNs */ + NULL, /* endElementNs */ + NULL /* serror */ +}; + + + +static void +removeDocSizeLimit(xmlParserCtx * const parserP ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + Set up *parserP to accept a document of any size. + + Newer Libxml2 by default fails any attempt to parse a document larger than + 10 MiB, because it wants to avoid running the system out of resources. + This is not an appropriate role for the library, and 10 MiB is a completely + arbitrary number anyway, so we don't use this feature. +-----------------------------------------------------------------------------*/ +#if LIBXML_VERSION > 20700 + + xmlCtxtUseOptions(parserP, XML_PARSE_HUGE); + +#else + + /* There's never a size limit */ + +#endif +} + + + +static void +createParser(xmlrpc_env * const envP, + ParseContext * const contextP, + xmlParserCtx ** const parserPP) { +/*---------------------------------------------------------------------------- + Create an appropriate Libxml2 parser for our purpose. +-----------------------------------------------------------------------------*/ + xmlParserCtx * parserP; + + parserP = xmlCreatePushParserCtxt((xmlSAXHandler *)&saxHandler, contextP, + NULL, 0, NULL); + + if (!parserP) + xmlrpc_faultf(envP, "Failed to create libxml2 parser."); + else { + removeDocSizeLimit(parserP); + + *parserPP = parserP; + } +} + + + +void +xml_parse(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP ATTR_UNUSED, + xml_element ** const resultPP) { +/*---------------------------------------------------------------------------- + This is an implementation of the interface declared in xmlparser.h. This + implementation uses Libxml2. +-----------------------------------------------------------------------------*/ + ParseContext context; + xmlParserCtxt * parserP; + + XMLRPC_ASSERT_ENV_OK(envP); + assert(xmlData != NULL); + + xmlrpc_env_init(&context.env); + context.rootP = NULL; + context.currentP = NULL; + + createParser(envP, &context, &parserP); + + if (!envP->fault_occurred) { + int rc; + + rc = xmlParseChunk(parserP, xmlData, xmlDataLen, 1); + + if (rc != 0) + xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, + "XML parsing failed"); + else { + if (context.env.fault_occurred) { + xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR, + context.env.fault_string); + /* This should be done by the parser, but I'm not sure which + callbacks need to do it. + */ + if (context.rootP) + xml_element_free(context.rootP); + } else { + assert(context.rootP != NULL); + assert(context.currentP == NULL); + + *resultPP = context.rootP; + } + } + /* xmlParseChunk() creates a document. You find it with + parserP->myDoc. + */ + if (parserP->myDoc) + xmlFreeDoc(parserP->myDoc); + xmlFreeParserCtxt(parserP); + } + xmlrpc_env_clean(&context.env); +} + + + diff --git a/trunk/src/xmlrpc_parse.c b/trunk/src/xmlrpc_parse.c new file mode 100644 index 000000000..0d86d72a4 --- /dev/null +++ b/trunk/src/xmlrpc_parse.c @@ -0,0 +1,754 @@ +/* Copyright information is at end of file. */ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "bool.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/util.h" +#include "xmlparser.h" +#include "parse_value.h" + +#include "xmlrpc_parse.h" + +/* Notes about XML-RPC XML documents: + + Contain CDATA: methodName, i4, int, boolean, string, double, + dateTime.iso8601, base64, name + + We attempt to validate the structure of the XML document carefully. + We also try *very* hard to handle malicious data gracefully, and without + leaking memory. + + The CHECK_NAME and CHECK_CHILD_COUNT macros examine an XML element, and + invoke XMLRPC_FAIL if something looks wrong. +*/ + +static void +setParseFault(xmlrpc_env * const envP, + const char * const format, + ...) { + + va_list args; + va_start(args, format); + xmlrpc_set_fault_formatted_v(envP, XMLRPC_PARSE_ERROR, format, args); + va_end(args); +} + + + +static void +validateName(xmlrpc_env * const envP, + const xml_element * const elemP, + const char * const name) { + + if (!xmlrpc_streq(name, xml_element_name(elemP))) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Expected element of type <%s>, found <%s>", + name, xml_element_name(elemP)); +} + + + +static void +validateChildCount(xmlrpc_env * const envP, + const xml_element * const elemP, + unsigned int const requiredCount) { + + if (xml_element_children_size(elemP) != requiredCount) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Expected <%s> to have %u children, found %u", + xml_element_name(elemP), requiredCount, + (unsigned)xml_element_children_size(elemP)); +} + + + +static xml_element * +getChildByName (xmlrpc_env * const envP, + xml_element * const parentP, + const char * const name) { + + size_t const childCount = xml_element_children_size(parentP); + xml_element ** const childrenP = xml_element_children(parentP); + + unsigned int i; + + for (i = 0; i < childCount; ++i) { + if (xmlrpc_streq(xml_element_name(childrenP[i]), name)) + return childrenP[i]; + } + + setParseFault(envP, "Expected <%s> to have child <%s>", + xml_element_name(parentP), name); + return NULL; +} + + + +static xmlrpc_value * +convertParams(xmlrpc_env * const envP, + const xml_element * const elemP) { +/*---------------------------------------------------------------------------- + Convert an XML element representing a list of parameters (i.e. a + element) to an xmlrpc_value of type array. Note that an xmlrpc_value is + normally represented in XML by a element, not a element. + We use type xmlrpc_value to represent the parameter list just for + convenience. +-----------------------------------------------------------------------------*/ + xmlrpc_value * arrayP; + xmlrpc_value * itemP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(elemP != NULL); + + /* Allocate an array to hold our parameters. */ + arrayP = xmlrpc_array_new(envP); + if (!envP->fault_occurred) { + /* We're responsible for checking our own element name. */ + validateName(envP, elemP, "params"); + + if (!envP->fault_occurred) { + /* Iterate over our children. */ + unsigned int const size = xml_element_children_size(elemP); + xml_element ** const paramPList = xml_element_children(elemP); + + unsigned int i; + + for (i = 0; i < size; ++i) { + xml_element * const paramP = paramPList[i]; + unsigned int const maxNest = (unsigned int) + xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); + + validateName(envP, paramP, "param"); + if (!envP->fault_occurred) { + validateChildCount(envP, paramP, 1); + if (!envP->fault_occurred) { + xml_element * const valueEltP = + xml_element_children(paramP)[0]; + + validateName(envP, valueEltP, "value"); + + if (!envP->fault_occurred) { + xmlrpc_parseValue(envP, maxNest, valueEltP, + &itemP); + if (!envP->fault_occurred) { + xmlrpc_array_append_item(envP, arrayP, itemP); + xmlrpc_DECREF(itemP); + } + } + } + } + } + } + if (envP->fault_occurred) + xmlrpc_DECREF(arrayP); + } + return arrayP; +} + + + +static void +parseCallXml(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xml_element ** const callElemPP) { +/*---------------------------------------------------------------------------- + Parse the XML of an XML-RPC call. +-----------------------------------------------------------------------------*/ + xml_element * callElemP; + xmlrpc_env env; + + xmlrpc_env_init(&env); + xml_parse(&env, xmlData, xmlDataLen, memPoolP, &callElemP); + if (env.fault_occurred) + xmlrpc_env_set_fault_formatted( + envP, env.fault_code, "Call is not valid XML. %s", + env.fault_string); + else { + if (!xmlrpc_streq(xml_element_name(callElemP), "methodCall")) + setParseFault(envP, + "XML-RPC call should be a element. " + "Instead, we have a <%s> element.", + xml_element_name(callElemP)); + + if (envP->fault_occurred) + xml_element_free(callElemP); + } + *callElemPP = callElemP; + + xmlrpc_env_clean(&env); +} + + + +static void +parseMethodNameElement(xmlrpc_env * const envP, + xml_element * const nameElemP, + const char ** const methodNameP) { + + XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(nameElemP), "methodName")); + + if (xml_element_children_size(nameElemP) > 0) + setParseFault(envP, "A element should not have " + "children. This one has %u of them.", + xml_element_children_size(nameElemP)); + else { + const char * const cdata = xml_element_cdata(nameElemP); + + xmlrpc_validate_utf8(envP, cdata, strlen(cdata)); + + if (!envP->fault_occurred) { + *methodNameP = strdup(cdata); + if (*methodNameP == NULL) + xmlrpc_faultf(envP, + "Could not allocate memory for method name"); + } + } +} + + + +static void +parseCallChildren(xmlrpc_env * const envP, + xml_element * const callElemP, + const char ** const methodNameP, + xmlrpc_value ** const paramArrayPP ) { +/*---------------------------------------------------------------------------- + Parse the children of a XML element *callElemP. They should + be and . +-----------------------------------------------------------------------------*/ + size_t const callChildCount = xml_element_children_size(callElemP); + + xml_element * nameElemP; + + XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(callElemP), "methodCall")); + + nameElemP = getChildByName(envP, callElemP, "methodName"); + + if (!envP->fault_occurred) { + parseMethodNameElement(envP, nameElemP, methodNameP); + + if (!envP->fault_occurred) { + /* Convert our parameters. */ + if (callChildCount > 1) { + xml_element * paramsElemP; + + paramsElemP = getChildByName(envP, callElemP, "params"); + + if (!envP->fault_occurred) + *paramArrayPP = convertParams(envP, paramsElemP); + } else { + /* Workaround for Ruby XML-RPC and old versions of + xmlrpc-epi. Future improvement: Instead of looking + at child count, we should just check for existence + of . + */ + *paramArrayPP = xmlrpc_array_new(envP); + } + if (!envP->fault_occurred) { + if (callChildCount > 2) + setParseFault(envP, " has extraneous " + "children, other than and " + ". Total child count = %u", + callChildCount); + + if (envP->fault_occurred) + xmlrpc_DECREF(*paramArrayPP); + } + if (envP->fault_occurred) + xmlrpc_strfree(*methodNameP); + } + } +} + + + +void +xmlrpc_parse_call2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + const char ** const methodNameP, + xmlrpc_value ** const paramArrayPP) { +/*---------------------------------------------------------------------------- + Given some XML text, attempt to parse it as an XML-RPC call. + Return as *methodNameP the name of the method identified in the call + and as *paramArrayPP the parameter list as an XML-RPC array. + Caller must free() and xmlrpc_DECREF() these, respectively). +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(xmlData != NULL); + XMLRPC_ASSERT(methodNameP != NULL && paramArrayPP != NULL); + + /* SECURITY: Last-ditch attempt to make sure our content length is + legal. XXX - This check occurs too late to prevent an attacker + from creating an enormous memory block, so you should try to + enforce it *before* reading any data off the network. + */ + if (xmlDataLen > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_LIMIT_EXCEEDED_ERROR, + "XML-RPC request too large. Max allowed is %u bytes", + (unsigned)xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)); + else { + xml_element * callElemP; + parseCallXml(envP, xmlData, xmlDataLen, memPoolP, &callElemP); + if (!envP->fault_occurred) { + parseCallChildren(envP, callElemP, methodNameP, paramArrayPP); + + xml_element_free(callElemP); + } + } + if (envP->fault_occurred) { + /* Should not be necessary, but for backward compatibility: */ + *methodNameP = NULL; + *paramArrayPP = NULL; + } +} + + + +void +xmlrpc_parse_call(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + const char ** const methodNameP, + xmlrpc_value ** const paramArrayPP) { + + xmlrpc_parse_call2(envP, xmlData, xmlDataLen, NULL, + methodNameP, paramArrayPP); +} + + + +static void +interpretFaultCode(xmlrpc_env * const envP, + xmlrpc_value * const faultCodeVP, + int * const faultCodeP) { + + xmlrpc_env fcEnv; + xmlrpc_env_init(&fcEnv); + + xmlrpc_read_int(&fcEnv, faultCodeVP, faultCodeP); + if (fcEnv.fault_occurred) + xmlrpc_faultf(envP, "Invalid value for 'faultCode' member. %s", + fcEnv.fault_string); + + xmlrpc_env_clean(&fcEnv); +} + + + +static void +interpretFaultString(xmlrpc_env * const envP, + xmlrpc_value * const faultStringVP, + const char ** const faultStringP) { + + xmlrpc_env fsEnv; + xmlrpc_env_init(&fsEnv); + + xmlrpc_read_string(&fsEnv, faultStringVP, faultStringP); + + if (fsEnv.fault_occurred) + xmlrpc_faultf(envP, "Invalid value for 'faultString' member. %s", + fsEnv.fault_string); + + xmlrpc_env_clean(&fsEnv); +} + + + +static void +interpretFaultValue(xmlrpc_env * const envP, + xmlrpc_value * const faultVP, + int * const faultCodeP, + const char ** const faultStringP) { + + if (faultVP->_type != XMLRPC_TYPE_STRUCT) + setParseFault(envP, + " element of response is not " + "of structure type"); + else { + xmlrpc_value * faultCodeVP; + xmlrpc_env fvEnv; + + xmlrpc_env_init(&fvEnv); + + xmlrpc_struct_read_value(&fvEnv, faultVP, "faultCode", &faultCodeVP); + if (!fvEnv.fault_occurred) { + interpretFaultCode(&fvEnv, faultCodeVP, faultCodeP); + + if (!fvEnv.fault_occurred) { + xmlrpc_value * faultStringVP; + + xmlrpc_struct_read_value(&fvEnv, faultVP, "faultString", + &faultStringVP); + if (!fvEnv.fault_occurred) { + interpretFaultString(&fvEnv, faultStringVP, faultStringP); + + xmlrpc_DECREF(faultStringVP); + } + } + xmlrpc_DECREF(faultCodeVP); + } + if (fvEnv.fault_occurred) + setParseFault(envP, "Invalid struct for value. %s", + fvEnv.fault_string); + + xmlrpc_env_clean(&fvEnv); + } +} + + + +static void +parseFaultElement(xmlrpc_env * const envP, + const xml_element * const faultElement, + int * const faultCodeP, + const char ** const faultStringP) { + + unsigned int const maxRecursion = (unsigned int) + xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); + + XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(faultElement), "fault")); + + if (xml_element_children_size(faultElement) != 1) + setParseFault(envP, " element should have 1 child, " + "but it has %u.", + xml_element_children_size(faultElement)); + else { + xml_element * const faultValueP = + xml_element_children(faultElement)[0]; + const char * const elemName = xml_element_name(faultValueP); + + if (!xmlrpc_streq(elemName, "value")) + setParseFault(envP, + " contains a <%s> element. " + "Only makes sense.", + elemName); + else { + xmlrpc_value * faultVP; + + xmlrpc_parseValue(envP, maxRecursion, faultValueP, &faultVP); + + if (!envP->fault_occurred) { + interpretFaultValue(envP, faultVP, faultCodeP, faultStringP); + + xmlrpc_DECREF(faultVP); + } + } + } +} + + + +static void +parseParamsElement(xmlrpc_env * const envP, + const xml_element * const paramsElementP, + xmlrpc_value ** const resultPP) { + + xmlrpc_value * paramsVP; + xmlrpc_env env; + + xmlrpc_env_init(&env); + + XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(paramsElementP), "params")); + + paramsVP = convertParams(envP, paramsElementP); + + if (!envP->fault_occurred) { + int arraySize; + xmlrpc_env sizeEnv; + + XMLRPC_ASSERT_ARRAY_OK(paramsVP); + + xmlrpc_env_init(&sizeEnv); + + arraySize = xmlrpc_array_size(&sizeEnv, paramsVP); + /* Since it's a valid array, as asserted above, can't fail */ + XMLRPC_ASSERT(!sizeEnv.fault_occurred); + + if (arraySize != 1) + setParseFault(envP, "Contains %d items. It should have 1.", + arraySize); + else { + xmlrpc_array_read_item(envP, paramsVP, 0, resultPP); + } + xmlrpc_DECREF(paramsVP); + xmlrpc_env_clean(&sizeEnv); + } + if (env.fault_occurred) + xmlrpc_env_set_fault_formatted( + envP, env.fault_code, + "Invalid element. %s", env.fault_string); + + xmlrpc_env_clean(&env); +} + + + +static void +parseMethodResponseElt(xmlrpc_env * const envP, + const xml_element * const methodResponseEltP, + xmlrpc_value ** const resultPP, + int * const faultCodeP, + const char ** const faultStringP) { + + XMLRPC_ASSERT(xmlrpc_streq(xml_element_name(methodResponseEltP), + "methodResponse")); + + if (xml_element_children_size(methodResponseEltP) == 1) { + xml_element * const child = + xml_element_children(methodResponseEltP)[0]; + + if (xmlrpc_streq(xml_element_name(child), "params")) { + /* It's a successful response */ + parseParamsElement(envP, child, resultPP); + *faultStringP = NULL; + } else if (xmlrpc_streq(xml_element_name(child), "fault")) { + /* It's a failure response */ + parseFaultElement(envP, child, faultCodeP, faultStringP); + } else + setParseFault(envP, + " must contain or , " + "but contains <%s>.", xml_element_name(child)); + } else + setParseFault(envP, + " has %u children, should have 1.", + xml_element_children_size(methodResponseEltP)); +} + + + +static void +parseResponseXml(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xml_element ** const responseEltPP) { + + xmlrpc_env env; + xmlrpc_env_init(&env); + + xml_parse(&env, xmlData, xmlDataLen, memPoolP, responseEltPP); + + if (env.fault_occurred) + setParseFault(envP, "Not valid XML. %s", env.fault_string); + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_parse_response3(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xmlrpc_value ** const resultPP, + int * const faultCodeP, + const char ** const faultStringP) { +/*---------------------------------------------------------------------------- + Given some XML text, attempt to parse it as an XML-RPC response. + + If the response is a regular, valid response, return a new reference + to the appropriate value as *resultP and return NULL as + *faultStringP and nothing as *faultCodeP. + + If the response is valid, but indicates a failure of the RPC, return the + fault string in newly malloc'ed space as *faultStringP and the fault + code as *faultCodeP and nothing as *resultP. + + If the XML text is not a valid response or something prevents us from + parsing it, return a description of the error as *envP and nothing else. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(xmlData != NULL); + + /* SECURITY: Last-ditch attempt to make sure our content length is legal. + ** XXX - This check occurs too late to prevent an attacker from creating + ** an enormous memory block, so you should try to enforce it + ** *before* reading any data off the network. */ + if (xmlDataLen > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_LIMIT_EXCEEDED_ERROR, + "XML-RPC response too large. Our limit is %u characters. " + "We got %u characters", + (unsigned)xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID), + (unsigned)xmlDataLen); + else { + xml_element * responseEltP; + parseResponseXml(envP, xmlData, xmlDataLen, memPoolP, &responseEltP); + + if (!envP->fault_occurred) { + if (xmlrpc_streq(xml_element_name(responseEltP), + "methodResponse")) { + parseMethodResponseElt(envP, responseEltP, + resultPP, faultCodeP, faultStringP); + } else + setParseFault(envP, "XML-RPC response must consist of a " + " element. " + "This has a <%s> instead.", + xml_element_name(responseEltP)); + + xml_element_free(responseEltP); + } + } +} + + + +void +xmlrpc_parse_response2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_value ** const resultPP, + int * const faultCodeP, + const char ** const faultStringP) { +/*---------------------------------------------------------------------------- + This exists for backward compatibility. It is like + xmlrpc_parse_response3(), except that it uses the unlimited system memory + pool. +-----------------------------------------------------------------------------*/ + xmlrpc_parse_response3(envP, xmlData, xmlDataLen, NULL, + resultPP, faultCodeP, faultStringP); +} + + + +xmlrpc_value * +xmlrpc_parse_response(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen) { +/*---------------------------------------------------------------------------- + This exists for backward compatibility. It is like + xmlrpc_parse_response2(), except that it merges the concepts of a + failed RPC and an error in executing the RPC. +-----------------------------------------------------------------------------*/ + xmlrpc_value * retval; + xmlrpc_value * result; + const char * faultString; + int faultCode; + + xmlrpc_parse_response3(envP, xmlData, xmlDataLen, NULL, + &result, &faultCode, &faultString); + + if (envP->fault_occurred) + retval = NULL; + else { + if (faultString) { + xmlrpc_env_set_fault(envP, faultCode, faultString); + xmlrpc_strfree(faultString); + retval = NULL; + } else + retval = result; /* transfer reference */ + } + return retval; +} + + + +void +xmlrpc_parse_value_xml2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Compute the xmlrpc_value represented by the XML document 'xmlData' (of + length 'xmlDataLen' characters), which must consist of a single + element. Return that xmlrpc_value. + + We call convert_array() and convert_struct(), which may ultimately + call us recursively. Don't recurse any more than 'maxRecursion' + times. + + This isn't generally useful in XML-RPC programs, because such programs + parse a whole XML-RPC call or response document, and never see the XML text + of just a element. But a program may do some weird form of XML-RPC + processing or just borrow Xmlrpc-c's value serialization facilities for + something unrelated to XML-RPC. In any case, it makes sense to have an + inverse of xmlrpc_serialize_value2(), which generates XML text from an + xmlrpc_value. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + + xml_element * valueEltP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(xmlData != NULL); + + xmlrpc_env_init(&env); + + xml_parse(&env, xmlData, xmlDataLen, memPoolP, &valueEltP); + + if (env.fault_occurred) { + setParseFault(envP, "Not valid XML. %s", env.fault_string); + } else { + if (xmlrpc_streq(xml_element_name(valueEltP), "value")) { + unsigned int const maxRecursion = (unsigned int) + xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID); + xmlrpc_parseValue(envP, maxRecursion, valueEltP, valuePP); + } else + setParseFault(envP, "XML-RPC value XML document must consist of " + "a element. This has a <%s> instead.", + xml_element_name(valueEltP)); + xml_element_free(valueEltP); + } + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_parse_value_xml(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_value ** const valuePP) { + + xmlrpc_parse_value_xml2(envP, xmlData, xmlDataLen, NULL, valuePP); +} + + + +/* 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. */ diff --git a/trunk/src/xmlrpc_parse.h b/trunk/src/xmlrpc_parse.h new file mode 100644 index 000000000..79bf1afc0 --- /dev/null +++ b/trunk/src/xmlrpc_parse.h @@ -0,0 +1,42 @@ +#ifndef XMLRPC_PARSE_H_INCLUDED +#define XMLRPC_PARSE_H_INCLUDED +/*============================================================================= + xmlrpc_parse.h +=============================================================================== + This declares the interface to the _internal_ XML-RPC XML parsing functions + in xmlrpc_parse.c. + + There are also _external_ functions in xmlrpc_parse.c, and those are + declared in an external interface header file. + + xmlrpc_parse.c is split that way because some functions use memory pools, + which is an internal concept we don't feel like making external right now. +=============================================================================*/ + +#include "xmlrpc-c/util_int.h" + +void +xmlrpc_parse_call2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + const char ** const methodNameP, + xmlrpc_value ** const paramArrayPP); + +void +xmlrpc_parse_response3(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xmlrpc_value ** const resultPP, + int * const faultCodeP, + const char ** const faultStringP); + +void +xmlrpc_parse_value_xml2(xmlrpc_env * const envP, + const char * const xmlData, + size_t const xmlDataLen, + xmlrpc_mem_pool * const memPoolP, + xmlrpc_value ** const valuePP); + +#endif diff --git a/trunk/src/xmlrpc_serialize.c b/trunk/src/xmlrpc_serialize.c new file mode 100644 index 000000000..f1679a07b --- /dev/null +++ b/trunk/src/xmlrpc_serialize.c @@ -0,0 +1,780 @@ +/* Copyright information is at end of file */ + +/* Implementation note: + + The printf format specifiers we use appear to be entirely standard, + except for the "long long" one, which is %I64 on Windows and %lld + everywhere else. We could use the C99 standard macro PRId64 for that, + but on at least one 64-bit-long GNU compiler, PRId64 is "ld", which is + considered to be incompatible with long long. So we have XMLRPC_PRId64. +*/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "int.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "double.h" + +#define CRLF "\015\012" +#define XML_PROLOGUE ""CRLF +#define APACHE_URL "http://ws.apache.org/xmlrpc/namespaces/extensions" +#define XMLNS_APACHE "xmlns:ex=\"" APACHE_URL "\"" + + +static void +addString(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + const char * const string) { + + XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, string, strlen(string)); +} + + + +static void +formatOut(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + const char * const formatString, + ...) { +/*---------------------------------------------------------------------------- + A lightweight print routine for use with various serialization + functions. + + Use this routine only for printing small objects -- it uses a + fixed-size internal buffer and returns an error on overflow. In + particular, do NOT use this routine to print XML-RPC string values! +-----------------------------------------------------------------------------*/ + va_list args; + char buffer[128]; + int rc; + + XMLRPC_ASSERT_ENV_OK(envP); + + va_start(args, formatString); + + rc = XMLRPC_VSNPRINTF(buffer, sizeof(buffer), formatString, args); + + /* Old vsnprintf() (and Windows) fails with return value -1 if the full + string doesn't fit in the buffer. New vsnprintf() puts whatever will + fit in the buffer, and returns the length of the full string + regardless. For us, this truncation is a failure. + */ + + if (rc < 0) + xmlrpc_faultf(envP, "formatOut() overflowed internal buffer"); + else { + unsigned int const formattedLen = rc; + + if (formattedLen + 1 >= (sizeof(buffer))) + xmlrpc_faultf(envP, "formatOut() overflowed internal buffer"); + else + XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, buffer, formattedLen); + } + va_end(args); +} + + + +static void +assertValidUtf8(const char * const str ATTR_UNUSED, + size_t const len ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + Assert that the string 'str' of length 'len' is valid UTF-8. +-----------------------------------------------------------------------------*/ +#if !defined NDEBUG + /* Check the assertion; if it's false, issue a message to + Standard Error, but otherwise ignore it. + */ + xmlrpc_env env; + + xmlrpc_env_init(&env); + xmlrpc_validate_utf8(&env, str, len); + if (env.fault_occurred) + fprintf(stderr, "*** xmlrpc-c WARNING ***: %s (%s)\n", + "Xmlrpc-c sending corrupted UTF-8 data to network", + env.fault_string); + xmlrpc_env_clean(&env); +#endif +} + + + +static size_t +escapedSize(const char * const chars, + size_t const len) { + + size_t size; + size_t i; + + size = 0; + for (i = 0; i < len; ++i) { + if (chars[i] == '<') + size += 4; /* < */ + else if (chars[i] == '>') + size += 4; /* > */ + else if (chars[i] == '&') + size += 5; /* & */ + else if (chars[i] == '\r') + size += 6; /* */ + else + size += 1; + } + return size; +} + + + +static void +escapeForXml(xmlrpc_env * const envP, + const char * const chars, + size_t const len, + xmlrpc_mem_block ** const outputPP) { +/*---------------------------------------------------------------------------- + Escape & and < in a UTF-8 string so as to make it suitable for the + content of an XML element. I.e. turn them into entity references + & and <. + + Also change > to >, even though not required for XML, for + symmetry. + + < etc. are known in XML as "entity references." + + Also Escape CR as . While raw CR _is_ allowed in the content + of an XML element, it has a special meaning -- it means line ending. + Our input uses LF for for line endings. Since it also means line ending + in XML, we just pass it through to our output like it were a regular + character. + + is known in XML as a "character reference." + + We assume chars[] is is ASCII. That isn't right -- we should + handle all valid UTF-8. Someday, we must do something more complex + and copy over multibyte characters verbatim. (The code here could + erroneously find that e.g. the 2nd byte of a UTF-8 character is a + CR). +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * outputP; + size_t outputSize; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(chars != NULL); + + assertValidUtf8(chars, len); + + /* Note that in UTF-8, any byte that has high bit of zero is a + character all by itself (every byte of a multi-byte UTF-8 character + has the high bit set). Also, the Unicode code points < 128 are + identical to the ASCII ones. + */ + + outputSize = escapedSize(chars, len); + + outputP = XMLRPC_MEMBLOCK_NEW(char, envP, outputSize); + if (!envP->fault_occurred) { + char * p; + size_t i; + p = XMLRPC_MEMBLOCK_CONTENTS(char, outputP); /* Start at beginning */ + + for (i = 0; i < len; i++) { + if (chars[i] == '<') { + memcpy(p, "<", 4); + p += 4; + } else if (chars[i] == '>') { + memcpy(p, ">", 4); + p += 4; + } else if (chars[i] == '&') { + memcpy(p, "&", 5); + p += 5; + } else if (chars[i] == '\r') { + memcpy(p, " ", 6); + p += 6; + } else { + /* Either a plain character or a LF line delimiter */ + *p = chars[i]; + p += 1; + } + } + *outputPP = outputP; + assert(p == XMLRPC_MEMBLOCK_CONTENTS(char, outputP) + outputSize); + + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, outputP); + } +} + + + +static void +serializeUtf8MemBlock(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_mem_block * const inputP) { +/*---------------------------------------------------------------------------- + Append the characters in *inputP to the XML stream in *outputP. + + *inputP contains Unicode characters in UTF-8. + + We assume *inputP ends with a NUL character that marks end of + string, and we ignore that. + + To the extent that *inputP contains code points that do not represent an + XML character (for example, ASCII control characters), we generate a + non-XML stream. But it is important for us to do that, because the + unfortunate way in which Xmlrpc-c defines its string type means Caller + is actually supposed to generate non-XML output sometimes. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * escapedP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(outputP != NULL); + XMLRPC_ASSERT(inputP != NULL); + + escapeForXml(envP, + XMLRPC_MEMBLOCK_CONTENTS(const char, inputP), + XMLRPC_MEMBLOCK_SIZE(const char, inputP) - 1, + /* -1 is for the terminating NUL */ + &escapedP); + if (!envP->fault_occurred) { + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(const char, escapedP); + size_t const size = XMLRPC_MEMBLOCK_SIZE(char, escapedP); + + XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, contents, size); + + XMLRPC_MEMBLOCK_FREE(const char, escapedP); + } +} + + + +static void +xmlrpc_serialize_base64_data(xmlrpc_env * const envP, + xmlrpc_mem_block * const output, + unsigned char * const data, + size_t const len) { +/*---------------------------------------------------------------------------- + Encode the 'len' bytes at 'data' in base64 ASCII and append the result to + 'output'. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * encoded; + + encoded = xmlrpc_base64_encode(envP, data, len); + if (!envP->fault_occurred) { + unsigned char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(unsigned char, encoded); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(unsigned char, encoded); + + XMLRPC_MEMBLOCK_APPEND(char, envP, output, contents, size); + + XMLRPC_MEMBLOCK_FREE(char, encoded); + } +} + + + +static void +serializeDatetime(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const valueP) { +/*---------------------------------------------------------------------------- + Add to *outputP the content of a element to represent + the datetime value *valueP. I.e. + " ... ". +-----------------------------------------------------------------------------*/ + + addString(envP, outputP, ""); + if (!envP->fault_occurred) { + char dtString[64]; + + XMLRPC_SNPRINTF(dtString, sizeof(dtString), + "%u%02u%02uT%02u:%02u:%02u", + valueP->_value.dt.Y, + valueP->_value.dt.M, + valueP->_value.dt.D, + valueP->_value.dt.h, + valueP->_value.dt.m, + valueP->_value.dt.s); + + if (valueP->_value.dt.u != 0) { + char usecString[64]; + assert(valueP->_value.dt.u < 1000000); + XMLRPC_SNPRINTF(usecString, sizeof(usecString), ".%06u", + valueP->_value.dt.u); + STRSCAT(dtString, usecString); + } + addString(envP, outputP, dtString); + + if (!envP->fault_occurred) { + addString(envP, outputP, ""); + } + } +} + + + +static void +serializeStructMember(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const memberKeyP, + xmlrpc_value * const memberValueP, + xmlrpc_dialect const dialect) { + + addString(envP, outputP, ""); + + if (!envP->fault_occurred) { + serializeUtf8MemBlock(envP, outputP, memberKeyP->blockP); + + if (!envP->fault_occurred) { + addString(envP, outputP, ""CRLF); + + if (!envP->fault_occurred) { + xmlrpc_serialize_value2(envP, outputP, memberValueP, dialect); + + if (!envP->fault_occurred) { + addString(envP, outputP, ""CRLF); + } + } + } + } +} + + + +static void +serializeStruct(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const structP, + xmlrpc_dialect const dialect) { +/*---------------------------------------------------------------------------- + Add to *outputP the content of a element to represent + the structure value *valueP. I.e. " ... ". +-----------------------------------------------------------------------------*/ + addString(envP, outputP, ""CRLF); + if (!envP->fault_occurred) { + unsigned int const size = xmlrpc_struct_size(envP, structP); + if (!envP->fault_occurred) { + unsigned int i; + for (i = 0; i < size && !envP->fault_occurred; ++i) { + xmlrpc_value * memberKeyP; + xmlrpc_value * memberValueP; + + xmlrpc_struct_get_key_and_value(envP, structP, i, + &memberKeyP, &memberValueP); + if (!envP->fault_occurred) { + serializeStructMember(envP, outputP, + memberKeyP, memberValueP, dialect); + } + } + if (!envP->fault_occurred) + addString(envP, outputP, ""); + } + } +} + + + +static void +serializeArray(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const valueP, + xmlrpc_dialect const dialect) { +/*---------------------------------------------------------------------------- + Add to *outputP the content of a element to represent + the array value *valueP. I.e. " ... ". +-----------------------------------------------------------------------------*/ + int const size = xmlrpc_array_size(envP, valueP); + + if (!envP->fault_occurred) { + addString(envP, outputP, ""CRLF); + if (!envP->fault_occurred) { + int i; + /* Serialize each item. */ + for (i = 0; i < size && !envP->fault_occurred; ++i) { + xmlrpc_value * const itemP = + xmlrpc_array_get_item(envP, valueP, i); + if (!envP->fault_occurred) { + xmlrpc_serialize_value2(envP, outputP, itemP, dialect); + if (!envP->fault_occurred) + addString(envP, outputP, CRLF); + } + } + } + } + if (!envP->fault_occurred) + addString(envP, outputP, ""); +} + + + +static void +formatValueContent(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const valueP, + xmlrpc_dialect const dialect) { +/*---------------------------------------------------------------------------- + Add to *outputP the content of a element to represent + value *valueP. E.g. "42" +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + + switch (valueP->_type) { + case XMLRPC_TYPE_INT: + formatOut(envP, outputP, "%d", valueP->_value.i); + break; + + case XMLRPC_TYPE_I8: { + const char * const elemName = + dialect == xmlrpc_dialect_apache ? "ex:i8" : "i8"; + formatOut(envP, outputP, "<%s>%" PRId64 "", + elemName, valueP->_value.i8, elemName); + } break; + + case XMLRPC_TYPE_BOOL: + formatOut(envP, outputP, "%s", + valueP->_value.b ? "1" : "0"); + break; + + case XMLRPC_TYPE_DOUBLE: { + const char * serializedValue; + xmlrpc_formatFloat(envP, valueP->_value.d, &serializedValue); + if (!envP->fault_occurred) { + addString(envP, outputP, ""); + if (!envP->fault_occurred) { + addString(envP, outputP, serializedValue); + if (!envP->fault_occurred) + addString(envP, outputP, ""); + } + xmlrpc_strfree(serializedValue); + } + } break; + + case XMLRPC_TYPE_DATETIME: + serializeDatetime(envP, outputP, valueP); + break; + + case XMLRPC_TYPE_STRING: + addString(envP, outputP, ""); + if (!envP->fault_occurred) { + serializeUtf8MemBlock(envP, outputP, valueP->blockP); + if (!envP->fault_occurred) + addString(envP, outputP, ""); + } + break; + + case XMLRPC_TYPE_BASE64: { + unsigned char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(unsigned char, valueP->blockP); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(unsigned char, valueP->blockP); + addString(envP, outputP, ""CRLF); + if (!envP->fault_occurred) { + xmlrpc_serialize_base64_data(envP, outputP, contents, size); + if (!envP->fault_occurred) + addString(envP, outputP, ""); + } + } break; + + case XMLRPC_TYPE_ARRAY: + serializeArray(envP, outputP, valueP, dialect); + break; + + case XMLRPC_TYPE_STRUCT: + serializeStruct(envP, outputP, valueP, dialect); + break; + + case XMLRPC_TYPE_C_PTR: + xmlrpc_faultf(envP, "Tried to serialize a C pointer value."); + break; + + case XMLRPC_TYPE_NIL: { + const char * const elemName = + dialect == xmlrpc_dialect_apache ? "ex:nil" : "nil"; + formatOut(envP, outputP, "<%s/>", elemName); + } break; + + case XMLRPC_TYPE_DEAD: + xmlrpc_faultf(envP, "Tried to serialize a dead value."); + break; + + default: + xmlrpc_faultf(envP, "Invalid xmlrpc_value type: %d", valueP->_type); + } +} + + + +void +xmlrpc_serialize_value2(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const valueP, + xmlrpc_dialect const dialect) { +/*---------------------------------------------------------------------------- + Generate the XML to represent XML-RPC value 'valueP' in XML-RPC. + + Add it to *outputP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(outputP != NULL); + XMLRPC_ASSERT_VALUE_OK(valueP); + + addString(envP, outputP, ""); + + if (!envP->fault_occurred) { + formatValueContent(envP, outputP, valueP, dialect); + + if (!envP->fault_occurred) + addString(envP, outputP, ""); + } +} + + + +void +xmlrpc_serialize_value(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const valueP) { + + xmlrpc_serialize_value2(envP, outputP, valueP, xmlrpc_dialect_i8); +} + + + +void +xmlrpc_serialize_params2(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const paramArrayP, + xmlrpc_dialect const dialect) { +/*---------------------------------------------------------------------------- + Serialize the parameter list of an XML-RPC call. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(outputP != NULL); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + + addString(envP, outputP, ""CRLF); + if (!envP->fault_occurred) { + /* Serialize each parameter. */ + int const paramCount = xmlrpc_array_size(envP, paramArrayP); + if (!envP->fault_occurred) { + int paramSeq; + for (paramSeq = 0; + paramSeq < paramCount && !envP->fault_occurred; + ++paramSeq) { + + addString(envP, outputP, ""); + if (!envP->fault_occurred) { + xmlrpc_value * const itemP = + xmlrpc_array_get_item(envP, paramArrayP, paramSeq); + if (!envP->fault_occurred) { + xmlrpc_serialize_value2(envP, outputP, itemP, dialect); + if (!envP->fault_occurred) + addString(envP, outputP, ""CRLF); + } + } + } + } + } + + if (!envP->fault_occurred) + addString(envP, outputP, ""CRLF); +} + + + +void +xmlrpc_serialize_params(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const paramArrayP) { +/*---------------------------------------------------------------------------- + Serialize the parameter list of an XML-RPC call in the original + "i8" dialect. +-----------------------------------------------------------------------------*/ + xmlrpc_serialize_params2(envP, outputP, paramArrayP, xmlrpc_dialect_i8); +} + + + +/*========================================================================= +** xmlrpc_serialize_call +**========================================================================= +** Serialize an XML-RPC call. +*/ + +void +xmlrpc_serialize_call2(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + const char * const methodName, + xmlrpc_value * const paramArrayP, + xmlrpc_dialect const dialect) { +/*---------------------------------------------------------------------------- + Serialize an XML-RPC call of method named 'methodName' with parameter + list *paramArrayP. Use XML-RPC dialect 'dialect'. + + Append the call XML to *outputP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(outputP != NULL); + XMLRPC_ASSERT(methodName != NULL); + XMLRPC_ASSERT_VALUE_OK(paramArrayP); + + addString(envP, outputP, XML_PROLOGUE); + if (!envP->fault_occurred) { + const char * const xmlns = + dialect == xmlrpc_dialect_apache ? " " XMLNS_APACHE : ""; + formatOut(envP, outputP, ""CRLF"", xmlns); + if (!envP->fault_occurred) { + xmlrpc_mem_block * encodedP; + escapeForXml(envP, methodName, strlen(methodName), &encodedP); + if (!envP->fault_occurred) { + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, encodedP); + size_t const size = XMLRPC_MEMBLOCK_SIZE(char, encodedP); + XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, contents, size); + if (!envP->fault_occurred) { + addString(envP, outputP, ""CRLF); + if (!envP->fault_occurred) { + xmlrpc_serialize_params2(envP, outputP, paramArrayP, + dialect); + if (!envP->fault_occurred) + addString(envP, outputP, ""CRLF); + } + } + XMLRPC_MEMBLOCK_FREE(char, encodedP); + } + } + } +} + + + +void +xmlrpc_serialize_call(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + const char * const methodName, + xmlrpc_value * const paramArrayP) { + + xmlrpc_serialize_call2(envP, outputP, methodName, paramArrayP, + xmlrpc_dialect_i8); +} + + + +void +xmlrpc_serialize_response2(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const valueP, + xmlrpc_dialect const dialect) { +/*---------------------------------------------------------------------------- + Serialize a result response to an XML-RPC call. + + The result is 'valueP'. + + Add the response XML to *outputP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(outputP != NULL); + XMLRPC_ASSERT_VALUE_OK(valueP); + + addString(envP, outputP, XML_PROLOGUE); + if (!envP->fault_occurred) { + const char * const xmlns = + dialect == xmlrpc_dialect_apache ? " " XMLNS_APACHE : ""; + formatOut(envP, outputP, + ""CRLF""CRLF"", xmlns); + if (!envP->fault_occurred) { + xmlrpc_serialize_value2(envP, outputP, valueP, dialect); + if (!envP->fault_occurred) { + addString(envP, outputP, + ""CRLF""CRLF + ""CRLF); + } + } + } +} + + + +void +xmlrpc_serialize_response(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + xmlrpc_value * const valueP) { + + xmlrpc_serialize_response2(envP, outputP, valueP, xmlrpc_dialect_i8); +} + + + +void +xmlrpc_serialize_fault(xmlrpc_env * const envP, + xmlrpc_mem_block * const outputP, + const xmlrpc_env * const faultP) { +/*---------------------------------------------------------------------------- + Serialize a fault response to an XML-RPC call. + + 'faultP' is the fault. + + Add the response XML to *outputP. +-----------------------------------------------------------------------------*/ + xmlrpc_value * faultStructP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(outputP != NULL); + XMLRPC_ASSERT(faultP != NULL); + XMLRPC_ASSERT(faultP->fault_occurred); + + faultStructP = xmlrpc_build_value(envP, "{s:i,s:s}", + "faultCode", + (xmlrpc_int32) faultP->fault_code, + "faultString", faultP->fault_string); + if (!envP->fault_occurred) { + addString(envP, outputP, XML_PROLOGUE); + if (!envP->fault_occurred) { + addString(envP, outputP, ""CRLF""CRLF); + if (!envP->fault_occurred) { + xmlrpc_serialize_value(envP, outputP, faultStructP); + if (!envP->fault_occurred) { + addString(envP, outputP, + CRLF""CRLF""CRLF); + } + } + } + xmlrpc_DECREF(faultStructP); + } +} + + + +/* 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. */ diff --git a/trunk/src/xmlrpc_server_abyss.c b/trunk/src/xmlrpc_server_abyss.c new file mode 100644 index 000000000..47c7042aa --- /dev/null +++ b/trunk/src/xmlrpc_server_abyss.c @@ -0,0 +1,1374 @@ +/* Copyright information is at the end of the file */ + +#include "xmlrpc_config.h" + +#define _XOPEN_SOURCE 600 /* For strdup(), sigaction */ +#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ + +#include +#include +#include +#include +#include +#include +#include +#if MSVCRT +# include +# pragma comment(lib, "Ws2_32.lib") +#else +# include +# include +# include +# include +# include +#endif + +#include "bool.h" +#include "int.h" +#include "mallocvar.h" + +#include "xmlrpc-c/abyss.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/server_abyss.h" + +#include "abyss_handler.h" + + +struct xmlrpc_server_abyss { + TServer abyssServer; + TChanSwitch * chanSwitchP; + bool shutdownEnabled; + /* User wants system.shutdown to succeed */ +}; + + + +static void +dieIfFaultOccurred(xmlrpc_env * const envP) { + + if (envP->fault_occurred) { + fprintf(stderr, "Unexpected XML-RPC fault: %s (%d)\n", + envP->fault_string, envP->fault_code); + exit(1); + } +} + + + +static void +initAbyss(xmlrpc_env * const envP) { + + const char * error; + AbyssInit(&error); + if (error) { + xmlrpc_faultf(envP, "Failed to initialize the Abyss library. %s", + error); + xmlrpc_strfree(error); + } +} + + + +static void +termAbyss(void) { + + AbyssTerm(); +} + + + +static unsigned int globallyInitialized = 0; + /* Initialization count */ + + +void +xmlrpc_server_abyss_global_init(xmlrpc_env * const envP) { + + /* Note that this is specified as not thread safe; user calls it at + the beginning of his program, when it is only one thread. + */ + + XMLRPC_ASSERT_ENV_OK(envP); + + if (globallyInitialized == 0) + initAbyss(envP); + + ++globallyInitialized; +} + + + +void +xmlrpc_server_abyss_global_term(void) { + + /* Note that this is specified as not thread safe; user calls it at + the end of his program, when it is only one thread. + */ + + XMLRPC_ASSERT(globallyInitialized > 0); + + --globallyInitialized; + + if (globallyInitialized == 0) + termAbyss(); +} + + + +static void +validateGlobalInit(xmlrpc_env * const envP) { + + if (!globallyInitialized) + xmlrpc_faultf(envP, "libxmlrpc_server_abyss has not been globally " + "initialized. See xmlrpc_server_abyss_init()"); +} + + + +static void +processXmlrpcCall(xmlrpc_env * const envP, + void * const arg, + const char * const callXml, + size_t const callXmlLen, + TSession * const abyssSessionP, + xmlrpc_mem_block ** const responseXmlPP) { + + xmlrpc_registry * const registryP = arg; + + xmlrpc_registry_process_call2(envP, registryP, + callXml, callXmlLen, abyssSessionP, + responseXmlPP); + +} + + + +static void +setHandler(xmlrpc_env * const envP, + TServer * const srvP, + struct uriHandlerXmlrpc * const uriHandlerXmlrpcP, + size_t const xmlProcessorMaxStackSize) { + + abyss_bool success; + + xmlrpc_abyss_handler_trace( + getenv("XMLRPC_TRACE_ABYSS")); + + { + size_t const stackSize = + xmlrpc_abyss_handler_stacksize() + xmlProcessorMaxStackSize; + struct ServerReqHandler3 const handlerDesc = { + /* .term = */ &xmlrpc_termUriHandler, + /* .handleReq = */ &xmlrpc_handleIfXmlrpcReq, + /* .userdata = */ uriHandlerXmlrpcP, + /* .handleReqStackSize = */ stackSize + }; + ServerAddHandler3(srvP, &handlerDesc, &success); + } + if (!success) + xmlrpc_faultf(envP, "Abyss failed to register the Xmlrpc-c request " + "handler. ServerAddHandler3() failed."); +} + + + +static void +interpretHttpAccessControl( + const xmlrpc_server_abyss_handler_parms * const parmsP, + unsigned int const parmSize, + ResponseAccessCtl * const accessCtlP) { + + const char * allowOrigin; + bool expires; + unsigned int maxAge; + + if (parmSize >= XMLRPC_AHPSIZE(allow_origin) && parmsP->allow_origin) + allowOrigin = parmsP->allow_origin; + else + allowOrigin = NULL; + + if (parmSize >= XMLRPC_AHPSIZE(access_ctl_expires) + && parmsP->access_ctl_expires) { + expires = true; + + if (parmSize >= XMLRPC_AHPSIZE(access_ctl_max_age)) + maxAge = parmsP->access_ctl_max_age; + else + maxAge = 0; + } else { + expires = false; + maxAge = 0; /* Meaningless; just to quiet runtime memory checks */ + } + + xmlrpc_initAccessCtl(accessCtlP, allowOrigin, expires, maxAge); +} + + + +void +xmlrpc_server_abyss_set_handler3( + xmlrpc_env * const envP, + TServer * const srvP, + const xmlrpc_server_abyss_handler_parms * const parmsP, + unsigned int const parmSize) { + + struct uriHandlerXmlrpc * uriHandlerXmlrpcP; + size_t xmlProcessorMaxStackSize; + + MALLOCVAR_NOFAIL(uriHandlerXmlrpcP); + + if (!envP->fault_occurred) { + if (parmSize >= XMLRPC_AHPSIZE(xml_processor)) + uriHandlerXmlrpcP->xmlProcessor = parmsP->xml_processor; + else + xmlrpc_faultf(envP, "Parameter too short to contain the required " + "'xml_processor' member"); + } + if (!envP->fault_occurred) { + if (parmSize >= XMLRPC_AHPSIZE(xml_processor_arg)) + uriHandlerXmlrpcP->xmlProcessorArg = parmsP->xml_processor_arg; + else + xmlrpc_faultf(envP, "Parameter too short to contain the required " + "'xml_processor_arg' member"); + } + if (!envP->fault_occurred) { + if (parmSize >= XMLRPC_AHPSIZE(xml_processor_max_stack)) + xmlProcessorMaxStackSize = parmsP->xml_processor_max_stack; + else + xmlrpc_faultf(envP, "Parameter too short to contain the required " + "'xml_processor_max_stack' member"); + } + if (!envP->fault_occurred) { + if (parmSize >= XMLRPC_AHPSIZE(uri_path) && parmsP->uri_path) + uriHandlerXmlrpcP->uriPath = xmlrpc_strdupsol(parmsP->uri_path); + else + uriHandlerXmlrpcP->uriPath = xmlrpc_strdupsol("/RPC2"); + + if (parmSize >= XMLRPC_AHPSIZE(chunk_response) && + parmsP->chunk_response) + uriHandlerXmlrpcP->chunkResponse = parmsP->chunk_response; + else + uriHandlerXmlrpcP->chunkResponse = false; + + interpretHttpAccessControl(parmsP, parmSize, + &uriHandlerXmlrpcP->accessControl); + + if (envP->fault_occurred) + xmlrpc_termAccessControl(&uriHandlerXmlrpcP->accessControl); + } + if (!envP->fault_occurred) + setHandler(envP, srvP, uriHandlerXmlrpcP, xmlProcessorMaxStackSize); + + if (envP->fault_occurred) + free(uriHandlerXmlrpcP); +} + + + +void +xmlrpc_server_abyss_set_handler2( + TServer * const srvP, + const char * const uriPath, + xmlrpc_call_processor xmlProcessor, + void * const xmlProcessorArg, + size_t const xmlProcessorMaxStackSize, + xmlrpc_bool const chunkResponse) { + + xmlrpc_env env; + xmlrpc_server_abyss_handler_parms parms; + + xmlrpc_env_init(&env); + + parms.xml_processor = xmlProcessor; + parms.xml_processor_arg = xmlProcessorArg; + parms.xml_processor_max_stack = xmlProcessorMaxStackSize; + parms.uri_path = uriPath; + parms.chunk_response = chunkResponse; + + xmlrpc_server_abyss_set_handler3(&env, srvP, + &parms, XMLRPC_AHPSIZE(chunk_response)); + + if (env.fault_occurred) + abort(); + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_server_abyss_set_handler(xmlrpc_env * const envP, + TServer * const srvP, + const char * const uriPath, + xmlrpc_registry * const registryP) { + + xmlrpc_server_abyss_handler_parms parms; + + parms.xml_processor = &processXmlrpcCall; + parms.xml_processor_arg = registryP; + parms.xml_processor_max_stack = xmlrpc_registry_max_stackSize(registryP); + parms.uri_path = uriPath; + + xmlrpc_server_abyss_set_handler3(envP, srvP, + &parms, XMLRPC_AHPSIZE(uri_path)); +} + + + +void +xmlrpc_server_abyss_set_default_handler(TServer * const srvP) { + + ServerDefaultHandler(srvP, xmlrpc_serverAbyssDefaultUriHandler); +} + + + +static void +setHandlersRegistry(TServer * const srvP, + const char * const uriPath, + xmlrpc_registry * const registryP, + bool const chunkResponse, + const char * const allowOrigin, + bool const expires, + unsigned int const maxAge) { + + xmlrpc_env env; + xmlrpc_server_abyss_handler_parms parms; + + xmlrpc_env_init(&env); + + parms.xml_processor = &processXmlrpcCall; + parms.xml_processor_arg = registryP; + parms.xml_processor_max_stack = xmlrpc_registry_max_stackSize(registryP), + parms.uri_path = uriPath; + parms.chunk_response = chunkResponse; + parms.allow_origin = allowOrigin; + parms.access_ctl_expires = expires; + parms.access_ctl_max_age = maxAge; + + xmlrpc_server_abyss_set_handler3( + &env, srvP, &parms, XMLRPC_AHPSIZE(access_ctl_max_age)); + + if (env.fault_occurred) + abort(); + + xmlrpc_env_clean(&env); + + xmlrpc_server_abyss_set_default_handler(srvP); +} + + + +void +xmlrpc_server_abyss_set_handlers2(TServer * const srvP, + const char * const uriPath, + xmlrpc_registry * const registryP) { + + setHandlersRegistry(srvP, uriPath, registryP, false, NULL, false, 0); +} + + + +void +xmlrpc_server_abyss_set_handlers(TServer * const srvP, + xmlrpc_registry * const registryP) { + + setHandlersRegistry(srvP, "/RPC2", registryP, false, NULL, false, 0); +} + + + +/*============================================================================ + createServer() +============================================================================*/ + +static void +setAdditionalServerParms(const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize, + TServer * const serverP) { + + if (parmSize >= XMLRPC_APSIZE(keepalive_timeout) && + parmsP->keepalive_timeout > 0) + ServerSetKeepaliveTimeout(serverP, parmsP->keepalive_timeout); + if (parmSize >= XMLRPC_APSIZE(keepalive_max_conn) && + parmsP->keepalive_max_conn > 0) + ServerSetKeepaliveMaxConn(serverP, parmsP->keepalive_max_conn); + if (parmSize >= XMLRPC_APSIZE(timeout) && + parmsP->timeout > 0) + ServerSetTimeout(serverP, parmsP->timeout); + if (parmSize >= XMLRPC_APSIZE(dont_advertise)) + ServerSetAdvertise(serverP, !parmsP->dont_advertise); + if (parmSize >= XMLRPC_APSIZE(max_conn)) { + if (parmsP->max_conn != 0) + ServerSetMaxConn(serverP, parmsP->max_conn); + } + if (parmSize >= XMLRPC_APSIZE(max_conn_backlog)) { + if (parmsP->max_conn_backlog != 0) + ServerSetMaxConnBacklog(serverP, parmsP->max_conn_backlog); + } + if (parmSize >= XMLRPC_APSIZE(max_rpc_mem)) { + if (parmsP->max_rpc_mem != 0) + ServerSetMaxSessionMem(serverP, parmsP->max_rpc_mem); + } +} + + + +static void +extractSockAddrParms(xmlrpc_env * const envP, + const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize, + const struct sockaddr ** const sockAddrPP, + socklen_t * const sockAddrLenP, + unsigned int * const portNumberP) { +/*---------------------------------------------------------------------------- + Return the server parameters that affect the address on which the server + socket shall listen. + + There are two ways the arguments can specify this: 1) user supplies a + complete socket address, which specifies both a TCP port number and an IP + address (which determines on which interface, ergo which network, if any, + the server listens); and 2) just a TCP port number, which means he wants + to listen on all IPv4 interfaces and networks. (2) is legacy. + + If the user specifies the 'sockaddrP' and 'sockaddrlen' arguments, he gets + (1) and we ignore his 'port' argument. We return his 'sockaddrP' and + 'sockaddrlen' values as *sockAddrPP and *sockAddrLenP and nothing as + *portNumberP. + + If the user doesn't specify 'sockaddrP', he gets (2). We return NULL as + *sockAddrP and his 'port_number' argument as *portNumberP. If he doesn't + specify 'port' either, we default it to 8080. + + Specifying 'sockaddrP' and not 'sockaddrlen' is an error. + + Note that the user's socket address may indicate "any IP address." +-----------------------------------------------------------------------------*/ + if (parmSize >= XMLRPC_APSIZE(sockaddr_p)) { + if (parmSize < XMLRPC_APSIZE(sockaddrlen)) + xmlrpc_faultf(envP, "You must specify 'sockaddrlen' when you " + "specify 'sockaddrP'"); + else { + *sockAddrPP = parmsP->sockaddr_p; + *sockAddrLenP = parmsP->sockaddrlen; + } + } else + *sockAddrPP = NULL; + + if (*sockAddrPP == NULL) { + unsigned int portNumber; + + if (parmSize >= XMLRPC_APSIZE(port_number)) + portNumber = parmsP->port_number; + else + portNumber = 8080; + + if (portNumber > 0xffff) + xmlrpc_faultf(envP, + "TCP port number %u exceeds the maximum possible " + "TCP port number (65535)", + portNumber); + + *portNumberP = portNumber; + } +} + + + +static void +extractServerCreateParms( + xmlrpc_env * const envP, + const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize, + bool * const socketBoundP, + const struct sockaddr ** const sockAddrPP, + socklen_t * const sockAddrLenP, + unsigned int * const portNumberP, + TOsSocket * const socketFdP, + const char ** const logFileNameP) { + + + if (parmSize >= XMLRPC_APSIZE(socket_bound)) + *socketBoundP = parmsP->socket_bound; + else + *socketBoundP = false; + + if (*socketBoundP) { + if (parmSize < XMLRPC_APSIZE(socket_handle)) + xmlrpc_faultf(envP, "socket_bound is true, but server parameter " + "structure does not contain socket_handle (it's too " + "short)"); + else + *socketFdP = parmsP->socket_handle; + } else { + extractSockAddrParms(envP, parmsP, parmSize, sockAddrPP, sockAddrLenP, + portNumberP); + } + if (!envP->fault_occurred) { + if (parmSize >= XMLRPC_APSIZE(log_file_name) && + parmsP->log_file_name) + *logFileNameP = strdup(parmsP->log_file_name); + else + *logFileNameP = NULL; + } +} + + + +static void +chanSwitchCreateOsSocket(TOsSocket const socketFd, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + +#if MSVCRT + ChanSwitchWinCreateWinsock(socketFd, chanSwitchPP, errorP); +#else + ChanSwitchUnixCreateFd(socketFd, chanSwitchPP, errorP); +#endif + +} + + + +static void +createChanSwitchOsSocket(xmlrpc_env * const envP, + TOsSocket const socketFd, + TChanSwitch ** const chanSwitchPP) { + + const char * error; + + chanSwitchCreateOsSocket(socketFd, chanSwitchPP, &error); + + if (error) { + xmlrpc_faultf(envP, "Unable to create Abyss channel switch out of " + "file descriptor %d. %s", socketFd, error); + xmlrpc_strfree(error); + } +} + + + +static void +chanSwitchCreateSockAddr(int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + +#if MSVCRT + ChanSwitchWinCreate2(protocolFamily, sockAddrP, sockAddrLen, + chanSwitchPP, errorP); +#else + ChanSwitchUnixCreate2(protocolFamily, sockAddrP, sockAddrLen, + chanSwitchPP, errorP); +#endif + +} + + + +static void +createChanSwitchSockAddr(xmlrpc_env * const envP, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + TChanSwitch ** const chanSwitchPP) { + + int protocolFamily; + + assert(sockAddrP); + + switch (sockAddrP->sa_family) { + case AF_INET: + protocolFamily = PF_INET; + break; + case AF_INET6: + protocolFamily = PF_INET6; + break; + default: + xmlrpc_faultf(envP, "Unknown socket address family %d. " + "We know only AF_INET and AF_INET6.", + sockAddrP->sa_family); + } + + if (!envP->fault_occurred) { + const char * error; + + chanSwitchCreateSockAddr(protocolFamily, sockAddrP, sockAddrLen, + chanSwitchPP, &error); + + if (error) { + xmlrpc_faultf(envP, "Unable to create Abyss channel switch " + "given the socket address. %s", error); + xmlrpc_strfree(error); + } + } +} + + + +static void +createChanSwitchIpv4Port(xmlrpc_env * const envP, + unsigned int const portNumber, + TChanSwitch ** const chanSwitchPP) { + + struct sockaddr_in sockAddr; + const char * error; + + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons(portNumber); + sockAddr.sin_addr.s_addr = INADDR_ANY; + + chanSwitchCreateSockAddr(PF_INET, (const struct sockaddr *)&sockAddr, + sizeof(sockAddr), + chanSwitchPP, &error); + + if (error) { + xmlrpc_faultf(envP, "Unable to create Abyss channel switch " + "to listen on Port %u at any IPv4 address. %s", + portNumber, error); + xmlrpc_strfree(error); + } +} + + + +static void +createServerBare(xmlrpc_env * const envP, + const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize, + TServer * const serverP, + TChanSwitch ** const chanSwitchPP) { +/*---------------------------------------------------------------------------- + Create a bare server. It will need further setup before it is ready + to use. +-----------------------------------------------------------------------------*/ + bool socketBound; + const struct sockaddr * sockAddrP; + socklen_t sockAddrLen; + unsigned int portNumber; + TOsSocket socketFd; + const char * logFileName; + + extractServerCreateParms(envP, parmsP, parmSize, + &socketBound, + &sockAddrP, &sockAddrLen, &portNumber, &socketFd, + &logFileName); + + if (!envP->fault_occurred) { + TChanSwitch * chanSwitchP; + + if (socketBound) + createChanSwitchOsSocket(envP, socketFd, &chanSwitchP); + else { + if (sockAddrP) + createChanSwitchSockAddr(envP, sockAddrP, sockAddrLen, + &chanSwitchP); + else + createChanSwitchIpv4Port(envP, portNumber, &chanSwitchP); + } + if (!envP->fault_occurred) { + const char * error; + + ServerCreateSwitch(serverP, chanSwitchP, &error); + + if (error) { + xmlrpc_faultf(envP, "Abyss failed to create server. %s", + error); + xmlrpc_strfree(error); + } else { + *chanSwitchPP = chanSwitchP; + + ServerSetName(serverP, "XmlRpcServer"); + + if (logFileName) + ServerSetLogFileName(serverP, logFileName); + } + if (envP->fault_occurred) + ChanSwitchDestroy(chanSwitchP); + } + if (logFileName) + xmlrpc_strfree(logFileName); + } +} + + + +static const char * +uriPathParm(const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize) { + + const char * uriPath; + + if (parmSize >= XMLRPC_APSIZE(uri_path) && parmsP->uri_path) + uriPath = parmsP->uri_path; + else + uriPath = "/RPC2"; + + return uriPath; +} + + + +static bool +chunkResponseParm(const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize) { + + return + parmSize >= XMLRPC_APSIZE(chunk_response) && + parmsP->chunk_response; +} + + + +static const char * +allowOriginParm(const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize) { + + return + parmSize >= XMLRPC_APSIZE(allow_origin) ? + parmsP->allow_origin : NULL; +} + + + +static bool +expiresParm(const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize) { + + return + parmSize >= XMLRPC_APSIZE(access_ctl_expires) ? + parmsP->access_ctl_expires : false; +} + + + +static unsigned int +maxAgeParm(const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize) { + + return + parmSize >= XMLRPC_APSIZE(access_ctl_max_age) ? + parmsP->access_ctl_max_age : 0; +} + + + +static void +createServer(xmlrpc_env * const envP, + const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize, + TServer * const abyssServerP, + TChanSwitch ** const chanSwitchPP) { + + createServerBare(envP, parmsP, parmSize, abyssServerP, chanSwitchPP); + + if (!envP->fault_occurred) { + const char * error; + + setAdditionalServerParms(parmsP, parmSize, abyssServerP); + + setHandlersRegistry(abyssServerP, uriPathParm(parmsP, parmSize), + parmsP->registryP, + chunkResponseParm(parmsP, parmSize), + allowOriginParm(parmsP, parmSize), + expiresParm(parmsP, parmSize), + maxAgeParm(parmsP, parmSize)); + + ServerInit2(abyssServerP, &error); + + if (error) { + xmlrpc_faultf(envP, error); + xmlrpc_strfree(error); + } + } +} + + + +static bool +enableShutdownParm(const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize) { + + return + parmSize >= XMLRPC_APSIZE(enable_shutdown) && + parmsP->enable_shutdown; +} + + + +static xmlrpc_server_shutdown_fn shutdownAbyss; + +static void +shutdownAbyss(xmlrpc_env * const faultP, + void * const context, + const char * const comment ATTR_UNUSED, + void * const callInfo ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + Tell Abyss to wrap up whatever it's doing and shut down. + + This is a server shutdown function to be registered in the method + registry, for use by the 'system.shutdown' system method. + + After we return, Abyss will finish up the system.shutdown and any + other connections that are in progress, then the call to + ServerRun() etc. will return. + + *faultP is the result of the shutdown request, not whether we + succeeded or failed. We are not allowed to fail. +-----------------------------------------------------------------------------*/ + xmlrpc_server_abyss_t * const serverP = context; + + xmlrpc_env_init(faultP); + + if (!serverP->shutdownEnabled) + xmlrpc_env_set_fault_formatted( + faultP, XMLRPC_REQUEST_REFUSED_ERROR, + "Shutdown by client is disabled on this server."); + else + ServerTerminate(&serverP->abyssServer); +} + + + +/*============================================================================= + xmlrpc_server_abyss object methods +=============================================================================*/ + +void +xmlrpc_server_abyss_create(xmlrpc_env * const envP, + const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize, + xmlrpc_server_abyss_t ** const serverPP) { + + xmlrpc_server_abyss_t * serverP; + + XMLRPC_ASSERT_ENV_OK(envP); + + validateGlobalInit(envP); + + if (!envP->fault_occurred) { + if (parmSize < XMLRPC_APSIZE(registryP)) + xmlrpc_faultf(envP, + "You must specify members at least up through " + "'registryP' in the server parameters argument. " + "That would mean the parameter size would be >= %u " + "but you specified a size of %u", + (unsigned)XMLRPC_APSIZE(registryP), parmSize); + else { + MALLOCVAR(serverP); + + if (serverP == NULL) + xmlrpc_faultf(envP, "Unable to allocate memory for " + "server descriptor."); + else { + createServer(envP, parmsP, parmSize, + &serverP->abyssServer, &serverP->chanSwitchP); + + if (!envP->fault_occurred) { + serverP->shutdownEnabled = + enableShutdownParm(parmsP, parmSize); + + xmlrpc_registry_set_shutdown( + parmsP->registryP, &shutdownAbyss, serverP); + + if (envP->fault_occurred) + free(serverP); + else + *serverPP = serverP; + } + } + } + } +} + + + +void +xmlrpc_server_abyss_destroy(xmlrpc_server_abyss_t * const serverP) { + + XMLRPC_ASSERT(globallyInitialized); + + ServerFree(&serverP->abyssServer); + + if (serverP->chanSwitchP) + ChanSwitchDestroy(serverP->chanSwitchP); + + free(serverP); +} + + + +void +xmlrpc_server_abyss_use_sigchld(xmlrpc_server_abyss_t * const serverP) { + + ServerUseSigchld(&serverP->abyssServer); +} + + + +void +xmlrpc_server_abyss_run_server(xmlrpc_env * const envP ATTR_UNUSED, + xmlrpc_server_abyss_t * const serverP) { + + ServerRun(&serverP->abyssServer); +} + + + +void +xmlrpc_server_abyss_terminate( + xmlrpc_env * const envP ATTR_UNUSED, + xmlrpc_server_abyss_t * const serverP) { + + ServerTerminate(&serverP->abyssServer); +} + + + +void +xmlrpc_server_abyss_reset_terminate( + xmlrpc_env * const envP ATTR_UNUSED, + xmlrpc_server_abyss_t * const serverP) { + + ServerResetTerminate(&serverP->abyssServer); +} + + + +static void +sigchld(int const signalClass ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + This is a signal handler for a SIGCHLD signal (which informs us that + one of our child processes has terminated). + + The only child processes we have are those that belong to the Abyss + server (and then only if the Abyss server was configured to use + forking as a threading mechanism), so we respond by passing the + signal on to the Abyss server. And reaping the dead child. +-----------------------------------------------------------------------------*/ +#if !MSVCRT + /* Reap zombie children / report to Abyss until there aren't any more. */ + + bool childrenLeft; + bool error; + + assert(signalClass == SIGCHLD); + + error = false; + childrenLeft = true; /* initial assumption */ + + /* Reap defunct children until there aren't any more. */ + while (childrenLeft && !error) { + int status; + pid_t pid; + + pid = waitpid((pid_t) -1, &status, WNOHANG); + + if (pid == 0) + childrenLeft = false; + else if (pid < 0) { + /* because of ptrace */ + if (errno != EINTR) + error = true; + } else + ServerHandleSigchld(pid); + } +#endif /* MSVCRT */ +} + + +struct xmlrpc_server_abyss_sig { + + /* A description of the state of the process' signal handlers before + functions in this library messed with them; useful for restoring + them later. + */ +#if MSVCRT + int dummy; +#else + struct sigaction pipe; + struct sigaction chld; +#endif +}; + + + +static void +setupSignalHandlers(xmlrpc_server_abyss_sig * const oldHandlersP) { +#if !MSVCRT + struct sigaction mysigaction; + + sigemptyset(&mysigaction.sa_mask); + mysigaction.sa_flags = 0; + + /* This signal indicates connection closed in the middle */ + mysigaction.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &mysigaction, &oldHandlersP->pipe); + + /* This signal indicates a child process (request handler) has died */ + mysigaction.sa_handler = sigchld; + sigaction(SIGCHLD, &mysigaction, &oldHandlersP->chld); +#endif +} + + + +static void +restoreSignalHandlers(const xmlrpc_server_abyss_sig * const oldHandlersP) { +#if !MSVCRT + sigaction(SIGPIPE, &oldHandlersP->pipe, NULL); + sigaction(SIGCHLD, &oldHandlersP->chld, NULL); + +#endif +} + + + +void +xmlrpc_server_abyss_setup_sig( + xmlrpc_env * const envP, + xmlrpc_server_abyss_t * const serverP, + xmlrpc_server_abyss_sig ** const oldHandlersPP) { + + xmlrpc_server_abyss_sig * oldHandlersP; + + XMLRPC_ASSERT_ENV_OK(envP); + + validateGlobalInit(envP); + + if (!envP->fault_occurred) { + MALLOCVAR(oldHandlersP); + + if (oldHandlersP == NULL) + xmlrpc_faultf(envP, "Unable to allocate memory to save signal " + "handling state."); + else { + setupSignalHandlers(oldHandlersP); + + xmlrpc_server_abyss_use_sigchld(serverP); + } + if (oldHandlersPP) + *oldHandlersPP = oldHandlersP; + else + free(oldHandlersP); + } +} + + + +void +xmlrpc_server_abyss_restore_sig( + const xmlrpc_server_abyss_sig * const oldHandlersP) { + + restoreSignalHandlers(oldHandlersP); +} + + + +static void +runServerDaemon(TServer * const serverP, + runfirstFn const runfirst, + void * const runfirstArg) { + + xmlrpc_server_abyss_sig oldHandlers; + + setupSignalHandlers(&oldHandlers); + + ServerUseSigchld(serverP); + + ServerDaemonize(serverP); + + /* We run the user supplied runfirst after forking, but before accepting + connections (helpful when running with threads) + */ + if (runfirst) + runfirst(runfirstArg); + + ServerRun(serverP); + + restoreSignalHandlers(&oldHandlers); +} + + + +static void +oldHighLevelAbyssRun(xmlrpc_env * const envP, + const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize) { +/*---------------------------------------------------------------------------- + This is the old deprecated interface, where the caller of the + xmlrpc_server_abyss API supplies an Abyss configuration file and + we use it to daemonize (fork into the background, chdir, set uid, etc.) + and run the Abyss server. + + The new preferred interface, implemented by normalLevelAbyssRun(), + instead lets Caller set up the process environment himself and pass + Abyss parameters in memory. That's a more conventional and + flexible API. +-----------------------------------------------------------------------------*/ + TServer server; + abyss_bool success; + + success = ServerCreate(&server, "XmlRpcServer", 8080, DEFAULT_DOCS, NULL); + + if (!success) + xmlrpc_faultf(envP, "Failed to create Abyss server object"); + else { + runfirstFn runfirst; + void * runfirstArg; + + assert(parmSize >= XMLRPC_APSIZE(config_file_name)); + + ConfReadServerFile(parmsP->config_file_name, &server); + + assert(parmSize >= XMLRPC_APSIZE(registryP)); + + setHandlersRegistry(&server, "/RPC2", parmsP->registryP, false, NULL, + false, 0); + + ServerInit(&server); + + if (parmSize >= XMLRPC_APSIZE(runfirst_arg)) { + runfirst = parmsP->runfirst; + runfirstArg = parmsP->runfirst_arg; + } else { + runfirst = NULL; + runfirstArg = NULL; + } + runServerDaemon(&server, runfirst, runfirstArg); + + ServerFree(&server); + } +} + + + +static void +normalLevelAbyssRun(xmlrpc_env * const envP, + const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize) { + + xmlrpc_server_abyss_t * serverP; + + xmlrpc_server_abyss_create(envP, parmsP, parmSize, &serverP); + + if (!envP->fault_occurred) { + xmlrpc_server_abyss_sig * oldHandlersP; + + xmlrpc_server_abyss_setup_sig(envP, serverP, &oldHandlersP); + + if (!envP->fault_occurred) { + xmlrpc_server_abyss_run_server(envP, serverP); + + xmlrpc_server_abyss_restore_sig(oldHandlersP); + + free(oldHandlersP); + } + xmlrpc_server_abyss_destroy(serverP); + } +} + + + +void +xmlrpc_server_abyss(xmlrpc_env * const envP, + const xmlrpc_server_abyss_parms * const parmsP, + unsigned int const parmSize) { +/*---------------------------------------------------------------------------- + Note that this is not re-entrant and not thread-safe, because of the + global library initialization. If you want to run a server inside + a thread of a multi-threaded program, use + xmlrpc_server_abyss_create() instead. As required by that + subroutine, your program will contain a call to + xmlrpc_server_abyss_global_init() early in your program, when it is only + one thread. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + + xmlrpc_server_abyss_global_init(envP); + + if (!envP->fault_occurred) { + if (parmSize < XMLRPC_APSIZE(registryP)) + xmlrpc_faultf(envP, + "You must specify members at least up through " + "'registryP' in the server parameters argument. " + "That would mean the parameter size would be >= %u " + "but you specified a size of %u", + (unsigned)XMLRPC_APSIZE(registryP), parmSize); + else { + if (parmsP->config_file_name) + oldHighLevelAbyssRun(envP, parmsP, parmSize); + else + normalLevelAbyssRun(envP, parmsP, parmSize); + } + xmlrpc_server_abyss_global_term(); + } +} + + + +/*========================================================================= + XML-RPC Server Method Registry + + This is an old deprecated form of the server facilities that uses + global variables. +=========================================================================*/ + +/* These global variables must be treated as read-only after the + server has started. +*/ + +static TServer globalSrv; + /* When you use the old interface (xmlrpc_server_abyss_init(), etc.), + this is the Abyss server to which they refer. Obviously, there can be + only one Abyss server per program using this interface. + */ + +static xmlrpc_registry * builtin_registryP; + + + +void +xmlrpc_server_abyss_init_registry(void) { + + /* This used to just create the registry and Caller would be + responsible for adding the handlers that use it. + + But that isn't very modular -- the handlers and registry go + together; there's no sense in using the built-in registry and + not the built-in handlers because if you're custom building + something, you can just make your own regular registry. So now + we tie them together, and we don't export our handlers. + */ + xmlrpc_env env; + + xmlrpc_env_init(&env); + builtin_registryP = xmlrpc_registry_new(&env); + dieIfFaultOccurred(&env); + xmlrpc_env_clean(&env); + + setHandlersRegistry(&globalSrv, "/RPC2", builtin_registryP, false, NULL, + false, 0); +} + + + +xmlrpc_registry * +xmlrpc_server_abyss_registry(void) { + + /* This is highly deprecated. If you want to mess with a registry, + make your own with xmlrpc_registry_new() -- don't mess with the + internal one. + */ + return builtin_registryP; +} + + + +/* A quick & easy shorthand for adding a method. */ +void +xmlrpc_server_abyss_add_method(char * const method_name, + xmlrpc_method const method, + void * const user_data) { + xmlrpc_env env; + + xmlrpc_env_init(&env); + xmlrpc_registry_add_method(&env, builtin_registryP, NULL, method_name, + method, user_data); + dieIfFaultOccurred(&env); + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_server_abyss_add_method_w_doc(char * const method_name, + xmlrpc_method const method, + void * const user_data, + char * const signature, + char * const help) { + + xmlrpc_env env; + xmlrpc_env_init(&env); + xmlrpc_registry_add_method_w_doc( + &env, builtin_registryP, NULL, method_name, + method, user_data, signature, help); + dieIfFaultOccurred(&env); + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_server_abyss_init(int const flags ATTR_UNUSED, + const char * const config_file) { + + abyss_bool success; + + success = ServerCreate(&globalSrv, "XmlRpcServer", 8080, + DEFAULT_DOCS, NULL); + + if (!success) + abort(); + else { + ConfReadServerFile(config_file, &globalSrv); + + xmlrpc_server_abyss_init_registry(); + /* Installs /RPC2 handler and default handler that use the + built-in registry. + */ + + ServerInit(&globalSrv); + } +} + + + +void +xmlrpc_server_abyss_run_first(runfirstFn const runfirst, + void * const runfirstArg) { + + runServerDaemon(&globalSrv, runfirst, runfirstArg); +} + + + +void +xmlrpc_server_abyss_run(void) { + runServerDaemon(&globalSrv, NULL, NULL); +} + + + +/* +** Copyright (C) 2001 by First Peer, Inc. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. +** +** There is more copyright information in the bottom half of this file. +** Please see it for more details. +*/ diff --git a/trunk/src/xmlrpc_server_cgi.c b/trunk/src/xmlrpc_server_cgi.c new file mode 100644 index 000000000..00ca5042f --- /dev/null +++ b/trunk/src/xmlrpc_server_cgi.c @@ -0,0 +1,331 @@ +/* Copyright (C) 2001 by Eric Kidd. All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +** SUCH DAMAGE. */ + + +#include "xmlrpc_config.h" + +#include +#include +#include + +/* Windows NT stdout binary mode fix. */ +#if MSVCRT +#include +#include +#endif + +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/server_cgi.h" + + +/*========================================================================= +** Output Routines +**========================================================================= +** These routines send various kinds of responses to the server. +*/ + +static void +send_xml(const char * const xml_data, + size_t const xml_len) { +#if MSVCRT + _setmode(_fileno(stdout), _O_BINARY); +#endif + /* Send our CGI headers back to the server. + ** XXX - Coercing 'size_t' to 'unsigned long' might be unsafe under + ** really weird circumstances. */ + fprintf(stdout, "Status: 200 OK\n"); + /* Handle authentication cookie being sent back. */ + if (getenv("HTTP_COOKIE_AUTH") != NULL) + fprintf(stdout, "Set-Cookie: auth=%s\n", getenv("HTTP_COOKIE_AUTH")); + fprintf(stdout, "Content-type: text/xml; charset=\"utf-8\"\n"); + fprintf(stdout, "Content-length: %ld\n\n", (unsigned long) xml_len); + + /* Blast out our data. */ + fwrite(xml_data, sizeof(char), xml_len, stdout); +} + + + +static void +send_error(int const code, + const char * const message, + xmlrpc_env * const env) { + +#if MSVCRT + _setmode(_fileno(stdout), _O_BINARY); +#endif + /* Send an error header. */ + fprintf(stdout, "Status: %d %s\n", code, message); + fprintf(stdout, "Content-type: text/html\n\n"); + + /* Send an error message. */ + fprintf(stdout, "%d %s\n", code, message); + fprintf(stdout, "

%d %s

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

An error occurred processing your request.

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

XML-RPC Fault #%d: %s

\n", + env->fault_code, env->fault_string); +} + + +/*========================================================================= +** die_if_fault_occurred +**========================================================================= +** Certain kinds of errors aren't worth the trouble of generating +** an XML-RPC fault. For these, we just send status 500 to our web server +** and log the fault to our server log. +*/ + +static void +die_if_fault_occurred(xmlrpc_env * const env) { + if (env->fault_occurred) { + fprintf(stderr, "Unexpected XML-RPC fault: %s (%d)\n", + env->fault_string, env->fault_code); + send_error(500, "Internal Server Error", env); + exit(1); + } +} + + +/*========================================================================= +** Initialization, Cleanup & Method Registry +**========================================================================= +** These are all related, so we group them together. +*/ + +static xmlrpc_registry * globalRegistryP; + +/*========================================================================= +** get_body +**========================================================================= +** Slurp the body of the request into an xmlrpc_mem_block. +*/ + +static xmlrpc_mem_block * +get_body(xmlrpc_env * const env, + size_t const length) { + + xmlrpc_mem_block *result; + char *contents; + size_t count; + + XMLRPC_ASSERT_ENV_OK(env); + + /* Error-handling preconditions. */ + result = NULL; + +#if MSVCRT + /* Fix from Jeff Stewart: NT opens stdin and stdout in text mode + by default, badly confusing our length calculations. So we need + to set the file handle to binary. + */ + _setmode(_fileno(stdin), _O_BINARY); +#endif + /* XXX - Puke if length is too big. */ + + /* Allocate our memory block. */ + result = xmlrpc_mem_block_new(env, length); + XMLRPC_FAIL_IF_FAULT(env); + contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, result); + + /* Get our data off the network. + ** XXX - Coercing 'size_t' to 'unsigned long' might be unsafe under + ** really weird circumstances. */ + count = fread(contents, sizeof(char), length, stdin); + if (count < length) + XMLRPC_FAIL2(env, XMLRPC_INTERNAL_ERROR, + "Expected %ld bytes, received %ld", + (unsigned long) length, (unsigned long) count); + + cleanup: + if (env->fault_occurred) { + if (result) + xmlrpc_mem_block_free(result); + return NULL; + } + return result; +} + + + +void +xmlrpc_server_cgi_process_call(xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Get the XML-RPC call from Standard Input and environment variables, + parse it, find the right method, call it, prepare an XML-RPC + response with the result, and write it to Standard Output. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + char *method, *type, *length_str; + int length; + xmlrpc_mem_block *input, *output; + char *input_data, *output_data; + size_t input_size, output_size; + int code; + char *message; + + /* Error-handling preconditions. */ + xmlrpc_env_init(&env); + input = output = NULL; + + /* Set up a default error message. */ + code = 500; message = "Internal Server Error"; + + /* Get our HTTP information from the environment. */ + method = getenv("REQUEST_METHOD"); + type = getenv("CONTENT_TYPE"); + length_str = getenv("CONTENT_LENGTH"); + + /* Perform some sanity checks. */ + if (!method || !xmlrpc_streq(method, "POST")) { + code = 405; message = "Method Not Allowed"; + XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Expected HTTP method POST"); + } + if (!type || !xmlrpc_strneq(type, "text/xml", strlen("text/xml"))) { + char *template = "Expected content type: \"text/xml\", received: \"%s\""; + size_t err_len = strlen(template) + strlen(type) + 1; + char *err = malloc(err_len); + + XMLRPC_SNPRINTF(err, err_len, template, type); + code = 400; message = "Bad Request"; + XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, err); + free(err); + } + if (!length_str) { + code = 411; message = "Length Required"; + XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Content-length required"); + } + + /* Get our content length. */ + length = atoi(length_str); + if (length <= 0) { + code = 400; message = "Bad Request"; + XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Content-length must be > 0"); + } + + /* SECURITY: Make sure our content length is legal. + ** XXX - We can cast 'input_len' because we know it's >= 0, yes? */ + if ((size_t) length > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) { + code = 400; message = "Bad Request"; + XMLRPC_FAIL(&env, XMLRPC_LIMIT_EXCEEDED_ERROR, + "XML-RPC request too large"); + } + + /* Get our body. */ + input = get_body(&env, length); + XMLRPC_FAIL_IF_FAULT(&env); + input_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, input); + input_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, input); + + /* Process our call. */ + xmlrpc_registry_process_call2(&env, registryP, + input_data, input_size, NULL, &output); + XMLRPC_FAIL_IF_FAULT(&env); + output_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output); + output_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); + + /* Send our data. */ + send_xml(output_data, output_size); + + cleanup: + if (input) + xmlrpc_mem_block_free(input); + if (output) + xmlrpc_mem_block_free(output); + + if (env.fault_occurred) + send_error(code, message, &env); + + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_cgi_init(int const flags ATTR_UNUSED) { + xmlrpc_env env; + + xmlrpc_env_init(&env); + globalRegistryP = xmlrpc_registry_new(&env); + die_if_fault_occurred(&env); + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_cgi_cleanup(void) { + xmlrpc_registry_free(globalRegistryP); +} + + + +xmlrpc_registry * +xmlrpc_cgi_registry(void) { + return globalRegistryP; +} + + + +void +xmlrpc_cgi_add_method(const char * const method_name, + xmlrpc_method const method, + void * const user_data) { + xmlrpc_env env; + xmlrpc_env_init(&env); + xmlrpc_registry_add_method(&env, globalRegistryP, NULL, method_name, + method, user_data); + die_if_fault_occurred(&env); + xmlrpc_env_clean(&env); +} + + + +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) { + xmlrpc_env env; + xmlrpc_env_init(&env); + xmlrpc_registry_add_method_w_doc(&env, globalRegistryP, NULL, method_name, + method, user_data, signature, help); + die_if_fault_occurred(&env); + xmlrpc_env_clean(&env); +} + + + +void +xmlrpc_cgi_process_call(void) { + + xmlrpc_server_cgi_process_call(globalRegistryP); +} diff --git a/trunk/src/xmlrpc_server_info.c b/trunk/src/xmlrpc_server_info.c new file mode 100644 index 000000000..2e06c025d --- /dev/null +++ b/trunk/src/xmlrpc_server_info.c @@ -0,0 +1,350 @@ +/*============================================================================= + xmlrpc_server_info +=============================================================================== + The xmlrpc_server_info class. + + By Bryan Henderson, San Jose CA 2007.10.17. + + Contributed to the public domain by its author + + The xmlrpc_server_info class was originally just supposed to be + information about an HTTP server, hence the name. But we think of it + now as a generic carriage parameter, as in the C++ library. In + the future, it should be a union or maybe contain an opaque pointer + to the carriage parameter for a particular kind of transport. That + way, the client XML transports can be more than just HTTP XML + transports. +=============================================================================*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include + +#include "bool.h" +#include "mallocvar.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/client_int.h" + + + +xmlrpc_server_info * +xmlrpc_server_info_new(xmlrpc_env * const envP, + const char * const serverUrl) { + + xmlrpc_server_info * serverInfoP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(serverUrl); + + MALLOCVAR(serverInfoP); + if (serverInfoP == NULL) + xmlrpc_faultf(envP, "Couldn't allocate memory for xmlrpc_server_info"); + else { + serverInfoP->serverUrl = strdup(serverUrl); + if (serverInfoP->serverUrl == NULL) + xmlrpc_faultf(envP, "Couldn't allocate memory for server URL"); + else { + serverInfoP->allowedAuth.basic = false; + serverInfoP->allowedAuth.digest = false; + serverInfoP->allowedAuth.gssnegotiate = false; + serverInfoP->allowedAuth.ntlm = false; + serverInfoP->userNamePw = NULL; + serverInfoP->basicAuthHdrValue = NULL; + if (envP->fault_occurred) + xmlrpc_strfree(serverInfoP->serverUrl); + } + if (envP->fault_occurred) + free(serverInfoP); + } + return serverInfoP; +} + + + +static void +copyUserNamePw(xmlrpc_env * const envP, + const char * const src, + const char ** const dstP) { + + if (src == NULL) + *dstP = NULL; + else { + *dstP = strdup(src); + if (*dstP == NULL) + xmlrpc_faultf(envP, "Couldn't allocate memory for user name/pw"); + } +} + + + +static void +freeIfNonNull(const char * const arg) { + + if (arg) + xmlrpc_strfree(arg); +} + + + +static void +copyBasicAuthHdrValue(xmlrpc_env * const envP, + const char * const src, + const char ** const dstP) { + + if (src == NULL) + *dstP = NULL; + else { + *dstP = strdup(src); + if (*dstP == NULL) + xmlrpc_faultf(envP, "Couldn't allocate memory " + "for authentication header value"); + } +} + + + +static void +copyServerInfoContent(xmlrpc_env * const envP, + xmlrpc_server_info * const dstP, + const xmlrpc_server_info * const srcP) { + + dstP->serverUrl = strdup(srcP->serverUrl); + if (dstP->serverUrl == NULL) + xmlrpc_faultf(envP, "Couldn't allocate memory for server URL"); + else { + copyUserNamePw(envP, srcP->userNamePw, &dstP->userNamePw); + + if (!envP->fault_occurred) { + copyBasicAuthHdrValue(envP, srcP->basicAuthHdrValue, + &dstP->basicAuthHdrValue); + + if (!envP->fault_occurred) { + dstP->allowedAuth.basic = + srcP->allowedAuth.basic; + dstP->allowedAuth.digest = + srcP->allowedAuth.digest; + dstP->allowedAuth.gssnegotiate = + srcP->allowedAuth.gssnegotiate; + dstP->allowedAuth.ntlm = + srcP->allowedAuth.ntlm; + + if (envP->fault_occurred) + freeIfNonNull(dstP->basicAuthHdrValue); + } + if (envP->fault_occurred) + freeIfNonNull(dstP->userNamePw); + } + if (envP->fault_occurred) + xmlrpc_strfree(dstP->serverUrl); + } +} + + + +xmlrpc_server_info * +xmlrpc_server_info_copy(xmlrpc_env * const envP, + xmlrpc_server_info * const srcP) { + + xmlrpc_server_info * serverInfoP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(srcP); + + MALLOCVAR(serverInfoP); + if (serverInfoP == NULL) + xmlrpc_faultf(envP, + "Couldn't allocate memory for xmlrpc_server_info"); + else { + copyServerInfoContent(envP, serverInfoP, srcP); + + if (envP->fault_occurred) + free(serverInfoP); + } + return serverInfoP; +} + + + +void +xmlrpc_server_info_free(xmlrpc_server_info * const serverInfoP) { + + XMLRPC_ASSERT_PTR_OK(serverInfoP); + XMLRPC_ASSERT(serverInfoP->serverUrl != XMLRPC_BAD_POINTER); + + if (serverInfoP->userNamePw) + xmlrpc_strfree(serverInfoP->userNamePw); + serverInfoP->userNamePw = XMLRPC_BAD_POINTER; + + if (serverInfoP->basicAuthHdrValue) + xmlrpc_strfree(serverInfoP->basicAuthHdrValue); + serverInfoP->basicAuthHdrValue = XMLRPC_BAD_POINTER; + + xmlrpc_strfree(serverInfoP->serverUrl); + serverInfoP->serverUrl = XMLRPC_BAD_POINTER; + + free(serverInfoP); +} + + + +void +xmlrpc_server_info_set_user(xmlrpc_env * const envP, + xmlrpc_server_info * const serverInfoP, + const char * const username, + const char * const password) { + + const char * userNamePw; + xmlrpc_mem_block * userNamePw64; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_PTR_OK(serverInfoP); + XMLRPC_ASSERT_PTR_OK(username); + XMLRPC_ASSERT_PTR_OK(password); + + xmlrpc_asprintf(&userNamePw, "%s:%s", username, password); + + userNamePw64 = + xmlrpc_base64_encode_without_newlines(envP, + (unsigned char*) userNamePw, + strlen(userNamePw)); + if (!envP->fault_occurred) { + const char * const data = XMLRPC_MEMBLOCK_CONTENTS(char, userNamePw64); + size_t const len = XMLRPC_MEMBLOCK_SIZE(char, userNamePw64); + const char * const authType = "Basic "; + + char * hdrValue; + + hdrValue = malloc(strlen(authType) + len + 1); + if (hdrValue == NULL) + xmlrpc_faultf(envP, "Could not allocate memory to store " + "authorization header value."); + else { + strcpy(hdrValue, authType); + strncat(hdrValue, data, len); + + if (serverInfoP->basicAuthHdrValue) + xmlrpc_strfree(serverInfoP->basicAuthHdrValue); + + serverInfoP->basicAuthHdrValue = hdrValue; + } + XMLRPC_MEMBLOCK_FREE(char, userNamePw64); + } + if (serverInfoP->userNamePw) + xmlrpc_strfree(serverInfoP->userNamePw); + + serverInfoP->userNamePw = userNamePw; +} + + + +void +xmlrpc_server_info_set_basic_auth(xmlrpc_env * const envP, + xmlrpc_server_info * const serverInfoP, + const char * const username, + const char * const password) { + + xmlrpc_server_info_set_user(envP, serverInfoP, username, password); + + if (!envP->fault_occurred) { + serverInfoP->allowedAuth.basic = true; + serverInfoP->allowedAuth.digest = false; + serverInfoP->allowedAuth.gssnegotiate = false; + serverInfoP->allowedAuth.ntlm = false; + } +} + + + +void +xmlrpc_server_info_allow_auth_basic(xmlrpc_env * const envP, + xmlrpc_server_info * const sP) { + + if (sP->userNamePw == NULL) + xmlrpc_faultf(envP, "You must set username/password with " + "xmlrpc_server_info_set_user()"); + else + sP->allowedAuth.basic = true; +} + + + +void +xmlrpc_server_info_disallow_auth_basic( + xmlrpc_env * const envP ATTR_UNUSED, + xmlrpc_server_info * const sP) { + + sP->allowedAuth.basic = false; +} + + + +void +xmlrpc_server_info_allow_auth_digest(xmlrpc_env * const envP, + xmlrpc_server_info * const sP) { + + if (sP->userNamePw == NULL) + xmlrpc_faultf(envP, "You must set username/password with " + "xmlrpc_server_info_set_user()"); + else + sP->allowedAuth.digest = true; +} + + + +void +xmlrpc_server_info_disallow_auth_digest( + xmlrpc_env * const envP ATTR_UNUSED, + xmlrpc_server_info * const sP) { + + sP->allowedAuth.digest = false; +} + + + +void +xmlrpc_server_info_allow_auth_negotiate(xmlrpc_env * const envP, + xmlrpc_server_info * const sP) { + + if (sP->userNamePw == NULL) + xmlrpc_faultf(envP, "You must set username/password with " + "xmlrpc_server_info_set_user()"); + else + sP->allowedAuth.gssnegotiate = true; +} + + + +void +xmlrpc_server_info_disallow_auth_negotiate( + xmlrpc_env * const envP ATTR_UNUSED, + xmlrpc_server_info * const sP) { + + sP->allowedAuth.gssnegotiate = false; +} + + + +void +xmlrpc_server_info_allow_auth_ntlm(xmlrpc_env * const envP, + xmlrpc_server_info * const sP) { + + if (sP->userNamePw == NULL) + xmlrpc_faultf(envP, "You must set username/password with " + "xmlrpc_server_info_set_user()"); + else + sP->allowedAuth.ntlm = true; +} + + + +void +xmlrpc_server_info_disallow_auth_ntlm( + xmlrpc_env * const envP ATTR_UNUSED, + xmlrpc_server_info * const sP) { + + sP->allowedAuth.ntlm = true; +} diff --git a/trunk/src/xmlrpc_server_w32httpsys.c b/trunk/src/xmlrpc_server_w32httpsys.c new file mode 100644 index 000000000..7e96d208b --- /dev/null +++ b/trunk/src/xmlrpc_server_w32httpsys.c @@ -0,0 +1,1016 @@ +/* Copyright information is at end of file. */ + +/* 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 XML-RPC server program, it is safe to exclude the + xmlrpc_server_w32httpsys.c file from the xmlrpc project and you will not + have this dependency. 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 UNICODE +#define UNICODE +#endif + +#ifndef _UNICODE +#define _UNICODE +#endif + +/* Declare that we require the Windows XP SP2 or better version of the + interface to Windows. + + Microsoft recommends + (http://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx) defining + NTDDI_VERSION instead of _WIN32_WINNT for this purpose, but as it was + invented recently, it's pretty useless. Windows header files from old + Windows SDKs won't know what to do with it. +*/ +#define _WIN32_WINNT 0x0502 + +/* See compilation note above if the compiler doesn't find this header file */ +#include +#include + +#include "xmlrpc_config.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "xmlrpc-c/server_w32httpsys.h" +#include "version.h" + +#pragma comment( lib, "httpapi" ) +#pragma message( "Compiling HTTPS server ..." ) + +/* XXX - This variable is *not* currently threadsafe. Once the server has +** been started, it must be treated as read-only. */ +static xmlrpc_registry *global_registryP; + +//set TRUE if you want a log +static BOOL g_bDebug; +//set log filename +static char g_fLogFile[MAX_PATH]; +//do you want OutputDebugString() to be called? +static BOOL g_bDebugString; + +// +// Macros. +// +#define INITIALIZE_HTTP_RESPONSE( resp, status, reason ) \ + do \ + { \ + RtlZeroMemory( (resp), sizeof(*(resp)) ); \ + (resp)->StatusCode = (status); \ + (resp)->pReason = (reason); \ + (resp)->ReasonLength = (USHORT) strlen(reason); \ + } while (FALSE) + + +#define ADD_KNOWN_HEADER(Response, HeaderId, RawValue) \ + do \ + { \ + (Response).Headers.KnownHeaders[(HeaderId)].pRawValue = (RawValue); \ + (Response).Headers.KnownHeaders[(HeaderId)].RawValueLength = \ + (USHORT) strlen(RawValue); \ + } while(FALSE) + +#define ALLOC_MEM(cb) HeapAlloc(GetProcessHeap(), 0, (cb)) +#define FREE_MEM(ptr) HeapFree(GetProcessHeap(), 0, (ptr)) + +// +// Prototypes for Internal Functions. +// +DWORD +DoReceiveRequests( + HANDLE hReqQueue, + const xmlrpc_server_httpsys_parms * const parmsP + ); + +DWORD +SendHttpResponse( + IN HANDLE hReqQueue, + IN PHTTP_REQUEST pRequest, + IN USHORT StatusCode, + IN PSTR pReason, + IN PSTR pEntity + ); + +DWORD +SendHttpResponseAuthRequired( + IN HANDLE hReqQueue, + IN PHTTP_REQUEST pRequest + ); + +void +processRPCCall( + xmlrpc_env * const envP, + IN HANDLE hReqQueue, + IN PHTTP_REQUEST pRequest + ); + +__inline void TraceA(const char *format, ...); +__inline void TraceW(const wchar_t *format, ...); + + +// +// External Function Implementation. +// + +void +xmlrpc_server_httpsys( + xmlrpc_env * const envP, + const xmlrpc_server_httpsys_parms * const parmsP, + unsigned int const parm_size + ) +{ + ULONG retCode; + HANDLE hReqQueue = NULL; + HTTPAPI_VERSION HttpApiVersion = HTTPAPI_VERSION_1; + WCHAR wszURL[35]; + + XMLRPC_ASSERT_ENV_OK(envP); + + if (parm_size < XMLRPC_HSSIZE(authfn)) + { + xmlrpc_faultf(envP, + "You must specify members at least up through " + "'authfn' in the server parameters argument. " + "That would mean the parameter size would be >= %u " + "but you specified a size of %u", + XMLRPC_HSSIZE(authfn), parm_size); + return; + } + + //Set logging options + if (parmsP->logLevel>0) + g_bDebug=TRUE; + else + g_bDebug=FALSE; + + if (parmsP->logLevel>1) + g_bDebugString=TRUE; + else + g_bDebugString=FALSE; + + if (!parmsP->logFile) + g_bDebug=FALSE; + else + StringCchPrintfA(g_fLogFile,MAX_PATH,parmsP->logFile); + + //construct the URL we are listening on + if (parmsP->useSSL!=0) + StringCchPrintf(wszURL,35,L"https://+:%u/RPC2",parmsP->portNum); + else + StringCchPrintf(wszURL,35,L"http://+:%u/RPC2",parmsP->portNum); + + global_registryP = parmsP->registryP; + + // Initialize HTTP APIs. + retCode = HttpInitialize(HttpApiVersion, + HTTP_INITIALIZE_SERVER, // Flags + NULL // Reserved + ); + if (retCode != NO_ERROR) + { + xmlrpc_faultf(envP, "HttpInitialize failed with %lu", + retCode); + return; + } + + // Create a Request Queue Handle + retCode = HttpCreateHttpHandle(&hReqQueue, // Req Queue + 0 // Reserved + ); + if (retCode != NO_ERROR) + { + xmlrpc_faultf(envP, "HttpCreateHttpHandle failed with %lu", retCode); + goto CleanUp; + } + + retCode = HttpAddUrl(hReqQueue, // Req Queue + wszURL, // Fully qualified URL + NULL // Reserved + ); + + if (retCode != NO_ERROR) + { + xmlrpc_faultf(envP, "HttpAddUrl failed with %lu", retCode); + goto CleanUp; + } + + TraceW(L"we are listening for requests on the following url: %ws", + wszURL); + + // Loop while receiving requests + for(;;) + { + TraceW(L"Calling DoReceiveRequests()"); + retCode = DoReceiveRequests(hReqQueue, parmsP); + if(NO_ERROR == retCode) + { + TraceW(L"DoReceiveRequests() returned NO_ERROR, breaking"); + break; + } + } + +CleanUp: + + TraceW(L"Tearing down the server.", wszURL); + + // Call HttpRemoveUrl for the URL that we added. + HttpRemoveUrl( hReqQueue, wszURL ); + + // Close the Request Queue handle. + if(hReqQueue) + CloseHandle(hReqQueue); + + // Call HttpTerminate. + HttpTerminate(HTTP_INITIALIZE_SERVER, NULL); + return; +} + +// +// Internal Function Implementations. +// + +__inline void TraceA(const char *format, ...) +{ + if(g_bDebug) + { + if (format) + { + va_list arglist; + char str[4096]; + + va_start(arglist, format); + StringCchVPrintfA(str, sizeof(str), format, arglist); + StringCbCatA(str, sizeof(str), "\n"); + if (g_fLogFile) + { + FILE *fout = fopen(g_fLogFile, "a+t"); + if (fout) + { + fprintf(fout, str); + fclose(fout); + } + } + + printf(str); + + if (g_bDebugString) + { + + OutputDebugStringA(str); + } + + va_end(arglist); + } + } +} + +__inline void TraceW(const wchar_t *format, ...) +{ + if(g_bDebug) + { + if (format) + { + va_list arglist; + wchar_t str[4096]; + + va_start(arglist, format); + StringCchVPrintfW(str, 4096, format, arglist); + StringCbCatW(str, sizeof(str), L"\n"); + if (g_fLogFile) + { + FILE *fout = fopen(g_fLogFile, "a+t"); + if (fout) + { + fwprintf(fout, str); + fclose(fout); + } + } + + wprintf(str); + + if (g_bDebugString) + { + OutputDebugStringW(str); + } + + va_end(arglist); + } + } +} + +/* + * This is a blocking function that merely sits on the request queue + * for our URI and processes them one at a time. Once a request comes + * in, we check it for content-type, content-length, and verb. As long + * as the initial validations are done, we pass the request to the + * processRPCCall() function, which collects the body of the request + * and processes it. If we get an error back other than network type, + * we are responsible for notifing the client. + */ +DWORD +DoReceiveRequests( + IN HANDLE hReqQueue, + const xmlrpc_server_httpsys_parms * const parmsP + ) +{ + ULONG result; + HTTP_REQUEST_ID requestId; + DWORD bytesRead; + PHTTP_REQUEST pRequest; + PCHAR pRequestBuffer; + ULONG RequestBufferLength; + xmlrpc_env env; + char szHeaderBuf[255]; + long lContentLength; + + // Allocate a 2K buffer. Should be good for most requests, we'll grow + // this if required. We also need space for a HTTP_REQUEST structure. + RequestBufferLength = sizeof(HTTP_REQUEST) + 2048; + pRequestBuffer = (PCHAR) ALLOC_MEM( RequestBufferLength ); + if (pRequestBuffer == NULL) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + + pRequest = (PHTTP_REQUEST)pRequestBuffer; + + // Wait for a new request -- This is indicated by a NULL request ID. + HTTP_SET_NULL_ID( &requestId ); + for(;;) + { + RtlZeroMemory(pRequest, RequestBufferLength); + + result = HttpReceiveHttpRequest( + hReqQueue, // Req Queue + requestId, // Req ID + 0, // Flags + pRequest, // HTTP request buffer + RequestBufferLength,// req buffer length + &bytesRead, // bytes received + NULL // LPOVERLAPPED + ); + + if(NO_ERROR == result) + { + // Got a request with a filled buffer. + switch(pRequest->Verb) + { + case HttpVerbPOST: + + TraceW(L"Got a POST request for %ws", + pRequest->CookedUrl.pFullUrl); + + //Check if we need use authorization. + if(parmsP->authfn) + { + xmlrpc_env_init(&env); + if(pRequest->Headers.KnownHeaders[ + HttpHeaderAuthorization].RawValueLength + < 6) + { + xmlrpc_env_set_fault( + &env, XMLRPC_REQUEST_REFUSED_ERROR, + "Authorization header too short."); + } + else + { + //unencode the headers + if(_strnicmp( + "basic", + pRequest->Headers.KnownHeaders[ + HttpHeaderAuthorization].pRawValue,5) + !=0) + { +#ifndef NDEBUG + PCHAR pTmp = (PCHAR) + ALLOC_MEM(pRequest->Headers.KnownHeaders[ + HttpHeaderAuthorization + ].RawValueLength + 1 ); + if( pTmp ) { + strncpy(pTmp, + pRequest->Headers.KnownHeaders[ + HttpHeaderAuthorization + ].pRawValue, + pRequest->Headers.KnownHeaders[ + HttpHeaderAuthorization + ].RawValueLength ); + pTmp[pRequest->Headers.KnownHeaders[ + HttpHeaderAuthorization + ].RawValueLength] = 0; + TraceA("Got HEADER [%s]",pTmp); + FREE_MEM(pTmp); + } +#endif /* #ifndef NDEBUG */ + xmlrpc_env_set_fault( + &env, XMLRPC_REQUEST_REFUSED_ERROR, + "Authorization header does not start " + "with type 'basic'!"); + } + else + { + xmlrpc_mem_block * decoded; + + decoded = + xmlrpc_base64_decode( + &env, + pRequest->Headers.KnownHeaders[ + HttpHeaderAuthorization + ].pRawValue+6, + pRequest->Headers.KnownHeaders[ + HttpHeaderAuthorization + ].RawValueLength-6); + if(!env.fault_occurred) + { + char *pDecodedStr; + char *pUser; + char *pPass; + char *pColon; + + pDecodedStr = (char*) + malloc(xmlrpc_mem_block_size(decoded)+1); + memcpy(pDecodedStr, + xmlrpc_mem_block_contents(decoded), + xmlrpc_mem_block_size(decoded)); + pDecodedStr[xmlrpc_mem_block_size(decoded)]='\0'; + pUser = pPass = pDecodedStr; + pColon=strchr(pDecodedStr,':'); + if(pColon) + { + *pColon='\0'; + pPass=pColon+1; + //The authfn should set env to + //fail if auth is denied. + parmsP->authfn(&env,pUser,pPass); + } + else + { + xmlrpc_env_set_fault( + &env, + XMLRPC_REQUEST_REFUSED_ERROR, + "Decoded auth not of the correct " + "format."); + } + free(pDecodedStr); + } + if(decoded) + XMLRPC_MEMBLOCK_FREE(char, decoded); + } + } + if(env.fault_occurred) + { + //request basic authorization, as the user + //did not provide it. + xmlrpc_env_clean(&env); + TraceW(L"POST request did not provide valid " + L"authorization header."); + result = + SendHttpResponseAuthRequired( hReqQueue, + pRequest); + break; + } + xmlrpc_env_clean(&env); + } + + //Check content type to make sure it is text/xml. + memcpy(szHeaderBuf, + pRequest->Headers.KnownHeaders[ + HttpHeaderContentType + ].pRawValue, + pRequest->Headers.KnownHeaders[ + HttpHeaderContentType + ].RawValueLength); + szHeaderBuf[pRequest->Headers.KnownHeaders[ + HttpHeaderContentType + ].RawValueLength] = '\0'; + if (_stricmp(szHeaderBuf,"text/xml")!=0) + { + //We handle only text/xml data. Anything else + //is not valid. + TraceW(L"POST request had an unrecognized " + L"content-type: %s", szHeaderBuf); + result = SendHttpResponse( + hReqQueue, + pRequest, + 400, + "Bad Request", + NULL + ); + break; + } + + //Check content length to make sure it exists and + //is not too big. + memcpy(szHeaderBuf, + pRequest->Headers.KnownHeaders[ + HttpHeaderContentLength + ].pRawValue, + pRequest->Headers.KnownHeaders[ + HttpHeaderContentLength + ].RawValueLength); + szHeaderBuf[pRequest->Headers.KnownHeaders[ + HttpHeaderContentLength + ].RawValueLength]='\0'; + lContentLength = atol(szHeaderBuf); + if (lContentLength<=0) + { + //Make sure a content length was supplied. + TraceW(L"POST request did not include a " + L"content-length", szHeaderBuf); + result = SendHttpResponse( + hReqQueue, + pRequest, + 411, + "Length Required", + NULL + ); + break; + } + if((size_t) lContentLength > + xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) + { + //Content-length is too big for us to handle + TraceW(L"POST request content-length is too big " + L"for us to handle: %d bytes", + lContentLength); + result = SendHttpResponse( + hReqQueue, + pRequest, + 500, + "content-length too large", + NULL + ); + break; + } + + //our initial validations of POST, content-type, + //and content-length all check out. Collect and + //pass the complete buffer to the XMLRPC-C library + + xmlrpc_env_init(&env); + processRPCCall(&env,hReqQueue, pRequest); + if (env.fault_occurred) + { + //if we fail and it is anything other than a + //network error, we should return a failure + //response to the client. + if (env.fault_code != XMLRPC_NETWORK_ERROR) + { + if (env.fault_string) + result = SendHttpResponse( + hReqQueue, + pRequest, + 500, + env.fault_string, + NULL + ); + else + result = SendHttpResponse( + hReqQueue, + pRequest, + 500, + "Unknown Error", + NULL + ); + } + } + + xmlrpc_env_clean(&env); + break; + + default: + //We handle only POST data. Anything else is not valid. + TraceW(L"Got an unrecognized Verb request for URI %ws", + pRequest->CookedUrl.pFullUrl); + + result = SendHttpResponse( + hReqQueue, + pRequest, + 405, + "Method Not Allowed", + NULL + ); + break; + } + if(result != NO_ERROR) + { + break; + } + + // Reset the Request ID so that we pick up the next request. + HTTP_SET_NULL_ID( &requestId ); + } + else if(result == ERROR_MORE_DATA) + { + // The input buffer was too small to hold the request headers + // We have to allocate more buffer & call the API again. + // + // When we call the API again, we want to pick up the request + // that just failed. This is done by passing a RequestID. + // This RequestID is picked from the old buffer. + requestId = pRequest->RequestId; + + // Free the old buffer and allocate a new one. + RequestBufferLength = bytesRead; + FREE_MEM( pRequestBuffer ); + pRequestBuffer = (PCHAR) ALLOC_MEM( RequestBufferLength ); + + if (pRequestBuffer == NULL) + { + result = ERROR_NOT_ENOUGH_MEMORY; + break; + } + + pRequest = (PHTTP_REQUEST)pRequestBuffer; + + } + else if(ERROR_CONNECTION_INVALID == result && + !HTTP_IS_NULL_ID(&requestId)) + { + // The TCP connection got torn down by the peer when we were + // trying to pick up a request with more buffer. We'll just move + // onto the next request. + HTTP_SET_NULL_ID( &requestId ); + } + else + { + break; + } + + } // for(;;) + + if(pRequestBuffer) + { + FREE_MEM( pRequestBuffer ); + } + + return result; +} + +/* + * SendHttpResponse sends a text/html content type back with + * the user specified status code and reason. Used for returning + * errors to clients. + */ +DWORD +SendHttpResponse( + IN HANDLE hReqQueue, + IN PHTTP_REQUEST pRequest, + IN USHORT StatusCode, + IN PSTR pReason, + IN PSTR pEntityString + ) +{ + HTTP_RESPONSE response; + HTTP_DATA_CHUNK dataChunk; + DWORD result; + DWORD bytesSent; + CHAR szServerHeader[20]; + + // Initialize the HTTP response structure. + INITIALIZE_HTTP_RESPONSE(&response, StatusCode, pReason); + + ADD_KNOWN_HEADER(response, HttpHeaderContentType, "text/html"); + + StringCchPrintfA(szServerHeader, sizeof(szServerHeader), "Xmlrpc-c/%s", + XMLRPC_C_VERSION); + ADD_KNOWN_HEADER(response, HttpHeaderServer, szServerHeader); + + if(pEntityString) + { + // Add an entity chunk + dataChunk.DataChunkType = HttpDataChunkFromMemory; + dataChunk.FromMemory.pBuffer = pEntityString; + dataChunk.FromMemory.BufferLength = (ULONG) strlen(pEntityString); + + response.EntityChunkCount = 1; + response.pEntityChunks = &dataChunk; + } + + // Since we are sending all the entity body in one call, we don't have + // to specify the Content-Length. + result = HttpSendHttpResponse( + hReqQueue, // ReqQueueHandle + pRequest->RequestId, // Request ID + 0, // Flags + &response, // HTTP response + NULL, // pReserved1 + &bytesSent, // bytes sent (OPTIONAL) + NULL, // pReserved2 (must be NULL) + 0, // Reserved3 (must be 0) + NULL, // LPOVERLAPPED (OPTIONAL) + NULL // pReserved4 (must be NULL) + ); + + if(result != NO_ERROR) + { + TraceW(L"HttpSendHttpResponse failed with %lu", result); + } + + return result; +} + +/* SendHttpResponseAuthRequired sends a 401 status code requesting + * authorization + */ + +DWORD +SendHttpResponseAuthRequired( + IN HANDLE hReqQueue, + IN PHTTP_REQUEST pRequest + ) +{ + HTTP_RESPONSE response; + DWORD result; + DWORD bytesSent; + CHAR szServerHeader[20]; + + // Initialize the HTTP response structure. + INITIALIZE_HTTP_RESPONSE(&response, 401, "Authentication Required"); + + // Add the WWW_Authenticate header. + ADD_KNOWN_HEADER(response, HttpHeaderWwwAuthenticate, + "Basic realm=\"xmlrpc\""); + + StringCchPrintfA(szServerHeader, sizeof(szServerHeader), "Xmlrpc-c/%s", + XMLRPC_C_VERSION); + ADD_KNOWN_HEADER(response, HttpHeaderServer, szServerHeader); + + // Since we are sending all the entity body in one call, we don't have + // to specify the Content-Length. + result = HttpSendHttpResponse( + hReqQueue, // ReqQueueHandle + pRequest->RequestId, // Request ID + 0, // Flags + &response, // HTTP response + NULL, // pReserved1 + &bytesSent, // bytes sent (OPTIONAL) + NULL, // pReserved2 (must be NULL) + 0, // Reserved3 (must be 0) + NULL, // LPOVERLAPPED (OPTIONAL) + NULL // pReserved4 (must be NULL) + ); + + if(result != NO_ERROR) + { + TraceW(L"SendHttpResponseAuthRequired failed with %lu", result); + } + + return result; +} + +/* + * processRPCCall() is called after some validations. The assumption is that + * the request is an HTTP post of content-type text/xml with a content-length + * that is less than the maximum the library can handle. + * + * The caller should check the error status, and if the error was other than + * a network type, respond back to the client to let them know the call failed. + */ +void +processRPCCall( + xmlrpc_env * const envP, + IN HANDLE hReqQueue, + IN PHTTP_REQUEST pRequest + ) +{ + HTTP_RESPONSE response; + DWORD result; + DWORD bytesSent; + PUCHAR pEntityBuffer; + ULONG EntityBufferLength; + ULONG BytesRead; +#define MAX_ULONG_STR ((ULONG) sizeof("4294967295")) + CHAR szContentLength[MAX_ULONG_STR]; + CHAR szServerHeader[20]; + HTTP_DATA_CHUNK dataChunk; + ULONG TotalBytesRead = 0; + xmlrpc_mem_block * body; + xmlrpc_mem_block * output; + + BytesRead = 0; + body = NULL; + output = NULL; + + // Allocate some space for an entity buffer. + EntityBufferLength = 2048; + pEntityBuffer = (PUCHAR) ALLOC_MEM( EntityBufferLength ); + if (pEntityBuffer == NULL) + { + xmlrpc_faultf(envP, "Out of Memory"); + goto Done; + } + + // NOTE: If we had passed the HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY + // flag with HttpReceiveHttpRequest(), the entity would have + // been a part of HTTP_REQUEST (using the pEntityChunks field). + // Since we have not passed that flag, we can be assured that + // there are no entity bodies in HTTP_REQUEST. + if(pRequest->Flags & HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS) + { + //Allocate some space for an XMLRPC memory block. + body = xmlrpc_mem_block_new(envP, 0); + if (envP->fault_occurred) + goto Done; + + // The entity body can be sent over multiple calls. Let's collect all + // of these in a buffer and send the buffer to the xmlrpc-c library + do + { + // Read the entity chunk from the request. + BytesRead = 0; + result = HttpReceiveRequestEntityBody( + hReqQueue, + pRequest->RequestId, + 0, + pEntityBuffer, + EntityBufferLength, + &BytesRead, + NULL + ); + switch(result) + { + case NO_ERROR: + if(BytesRead != 0) + { + XMLRPC_MEMBLOCK_APPEND(char, envP, body, + pEntityBuffer, BytesRead); + if(envP->fault_occurred) + goto Done; + } + break; + + case ERROR_HANDLE_EOF: + // We have read the last request entity body. We can now + // process the suppossed XMLRPC data. + if(BytesRead != 0) + { + XMLRPC_MEMBLOCK_APPEND(char, envP, body, + pEntityBuffer, BytesRead); + if(envP->fault_occurred) + goto Done; + } + + // We will send the response over multiple calls. + // This is achieved by passing the + // HTTP_SEND_RESPONSE_FLAG_MORE_DATA flag. + + // NOTE: Since we are accumulating the TotalBytesRead in + // a ULONG, this will not work for entity bodies that + // are larger than 4 GB. To work with large entity + // bodies, we would have to use a ULONGLONG. + TraceA("xmlrpc_server RPC2 handler processing " + "RPC request."); + + // Process the RPC. + xmlrpc_registry_process_call2( + envP, global_registryP, + XMLRPC_MEMBLOCK_CONTENTS(char, body), + XMLRPC_MEMBLOCK_SIZE(char, body), + NULL, + &output); + if (envP->fault_occurred) + goto Done; + + // Initialize the HTTP response structure. + INITIALIZE_HTTP_RESPONSE(&response, 200, "OK"); + + //Add the content-length + StringCchPrintfA(szContentLength,MAX_ULONG_STR, "%lu", + XMLRPC_MEMBLOCK_SIZE(char, output)); + ADD_KNOWN_HEADER( + response, + HttpHeaderContentLength, + szContentLength ); + + //Add the content-type + ADD_KNOWN_HEADER(response, HttpHeaderContentType, + "text/xml"); + + StringCchPrintfA(szServerHeader, sizeof(szServerHeader), + "Xmlrpc-c/%s", XMLRPC_C_VERSION); + ADD_KNOWN_HEADER(response, HttpHeaderServer, + szServerHeader); + + //send the response + result = HttpSendHttpResponse( + hReqQueue, // ReqQueueHandle + pRequest->RequestId, // Request ID + HTTP_SEND_RESPONSE_FLAG_MORE_DATA, + &response, // HTTP response + NULL, // pReserved1 + &bytesSent, // bytes sent (optional) + NULL, // pReserved2 + 0, // Reserved3 + NULL, // LPOVERLAPPED + NULL // pReserved4 + ); + if(result != NO_ERROR) + { + TraceW(L"HttpSendHttpResponse failed with %lu", + result); + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_NETWORK_ERROR, + "HttpSendHttpResponse failed with %lu", result); + goto Done; + } + + // Send entity body from a memory chunk. + dataChunk.DataChunkType = HttpDataChunkFromMemory; + dataChunk.FromMemory.BufferLength = + (ULONG)XMLRPC_MEMBLOCK_SIZE(char, output); + dataChunk.FromMemory.pBuffer = + XMLRPC_MEMBLOCK_CONTENTS(char, output); + + result = HttpSendResponseEntityBody( + hReqQueue, + pRequest->RequestId, + 0, // This is the last send. + 1, // Entity Chunk Count. + &dataChunk, + NULL, + NULL, + 0, + NULL, + NULL + ); + if(result != NO_ERROR) + { + TraceW(L"HttpSendResponseEntityBody failed " + L"with %lu", result); + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_NETWORK_ERROR, + "HttpSendResponseEntityBody failed with %lu", + result); + goto Done; + } + goto Done; + break; + default: + TraceW(L"HttpReceiveRequestEntityBody failed with %lu", + result); + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_NETWORK_ERROR, + "HttpReceiveRequestEntityBody failed " + "with %lu", result); + goto Done; + } + } while(TRUE); + } + else + { + // This request does not have an entity body. + TraceA("Received a bad request (no body in HTTP post)."); + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_PARSE_ERROR, + "Bad POST request (no body)"); + goto Done; + } + +Done: + + if(pEntityBuffer) + FREE_MEM(pEntityBuffer); + + if(output) + XMLRPC_MEMBLOCK_FREE(char, output); + + if(body) + XMLRPC_MEMBLOCK_FREE(char, body); + + return; +} + + + +/* 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. */ + diff --git a/trunk/src/xmlrpc_string.c b/trunk/src/xmlrpc_string.c new file mode 100644 index 000000000..e6e007166 --- /dev/null +++ b/trunk/src/xmlrpc_string.c @@ -0,0 +1,993 @@ +/*============================================================================= + xmlrpc_string +=============================================================================== + Routines for the "string" type of xmlrpc_value. + + By Bryan Henderson. + + Contributed to the public domain by its author. +=============================================================================*/ + +#include "xmlrpc_config.h" + +#include +#include +#include +#include +#include + +#include "bool.h" +#include "mallocvar.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "xmlrpc-c/string_int.h" +#include "xmlrpc-c/util.h" + + + +void +xmlrpc_destroyString(xmlrpc_value * const valueP) { + + if (valueP->_wcs_block) + xmlrpc_mem_block_free(valueP->_wcs_block); + + xmlrpc_mem_block_free(valueP->blockP); +} + + + +static void +verifyNoNulls(xmlrpc_env * const envP, + const char * const contents, + unsigned int const len) { +/*---------------------------------------------------------------------------- + Verify that the character array 'contents', which is 'len' bytes long, + does not contain any NUL characters, which means it can be made into + a passable ASCIIZ string just by adding a terminating NUL. + + Fail if the array contains a NUL. +-----------------------------------------------------------------------------*/ + unsigned int i; + + for (i = 0; i < len && !envP->fault_occurred; ++i) + if (contents[i] == '\0') + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, + "String must not contain NUL characters"); +} + + + +#if HAVE_UNICODE_WCHAR + +static void +verifyNoNullsW(xmlrpc_env * const envP, + const wchar_t * const contents, + unsigned int const len) { +/*---------------------------------------------------------------------------- + Same as verifyNoNulls(), but for wide characters. +-----------------------------------------------------------------------------*/ + unsigned int i; + + for (i = 0; i < len && !envP->fault_occurred; i++) + if (contents[i] == '\0') + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, + "String must not contain NUL characters"); +} +#endif + + + +static void +validateStringType(xmlrpc_env * const envP, + const xmlrpc_value * const valueP) { + + if (valueP->_type != XMLRPC_TYPE_STRING) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " + "string type was expected.", + xmlrpc_type_name(valueP->_type)); + } +} + + + +static void +accessStringValue(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + size_t * const lengthP, + const char ** const contentsP) { + + validateStringType(envP, valueP); + if (!envP->fault_occurred) { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); + size_t const len = size - 1; + /* The memblock has a null character added to the end */ + + verifyNoNulls(envP, contents, len); + + *lengthP = len; + *contentsP = contents; + } +} + + + +void +xmlrpc_read_string(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + const char ** const stringValueP) { +/*---------------------------------------------------------------------------- + Read the value of an XML-RPC string as an ASCIIZ string, with + LF for line delimiters. + + Return the string in newly malloc'ed storage that Caller must free. + + Fail if the string contains null characters (which means it wasn't + really a string, but XML-RPC doesn't seem to understand what a string + is, and such values are possible). +-----------------------------------------------------------------------------*/ + size_t length; + const char * contents; + + accessStringValue(envP, valueP, &length, &contents); + + if (!envP->fault_occurred) { + char * stringValue; + + MALLOCARRAY(stringValue, length + 1); + if (stringValue == NULL) + xmlrpc_faultf(envP, "Unable to allocate space " + "for %u-character string", (unsigned)length); + else { + memcpy(stringValue, contents, length); + stringValue[length] = '\0'; + + *stringValueP = stringValue; + } + } +} + + + +static unsigned int +lineDelimCount(const char * const start, + const char * const end) { + + unsigned int count; + const char * p; + + for (p = start, count = 0; p < end; ) { + const char * const nlPos = memchr(p, '\n', end-p); + if (nlPos) { + ++count; + p = nlPos + 1; + } else + p = end; + } + + return count; +} + + + +static void +copyAndConvertLfToCrlf(xmlrpc_env * const envP, + size_t const srcLen, + const char * const src, + size_t * const dstLenP, + const char ** const dstP) { + + const char * const srcEnd = src + srcLen; + unsigned int const nLineDelim = lineDelimCount(src, srcEnd); + size_t const dstLen = srcLen + nLineDelim; + char * dst; + + MALLOCARRAY(dst, dstLen + 1); + if (dst == NULL) + xmlrpc_faultf(envP, "Unable to allocate space " + "for %u-character string", (unsigned)dstLen + 1); + else { + const char * p; /* source pointer */ + char * q; /* destination pointer */ + + for (p = &src[0], q = &dst[0]; p < srcEnd; ++p) { + if (*p == '\n') + *q++ = '\r'; + + *q++ = *p; + } + XMLRPC_ASSERT(q == dst + dstLen); + + *q = '\0'; + + *dstP = dst; + *dstLenP = dstLen; + } +} + + + +void +xmlrpc_read_string_crlf(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + const char ** const stringValueP) { +/*---------------------------------------------------------------------------- + Same as xmlrpc_read_string(), but return CRLF instead of LF for + line delimiters. +-----------------------------------------------------------------------------*/ + size_t length; + const char * contents; + + accessStringValue(envP, valueP, &length, &contents); + + if (!envP->fault_occurred) { + size_t stringLen; + + copyAndConvertLfToCrlf(envP, length, contents, + &stringLen, stringValueP); + } +} + + + +void +xmlrpc_read_string_old(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + const char ** const stringValueP) { +/*---------------------------------------------------------------------------- + Like xmlrpc_read_string(), except it returns as *stringValueP a pointer + into memory owned by *valueP, rather than new memory to be owned by + Caller. + + This is for internal use; it's necessary to implement the deprecated + xmlrpc_parse_value(), which also returns pointers to someone else's + storage. +-----------------------------------------------------------------------------*/ + size_t length; + accessStringValue(envP, valueP, &length, stringValueP); +} + + + +void +xmlrpc_read_string_lp(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + size_t * const lengthP, + const char ** const stringValueP) { + + validateStringType(envP, valueP); + if (!envP->fault_occurred) { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); + + char * stringValue; + + stringValue = malloc(size); + if (stringValue == NULL) + xmlrpc_faultf(envP, "Unable to allocate %u bytes for string.", + (unsigned int)size); + else { + memcpy(stringValue, contents, size); + *stringValueP = stringValue; + *lengthP = size - 1; /* Size includes terminating NUL */ + } + } +} + + + +void +xmlrpc_read_string_lp_crlf(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + size_t * const lengthP, + const char ** const stringValueP) { + + validateStringType(envP, valueP); + if (!envP->fault_occurred) { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP); /* Includes NUL */ + const char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); + + copyAndConvertLfToCrlf(envP, size-1, contents, + lengthP, stringValueP); + } +} + + + +void +xmlrpc_read_string_lp_old(xmlrpc_env * const envP, + const xmlrpc_value * const valueP, + size_t * const lengthP, + const char ** const stringValueP) { +/*---------------------------------------------------------------------------- + This is to xmlrpc_read_string_lp() as xmlrpc_read_string_old() is + to xmlrpc_read_string(). +-----------------------------------------------------------------------------*/ + validateStringType(envP, valueP); + if (!envP->fault_occurred) { + *lengthP = XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP) - 1; + *stringValueP = XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); + } +} + + + +static __inline__ void +setupWcsBlock(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { +/*---------------------------------------------------------------------------- + Add a wcs block (wchar_t string) to the indicated xmlrpc_value if it + doesn't have one already. +-----------------------------------------------------------------------------*/ + if (!valueP->_wcs_block) { + char * const contents = + XMLRPC_MEMBLOCK_CONTENTS(char, valueP->blockP); + size_t const len = + XMLRPC_MEMBLOCK_SIZE(char, valueP->blockP) - 1; + valueP->_wcs_block = + xmlrpc_utf8_to_wcs(envP, contents, len + 1); + } +} + + + +#if HAVE_UNICODE_WCHAR + +static void +accessStringValueW(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + size_t * const lengthP, + const wchar_t ** const stringValueP) { + + validateStringType(envP, valueP); + if (!envP->fault_occurred) { + setupWcsBlock(envP, valueP); + + if (!envP->fault_occurred) { + wchar_t * const wcontents = + XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); + size_t const len = + XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block) - 1; + + verifyNoNullsW(envP, wcontents, len); + + *lengthP = len; + *stringValueP = wcontents; + } + } +} + + + +void +xmlrpc_read_string_w(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + const wchar_t ** const stringValueP) { + + size_t length; + const wchar_t * wcontents; + + accessStringValueW(envP, valueP, &length, &wcontents); + + if (!envP->fault_occurred) { + wchar_t * stringValue; + MALLOCARRAY(stringValue, length + 1); + if (stringValue == NULL) + xmlrpc_faultf(envP, "Unable to allocate space for %u-byte string", + (unsigned)length); + else { + memcpy(stringValue, wcontents, length * sizeof(wchar_t)); + stringValue[length] = '\0'; + + *stringValueP = stringValue; + } + } +} + + + +static unsigned int +lineDelimCountW(const wchar_t * const start, + const wchar_t * const end) { + + unsigned int count; + const wchar_t * p; + + count = 0; + p = start; + + while (p && p < end) { + /* We used to use memchr(), but Windows doesn't have it */ + p = wcsstr(p, L"\n"); + if (p && p < end) { + ++count; /* count the newline */ + ++p; /* skip the newline */ + } + } + + return count; +} + + + +static void +wCopyAndConvertLfToCrlf(xmlrpc_env * const envP, + size_t const srcLen, + const wchar_t * const src, + size_t * const dstLenP, + const wchar_t ** const dstP) { + + const wchar_t * const srcEnd = src + srcLen; + unsigned int const nLineDelim = lineDelimCountW(src, srcEnd); + size_t const dstLen = srcLen + nLineDelim; + wchar_t * dst; + + MALLOCARRAY(dst, dstLen + 1); + if (dst == NULL) + xmlrpc_faultf(envP, "Unable to allocate space " + "for %u-character string", (unsigned)dstLen + 1); + else { + const wchar_t * p; /* source pointer */ + wchar_t * q; /* destination pointer */ + + for (p = &src[0], q = &dst[0]; p < srcEnd; ++p) { + if (*p == '\n') + *q++ = '\r'; + + *q++ = *p; + } + XMLRPC_ASSERT(q == dst + dstLen); + + *q = '\0'; + + *dstP = dst; + *dstLenP = dstLen; + } +} + + + +void +xmlrpc_read_string_w_crlf(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + const wchar_t ** const stringValueP) { + + size_t size; + const wchar_t * contents; + + accessStringValueW(envP, valueP, &size, &contents); + + if (!envP->fault_occurred) { + size_t stringLen; + + wCopyAndConvertLfToCrlf(envP, size, contents, + &stringLen, stringValueP); + } +} + + + +void +xmlrpc_read_string_w_old(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + const wchar_t ** const stringValueP) { +/*---------------------------------------------------------------------------- + This is to xmlrpc_read_string_w() as xmlrpc_read_string_old() is + to xmlrpc_read_string(). +-----------------------------------------------------------------------------*/ + size_t length; + + accessStringValueW(envP, valueP, &length, stringValueP); +} + + + +void +xmlrpc_read_string_w_lp(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + size_t * const lengthP, + const wchar_t ** const stringValueP) { + + validateStringType(envP, valueP); + if (!envP->fault_occurred) { + setupWcsBlock(envP, valueP); + + if (!envP->fault_occurred) { + wchar_t * const wcontents = + XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block); + + wchar_t * stringValue; + + MALLOCARRAY(stringValue, size); + if (stringValue == NULL) + xmlrpc_faultf(envP, + "Unable to allocate space for %u-byte string", + (unsigned int)size); + else { + memcpy(stringValue, wcontents, size * sizeof(wchar_t)); + + *lengthP = size - 1; /* size includes terminating NUL */ + *stringValueP = stringValue; + } + } + } +} + + + +void +xmlrpc_read_string_w_lp_crlf(xmlrpc_env * const envP, + xmlrpc_value * const valueP, + size_t * const lengthP, + const wchar_t ** const stringValueP) { + + validateStringType(envP, valueP); + if (!envP->fault_occurred) { + setupWcsBlock(envP, valueP); + + if (!envP->fault_occurred) { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block); + wchar_t * const wcontents = + XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); + + wCopyAndConvertLfToCrlf(envP, size-1, wcontents, + lengthP, 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) { +/*---------------------------------------------------------------------------- + This is to xmlrpc_read_string_w_lp() as xmlrpc_read_string_old() is + to xmlrpc_read_string(). +-----------------------------------------------------------------------------*/ + validateStringType(envP, valueP); + if (!envP->fault_occurred) { + setupWcsBlock(envP, valueP); + + if (!envP->fault_occurred) { + wchar_t * const wcontents = + XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block); + + *lengthP = size - 1; /* size includes terminating NUL */ + *stringValueP = wcontents; + } + } +} +#endif /* HAVE_UNICODE_WCHAR */ + + + +void +xmlrpc_string_validate(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { +/*---------------------------------------------------------------------------- + Validate that *valueP is not the kind of value that would serialize into + invalid XML. + + To wit, the string does not contain any characters that are not valid XML + characters, which means it does not contain ASCII control characters + other than carriage return, line feed, and tab. + + Xmlrpc-c has the odd function, because of mistakes that were made in the + early days of XML-RPC, that it is possible to cause it to generate an + XML-RPC call or response that is invalid XML, which you do with a string + value which contains things other than XML characters. But it's a really + bad idea to exercise that option, so code that constructs string values can + use this function to ensure that it does not. See the discussion of the + string data type in the Xmlrpc-c user's guide for a detailed explanation of + this issue. +-----------------------------------------------------------------------------*/ + enum {LF = 0x0a, CR = 0x0d, TAB = 0x08}; + + size_t length; + const char * contents; + + accessStringValue(envP, valueP, &length, &contents); + + if (!envP->fault_occurred) { + unsigned int i; + for (i = 0; i < length && !envP->fault_occurred; ++i) { + char const c = contents[i]; + if (iscntrl(c) && c != LF && c != CR && c != TAB) + xmlrpc_faultf(envP, "String contains an invalid value " + "(Not a Unicode codepoint for a legal XML " + "character) x%02x at position %u", + c, i); + } + } +} + + + +static void +copyLines(xmlrpc_env * const envP, + const char * const src, + size_t const srcLen, + xmlrpc_mem_block ** const dstPP) { +/*---------------------------------------------------------------------------- + Generate the internal representation of string xmlrpc_value contents for + string 'src', which is 'srcLen' characters long and has lines separated by + LF, CR, and/or CRLF. Return it as a new xmlrpc_mem_block at *dstPP. + + Note that the source format differs from the destination format in + that in the destination format, lines are separated only by newline + (LF). + + It is tempting to believe that if we just put the user's line + delimiters in the xmlrpc_value here (i.e. where user has CRLF, the + xmlrpc_value also has CRLF), the user's line delimiters would go + all the way across to the XML-RPC partner. But that won't work, + because the XML processor on the other side will, following Section + 2.11 of the XML spec, normalize all line endings to LF anyhow. So + then you might ask, why do we bother to do all the work to convert + them here? Because: besides just being logically cleaner, this way + xmlrpc_read_string() gets the proper value -- the same one the + XML-RPC partner would see. +-----------------------------------------------------------------------------*/ + /* Destination format is sometimes smaller than source (because + CRLF turns into LF), but never smaller. So we allocate + destination space equal to source size (plus one for + terminating NUL), but don't necessarily use it all. + */ + + /* To convert LF, CR, and CRLF to LF, all we have to do is + copy everything up to a CR verbatim, then insert an LF and + skip the CR and any following LF, and repeat. + */ + + xmlrpc_mem_block * dstP; + + dstP = XMLRPC_MEMBLOCK_NEW(char, envP, srcLen + 1); + + if (!envP->fault_occurred) { + const char * const srcEnd = &src[srcLen]; + char * const contents = XMLRPC_MEMBLOCK_CONTENTS(char, dstP); + + const char * srcCursor; + char * dstCursor; + + for (srcCursor = &src[0], dstCursor = &contents[0]; + srcCursor < srcEnd;) { + + char * const crPos = memchr(srcCursor, '\r', srcEnd - srcCursor); + + if (crPos) { + size_t const copyLen = crPos - srcCursor; + memcpy(dstCursor, srcCursor, copyLen); + srcCursor += copyLen; + dstCursor += copyLen; + + *(dstCursor++) = '\n'; + + XMLRPC_ASSERT(*srcCursor == '\r'); + ++srcCursor; /* Move past CR */ + if (*srcCursor == '\n') + ++srcCursor; /* Move past LF */ + } else { + size_t const remainingLen = srcEnd - srcCursor; + memcpy(dstCursor, srcCursor, remainingLen); + srcCursor += remainingLen; + dstCursor += remainingLen; + } + } + + *dstCursor++ = '\0'; + + XMLRPC_ASSERT((unsigned)(dstCursor - &contents[0]) <= srcLen + 1); + + XMLRPC_MEMBLOCK_RESIZE(char, envP, dstP, dstCursor - &contents[0]); + + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, dstP); + } + *dstPP = dstP; +} + + + +static void +copySimple(xmlrpc_env * const envP, + const char * const src, + size_t const srcLen, + xmlrpc_mem_block ** const dstPP) { +/*---------------------------------------------------------------------------- + Generate the internal representation of string xmlrpc_value contents for + string 'src', which is 'srcLen' characters long and, conveniently enough, + has the exact same format as the internal representation. + + To wit, 'src' has lines separated by LFs only -- no CR or CRLF. + + Return it as a new xmlrpc_mem_block at *dstPP. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * dstP; + + dstP = XMLRPC_MEMBLOCK_NEW(char, envP, srcLen + 1); + + if (!envP->fault_occurred) { + char * const contents = XMLRPC_MEMBLOCK_CONTENTS(char, dstP); + + memcpy(contents, src, srcLen); + contents[srcLen] = '\0'; + } + *dstPP = dstP; +} + + + +enum crTreatment { CR_IS_LINEDELIM, CR_IS_CHAR }; + +static void +stringNew(xmlrpc_env * const envP, + size_t const length, + const char * const value, + enum crTreatment const crTreatment, + xmlrpc_value ** const valPP) { + + xmlrpc_value * valP; + + xmlrpc_validate_utf8(envP, value, length); + + if (!envP->fault_occurred) { + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_STRING; + valP->_wcs_block = NULL; + + /* Note that copyLines() works for strings with no CRs, but + it's slower. + */ + if (memchr(value, '\r', length) && crTreatment == CR_IS_LINEDELIM) + copyLines(envP, value, length, &valP->blockP); + else + copySimple(envP, value, length, &valP->blockP); + + if (envP->fault_occurred) + free(valP); + else + *valPP = valP; + } + } +} + + + +xmlrpc_value * +xmlrpc_string_new_lp(xmlrpc_env * const envP, + size_t const length, + const char * const value) { + + xmlrpc_value * retval; + stringNew(envP, length, value, CR_IS_LINEDELIM, &retval); + return retval; +} + + + +xmlrpc_value * +xmlrpc_string_new_lp_cr(xmlrpc_env * const envP, + size_t const length, + const char * const value) { + + xmlrpc_value * retval; + stringNew(envP, length, value, CR_IS_CHAR, &retval); + return retval; +} + + + +xmlrpc_value * +xmlrpc_string_new(xmlrpc_env * const envP, + const char * const value) { + + xmlrpc_value * retval; + stringNew(envP, strlen(value), value, CR_IS_LINEDELIM, &retval); + return retval; +} + + + +xmlrpc_value * +xmlrpc_string_new_cr(xmlrpc_env * const envP, + const char * const value) { + + xmlrpc_value * retval; + stringNew(envP, strlen(value), value, CR_IS_CHAR, &retval); + return retval; +} + + + +xmlrpc_value * +xmlrpc_string_new_va(xmlrpc_env * const envP, + const char * const format, + va_list args) { + + const char * formattedString; + xmlrpc_value * retvalP; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(format != NULL); + + xmlrpc_vasprintf(&formattedString, format, args); + + if (xmlrpc_strnomem(formattedString)) { + xmlrpc_faultf(envP, "Out of memory building formatted string"); + retvalP = NULL; /* defeat compiler warning */ + } else + retvalP = xmlrpc_string_new(envP, formattedString); + + xmlrpc_strfree(formattedString); + + return retvalP; +} + + + +xmlrpc_value * +xmlrpc_string_new_f(xmlrpc_env * const envP, + const char * const format, + ...) { + + va_list args; + xmlrpc_value * retval; + + va_start(args, format); + + retval = xmlrpc_string_new_va(envP, format, args); + + va_end(args); + + return retval; +} + + + +#if HAVE_UNICODE_WCHAR + +static void +stringWNew(xmlrpc_env * const envP, + size_t const length, + const wchar_t * const value, + enum crTreatment const crTreatment, + xmlrpc_value ** const valPP) { + + xmlrpc_mem_block * utf8P; + + utf8P = xmlrpc_wcs_to_utf8(envP, value, length); + if (!envP->fault_occurred) { + char * const utf8_value = XMLRPC_MEMBLOCK_CONTENTS(char, utf8P); + size_t const utf8_len = XMLRPC_MEMBLOCK_SIZE(char, utf8P); + + if (!envP->fault_occurred) { + stringNew(envP, utf8_len, utf8_value, crTreatment, valPP); + + XMLRPC_MEMBLOCK_FREE(char, utf8P); + } + } +} + + + +xmlrpc_value * +xmlrpc_string_w_new_lp(xmlrpc_env * const envP, + size_t const length, + const wchar_t * const value) { + + xmlrpc_value * valP; + stringWNew(envP, length, value, CR_IS_LINEDELIM, &valP); + return valP; +} + + + + +xmlrpc_value * +xmlrpc_string_w_new_lp_cr(xmlrpc_env * const envP, + size_t const length, + const wchar_t * const value) { + + xmlrpc_value * valP; + stringWNew(envP, length, value, CR_IS_CHAR, &valP); + return valP; +} + + + + +xmlrpc_value * +xmlrpc_string_w_new(xmlrpc_env * const envP, + const wchar_t * const value) { + + xmlrpc_value * valP; + stringWNew(envP, wcslen(value), value, CR_IS_LINEDELIM, &valP); + return valP; +} + + + +xmlrpc_value * +xmlrpc_string_w_new_cr(xmlrpc_env * const envP, + const wchar_t * const value) { + + xmlrpc_value * valP; + stringWNew(envP, wcslen(value), value, CR_IS_CHAR, &valP); + return valP; +} + + + +#endif /* HAVE_UNICODE_WCHAR */ + + + +xmlrpc_value * +xmlrpc_string_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * valP; + + if (valueP->_type != XMLRPC_TYPE_STRING) { + xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, + "Value is not a string. " + "It is type #%d", valueP->_type); + valP = NULL; + } else { + xmlrpc_createXmlrpcValue(envP, &valP); + + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_STRING; + + valP->blockP = + xmlrpc_mem_block_new(envP, + xmlrpc_mem_block_size(valueP->blockP)); + + if (!envP->fault_occurred) { + memcpy(xmlrpc_mem_block_contents(valP->blockP), + xmlrpc_mem_block_contents(valueP->blockP), + xmlrpc_mem_block_size(valueP->blockP)); + } + } + if (!envP->fault_occurred) { + if (valueP->_wcs_block) { + valP->_wcs_block = + xmlrpc_mem_block_new( + envP, + xmlrpc_mem_block_size(valueP->_wcs_block)); + + if (!envP->fault_occurred) { + memcpy(xmlrpc_mem_block_contents(valP->_wcs_block), + xmlrpc_mem_block_contents(valueP->_wcs_block), + xmlrpc_mem_block_size(valueP->_wcs_block)); + } + } else + valP->_wcs_block = NULL; + } + } + return valP; +} + + + diff --git a/trunk/src/xmlrpc_struct.c b/trunk/src/xmlrpc_struct.c new file mode 100644 index 000000000..d5606906b --- /dev/null +++ b/trunk/src/xmlrpc_struct.c @@ -0,0 +1,711 @@ +#include "xmlrpc_config.h" + +#include +#include +#include +#include + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/base_int.h" +#include "int.h" + +#define KEY_ERROR_BUFFER_SZ (32) + + + +static uint32_t +hashStructKey(const char * const key, + size_t const keyLen) { + + uint32_t hash; + size_t i; + + XMLRPC_ASSERT(key != NULL); + + /* This is the Bernstein hash, optimized for lower case ASCII + keys. Note that the bytes of such a key differ only in their + lower 5 bits. + */ + for (hash = 0, i = 0; i < keyLen; ++i) + hash = hash + key[i] + (hash << 5); + + return hash; +} + + + +static void +changeMemberValue(xmlrpc_value * const structP, + unsigned int const mbrIndex, + xmlrpc_value * const newValueP) { +/*---------------------------------------------------------------------------- + Change the value of an existing member. (But be careful--the original and + new values might be the same object, so watch the order of INCREF and DECREF + calls!) +-----------------------------------------------------------------------------*/ + _struct_member * const members = + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); + _struct_member * const memberP = &members[mbrIndex]; + xmlrpc_value * const oldValueP = memberP->value; + + /* Juggle our references. */ + memberP->value = newValueP; + xmlrpc_INCREF(memberP->value); + xmlrpc_DECREF(oldValueP); +} + + + +static void +addNewMember(xmlrpc_env * const envP, + xmlrpc_value * const structP, + xmlrpc_value * const keyvalP, + xmlrpc_value * const valueP) { +/*---------------------------------------------------------------------------- + Add a new member. Assume no member already exists with this key. +-----------------------------------------------------------------------------*/ + const char * const key = + XMLRPC_MEMBLOCK_CONTENTS(char, keyvalP->blockP); + size_t const keyLen = + XMLRPC_MEMBLOCK_SIZE(char, keyvalP->blockP) - 1; + + _struct_member newMember; + + newMember.keyHash = hashStructKey(key, keyLen); + newMember.key = keyvalP; + newMember.value = valueP; + + XMLRPC_MEMBLOCK_APPEND(_struct_member, envP, structP->blockP, + &newMember, 1); + + if (!envP->fault_occurred) { + xmlrpc_INCREF(keyvalP); + xmlrpc_INCREF(valueP); + } +} + + + +void +xmlrpc_destroyStruct(xmlrpc_value * const structP) { +/*---------------------------------------------------------------------------- + Dispose of the contents of struct *structP (but not the struct value + itself). The value is not valid after this. +-----------------------------------------------------------------------------*/ + _struct_member * const members = + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); + + unsigned int i; + + for (i = 0; i < size; ++i) { + xmlrpc_DECREF(members[i].key); + xmlrpc_DECREF(members[i].value); + } + XMLRPC_MEMBLOCK_FREE(_struct_member, structP->blockP); +} + + + +/*========================================================================= +** xmlrpc_struct_new +**========================================================================= +** Create a new value. The corresponding destructor code +** currently lives in xmlrpc_DECREF. +** +** We store the individual members in an array of _struct_member. This +** contains a key, a hash code, and a value. We look up keys by doing +** a linear search of the hash codes. +*/ + +xmlrpc_value * +xmlrpc_struct_new(xmlrpc_env * const envP) { + + xmlrpc_value * valP; + + XMLRPC_ASSERT_ENV_OK(envP); + + xmlrpc_createXmlrpcValue(envP, &valP); + if (!envP->fault_occurred) { + valP->_type = XMLRPC_TYPE_STRUCT; + + valP->blockP = XMLRPC_MEMBLOCK_NEW(_struct_member, envP, 0); + + if (envP->fault_occurred) + free(valP); + } + return valP; +} + + + +xmlrpc_value * +xmlrpc_struct_new_value(xmlrpc_env * const envP, + xmlrpc_value * const valueP) { + + xmlrpc_value * structP; + + if (valueP->_type != XMLRPC_TYPE_STRUCT) { + xmlrpc_env_set_fault_formatted(envP, XMLRPC_TYPE_ERROR, + "Value is not a structure. " + "It is type #%d", valueP->_type); + structP = NULL; + } else { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, structP->blockP); + + xmlrpc_createXmlrpcValue(envP, &structP); + if (!envP->fault_occurred) { + structP->_type = XMLRPC_TYPE_STRUCT; + + structP->blockP = XMLRPC_MEMBLOCK_NEW(xmlrpc_value *, envP, 0); + + if (envP->fault_occurred) + free(structP); + else { + _struct_member * const srcMemberList = + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, valueP->blockP); + + unsigned int i; + + for (i = 0; i < size && !envP->fault_occurred; ++i) { + const _struct_member * const thisMemberP = + &srcMemberList[i]; + + xmlrpc_value * keyValP = + xmlrpc_string_new_value(envP, thisMemberP->key); + if (!envP->fault_occurred) { + xmlrpc_value * valueP = + xmlrpc_value_new(envP, thisMemberP->value); + + if (!envP->fault_occurred) { + addNewMember(envP, structP, keyValP, valueP); + + xmlrpc_DECREF(valueP); + } + xmlrpc_DECREF(keyValP); + } + } + if (envP->fault_occurred) + xmlrpc_destroyStruct(structP); + } + + if (envP->fault_occurred) + free(structP); + } + } + return structP; +} + + + +/*========================================================================= +** xmlrpc_struct_size +**========================================================================= +** Return the number of key-value pairs contained in the struct. If the +** value is not a struct, return -1 and set a fault. +*/ + +int +xmlrpc_struct_size(xmlrpc_env * const envP, + xmlrpc_value * const structP) { + + int retval; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(structP); + + if (structP->_type != XMLRPC_TYPE_STRUCT) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", + structP->_type); + retval = -1; + } else { + size_t const size = + XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); + + assert((size_t)(int)size == size); + /* Because structs are defined to have few enough members */ + + retval = (int)size; + } + return retval; +} + + + +static void +findMember(xmlrpc_value * const structP, + const char * const key, + size_t const keyLen, + bool * const foundP, + unsigned int * const indexP) { + + size_t size, i; + uint32_t searchHash; + _struct_member * contents; /* array */ + bool found; + size_t foundIndex; /* Meaningful only when 'found' is true */ + + XMLRPC_ASSERT_VALUE_OK(structP); + XMLRPC_ASSERT(key != NULL); + foundIndex = 0; /* defeat used-before-set compiler warning */ + + /* Look for our key. */ + searchHash = hashStructKey(key, keyLen); + size = XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); + contents = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); + for (i = 0, found = false; i < size && !found; ++i) { + if (contents[i].keyHash == searchHash) { + xmlrpc_value * const keyvalP = contents[i].key; + const char * const keystr = + XMLRPC_MEMBLOCK_CONTENTS(char, keyvalP->blockP); + size_t const keystrSize = + XMLRPC_MEMBLOCK_SIZE(char, keyvalP->blockP)-1; + if (keystrSize == keyLen && memcmp(key, keystr, keyLen) == 0) { + found = true; + foundIndex = i; + } + } + } + if (found) { + assert((size_t)(int)foundIndex == foundIndex); + /* Definition of structure says it has few enough members */ + + if (indexP) + *indexP = foundIndex; + } + *foundP = found; +} + + + +/*========================================================================= +** xmlrpc_struct_has_key +**========================================================================= +*/ + +int +xmlrpc_struct_has_key(xmlrpc_env * const envP, + xmlrpc_value * const strctP, + const char * const key) { + + XMLRPC_ASSERT(key != NULL); + return xmlrpc_struct_has_key_n(envP, strctP, key, strlen(key)); +} + + + +int +xmlrpc_struct_has_key_n(xmlrpc_env * const envP, + xmlrpc_value * const structP, + const char * const key, + size_t const keyLen) { + int retval; + + /* Suppress a compiler warning about uninitialized variables. */ + retval = 0; + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(structP); + XMLRPC_ASSERT(key != NULL); + + if (structP->_type != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault(envP, XMLRPC_TYPE_ERROR, + "Value is not a struct"); + else { + bool found; + + findMember(structP, key, keyLen, &found, NULL); + + retval = found ? 1 : 0; + } + return retval; +} + + + +/*========================================================================= +** xmlrpc_struct_find_value... +**========================================================================= +** These functions look up a specified key value in a specified struct. +** If it exists, they return the value of the struct member. If not, +** they return a NULL to indicate such. +*/ + +/* It would be a nice extension to be able to look up a key that is + not a text string. +*/ + +void +xmlrpc_struct_find_value(xmlrpc_env * const envP, + xmlrpc_value * const structP, + const char * const key, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Given a key, retrieve a value from the struct. If the key is not + present, return NULL as *valuePP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(structP); + XMLRPC_ASSERT_PTR_OK(key); + + if (structP->_type != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", + structP->_type); + else { + bool found; + unsigned int index; + + /* Get our member index. */ + findMember(structP, key, strlen(key), &found, &index); + if (!found) + *valuePP = NULL; + else { + _struct_member * const members = + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); + *valuePP = members[index].value; + + XMLRPC_ASSERT_VALUE_OK(*valuePP); + + xmlrpc_INCREF(*valuePP); + } + } +} + + + +void +xmlrpc_struct_find_value_v(xmlrpc_env * const envP, + xmlrpc_value * const structP, + xmlrpc_value * const keyP, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Given a key, retrieve a value from the struct. If the key is not + present, return NULL as *valuePP. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(structP); + XMLRPC_ASSERT_VALUE_OK(keyP); + + if (structP->_type != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", + structP->_type); + else { + if (keyP->_type != XMLRPC_TYPE_STRING) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Key value is not a string. " + "It is type #%d", + keyP->_type); + else { + bool found; + unsigned int index; + + /* Get our member index. */ + findMember(structP, + XMLRPC_MEMBLOCK_CONTENTS(char, keyP->blockP), + XMLRPC_MEMBLOCK_SIZE(char, keyP->blockP)-1, + &found, &index); + if (!found) + *valuePP = NULL; + else { + _struct_member * const members = + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); + *valuePP = members[index].value; + + XMLRPC_ASSERT_VALUE_OK(*valuePP); + + xmlrpc_INCREF(*valuePP); + } + } + } +} + + + +/*========================================================================= +** xmlrpc_struct_read_value... +**========================================================================= +** These fail if no member with the specified key exists. +** Otherwise, they are the same as xmlrpc_struct_find_value... +*/ + +void +xmlrpc_struct_read_value_v(xmlrpc_env * const envP, + xmlrpc_value * const structP, + xmlrpc_value * const keyP, + xmlrpc_value ** const valuePP) { + + xmlrpc_struct_find_value_v(envP, structP, keyP, valuePP); + + if (!envP->fault_occurred) { + if (*valuePP == NULL) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, "No member of struct has key '%.*s'", + (int)XMLRPC_MEMBLOCK_SIZE(char, keyP->blockP), + XMLRPC_MEMBLOCK_CONTENTS(char, keyP->blockP)); + } + } +} + + + +void +xmlrpc_struct_read_value(xmlrpc_env * const envP, + xmlrpc_value * const structP, + const char * const key, + xmlrpc_value ** const valuePP) { + + xmlrpc_struct_find_value(envP, structP, key, valuePP); + + if (!envP->fault_occurred) { + if (*valuePP == NULL) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, "No member of struct has key '%s'", + key); + /* We should fix the error message to format the key for display */ + } + } +} + + + +/*========================================================================= +** xmlrpc_struct_get_value... +**========================================================================= +** These are for backward compatibility. They used to be the only ones. +** They're deprecated because they don't acquire a reference to the +** value they return. +*/ + +xmlrpc_value * +xmlrpc_struct_get_value_n(xmlrpc_env * const envP, + xmlrpc_value * const structP, + const char * const key, + size_t const keyLen) { + + xmlrpc_value * retval; + xmlrpc_value * keyP; /* 'key' as an XML-RPC string */ + + keyP = xmlrpc_string_new_lp(envP, keyLen, key); + if (!envP->fault_occurred) { + xmlrpc_struct_find_value_v(envP, structP, keyP, &retval); + + if (!envP->fault_occurred) { + if (retval == NULL) { + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, + "No member of struct has key '%.*s'", + (int)keyLen, key); + /* We should fix the error message to format the key + for display */ + } else + /* For backward compatibility. */ + xmlrpc_DECREF(retval); + } + xmlrpc_DECREF(keyP); + } + return retval; +} + + + +xmlrpc_value * +xmlrpc_struct_get_value(xmlrpc_env * const envP, + xmlrpc_value * const strctP, + const char * const key) { + + XMLRPC_ASSERT(key != NULL); + return xmlrpc_struct_get_value_n(envP, strctP, key, strlen(key)); +} + + + +/*========================================================================= +** xmlrpc_struct_set_value +**========================================================================= +*/ + +void +xmlrpc_struct_set_value(xmlrpc_env * const envP, + xmlrpc_value * const strctP, + const char * const key, + xmlrpc_value * const valueP) { + + XMLRPC_ASSERT(key != NULL); + xmlrpc_struct_set_value_n(envP, strctP, key, strlen(key), valueP); +} + + + +void +xmlrpc_struct_set_value_n(xmlrpc_env * const envP, + xmlrpc_value * const strctP, + const char * const key, + size_t const keyLen, + xmlrpc_value * const valueP) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT(key != NULL); + + if (xmlrpc_value_type(strctP) != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, + "Trying to set value in something not a struct. " + "Type is %d; struct is %d", + xmlrpc_value_type(strctP), XMLRPC_TYPE_STRUCT); + else { + xmlrpc_value * keyvalP; /* 'key' as an XML-RPC string */ + + keyvalP = xmlrpc_string_new_lp(envP, keyLen, key); + if (!envP->fault_occurred) + xmlrpc_struct_set_value_v(envP, strctP, keyvalP, valueP); + + xmlrpc_DECREF(keyvalP); + } +} + + + +void +xmlrpc_struct_set_value_v(xmlrpc_env * const envP, + xmlrpc_value * const structP, + xmlrpc_value * const keyvalP, + xmlrpc_value * const valueP) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(structP); + XMLRPC_ASSERT_VALUE_OK(keyvalP); + XMLRPC_ASSERT_VALUE_OK(valueP); + + if (structP->_type != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault(envP, XMLRPC_TYPE_ERROR, + "Value is not a struct"); + else if (keyvalP->_type != XMLRPC_TYPE_STRING) + xmlrpc_env_set_fault(envP, XMLRPC_TYPE_ERROR, + "Key value is not a string"); + else { + const char * const key = + XMLRPC_MEMBLOCK_CONTENTS(char, keyvalP->blockP); + size_t const keyLen = + XMLRPC_MEMBLOCK_SIZE(char, keyvalP->blockP) - 1; + + bool found; + unsigned int index; + + findMember(structP, key, keyLen, &found, &index); + + if (found) + changeMemberValue(structP, index, valueP); + else + addNewMember(envP, structP, keyvalP, valueP); + } +} + + + +/* Note that the order of keys and values is undefined, and may change + when you modify the struct. +*/ + +void +xmlrpc_struct_read_member(xmlrpc_env * const envP, + xmlrpc_value * const structP, + unsigned int const index, + xmlrpc_value ** const keyvalP, + xmlrpc_value ** const valueP) { + + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(structP); + XMLRPC_ASSERT_PTR_OK(keyvalP); + XMLRPC_ASSERT_PTR_OK(valueP); + + if (structP->_type != XMLRPC_TYPE_STRUCT) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_TYPE_ERROR, "Attempt to read a struct member " + "of something that is not a struct"); + else { + _struct_member * const members = + XMLRPC_MEMBLOCK_CONTENTS(_struct_member, structP->blockP); + size_t const size = + XMLRPC_MEMBLOCK_SIZE(_struct_member, structP->blockP); + + if (index >= size) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, "Index %u is beyond the end of " + "the %u-member structure", index, (unsigned int)size); + else { + _struct_member * const memberP = &members[index]; + *keyvalP = memberP->key; + xmlrpc_INCREF(memberP->key); + *valueP = memberP->value; + xmlrpc_INCREF(memberP->value); + } + } +} + + + +void +xmlrpc_struct_get_key_and_value(xmlrpc_env * const envP, + xmlrpc_value * const structP, + int const index, + xmlrpc_value ** const keyvalP, + xmlrpc_value ** const valueP) { +/*---------------------------------------------------------------------------- + Same as xmlrpc_struct_read_member(), except doesn't take a reference + to the returned value. + + This is obsolete. +-----------------------------------------------------------------------------*/ + XMLRPC_ASSERT_ENV_OK(envP); + XMLRPC_ASSERT_VALUE_OK(structP); + XMLRPC_ASSERT_PTR_OK(keyvalP); + XMLRPC_ASSERT_PTR_OK(valueP); + + if (index < 0) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INDEX_ERROR, "Index %d is negative.", index); + else { + xmlrpc_struct_read_member(envP, structP, index, keyvalP, valueP); + if (!envP->fault_occurred) { + xmlrpc_DECREF(*keyvalP); + xmlrpc_DECREF(*valueP); + } + } + if (envP->fault_occurred) { + *keyvalP = NULL; + *valueP = NULL; + } +} + + + +/* 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. */ + diff --git a/trunk/srcdir.mk.in b/trunk/srcdir.mk.in new file mode 100644 index 000000000..d389df1b6 --- /dev/null +++ b/trunk/srcdir.mk.in @@ -0,0 +1 @@ +SRCDIR=@abs_srcdir@ diff --git a/trunk/stamp-h.in b/trunk/stamp-h.in new file mode 100644 index 000000000..9788f7023 --- /dev/null +++ b/trunk/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/trunk/test/Makefile b/trunk/test/Makefile new file mode 100644 index 000000000..4fce824c7 --- /dev/null +++ b/trunk/test/Makefile @@ -0,0 +1,122 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + SRCDIR := $(call updir,$(CURDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := test + +include $(BLDDIR)/config.mk + +SUBDIRS = cpp + +XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test + +LDADD_CGI_SERVER = \ + $(shell $(XMLRPC_C_CONFIG) cgi-server --ldadd) + +default: all + +INCLUDES = -I$(BLDDIR) -Isrcdir/include -Isrcdir/lib/util/include \ + +PROGS = test cgitest1 + +all: $(PROGS) $(SUBDIRS:%=%/all) + +TEST_OBJS = \ + testtool.o \ + test.o \ + cgi.o \ + memblock.o \ + method_registry.o \ + parse_xml.o \ + serialize.o \ + serialize_value.o \ + value.o \ + value_datetime.o \ + xml_data.o \ + +ifeq ($(MUST_BUILD_CLIENT),yes) + TEST_OBJS += client.o + LIBXMLRPC_CLIENT_DEP = $(LIBXMLRPC_CLIENT_A) + LDADD_CLIENT = $(shell $(XMLRPC_C_CONFIG) client --ldadd) +else + TEST_OBJS += client_dummy.o + LIBXMLRPC_CLIENT_DEP = + LDADD_CLIENT = +endif + +ifeq ($(ENABLE_ABYSS_SERVER),yes) + TEST_OBJS += abyss.o server_abyss.o + LIBXMLRPC_ABYSS_DEP = $(LIBXMLRPC_ABYSS_A) + LIBXMLRPC_SERVER_ABYSS_DEP = $(LIBXMLRPC_ABYSS_A) + LDADD_ABYSS_SERVER = \ + $(shell $(XMLRPC_C_CONFIG) abyss-server --ldadd) +else + TEST_OBJS += abyss_dummy.o server_abyss_dummy.o + LIBXMLRPC_ABYSS_DEP = + LIBXMLRPC_SERVER_ABYSS_DEP = + LDADD_ABYSS_SERVER = +endif + +include $(SRCDIR)/common.mk + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +test: \ + $(XMLRPC_C_CONFIG) \ + $(TEST_OBJS) $(LIBXMLRPC_A) $(LIBXMLRPC_UTIL_A) \ + $(LIBXMLRPC_SERVER_A) $(LIBXMLRPC_SERVER_ABYSS_DEP) $(LIBXMLRPC_XML) \ + $(LIBXMLRPC_CLIENT_DEP) $(LIBXMLRPC_ABYSS_DEP) \ + $(LIBXMLRPC_XMLPARSE_A) $(LIBXMLRPC_XMLTOK_A) \ + $(CASPRINTF) + $(CCLD) -o $@ $(LDFLAGS_ALL) \ + $(TEST_OBJS) $(LDADD_CLIENT) $(LDADD_ABYSS_SERVER) $(CASPRINTF) + +CGITEST1_OBJS = cgitest1.o testtool.o + +cgitest1: $(CGITEST1_OBJS) $(LIBXMLRPC_SERVER_A) $(LIBXMLRPC_SERVER_CGI_A) \ + $(LIBXMLRPC_A) $(LIBXMLRPC_UTIL_A) $(LIBXMLRPC_XML) + $(CCLD) -o $@ $(CGITEST1_OBJS) $(LDFLAGS_ALL) $(LDADD_CGI_SERVER) + +OBJS = $(TEST_OBJS) cgitest1.o + +$(OBJS):%.o:%.c + $(CC) -c $(INCLUDES) $(CFLAGS_ALL) $< + +# Note the difference between 'check' and 'runtests'. 'check' means to check +# our own correctness. 'runtests' means to run the tests that check our +# parent's correctness + +.PHONY: check +check: + +.PHONY: runtests_local +runtests_local: test cgitest1 + ./test + +.PHONY: runtests +runtests: runtests_local cpp/runtests + +cpp/runtests: FORCE + $(MAKE) -C $(dir $@) $(notdir $@) + +.PHONY: install +install: + +.PHONY: uninstall +uninstall: + +.PHONY: clean clean-local distclean +clean: clean-common clean-local +clean-local: $(SUBDIRS:%=%/clean) + rm -f $(PROGS) + +distclean: clean $(SUBDIRS:%=%/distclean) distclean-common + +.PHONY: dep +dep: dep-common $(SUBDIRS:%=%/dep) + +include depend.mk diff --git a/trunk/test/abyss.c b/trunk/test/abyss.c new file mode 100644 index 000000000..84c5cb1d6 --- /dev/null +++ b/trunk/test/abyss.c @@ -0,0 +1,416 @@ +/* None of the tests in here rely on a client existing, or even a network + connection. We should figure out how to create a test client and do + such tests. +*/ +#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ + +#include "unistdx.h" +#include +#ifndef _WIN32 +#include +#include +#endif +#include +#include + +#include "xmlrpc_config.h" + +#include "int.h" +#include "casprintf.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "xmlrpc-c/abyss.h" + +#include "testtool.h" + +#include "abyss.h" + + + +static void +bindSocketToPort(int const fd, + uint16_t const portNumber) { + + struct sockaddr_in name; + int rc; + + name.sin_family = AF_INET; + name.sin_port = htons(portNumber); + name.sin_addr.s_addr = INADDR_ANY; + + rc = bind(fd, (struct sockaddr *)&name, sizeof(name)); + if (rc != 0) + fprintf(stderr, "bind() of %d failed, errno=%d (%s)", + fd, errno, strerror(errno)); + + TEST(rc == 0); +} + + + +static void +chanSwitchCreateFd(int const fd, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + +#ifdef _WIN32 + ChanSwitchWinCreateWinsock(fd, chanSwitchPP, errorP); +#else + ChanSwitchUnixCreateFd(fd, chanSwitchPP, errorP); +#endif +} + + + +static void +closesock(int const fd) { +#ifdef _WIN32 + closesocket(fd); +#else + close(fd); +#endif +} + + + +static void +chanSwitchCreate(uint16_t const portNumber, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + +#ifdef _WIN32 + ChanSwitchWinCreate(portNumber, chanSwitchPP, errorP); +#else + ChanSwitchUnixCreate(portNumber, chanSwitchPP, errorP); +#endif +} + + + +static void +chanSwitchCreate2(int const protocolFamily, + const struct sockaddr * const sockAddrP, + socklen_t const sockAddrLen, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + +#ifdef _WIN32 + ChanSwitchWinCreate2(protocolFamily, sockAddrP, sockAddrLen, + chanSwitchPP, errorP); +#else + ChanSwitchUnixCreate2(protocolFamily, sockAddrP, sockAddrLen, + chanSwitchPP, errorP); +#endif +} + + + +static void +chanSwitchCreateIpV6(uint16_t const portNumber, + TChanSwitch ** const chanSwitchPP, + const char ** const errorP) { + +#ifndef _WIN32 + ChanSwitchUnixCreateIpV6Port(portNumber, chanSwitchPP, errorP); +#endif +} + + + +static void +channelCreateFd(int const fd, + TChannel ** const channelPP, + const char ** const errorP) { + +#ifdef _WIN32 + struct abyss_win_chaninfo * channelInfoP; + ChannelWinCreateWinsock(fd, channelPP, &channelInfoP, errorP); +#else + struct abyss_unix_chaninfo * channelInfoP; + ChannelUnixCreateFd(fd, channelPP, &channelInfoP, errorP); +#endif +} + + + +static void +testChanSwitchOsSocket(void) { + + XMLRPC_SOCKET rc; + + rc = socket(AF_INET, SOCK_STREAM, 0); + if (rc < 0) { + fprintf(stderr, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + abort(); + } else { + int const fd = rc; + + TChanSwitch * chanSwitchP; + TServer server; + const char * error; + + bindSocketToPort(fd, 8080); + + chanSwitchCreateFd(fd, &chanSwitchP, &error); + + TEST_NULL_STRING(error); + + ServerCreateSwitch(&server, chanSwitchP, &error); + + TEST_NULL_STRING(error); + + ServerFree(&server); + + ChanSwitchDestroy(chanSwitchP); + + closesock(fd); + } +} + + + +static void +testChanSwitchSockAddr(void) { + + TServer server; + TChanSwitch * chanSwitchP; + const char * error; + + struct sockaddr_in sockAddr; + + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons(8080); + sockAddr.sin_addr = test_ipAddrFromDecimal(127, 0, 0, 1); + + chanSwitchCreate2(PF_INET, + (const struct sockaddr *) &sockAddr, sizeof(sockAddr), + &chanSwitchP, &error); + + TEST_NULL_STRING(error); + + ServerCreateSwitch(&server, chanSwitchP, &error); + + TEST_NULL_STRING(error); + + ServerFree(&server); + + ChanSwitchDestroy(chanSwitchP); +} + + + +static void +testChanSwitch(void) { + + TServer server; + TChanSwitch * chanSwitchP; + const char * error; + + chanSwitchCreate(8080, &chanSwitchP, &error); + + TEST_NULL_STRING(error); + + ServerCreateSwitch(&server, chanSwitchP, &error); + + TEST_NULL_STRING(error); + + ServerFree(&server); + + ChanSwitchDestroy(chanSwitchP); + +#ifndef _WIN32 + chanSwitchCreateIpV6(8080, &chanSwitchP, &error); + + TEST_NULL_STRING(error); + + ChanSwitchDestroy(chanSwitchP); + + testChanSwitchSockAddr(); + + testChanSwitchOsSocket(); +#endif +} + + + +static void +testChannel(void) { + + XMLRPC_SOCKET rc; + + rc = socket(AF_INET, SOCK_STREAM, 0); + if (rc < 0) { + fprintf(stderr, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + abort(); + } else { + int const fd = rc; + + TChannel * channelP; + const char * error; + + channelCreateFd(fd, &channelP, &error); + + TEST(error); + + TEST(strstr(error, "not in connected")); + + strfree(error); + } +} + + + +static void +testOsSocket(void) { + + XMLRPC_SOCKET rc; + + rc = socket(AF_INET, SOCK_STREAM, 0); + if (rc < 0) { + fprintf(stderr, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + abort(); + } else { + int const fd = rc; + + TServer server; + abyss_bool success; + + bindSocketToPort(fd, 8080); + + success = ServerCreateSocket(&server, NULL, fd, NULL, NULL); + + TEST(success); + + ServerFree(&server); + + closesock(fd); + } +} + + + +static void +testSocket(void) { + +#ifndef _WIN32 + int rc; + + rc = socket(AF_INET, SOCK_STREAM, 0); + if (rc < 0) { + fprintf(stderr, "socket() failed with errno %d (%s)", + errno, strerror(errno)); + abort(); + } else { + int const fd = rc; + + TSocket * socketP; + TServer server; + const char * error; + + SocketUnixCreateFd(fd, &socketP); + + TEST(socketP != NULL); + + ServerCreateSocket2(&server, socketP, &error); + + TEST(!error); + + ServerFree(&server); + + SocketDestroy(socketP); + + close(fd); + } +#endif +} + + + +static void +testServerCreate(void) { + + TServer server; + abyss_bool success; + + success = ServerCreate(&server, NULL, 8080, NULL, NULL); + TEST(success); + ServerInit(&server); + ServerFree(&server); + + success = ServerCreate(&server, "myserver", 8080, + "/tmp/docroot", "/tmp/logfile"); + TEST(success); + ServerInit(&server); + ServerFree(&server); + + success = ServerCreateNoAccept(&server, NULL, NULL, NULL); + TEST(success); + ServerFree(&server); + + { + TChanSwitch * chanSwitchP; + const char * error; + + chanSwitchCreate(8080, &chanSwitchP, &error); + + TEST_NULL_STRING(error); + + ServerCreateSwitch(&server, chanSwitchP, &error); + + TEST_NULL_STRING(error); + + ServerSetName(&server, "/tmp/docroot"); + ServerSetLogFileName(&server, "/tmp/logfile"); + ServerSetKeepaliveTimeout(&server, 50); + ServerSetKeepaliveMaxConn(&server, 5); + ServerSetTimeout(&server, 75); + ServerSetAdvertise(&server, 1); + ServerSetAdvertise(&server, 0); + + ServerInit(&server); + + ServerFree(&server); + + ChanSwitchDestroy(chanSwitchP); + } +} + + + +void +test_abyss(void) { + + const char * error; + + printf("Running Abyss server tests...\n"); + + AbyssInit(&error); + TEST_NULL_STRING(error); + + ChanSwitchInit(&error); + TEST_NULL_STRING(error); + + ChannelInit(&error); + TEST_NULL_STRING(error); + + testChanSwitch(); + + testChannel(); + + testOsSocket(); + + testSocket(); + + testServerCreate(); + + ChannelTerm(); + ChanSwitchTerm(); + AbyssTerm(); + + printf("\n"); + printf("Abyss server tests done.\n"); +} + diff --git a/trunk/test/abyss.h b/trunk/test/abyss.h new file mode 100644 index 000000000..64e8afbba --- /dev/null +++ b/trunk/test/abyss.h @@ -0,0 +1,2 @@ +void +test_abyss(void); diff --git a/trunk/test/abyss_dummy.c b/trunk/test/abyss_dummy.c new file mode 100644 index 000000000..192844dff --- /dev/null +++ b/trunk/test/abyss_dummy.c @@ -0,0 +1,14 @@ +#include + +#include "abyss.h" + + + +void +test_abyss(void) { + + printf("Running dummy Abyss test."); + + printf("\n"); + printf("Abyss server tests done.\n"); +} diff --git a/trunk/test/cgi.c b/trunk/test/cgi.c new file mode 100644 index 000000000..18dfa9bcf --- /dev/null +++ b/trunk/test/cgi.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#include "xmlrpc_config.h" + +#include "testtool.h" +#include "cgi.h" + +static const char cgiResponse1[] = + "....Status: 200 OK\n" + "Content-type: text/xml; charset=\"utf-8\"\n" + "Content-length: 141\n" + "\n" + "\r\n" + "\r\n" + "\r\n" + "12\r\n" + "\r\n" + "\r\n"; + + +#define TESTDATA_DIR "data" +#define DIRSEP DIRECTORY_SEPARATOR + +void +test_server_cgi(void) { +/*---------------------------------------------------------------------------- + Here, we pretend to be a web server when someone has requested a POST + to the CGI script "cgitest1". +-----------------------------------------------------------------------------*/ + FILE * cgiOutputP; + + printf("Running CGI tests...\n"); + + cgiOutputP = popen("REQUEST_METHOD=POST " + "CONTENT_TYPE=text/xml " + "CONTENT_LENGTH=211 " + "./cgitest1 " + "<" + TESTDATA_DIR DIRSEP "sample_add_call.xml", + "r"); + + if (cgiOutputP == NULL) + TEST_ERROR("Unable to run 'cgitest' program."); + else { + unsigned char cgiResponse[4096]; + size_t bytesRead; + + bytesRead = fread(cgiResponse, 1, sizeof(cgiResponse), cgiOutputP); + + TEST(bytesRead == strlen(cgiResponse1)); + + TEST(memcmp(cgiResponse, cgiResponse1, bytesRead) == 0); + } + fclose(cgiOutputP); + printf("\n"); + printf("CGI tests done.\n"); +} diff --git a/trunk/test/cgi.h b/trunk/test/cgi.h new file mode 100644 index 000000000..4e2de991c --- /dev/null +++ b/trunk/test/cgi.h @@ -0,0 +1,2 @@ +void +test_server_cgi(void); diff --git a/trunk/test/cgitest1.c b/trunk/test/cgitest1.c new file mode 100644 index 000000000..ce758b11d --- /dev/null +++ b/trunk/test/cgitest1.c @@ -0,0 +1,79 @@ +/*============================================================================ + Act like a CGI script -- read POST data from Standard Input, interpret + it as an XML-RPC call, and write an XML-RPC response to Standard Output. + + This is for use by a test program. +============================================================================*/ + +#include +#include +#include +#include + +#include "xmlrpc_config.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "xmlrpc-c/server_cgi.h" + +#include "testtool.h" + + +int total_tests; +int total_failures; + + + +static xmlrpc_value * +sample_add(xmlrpc_env * const env, + xmlrpc_value * const param_array, + void * const user_data ATTR_UNUSED) { + + xmlrpc_int32 x, y, z; + + /* Parse our argument array. */ + xmlrpc_decompose_value(env, param_array, "(ii)", &x, &y); + if (env->fault_occurred) + return NULL; + + /* Add our two numbers. */ + z = x + y; + + /* Return our result. */ + return xmlrpc_build_value(env, "i", z); +} + + + +int +main(int argc ATTR_UNUSED, + char ** argv ATTR_UNUSED) { + + xmlrpc_env env; + xmlrpc_registry * registryP; + xmlrpc_value * argArrayP; + + xmlrpc_env_init(&env); + + registryP = xmlrpc_registry_new(&env); + TEST(registryP != NULL); + TEST_NO_FAULT(&env); + + xmlrpc_registry_add_method(&env, registryP, NULL, "sample.add", + sample_add, NULL); + TEST_NO_FAULT(&env); + + argArrayP = xmlrpc_build_value(&env, "(ii)", + (xmlrpc_int32) 25, (xmlrpc_int32) 17); + TEST_NO_FAULT(&env); + + /* The following reads from Standard Input and writes to Standard + Output + */ + xmlrpc_server_cgi_process_call(registryP); + + xmlrpc_DECREF(argArrayP); + xmlrpc_registry_free(registryP); + + return 0; +} diff --git a/trunk/test/client.c b/trunk/test/client.c new file mode 100644 index 000000000..f3fc80ff1 --- /dev/null +++ b/trunk/test/client.c @@ -0,0 +1,508 @@ +#include +#include +#include +#include + +#include "xmlrpc_config.h" +#include "transport_config.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/transport.h" + +#include "bool.h" +#include "testtool.h" +#include "client.h" + + + +static void +testVersion(void) { + + unsigned int major, minor, point; + + xmlrpc_client_version(&major, &minor, &point); + +#ifndef _WIN32 + /* xmlrpc_client_version_major, etc. are not exported from a Windows DLL */ + + TEST(major == xmlrpc_client_version_major); + TEST(minor == xmlrpc_client_version_minor); + TEST(point == xmlrpc_client_version_point); +#endif +} + + + +static void +testGlobalConst(void) { + + xmlrpc_env env; + xmlrpc_env_init(&env); + + xmlrpc_client_setup_global_const(&env); + TEST_NO_FAULT(&env); + + xmlrpc_client_teardown_global_const(); + + xmlrpc_client_setup_global_const(&env); + TEST_NO_FAULT(&env); + xmlrpc_client_setup_global_const(&env); + TEST_NO_FAULT(&env); + + xmlrpc_client_teardown_global_const(); + xmlrpc_client_teardown_global_const(); + + xmlrpc_env_clean(&env); +} + + + +static xmlrpc_progress_fn myProgress; + +static void +myProgress(void * const userHandle, + struct xmlrpc_progress_data const data) { + + printf("Progress of %p: %f, %f, %f, %f\n", + userHandle, + data.call.total, + data.call.now, + data.response.total, + data.response.now); +} + + + +static void +testCreateCurlParms(void) { + +#if MUST_BUILD_CURL_CLIENT + + xmlrpc_env env; + xmlrpc_client * clientP; + struct xmlrpc_clientparms clientParms1; + struct xmlrpc_curl_xportparms curlTransportParms1; + + xmlrpc_env_init(&env); + + clientParms1.transport = "curl"; + clientParms1.transportparmsP = &curlTransportParms1; + + curlTransportParms1.network_interface = "eth0"; + clientParms1.transportparm_size = XMLRPC_CXPSIZE(network_interface); + xmlrpc_client_create(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparm_size), + &clientP); + TEST_NO_FAULT(&env); + xmlrpc_client_destroy(clientP); + + curlTransportParms1.no_ssl_verifypeer = 1; + curlTransportParms1.no_ssl_verifyhost = 1; + clientParms1.transportparm_size = XMLRPC_CXPSIZE(no_ssl_verifyhost); + xmlrpc_client_create(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparm_size), + &clientP); + TEST_NO_FAULT(&env); + xmlrpc_client_destroy(clientP); + + curlTransportParms1.user_agent = "testprog/1.0"; + clientParms1.transportparm_size = XMLRPC_CXPSIZE(user_agent); + xmlrpc_client_create(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparm_size), + &clientP); + TEST_NO_FAULT(&env); + xmlrpc_client_destroy(clientP); + + curlTransportParms1.ssl_cert = NULL; + curlTransportParms1.sslcerttype = NULL; + curlTransportParms1.sslcertpasswd = NULL; + curlTransportParms1.sslkey = NULL; + curlTransportParms1.sslkeytype = NULL; + curlTransportParms1.sslkeypasswd = NULL; + curlTransportParms1.sslengine = NULL; + curlTransportParms1.sslengine_default = false; + curlTransportParms1.sslversion = XMLRPC_SSLVERSION_DEFAULT; + curlTransportParms1.cainfo = NULL; + curlTransportParms1.capath = NULL; + curlTransportParms1.randomfile = NULL; + curlTransportParms1.egdsocket = NULL; + curlTransportParms1.ssl_cipher_list = NULL; + curlTransportParms1.timeout = 0; + curlTransportParms1.dont_advertise = 1; + curlTransportParms1.proxy = NULL; + curlTransportParms1.proxy_port = 0; + curlTransportParms1.proxy_type = XMLRPC_HTTPPROXY_HTTP; + curlTransportParms1.proxy_auth = XMLRPC_HTTPAUTH_NONE; + curlTransportParms1.proxy_userpwd = "mypassword"; + curlTransportParms1.gssapi_delegation = 1; + curlTransportParms1.referer = "myreferer"; + curlTransportParms1.connect_timeout = 0; + + clientParms1.transportparm_size = XMLRPC_CXPSIZE(referer); + xmlrpc_client_create(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparm_size), + &clientP); + TEST_NO_FAULT(&env); + xmlrpc_client_destroy(clientP); + + xmlrpc_env_clean(&env); +#endif /* MUST_BUILD_CURL_CLIENT */ +} + + + +static void +testCreateSeparateXport(void) { + +#if MUST_BUILD_CURL_CLIENT + xmlrpc_env env; + xmlrpc_client * clientP; + struct xmlrpc_clientparms clientParms1; + struct xmlrpc_curl_xportparms curlTransportParms1; + struct xmlrpc_client_transport * transportP; + + xmlrpc_env_init(&env); + + xmlrpc_curl_transport_ops.create( + &env, 0, "", "", &curlTransportParms1, 0, + &transportP); + + TEST_NO_FAULT(&env); + + clientParms1.transport = NULL; + clientParms1.transportparmsP = NULL; + clientParms1.transportparm_size = 0; + clientParms1.transportOpsP = NULL; + clientParms1.transportP = NULL; + + xmlrpc_client_create(&env, 0, "", "", + &clientParms1, XMLRPC_CPSIZE(transportP), + &clientP); + TEST_NO_FAULT(&env); + + xmlrpc_client_destroy(clientP); + + clientParms1.transport = "curl"; + clientParms1.transportparmsP = &curlTransportParms1; + clientParms1.transportparm_size = 0; + clientParms1.transportOpsP = NULL; + clientParms1.transportP = NULL; + + xmlrpc_client_create(&env, 0, "", "", + &clientParms1, XMLRPC_CPSIZE(transportP), + &clientP); + TEST_NO_FAULT(&env); + + xmlrpc_client_destroy(clientP); + + clientParms1.transportP = transportP; + xmlrpc_client_create(&env, 0, "", "", + &clientParms1, XMLRPC_CPSIZE(transportP), + &clientP); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + /* Both transportP and transport specified */ + + clientParms1.transport = NULL; + clientParms1.transportparmsP = NULL; + clientParms1.transportparm_size = 0; + clientParms1.transportOpsP = &xmlrpc_curl_transport_ops; + clientParms1.transportP = transportP; + + xmlrpc_client_create(&env, 0, "", "", + &clientParms1, XMLRPC_CPSIZE(transportOpsP), + &clientP); + + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + /* transportOpsP but no transportP */ + + xmlrpc_client_create(&env, 0, "", "", + &clientParms1, XMLRPC_CPSIZE(transportP), + &clientP); + + TEST_NO_FAULT(&env); + + xmlrpc_client_destroy(clientP); + + xmlrpc_curl_transport_ops.destroy(transportP); + + xmlrpc_env_clean(&env); + +#endif /* MUST_BUILD_CURL_CLIENT */ +} + + + +static void +testCreateDestroy(void) { + + xmlrpc_env env; + xmlrpc_client * clientP; + struct xmlrpc_clientparms clientParms1; + struct xmlrpc_curl_xportparms curlTransportParms1; + int interrupt; + + xmlrpc_env_init(&env); + + xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + /* Didn't set up global const */ + + xmlrpc_client_setup_global_const(&env); + TEST_NO_FAULT(&env); + + xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP); + TEST_NO_FAULT(&env); + xmlrpc_client_destroy(clientP); + + xmlrpc_client_create(&env, 0, "testprog", "1.0", &clientParms1, 0, + &clientP); + TEST_NO_FAULT(&env); + xmlrpc_client_destroy(clientP); + + clientParms1.transport = "curl"; + xmlrpc_client_create(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transport), &clientP); + TEST_NO_FAULT(&env); + xmlrpc_client_destroy(clientP); + + clientParms1.transportparmsP = NULL; + xmlrpc_client_create(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparmsP), + &clientP); + TEST_NO_FAULT(&env); + xmlrpc_client_destroy(clientP); + + clientParms1.transportOpsP = NULL; + clientParms1.transportP = NULL; + clientParms1.dialect = xmlrpc_dialect_apache; + clientParms1.progressFn = &myProgress; + xmlrpc_client_create(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(progressFn), + &clientP); + TEST_NO_FAULT(&env); + xmlrpc_client_destroy(clientP); + + clientParms1.transportparmsP = &curlTransportParms1; + + xmlrpc_client_create(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparmsP), + &clientP); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + clientParms1.transportparm_size = 0; + xmlrpc_client_create(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparm_size), + &clientP); + TEST_NO_FAULT(&env); + + xmlrpc_client_set_interrupt(clientP, &interrupt); + xmlrpc_client_set_interrupt(clientP, NULL); + + xmlrpc_client_destroy(clientP); + + testCreateCurlParms(); + + testCreateSeparateXport(); + + xmlrpc_client_teardown_global_const(); + + xmlrpc_env_clean(&env); +} + + + +static void +testSynchCall(void) { + + xmlrpc_env env; + xmlrpc_client * clientP; + xmlrpc_value * resultP; + xmlrpc_value * emptyArrayP; + xmlrpc_server_info * noSuchServerInfoP; + + xmlrpc_env_init(&env); + + emptyArrayP = xmlrpc_array_new(&env); + TEST_NO_FAULT(&env); + + xmlrpc_client_setup_global_const(&env); + TEST_NO_FAULT(&env); + + xmlrpc_client_create(&env, 0, "testprog", "1.0", NULL, 0, &clientP); + TEST_NO_FAULT(&env); + + noSuchServerInfoP = xmlrpc_server_info_new(&env, "nosuchserver"); + TEST_NO_FAULT(&env); + + xmlrpc_client_call2(&env, clientP, noSuchServerInfoP, "nosuchmethod", + emptyArrayP, &resultP); + TEST_FAULT(&env, XMLRPC_NETWORK_ERROR); /* No such server */ + + xmlrpc_client_call2f(&env, clientP, "nosuchserver", "nosuchmethod", + &resultP, "(i)", 7); + TEST_FAULT(&env, XMLRPC_NETWORK_ERROR); /* No such server */ + + xmlrpc_server_info_free(noSuchServerInfoP); + + xmlrpc_client_destroy(clientP); + + xmlrpc_DECREF(emptyArrayP); + + xmlrpc_client_teardown_global_const(); + + xmlrpc_env_clean(&env); +} + + + +static void +testInitCleanup(void) { + + xmlrpc_env env; + struct xmlrpc_clientparms clientParms1; + struct xmlrpc_curl_xportparms curlTransportParms1; + + xmlrpc_env_init(&env); + + xmlrpc_client_init2(&env, 0, "testprog", "1.0", NULL, 0); + TEST_NO_FAULT(&env); + xmlrpc_client_cleanup(); + + xmlrpc_client_init2(&env, 0, "testprog", "1.0", &clientParms1, 0); + TEST_NO_FAULT(&env); + xmlrpc_client_cleanup(); + + clientParms1.transport = "curl"; + xmlrpc_client_init2(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transport)); + TEST_NO_FAULT(&env); + xmlrpc_client_cleanup(); + + clientParms1.transportparmsP = NULL; + xmlrpc_client_init2(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparmsP)); + TEST_NO_FAULT(&env); + xmlrpc_client_cleanup(); + + clientParms1.transportparmsP = &curlTransportParms1; + + /* Fails because we didn't include transportparm_size: */ + xmlrpc_client_init2(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparmsP)); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + clientParms1.transportparm_size = 0; + xmlrpc_client_init2(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparm_size)); + TEST_NO_FAULT(&env); + xmlrpc_client_cleanup(); + + curlTransportParms1.network_interface = "eth0"; + clientParms1.transportparm_size = XMLRPC_CXPSIZE(network_interface); + xmlrpc_client_init2(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparm_size)); + TEST_NO_FAULT(&env); + xmlrpc_client_cleanup(); + + curlTransportParms1.no_ssl_verifypeer = 1; + curlTransportParms1.no_ssl_verifyhost = 1; + clientParms1.transportparm_size = XMLRPC_CXPSIZE(no_ssl_verifyhost); + xmlrpc_client_init2(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparm_size)); + TEST_NO_FAULT(&env); + xmlrpc_client_cleanup(); + + curlTransportParms1.user_agent = "testprog/1.0"; + clientParms1.transportparm_size = XMLRPC_CXPSIZE(user_agent); + xmlrpc_client_init2(&env, 0, "testprog", "1.0", + &clientParms1, XMLRPC_CPSIZE(transportparm_size)); + TEST_NO_FAULT(&env); + xmlrpc_client_cleanup(); + + xmlrpc_client_init(0, "testprog", "1.0"); + TEST_NO_FAULT(&env); + xmlrpc_client_cleanup(); + + xmlrpc_env_clean(&env); +} + + + +static void +testServerInfo(void) { + + xmlrpc_env env; + xmlrpc_server_info * serverInfoP; + xmlrpc_server_info * serverInfo2P; + + printf(" Running serverInfo tests...\n"); + + xmlrpc_env_init(&env); + + serverInfoP = xmlrpc_server_info_new(&env, "testurl"); + TEST_NO_FAULT(&env); + + serverInfo2P = xmlrpc_server_info_copy(&env, serverInfoP); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_free(serverInfo2P); + + /* Fails because we haven't set user/password yet: */ + xmlrpc_server_info_allow_auth_basic(&env, serverInfoP); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_server_info_set_basic_auth(&env, serverInfoP, + "username", "password"); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_set_user(&env, serverInfoP, "username", "password"); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_allow_auth_basic(&env, serverInfoP); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_disallow_auth_basic(&env, serverInfoP); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_allow_auth_digest(&env, serverInfoP); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_disallow_auth_digest(&env, serverInfoP); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_allow_auth_negotiate(&env, serverInfoP); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_disallow_auth_negotiate(&env, serverInfoP); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_allow_auth_ntlm(&env, serverInfoP); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_disallow_auth_ntlm(&env, serverInfoP); + TEST_NO_FAULT(&env); + + xmlrpc_server_info_free(serverInfoP); + + xmlrpc_env_clean(&env); +} + + + +void +test_client(void) { + + printf("Running client tests."); + + testVersion(); + testGlobalConst(); + testCreateDestroy(); + testInitCleanup(); + printf("\n"); + testServerInfo(); + testSynchCall(); + + printf("\n"); + printf("Client tests done.\n"); +} diff --git a/trunk/test/client.h b/trunk/test/client.h new file mode 100644 index 000000000..272761702 --- /dev/null +++ b/trunk/test/client.h @@ -0,0 +1,2 @@ +void +test_client(void); diff --git a/trunk/test/client_dummy.c b/trunk/test/client_dummy.c new file mode 100644 index 000000000..6377fb85e --- /dev/null +++ b/trunk/test/client_dummy.c @@ -0,0 +1,14 @@ +#include + +#include "client.h" + + + +void +test_client(void) { + + printf("Running dummy client test."); + + printf("\n"); + printf("Client tests done.\n"); +} diff --git a/trunk/test/cpp/Makefile b/trunk/test/cpp/Makefile new file mode 100644 index 000000000..7e57d36b5 --- /dev/null +++ b/trunk/test/cpp/Makefile @@ -0,0 +1,134 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + testDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(testDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := test/cpp + +include $(BLDDIR)/config.mk + +PROGS = test + +default: all + +all: $(PROGS) + +XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test + +LIBS := + +LIBS += $(SOCKETLIBOPT) $(THREAD_LIBS) + +INCLUDES = -Isrcdir/include -I$(BLDDIR) -Isrcdir -Isrcdir/lib/util/include + +# This 'common.mk' dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/common.mk: srcdir blddir + +include $(SRCDIR)/common.mk + +TEST_OBJS = \ + test.o \ + base64.o \ + registry.o \ + server_pstream.o \ + tools.o \ + value.o \ + xml.o \ + +ifeq ($(MUST_BUILD_CLIENT),yes) + TEST_OBJS += testclient.o + LIBS += $(shell $(XMLRPC_C_CONFIG) client --ldadd) +else + TEST_OBJS += testclient_dummy.o +endif + +ifeq ($(ENABLE_ABYSS_SERVER),yes) + TEST_OBJS += abyss.o server_abyss.o + LIBS += $(shell $(XMLRPC_C_CONFIG) abyss-server --ldadd) +else + TEST_OBJS += abyss_dummy.o server_abyss_dummy.o +endif + +#----------------------------------------------------------------------------- +# TEST_LIBS +#----------------------------------------------------------------------------- +TEST_LIBS = +ifeq ($(ENABLE_ABYSS_SERVER),yes) + TEST_LIBS += $(LIBXMLRPC_SERVER_ABYSSPP_A) +endif +TEST_LIBS += $(LIBXMLRPC_SERVER_PSTREAMPP_A) +TEST_LIBS += $(LIBXMLRPC_SERVERPP_A) +ifeq ($(MUST_BUILD_CLIENT),yes) + TEST_LIBS += $(LIBXMLRPC_CLIENTPP_A) $(LIBXMLRPC_CLIENT_A) +endif +TEST_LIBS += $(LIBXMLRPCPP_A) +TEST_LIBS += $(LIBXMLRPC_CPP_A) +ifeq ($(ENABLE_ABYSS_SERVER),yes) + TEST_LIBS += $(LIBXMLRPC_SERVER_ABYSS_A) +endif +TEST_LIBS += $(LIBXMLRPC_SERVER_A) +TEST_LIBS += $(LIBXMLRPC_A) +ifeq ($(ENABLE_ABYSS_SERVER),yes) + TEST_LIBS += $(LIBXMLRPC_ABYSS_A) + TEST_LIBS += $(LIBXMLRPC_ABYSSPP_A) +endif +TEST_LIBS += $(LIBXMLRPC_PACKETSOCKET_A) +TEST_LIBS += $(LIBXMLRPC_UTILPP_A) +TEST_LIBS += $(LIBXMLRPC_UTIL_A) +ifeq ($(MSVCRT),yes) + TEST_LIBS += socketpair.o +endif +ifneq ($(ENABLE_LIBXML2_BACKEND),yes) + # We're using the internal Expat XML parser + TEST_LIBS += $(LIBXMLRPC_XMLPARSE_A) + TEST_LIBS += $(LIBXMLRPC_XMLTOK_A) +endif + +ifneq ($(ENABLE_LIBXML2_BACKEND),yes) + # We're using the internal Expat XML parser + LIB_XML = + registry.o: D_INTERNAL_EXPAT=-DINTERNAL_EXPAT +else + LIB_XML = $(shell xml2-config --libs) +endif + +test: $(TEST_OBJS) $(TEST_LIBS) + $(CXXLD) -o $@ $(LDFLAGS_ALL) $^ $(LIB_XML) $(LIBS) + +%.o:%.cpp + $(CXX) -c $(INCLUDES) $(CXXFLAGS_ALL) $(D_INTERNAL_EXPAT) $< + +socketpair.o: $(SRCDIR)/Windows/socketpair.cpp + $(CXX) -c $(INCLUDES) $(CXXFLAGS_ALL) $(D_INTERNAL_EXPAT) $< + +# Note the difference between 'check' and 'runtests'. 'check' means to check +# our own correctness. 'runtests' means to run the tests that check our +# parent's correctness + +.PHONY: check +check: + +.PHONY: runtests +runtests: test + ./test + +.PHONY: install +install: + +.PHONY: uninstall +uninstall: + +.PHONY: clean clean-local distclean +clean: clean-common clean-local +clean-local: + rm -f $(PROGS) + +distclean: clean distclean-common + +.PHONY: dep +dep: dep-common + +include depend.mk diff --git a/trunk/test/cpp/abyss.cpp b/trunk/test/cpp/abyss.cpp new file mode 100644 index 000000000..473670505 --- /dev/null +++ b/trunk/test/cpp/abyss.cpp @@ -0,0 +1,115 @@ +/*============================================================================= + abyss +=============================================================================== + Test the Abyss server C++ facilities of XML-RPC for C/C++. + +=============================================================================*/ +#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ + +#include + +using namespace std; + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/AbyssServer.hpp" +#include "xmlrpc-c/AbyssEnvironment.hpp" +#include "xmlrpc-c/AbyssChanSwitch.hpp" +#ifdef _WIN32 +#include "xmlrpc-c/AbyssChanSwitchWin.hpp" +#else +#include "xmlrpc-c/AbyssChanSwitchUnix.hpp" +#endif + +using namespace xmlrpc_c; + +#include "tools.hpp" +#include "abyss.hpp" + + + +// We need 'global' because methods of class addHandlerTestSuite call +// functions in the Abyss C library. By virtue of global's static +// storage class, the program loader will call its constructor and +// destructor and thus initialize and terminate the Abyss C library. + +static const AbyssEnvironment global; + +namespace { + + + +class addHandlerTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "addHandlerTestSuite"; + } + virtual void runtests(unsigned int const) { + + class AbyssReqHandler_Test : public AbyssServer::ReqHandler { + public: + AbyssReqHandler_Test() {} + + void + handleRequest(AbyssServer::Session * const , + bool * const ) {} + }; + +#ifdef _WIN32 + AbyssChanSwitchWin chanSwitch(8080); +#else + AbyssChanSwitchUnix chanSwitch(8080); +#endif + + AbyssServer abyssServer(&chanSwitch); + + AbyssReqHandler_Test abyssReqHandler; + + abyssServer.addRequestHandler(&abyssReqHandler); + } +}; + + + +class createTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "createTestSuite"; + } + virtual void runtests(unsigned int const) { +#ifdef _WIN32 + AbyssChanSwitchWin chanSwitch(8080); +#else + AbyssChanSwitchUnix chanSwitch(8080); +#endif + AbyssServer abyssServer(&chanSwitch); + + } +}; + + + +} // namespace + + + +string +abyssTestSuite::suiteName() { + return "abyssTestSuite"; +} + + +void +abyssTestSuite::runtests(unsigned int const indentation) { + + createTestSuite().run(indentation+1); + + addHandlerTestSuite().run(indentation+1); +} + + + diff --git a/trunk/test/cpp/abyss.hpp b/trunk/test/cpp/abyss.hpp new file mode 100644 index 000000000..88c054baf --- /dev/null +++ b/trunk/test/cpp/abyss.hpp @@ -0,0 +1,8 @@ +#include "tools.hpp" + +class abyssTestSuite : public testSuite { + +public: + virtual std::string suiteName(); + virtual void runtests(unsigned int const); +}; diff --git a/trunk/test/cpp/abyss_dummy.cpp b/trunk/test/cpp/abyss_dummy.cpp new file mode 100644 index 000000000..0482370a4 --- /dev/null +++ b/trunk/test/cpp/abyss_dummy.cpp @@ -0,0 +1,29 @@ +/*============================================================================= + abyss_dummy +=============================================================================== + This is a substitute for abyss.cpp, for use in a test program that is + not linked with the Abyss libraries. + + It simply passes the test. +=============================================================================*/ + +#include +#include + +#include "tools.hpp" +#include "abyss.hpp" + +using namespace std; + +string +abyssTestSuite::suiteName() { + return "abyssTestSuite"; +} + + +void +abyssTestSuite::runtests(unsigned int const indentation) { + + cout << string((indentation+1)*2, ' ') + << "Running dummy test." << endl; +} diff --git a/trunk/test/cpp/base64.cpp b/trunk/test/cpp/base64.cpp new file mode 100644 index 000000000..17e4e780b --- /dev/null +++ b/trunk/test/cpp/base64.cpp @@ -0,0 +1,54 @@ +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "xmlrpc-c/base64.hpp" + +#include "tools.hpp" + +#include "base64.hpp" + +using namespace xmlrpc_c; +using namespace std; + + + +string +base64TestSuite::suiteName() { + return "base64TestSuite"; +} + + + +void +base64TestSuite::runtests(unsigned int const) { + + unsigned char const bytes0Data[] = "This is a test"; + + vector bytes0(&bytes0Data[0], + &bytes0Data[sizeof(bytes0Data)]); + + string const base64_0("VGhpcyBpcyBhIHRlc3QA"); + + string const expectedBase64_0(base64_0 + "\r\n"); + + TEST(base64FromBytes(bytes0) == expectedBase64_0); + + TEST(bytesFromBase64(base64_0) == bytes0); + + unsigned char const bytes1Data[] = {0x80, 0xff}; + + vector bytes1(&bytes1Data[0], + &bytes1Data[sizeof(bytes1Data)]); + + string const base64_1("gP8="); + + string const expectedBase64_1(base64_1 + "\r\n"); + + TEST(base64FromBytes(bytes1) == expectedBase64_1); + + TEST(bytesFromBase64(base64_1) == bytes1); + +} diff --git a/trunk/test/cpp/base64.hpp b/trunk/test/cpp/base64.hpp new file mode 100644 index 000000000..72ee02d93 --- /dev/null +++ b/trunk/test/cpp/base64.hpp @@ -0,0 +1,9 @@ +#include "tools.hpp" + +class base64TestSuite : public testSuite { + +public: + virtual std::string suiteName(); + virtual void runtests(unsigned int const indentation); +}; + diff --git a/trunk/test/cpp/registry.cpp b/trunk/test/cpp/registry.cpp new file mode 100644 index 000000000..0eb7d37c7 --- /dev/null +++ b/trunk/test/cpp/registry.cpp @@ -0,0 +1,550 @@ +/*============================================================================= + registry +=============================================================================== + Test the method registry (server) C++ facilities of XML-RPC for C/C++. + +=============================================================================*/ + +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/registry.hpp" + +#include "tools.hpp" +#include "registry.hpp" + +using namespace xmlrpc_c; +using namespace std; + + + +namespace { + +static string const +xmlPrologue("\r\n"); + +static string const +apacheUrl("http://ws.apache.org/xmlrpc/namespaces/extensions"); + +static string const +xmlnsApache("xmlns:ex=\"" + apacheUrl + "\""); + + +string const noElementFoundXml( + xmlPrologue + + "\r\n" + "\r\n" + "\r\n" + "faultCode\r\n" + "-503\r\n" + "faultString\r\n" + "Call XML not a proper XML-RPC call. " + "Call is not valid XML. no element found" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + ); + +string const invalidXMLCall( + xmlPrologue + + "\r\n" + "\r\n" + "\r\n" + "faultCode\r\n" + "-503\r\n" + "faultString\r\n" + "Call XML not a proper XML-RPC call. " + "Call is not valid XML. XML parsing failed" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + ); + +string const sampleAddGoodCallXml( + xmlPrologue + + "\r\n" + "sample.add\r\n" + "\r\n" + "5\r\n" + "7\r\n" + "\r\n" + "\r\n" + ); + +string const sampleAddGoodResponseXml( + xmlPrologue + + "\r\n" + "\r\n" + "12\r\n" + "\r\n" + "\r\n" + ); + + +string const sampleAddBadCallXml( + xmlPrologue + + "\r\n" + "sample.add\r\n" + "\r\n" + "5\r\n" + "\r\n" + "\r\n" + ); + +string const sampleAddBadResponseXml( + xmlPrologue + + "\r\n" + "\r\n" + "\r\n" + "faultCode\r\n" + "-501\r\n" + "faultString\r\n" + "Not enough parameters\r\n" + "\r\n" + "\r\n" + "\r\n" + ); + +string const testCallInfoCallXml( + xmlPrologue + + "\r\n" + "test.callinfo\r\n" + "\r\n" + "\r\n" + "\r\n" + ); + +string const testCallInfoResponseXml( + xmlPrologue + + "\r\n" + "\r\n" + "this is a test callInfo" + "\r\n" + "\r\n" + "\r\n" + ); + +string const nonexistentMethodCallXml( + xmlPrologue + + "\r\n" + "nosuchmethod\r\n" + "\r\n" + "5\r\n" + "7\r\n" + "\r\n" + "\r\n" + ); + +string const nonexistentMethodYesDefResponseXml( + xmlPrologue + + "\r\n" + "\r\n" + "no such method: nosuchmethod" + "\r\n" + "\r\n" + "\r\n" + ); + +string const nonexistentMethodNoDefResponseXml( + xmlPrologue + + "\r\n" + "\r\n" + "\r\n" + "faultCode\r\n" + "-506\r\n" + "faultString\r\n" + "Method 'nosuchmethod' not defined" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + ); + + + +string const echoI8ApacheCall( + xmlPrologue + + "\r\n" + "echo\r\n" + "\r\n" + "5\r\n" + "\r\n" + "\r\n" + ); + +string const echoI8ApacheResponse( + xmlPrologue + + "\r\n" + "\r\n" + "5\r\n" + "\r\n" + "\r\n" + ); + +string const echoNilApacheCall( + xmlPrologue + + "\r\n" + "echo\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + ); + +string const echoNilApacheResponse( + xmlPrologue + + "\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n" + ); + + +class callInfo_test : public callInfo { + +public: + callInfo_test() : data("this is a test callInfo") {} + + callInfo_test(string const& data) : data(data) {}; + + string data; +}; + + + +class sampleAddMethod : public method { +public: + sampleAddMethod() { + this->_signature = "i:ii"; + this->_help = "This method adds two integers together"; + } + void + execute(xmlrpc_c::paramList const& paramList, + value * const retvalP) { + + int const addend(paramList.getInt(0)); + int const adder(paramList.getInt(1)); + + paramList.verifyEnd(2); + + *retvalP = value_int(addend + adder); + } +}; + + + +class sampleAddMethod2 : public method2 { +public: + sampleAddMethod2() { + this->_signature = "i:ii"; + this->_help = "This method adds two integers together"; + } + void + execute(xmlrpc_c::paramList const& paramList, + const callInfo * const, + value * const retvalP) { + + int const addend(paramList.getInt(0)); + int const adder(paramList.getInt(1)); + + paramList.verifyEnd(2); + + *retvalP = value_int(addend + adder); + } +}; + + + +class testCallInfoMethod : public method2 { +public: + testCallInfoMethod() { + this->_signature = "s:"; + } + void + execute(xmlrpc_c::paramList const& paramList, + const callInfo * const callInfoPtr, + value * const retvalP) { + + const callInfo_test * const callInfoP( + dynamic_cast(callInfoPtr)); + + TEST(callInfoP != NULL); + + paramList.verifyEnd(0); + + *retvalP = value_string(callInfoP->data); + } +}; + + + +class nameMethod : public defaultMethod { + + void + execute(string const& methodName, + xmlrpc_c::paramList const& , // paramList + value * const retvalP) { + + *retvalP = value_string(string("no such method: ") + methodName); + } +}; + + + +class echoMethod : public method { +public: + void + execute(xmlrpc_c::paramList const& paramList, + value * const retvalP) { + + paramList.verifyEnd(1); + + *retvalP = paramList[0]; + } +}; + + + +static void +testEmptyXmlDocCall(xmlrpc_c::registry const& myRegistry) { + + string response; + myRegistry.processCall("", &response); + +#ifdef INTERNAL_EXPAT + TEST(response == noElementFoundXml); +#else + // This is what we get with libxml2 + TEST(response == invalidXMLCall); +#endif +} + + + +class registryRegMethodTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "registryRegMethodTestSuite"; + } + virtual void runtests(unsigned int const) { + + xmlrpc_c::registry myRegistry; + + sampleAddMethod m; + + myRegistry.addMethod("xyz", &m); + + myRegistry.addMethod("sample.add", + xmlrpc_c::methodPtr(new sampleAddMethod)); + + myRegistry.disableIntrospection(); + testEmptyXmlDocCall(myRegistry); + { + string response; + myRegistry.processCall(sampleAddGoodCallXml, &response); + TEST(response == sampleAddGoodResponseXml); + } + { + string response; + myRegistry.processCall(sampleAddBadCallXml, &response); + TEST(response == sampleAddBadResponseXml); + } + { + string response; + callInfo const callInfo; + myRegistry.processCall(sampleAddBadCallXml, &callInfo, &response); + TEST(response == sampleAddBadResponseXml); + } + } +}; + + + +class registryDefaultMethodTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "registryDefaultMethodTestSuite"; + } + virtual void runtests(unsigned int const) { + + xmlrpc_c::registry myRegistry; + + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + + { + string response; + myRegistry.processCall(sampleAddGoodCallXml, &response); + TEST(response == sampleAddGoodResponseXml); + } + { + string response; + myRegistry.processCall(nonexistentMethodCallXml, &response); + TEST(response == nonexistentMethodNoDefResponseXml); + } + // We're actually violating the spirit of setDefaultMethod by + // doing this to a registry that's already been used, but as long + // as it works, it's a convenient way to implement this test. + nameMethod dm; + myRegistry.setDefaultMethod(&dm); + myRegistry.setDefaultMethod(defaultMethodPtr(new nameMethod)); + + { + string response; + myRegistry.processCall(nonexistentMethodCallXml, &response); + TEST(response == nonexistentMethodYesDefResponseXml); + } + } +}; + + + +class method2TestSuite : public testSuite { + +public: + virtual string suiteName() { + return "method2TestSuite"; + } + virtual void runtests(unsigned int const) { + + xmlrpc_c::registry myRegistry; + + myRegistry.addMethod("sample.add", + xmlrpc_c::methodPtr(new sampleAddMethod2)); + + myRegistry.addMethod("test.callinfo", + xmlrpc_c::methodPtr(new testCallInfoMethod)); + + { + string response; + myRegistry.processCall(sampleAddGoodCallXml, &response); + TEST(response == sampleAddGoodResponseXml); + } + { + string response; + myRegistry.processCall(sampleAddBadCallXml, &response); + TEST(response == sampleAddBadResponseXml); + } + { + string response; + callInfo_test const callInfo; + myRegistry.processCall(testCallInfoCallXml, &callInfo, &response); + TEST(response == testCallInfoResponseXml); + } + } +}; + + + +class dialectTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "dialectTestSuite"; + } + virtual void runtests(unsigned int const) { + + registry myRegistry; + string response; + + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + myRegistry.addMethod("echo", methodPtr(new echoMethod)); + + myRegistry.setDialect(xmlrpc_dialect_i8); + + myRegistry.setDialect(xmlrpc_dialect_apache); + + myRegistry.processCall(echoI8ApacheCall, &response); + + TEST(response == echoI8ApacheResponse); + + myRegistry.processCall(echoNilApacheCall, &response); + + TEST(response == echoNilApacheResponse); + + EXPECT_ERROR( // invalid dialect + myRegistry.setDialect(static_cast(300)); + ); + } +}; + + + +class testShutdown : public xmlrpc_c::registry::shutdown { +/*---------------------------------------------------------------------------- + This class is logically local to + registryShutdownTestSuite::runtests(), but if we declare it that + way, gcc 2.95.3 fails with some bogus messages about undefined + references from random functions when we do that. +-----------------------------------------------------------------------------*/ +public: + void doit(string const&, + void * const) const { + + } +}; + + + +class registryShutdownTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "registryShutdownTestSuite"; + } + virtual void runtests(unsigned int const) { + + xmlrpc_c::registry myRegistry; + + testShutdown shutdown; + + myRegistry.setShutdown(&shutdown); + } +}; + + + +} // unnamed namespace + + + +string +registryTestSuite::suiteName() { + return "registryTestSuite"; +} + + + +void +registryTestSuite::runtests(unsigned int const indentation) { + + { + registryPtr myRegistryP(new registry); + + myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); + } + + registryRegMethodTestSuite().run(indentation+1); + + registryDefaultMethodTestSuite().run(indentation+1); + + method2TestSuite().run(indentation+1); + + registry myRegistry; + + myRegistry.disableIntrospection(); + + dialectTestSuite().run(indentation+1); + + registryShutdownTestSuite().run(indentation+1); + + TEST(myRegistry.maxStackSize() >= 256); + +} diff --git a/trunk/test/cpp/registry.hpp b/trunk/test/cpp/registry.hpp new file mode 100644 index 000000000..b8614257d --- /dev/null +++ b/trunk/test/cpp/registry.hpp @@ -0,0 +1,9 @@ +#include "tools.hpp" + +class registryTestSuite : public testSuite { + +public: + virtual std::string suiteName(); + virtual void runtests(unsigned int const indentation); +}; + diff --git a/trunk/test/cpp/server_abyss.cpp b/trunk/test/cpp/server_abyss.cpp new file mode 100644 index 000000000..c1b449952 --- /dev/null +++ b/trunk/test/cpp/server_abyss.cpp @@ -0,0 +1,410 @@ +/*============================================================================= + server_abyss +=============================================================================== + Test the Abyss XML-RPC server C++ facilities of XML-RPC for C/C++. + +=============================================================================*/ +#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WIN32 + #include +#else + #include + #include + #include + #include +#endif + +using namespace std; + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/registry.hpp" +#include "xmlrpc-c/server_abyss.hpp" +#include "xmlrpc-c/abyss.h" + +using namespace xmlrpc_c; + +#include "tools.hpp" +#include "server_abyss.hpp" + + + +namespace { + +static void +closesock(int const fd) { +#ifdef WIN32 + closesocket(fd); +#else + close(fd); +#endif +} + + + +static sockaddr_in +localhostSockAddr(short const portNumber) { + + struct sockaddr_in retval; + + retval.sin_family = AF_INET; + retval.sin_port = htons(portNumber); + retval.sin_addr = test_ipAddrFromDecimal(127, 0, 0, 1); + + return retval; +} + + + +class boundSocket { + +public: + boundSocket(short const portNumber) { + this->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (this->fd < 0) + throwf("socket() failed. errno=%d (%s)", + errno, strerror(errno)); + + struct sockaddr_in sockAddr; + int rc; + + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons(portNumber); + sockAddr.sin_addr.s_addr = 0; + + rc = bind(this->fd, (struct sockaddr *)&sockAddr, sizeof(sockAddr)); + + if (rc != 0) { + closesock(this->fd); + throwf("Couldn't bind. bind() failed with errno=%d (%s)", + errno, strerror(errno)); + } + } + + ~boundSocket() { + closesock(this->fd); + } + + XMLRPC_SOCKET fd; +}; + + + +class sampleAddMethod : public method { +public: + sampleAddMethod() { + this->_signature = "i:ii"; + this->_help = "This method adds two integers together"; + } + void + execute(xmlrpc_c::paramList const& paramList, + value * const retvalP) { + + int const addend(paramList.getInt(0)); + int const adder(paramList.getInt(1)); + + paramList.verifyEnd(2); + + *retvalP = value_int(addend + adder); + } +}; + + + +// We need 'global' because methods of class addHandlerTestSuite call +// functions in the Abyss C library. By virtue of global's static +// storage class, the program loader will call its constructor and +// destructor and thus initialize and terminate the Abyss C library. + +static class abyssGlobalState { +public: + abyssGlobalState() { + const char * error; + AbyssInit(&error); + if (error) { + string const e(error); + free(const_cast(error)); + throwf("AbyssInit() failed. %s", e.c_str()); + } + } + ~abyssGlobalState() { + AbyssTerm(); + } +} const global; + + + +class addHandlerTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "addHandlerTestSuite"; + } + virtual void runtests(unsigned int const) { + TServer abyssServer; + + ServerCreate(&abyssServer, "testserver", 8080, NULL, NULL); + + registry myRegistry; + + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + + registryPtr myRegistryP(new registry); + + myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); + + server_abyss_set_handlers(&abyssServer, myRegistry); + + server_abyss_set_handlers(&abyssServer, &myRegistry); + + server_abyss_set_handlers(&abyssServer, myRegistryP); + + server_abyss_set_handlers(&abyssServer, myRegistry, "/RPC3"); + + server_abyss_set_handlers(&abyssServer, &myRegistry, "/RPC3"); + + server_abyss_set_handlers(&abyssServer, myRegistryP, "/RPC3"); + + ServerFree(&abyssServer); + } +}; + + + +class setShutdownTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "setShutdownTestSuite"; + } + virtual void runtests(unsigned int const) { + + registry myRegistry; + + serverAbyss myServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + .portNumber(12345) + ); + + serverAbyss::shutdown shutdown(&myServer); + + myRegistry.setShutdown(&shutdown); + } +}; + + + +class createTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "createTestSuite"; + } + virtual void runtests(unsigned int const) { + + registry myRegistry; + + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + + registryPtr myRegistryP(new registry); + + myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); + + struct sockaddr_in const sockAddr(localhostSockAddr(8080)); + const struct sockaddr * const sockAddrP( + (const struct sockaddr *)&sockAddr); + + EXPECT_ERROR( // No registry + serverAbyss::constrOpt opt; + serverAbyss abyssServer(opt); + ); + EXPECT_ERROR( // Both registryP and registryPtr + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryPtr(myRegistryP) + .registryP(&myRegistry) + .portNumber(12345) + ); + ); + EXPECT_ERROR( // Both portNumber and socketFd + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + .portNumber(8080) + .socketFd(3)); + ); + + EXPECT_ERROR( // Both portNumber and sockAddrP + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + .portNumber(8080) + .sockAddrP(sockAddrP) + .sockAddrLen(sizeof(sockAddr))); + ); + + EXPECT_ERROR( // Both socketFd and sockAddrP + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + .socketFd(3) + .sockAddrP(sockAddrP) + .sockAddrLen(sizeof(sockAddr))); + ); + + EXPECT_ERROR( // sockAddrP but no sockAddrLen + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + .sockAddrP(sockAddrP)); + ); + + EXPECT_ERROR( // port number too big + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + .portNumber(65536)); + ); + + // Because of the vagaries of Abyss, construction of the following + // objects may exit the program if it detects an error, such as + // port number already in use. We need to fix Abyss some day. + + { + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + .portNumber(12345) + ); + } + { + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryPtr(myRegistryP) + .portNumber(12345) + ); + } + { + boundSocket socket(12345); + + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + .socketFd(socket.fd) + ); + } + { + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + ); + } + + { + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryPtr(myRegistryP) + .sockAddrP(sockAddrP) + .sockAddrLen(sizeof(sockAddr)) + ); + } + { + // Test all the options + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryPtr(myRegistryP) + .portNumber(12345) + .maxConn(10) + .maxConnBacklog(10) + .keepaliveTimeout(5) + .keepaliveMaxConn(4) + .timeout(20) + .dontAdvertise(true) + .uriPath("/xmlrpc") + .chunkResponse(true) + .allowOrigin("*") + .accessCtlMaxAge(42) + .logFileName("/tmp/logfile") + .serverOwnsSignals(false) + .expectSigchld(true) + ); + + } + { + serverAbyss abyssServer( + myRegistry, + 12345, // TCP port on which to listen + "/tmp/xmlrpc_log" // Log file + ); + } + } +}; + + + +class testCallInfoMethod : public method2 { +public: + void + execute(paramList const& paramList, + const callInfo * const callInfoPtr, + value * const retvalP) { + + const callInfo_serverAbyss * const callInfoP( + dynamic_cast(callInfoPtr)); + + TEST(callInfoP != NULL); + + paramList.verifyEnd(0); + + TEST(callInfoP->serverAbyssP != NULL); + TEST(callInfoP->abyssSessionP != NULL); + + *retvalP = value_nil(); + } +}; + + + +class callInfoTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "callInfoTestSuite"; + } + virtual void runtests(unsigned int const) { + + registry myRegistry; + + myRegistry.addMethod("sample.add", methodPtr(new testCallInfoMethod)); + + serverAbyss abyssServer(serverAbyss::constrOpt() + .registryP(&myRegistry) + .portNumber(12345) + ); + } +}; + + + +} // unnamed namespace + + + +string +serverAbyssTestSuite::suiteName() { + return "serverAbyssTestSuite"; +} + + +void +serverAbyssTestSuite::runtests(unsigned int const indentation) { + + addHandlerTestSuite().run(indentation+1); + + setShutdownTestSuite().run(indentation+1); + + createTestSuite().run(indentation+1); + + callInfoTestSuite().run(indentation+1); +} diff --git a/trunk/test/cpp/server_abyss.hpp b/trunk/test/cpp/server_abyss.hpp new file mode 100644 index 000000000..88da51594 --- /dev/null +++ b/trunk/test/cpp/server_abyss.hpp @@ -0,0 +1,8 @@ +#include "tools.hpp" + +class serverAbyssTestSuite : public testSuite { + +public: + virtual std::string suiteName(); + virtual void runtests(unsigned int const); +}; diff --git a/trunk/test/cpp/server_abyss_dummy.cpp b/trunk/test/cpp/server_abyss_dummy.cpp new file mode 100644 index 000000000..307ac99f0 --- /dev/null +++ b/trunk/test/cpp/server_abyss_dummy.cpp @@ -0,0 +1,29 @@ +/*============================================================================= + server_abyss_dummy +=============================================================================== + This is a substitute for server_abyss.cpp, for use in a test program that is + not linked with the Abyss XML-RPC server libraries. + + It simply passes the test. +=============================================================================*/ + +#include +#include + +#include "tools.hpp" +#include "server_abyss.hpp" + +using namespace std; + +string +serverAbyssTestSuite::suiteName() { + return "serverAbyssTestSuite"; +} + + +void +serverAbyssTestSuite::runtests(unsigned int const indentation) { + + cout << string((indentation+1)*2, ' ') + << "Running dummy test." << endl; +} diff --git a/trunk/test/cpp/server_pstream.cpp b/trunk/test/cpp/server_pstream.cpp new file mode 100644 index 000000000..1709bc414 --- /dev/null +++ b/trunk/test/cpp/server_pstream.cpp @@ -0,0 +1,821 @@ +/*============================================================================= + server_pstream +=============================================================================== + Test the pstream server C++ facilities of XML-RPC for C/C++. + +=============================================================================*/ + +#include "xmlrpc_config.h" + +#if MSVCRT + #include + #include +#else + #include + #include + #include + #include +#endif + +#include +#include +#include +#include + +#include "xmlrpc-c/config.h" + +#if MSVCRT + int + xmlrpc_win32_socketpair(int const domain, + int const type, + int const protocol, + SOCKET socks[2]); +#endif + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/sleep_int.h" +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/registry.hpp" +#include "xmlrpc-c/server_pstream.hpp" + +#include "tools.hpp" +#include "server_pstream.hpp" + +using namespace xmlrpc_c; +using namespace std; + + +namespace { + +static void +setNonBlocking(XMLRPC_SOCKET const socket) { + +#if MSVCRT + u_long iMode = 1; + ioctlsocket(socket, FIONBIO, &iMode); +#else + fcntl(socket, F_SETFL, O_NONBLOCK); +#endif +} + + + +#define ESC_STR "\x1B" + + +static string const +xmlPrologue("\r\n"); + +static string const +packetStart(ESC_STR "PKT"); + +static string const +packetEnd(ESC_STR "END"); + + +class callInfo_test : public callInfo { +public: + callInfo_test() : info("this is a test") {} + string const info; +}; + + + +class sampleAddMethod : public method { +public: + sampleAddMethod() { + this->_signature = "i:ii"; + this->_help = "This method adds two integers together"; + } + void + execute(xmlrpc_c::paramList const& paramList, + value * const retvalP) { + + int const addend(paramList.getInt(0)); + int const adder(paramList.getInt(1)); + + paramList.verifyEnd(2); + + *retvalP = value_int(addend + adder); + } +}; + +string const sampleAddCallXml( + xmlPrologue + + "\r\n" + "sample.add\r\n" + "\r\n" + "5\r\n" + "7\r\n" + "\r\n" + "\r\n" + ); + +string const sampleAddResponseXml( + xmlPrologue + + "\r\n" + "\r\n" + "12\r\n" + "\r\n" + "\r\n" + ); + + +class testCallInfoMethod : public method2 { + +public: + virtual void + execute(paramList const& paramList, + const callInfo * const callInfoPtr, + value * const retvalP) { + + const callInfo_test * const callInfoP( + dynamic_cast(callInfoPtr)); + + TEST(callInfoP != NULL); + + paramList.verifyEnd(0); + + TEST(callInfoP->info == string("this is a test")); + + *retvalP = value_nil(); + } +}; + +string const testCallInfoCallXml( + xmlPrologue + + "\r\n" + "test.callinfo\r\n" + "\r\n" + "\r\n" + "\r\n" + ); + +string const testCallInfoResponseXml( + xmlPrologue + + "\r\n" + "\r\n" + "" + "\r\n" + "\r\n" + "\r\n" + ); + + + +static void +waitForNetworkTransport() { +/*---------------------------------------------------------------------------- + Wait for a message to travel through the network. + + This is part of our hack to allow us to test client/server communication + without the bother of a separate thread for each. One party writes + to a socket, causing the OS to buffer the message, then the other party + reads from the socket, getting the buffered message. We never wait + to send or receive, because with only one thread to do both, we would + deadlock. Instead, we just count on the buffer being big enough. + + But on some systems, the message doesn't immediately travel like this. It + takes action by an independent thread (provided by the OS) to move the + message. In particular, we've seen this behavior on Windows (2010.10). + + So we just sleep for a small amount of time to let the message move. +-----------------------------------------------------------------------------*/ + + // xmlrpc_millisecond_sleep() is allowed to return early, and on Windows + // it does that in preference to returning late insofar as the clock + // resolution doesn't allow returning at the exact time. It is rumored + // that Windows clock period may be as long as 40 milliseconds. + + xmlrpc_millisecond_sleep(50); +} + + + +class client { +/*---------------------------------------------------------------------------- + This is an object you can use as a client to test a packet stream + server. + + You attach the 'serverFd' member to your packet stream server, then + call the 'sendCall' method to send a call to your server, then call + the 'recvResp' method to get the response. + + Destroying the object closes the connection. + + We rely on typical, though unguaranteed socket function: we need to + be able to write 'contents' to the socket in a single write() + system call before the other side reads anything -- i.e. the socket + has to have a buffer that big. We do this because we're lazy; doing + it right would require forking a writer process. +-----------------------------------------------------------------------------*/ +public: + + client(); + + ~client(); + + void + sendCall(string const& callBytes) const; + + void + hangup(); + + void + recvResp(string * const respBytesP) const; + + int serverFd; + +private: + + int clientFd; +}; + + + +client::client() { + + enum { + SERVER = 0, + CLIENT = 1, + }; + XMLRPC_SOCKET sockets[2]; + int rc; + + rc = XMLRPC_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, sockets); + + if (rc < 0) + throwf("Failed to create UNIX domain stream socket pair " + "as test tool. errno=%d (%s)", + errno, strerror(errno)); + else { + setNonBlocking(sockets[CLIENT]); + + this->serverFd = sockets[SERVER]; + this->clientFd = sockets[CLIENT]; + } +} + + + +client::~client() { + + XMLRPC_CLOSESOCKET(this->clientFd); + XMLRPC_CLOSESOCKET(this->serverFd); +} + + + +void +client::sendCall(string const& packetBytes) const { + + int rc; + + rc = send(this->clientFd, packetBytes.c_str(), packetBytes.length(), 0); + + waitForNetworkTransport(); + + if (rc < 0) + throwf("send() of test data to socket failed, errno=%d (%s)", + errno, strerror(errno)); + else { + unsigned int bytesWritten(rc); + + if (bytesWritten != packetBytes.length()) + throwf("Short write to socket"); + } +} + + + +void +client::hangup() { + + // Closing the socket (close()) would be a better simulation of the + // real world, and easier, but we shut down just the client->server + // half of the socket and remain open to receive an RPC response. + // That's because this test program is lazy and does the client and + // server in the same thread, depending on socket buffering on the + // receive side to provide parallelism. We need to be able to do the + // following sequence: + // + // - Client sends call + // - Client hangs up + // - Server gets call + // - Server sends response + // - Client gets response + // - Server notices hangup + + shutdown(this->clientFd, 1); // Shutdown for transmission only +} + + + +void +client::recvResp(string * const packetBytesP) const { + + char buffer[4096]; + int rc; + + waitForNetworkTransport(); + + rc = recv(this->clientFd, buffer, sizeof(buffer), 0); + + if (rc < 0) + throwf("recv() from socket failed, errno=%d (%s)", + errno, strerror(errno)); + else { + unsigned int bytesReceived(rc); + + *packetBytesP = string(buffer, bytesReceived); + } +} + + + +static void +testEmptyStream(registry const& myRegistry) { +/*---------------------------------------------------------------------------- + Here we send the pstream server an empty stream; i.e. we close the + socket from the client end without sending anything. + + This should cause the server to recognize EOF. +-----------------------------------------------------------------------------*/ + + client client; + + serverPstreamConn server(serverPstreamConn::constrOpt() + .registryP(&myRegistry) + .socketFd(client.serverFd)); + + client.hangup(); + + bool eof; + server.runOnce(&eof); + + TEST(eof); +} + + + +static void +testBrokenPacket(registry const& myRegistry) { +/*---------------------------------------------------------------------------- + Here we send a stream that is not a legal packetsocket stream: it + doesn't have any control word. +-----------------------------------------------------------------------------*/ + client client; + + serverPstreamConn server(serverPstreamConn::constrOpt() + .registryP(&myRegistry) + .socketFd(client.serverFd)); + + client.sendCall("junk"); + client.hangup(); + + bool eof; + + EXPECT_ERROR( + server.runOnce(&eof); + ); +} + + + +static void +testEmptyPacket(registry const& myRegistry) { +/*---------------------------------------------------------------------------- + Here we send the pstream server one empty packet. It should respond + with one packet, being an XML-RPC fault response complaining that the + call is not valid XML. +-----------------------------------------------------------------------------*/ + client client; + + serverPstreamConn server(serverPstreamConn::constrOpt() + .registryP(&myRegistry) + .socketFd(client.serverFd)); + + client.sendCall(packetStart + packetEnd); + + bool eof; + server.runOnce(&eof); + + TEST(!eof); + + string response; + client.recvResp(&response); + + // We ought to validate that the response is a complaint about + // the empty call + + client.hangup(); + + server.runOnce(&eof); + + TEST(eof); +} + + + +static void +testCallInfo(client * const clientP, + serverPstreamConn * const serverP) { + + string const testCallInfoCallStream( + packetStart + testCallInfoCallXml + packetEnd + ); + + string const testCallInfoResponseStream( + packetStart + testCallInfoResponseXml + packetEnd + ); + + clientP->sendCall(testCallInfoCallStream); + + callInfo_test callInfo; + int nointerrupt(0); + bool eof; + serverP->runOnce(&callInfo, &nointerrupt, &eof); + + TEST(!eof); + + string response; + clientP->recvResp(&response); + + TEST(response == testCallInfoResponseStream); +} + + + +static void +testNormalCall(registry const& myRegistry) { + + string const sampleAddGoodCallStream( + packetStart + sampleAddCallXml + packetEnd + ); + + string const sampleAddGoodResponseStream( + packetStart + sampleAddResponseXml + packetEnd + ); + + client client; + + serverPstreamConn server(serverPstreamConn::constrOpt() + .registryP(&myRegistry) + .socketFd(client.serverFd)); + + client.sendCall(sampleAddGoodCallStream); + + bool eof; + + int interrupt(1); + server.runOnce(&interrupt, &eof); // returns without reading socket + TEST(!eof); + + server.runOnce(&eof); + + TEST(!eof); + + string response; + client.recvResp(&response); + + TEST(response == sampleAddGoodResponseStream); + + testCallInfo(&client, &server); + + client.hangup(); + + server.runOnce(&eof); + + TEST(eof); +} + + + +static void +testNoWaitCall(registry const& myRegistry) { + + string const sampleAddGoodCallStream( + packetStart + + xmlPrologue + + "\r\n" + "sample.add\r\n" + "\r\n" + "5\r\n" + "7\r\n" + "\r\n" + "\r\n" + + packetEnd + ); + + + string const sampleAddGoodResponseStream( + packetStart + + xmlPrologue + + "\r\n" + "\r\n" + "12\r\n" + "\r\n" + "\r\n" + + packetEnd + ); + + client client; + + serverPstreamConn server(serverPstreamConn::constrOpt() + .registryP(&myRegistry) + .socketFd(client.serverFd)); + + bool eof; + bool gotOne; + string response; + + server.runOnceNoWait(&eof, &gotOne); + + TEST(!eof); + TEST(!gotOne); + + server.runOnceNoWait(&eof); + + TEST(!eof); + + client.sendCall(sampleAddGoodCallStream); + + server.runOnceNoWait(&eof, &gotOne); + + TEST(!eof); + TEST(gotOne); + + client.recvResp(&response); + + TEST(response == sampleAddGoodResponseStream); + + client.sendCall(sampleAddGoodCallStream); + + server.runOnce(&eof); + + TEST(!eof); + client.recvResp(&response); + TEST(response == sampleAddGoodResponseStream); + + client.hangup(); + + server.runOnce(&eof); + + TEST(eof); +} + + + +static void +testMultiRpcRunNoRpc(registry const& myRegistry) { + + client client; + + serverPstreamConn server(serverPstreamConn::constrOpt() + .registryP(&myRegistry) + .socketFd(client.serverFd)); + + client.hangup(); + + server.run(); +} + + + +static void +testMultiRpcRunOneRpc(registry const& myRegistry) { + + string const sampleAddGoodCallStream( + packetStart + + xmlPrologue + + "\r\n" + "sample.add\r\n" + "\r\n" + "5\r\n" + "7\r\n" + "\r\n" + "\r\n" + + packetEnd + ); + + + string const sampleAddGoodResponseStream( + packetStart + + xmlPrologue + + "\r\n" + "\r\n" + "12\r\n" + "\r\n" + "\r\n" + + packetEnd + ); + + client client; + + serverPstreamConn server(serverPstreamConn::constrOpt() + .registryP(&myRegistry) + .socketFd(client.serverFd)); + + + client.sendCall(sampleAddGoodCallStream); + client.hangup(); + + int interrupt; + + interrupt = 1; + server.run(&interrupt); // Returns without reading socket + + interrupt = 0; + server.run(&interrupt); // Does the buffered RPC + + string response; + client.recvResp(&response); + + TEST(response == sampleAddGoodResponseStream); +} + + + +class serverPstreamConnTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "serverPstreamConnTestSuite"; + } + virtual void runtests(unsigned int const) { + registry myRegistry; + + myRegistry.addMethod("sample.add", + methodPtr(new sampleAddMethod)); + myRegistry.addMethod("test.callinfo", + methodPtr(new testCallInfoMethod)); + + registryPtr myRegistryP(new registry); + + myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); + + EXPECT_ERROR( // Empty options + serverPstreamConn::constrOpt opt; + serverPstreamConn server(opt); + ); + + EXPECT_ERROR( // No registry + serverPstreamConn server(serverPstreamConn::constrOpt() + .socketFd(3)); + ); + + EXPECT_ERROR( // No socket fd + serverPstreamConn server(serverPstreamConn::constrOpt() + .registryP(&myRegistry)); + ); + + testEmptyStream(myRegistry); + + testBrokenPacket(myRegistry); + + testEmptyPacket(myRegistry); + + testNormalCall(myRegistry); + + testNoWaitCall(myRegistry); + + testMultiRpcRunNoRpc(myRegistry); + + testMultiRpcRunOneRpc(myRegistry); + } +}; + + + +static void +testMultiConnInterrupt(registry const& myRegistry) { + + // We use a nonexistent file descriptor, but the server won't + // ever access it, so it won't know. + + serverPstream server(serverPstream::constrOpt() + .registryP(&myRegistry) + .socketFd(37)); + + int interrupt(1); // interrupt immediately + + server.runSerial(&interrupt); +} + + + +class derivedServer : public xmlrpc_c::serverPstream { +public: + derivedServer(serverPstream::constrOpt const& constrOpt) : + serverPstream(constrOpt), + info("this is my derived server") {} + + string const info; +}; + + + +class multiTestCallInfoMethod : public method2 { + +// The test isn't sophisticated enough actually to do an RPC, so this +// code never runs. We just want to see if it compiles. + +public: + virtual void + execute(paramList const& paramList, + const callInfo * const callInfoPtr, + value * const retvalP) { + + const callInfo_serverPstream * const callInfoP( + dynamic_cast(callInfoPtr)); + + TEST(callInfoP != NULL); + + paramList.verifyEnd(0); + + derivedServer * const derivedServerP( + dynamic_cast(callInfoP->serverP)); + + TEST(derivedServerP->info == string("this is my derived server")); + + TEST(callInfoP->clientAddr.sa_family == AF_INET); + TEST(callInfoP->clientAddrSize >= sizeof(struct sockaddr_in)); + + *retvalP = value_nil(); + } +}; + +static void +testMultiConnCallInfo() { + + registry myRegistry; + + myRegistry.addMethod("testCallInfo", + methodPtr(new multiTestCallInfoMethod)); + + derivedServer server(serverPstream::constrOpt() + .registryP(&myRegistry) + .socketFd(37)); +} + + + +class multiConnServerTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "multiConnServerTestSuite"; + } + virtual void runtests(unsigned int const) { + registry myRegistry; + + myRegistry.addMethod("sample.add", + methodPtr(new sampleAddMethod)); + + registryPtr myRegistryP(new registry); + + myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod)); + + EXPECT_ERROR( // Empty options + serverPstream::constrOpt opt; + serverPstream server(opt); + ); + + EXPECT_ERROR( // No registry + serverPstream server(serverPstream::constrOpt() + .socketFd(3)); + ); + + EXPECT_ERROR( // No socket fd + serverPstream server(serverPstream::constrOpt() + .registryP(&myRegistry)); + ); + + testMultiConnInterrupt(myRegistry); + + testMultiConnCallInfo(); + } +}; + + + +} // unnamed namespace + + + +string +serverPstreamTestSuite::suiteName() { + return "serverPstreamTestSuite"; +} + + +void +serverPstreamTestSuite::runtests(unsigned int const indentation) { + + serverPstreamConnTestSuite().run(indentation + 1); + + multiConnServerTestSuite().run(indentation + 1); +} + diff --git a/trunk/test/cpp/server_pstream.hpp b/trunk/test/cpp/server_pstream.hpp new file mode 100644 index 000000000..181658037 --- /dev/null +++ b/trunk/test/cpp/server_pstream.hpp @@ -0,0 +1,8 @@ +#include "tools.hpp" + +class serverPstreamTestSuite : public testSuite { + +public: + virtual std::string suiteName(); + virtual void runtests(unsigned int const); +}; diff --git a/trunk/test/cpp/test.cpp b/trunk/test/cpp/test.cpp new file mode 100644 index 000000000..0546ea226 --- /dev/null +++ b/trunk/test/cpp/test.cpp @@ -0,0 +1,390 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/oldcppwrapper.hpp" +#include "xmlrpc-c/registry.hpp" + +#include "base64.hpp" +#include "xml.hpp" +#include "value.hpp" +#include "testclient.hpp" +#include "registry.hpp" +#include "server_abyss.hpp" +#include "server_pstream.hpp" +#include "abyss.hpp" +#include "tools.hpp" + +using namespace xmlrpc_c; +using namespace std; + +//========================================================================= +// Test Harness +//========================================================================= +// +// There are two styles of test in here. The older ones are vaguely +// inspired by Kent Beck's book on eXtreme Programming (XP) and use +// the TEST...() macros. +// +// But this style is not really appropriate for C++. It's based on +// code that explicitly tests for errors, as one would do in C. In C++, +// it is cumbersome to catch exceptions on every call, so we don't in +// the new style. + +// And there's not much point in trying to count test successes and +// failures. Any failure is a problem, so in the new style, we just +// quit after we recognize one (again, more in line with regular exception +// throwing). With exception throwing, you can't count what _didn't_ +// cause an exception, so there's no meaningful count of test successes. +// +// To run the tests, type './cpptest'. +// To check for memory leaks, install RedHat's 'memprof' utility, and +// type 'memprof cpptest'. +// +// If you add new tests to this file, please deallocate any data +// structures you use in the appropriate fashion. This allows us to test +// various destructor code for memory leaks. + + +//========================================================================= +// Test Suites +//========================================================================= + +void +test_fault (void) { + + // Create a new fault and perform basic operations. + XmlRpcFault fault1 = XmlRpcFault(6, "Sample fault"); + TEST(fault1.getFaultCode() == 6); + TEST(fault1.getFaultString() == "Sample fault"); + + // Extract and examine the underlying xmlrpc_env struct. + xmlrpc_env *env1 = fault1.getFaultEnv(); + TEST(env1 != NULL); + TEST(env1->fault_occurred); + TEST(env1->fault_code == 6); + TEST(strcmp(env1->fault_string, "Sample fault") == 0); + + // Test our copy constructor. + XmlRpcFault fault2 = fault1; + TEST(fault2.getFaultCode() == 6); + TEST(fault2.getFaultString() == "Sample fault"); + + // Construct a fault from a pre-existing xmlrpc_env structure. + xmlrpc_env env3; + xmlrpc_env_init(&env3); + xmlrpc_env_set_fault(&env3, 7, "Another fault"); + XmlRpcFault fault3 = XmlRpcFault(&env3); + xmlrpc_env_clean(&env3); + TEST(fault3.getFaultCode() == 7); + TEST(fault3.getFaultString() == "Another fault"); + + // Attempt to construct a fault from a fault-free xmlrpc_env. + xmlrpc_env env4; + xmlrpc_env_init(&env4); + try { + XmlRpcFault fault4 = XmlRpcFault(&env4); + TEST_FAILED("Constructed invalid XmlRpcFault"); + } catch (XmlRpcFault const& fault) { + TEST_PASSED(); + TEST(fault.getFaultCode() == XMLRPC_INTERNAL_ERROR); + } + xmlrpc_env_clean(&env4); +} + + + +void test_env (void) { + + // Declare these here to prevent silly compiler warnings about + // potentially uninitialized variables. + XmlRpcEnv env1; + XmlRpcEnv env2; + + // Perform simple environment tests. + TEST(!env1.hasFaultOccurred()); + xmlrpc_env_set_fault(env1, 8, "Fault 8"); + TEST(env1.hasFaultOccurred()); + XmlRpcFault fault1 = env1.getFault(); + TEST(fault1.getFaultCode() == 8); + TEST(fault1.getFaultString() == "Fault 8"); + + // Test throwIfFaultOccurred. + try { + env2.throwIfFaultOccurred(); + TEST_PASSED(); + } catch (XmlRpcFault const&) { + TEST_FAILED("We threw a fault when one hadn't occurred"); + } + xmlrpc_env_set_fault(env2, 9, "Fault 9"); + try { + env2.throwIfFaultOccurred(); + TEST_FAILED("A fault occurred, and we didn't throw it"); + } catch (XmlRpcFault const& fault) { + TEST_PASSED(); + TEST(fault.getFaultCode() == 9); + TEST(fault.getFaultString() == "Fault 9"); + } + + // Make sure we can't get a fault if one hasn't occurred. + XmlRpcEnv env3; + try { + XmlRpcFault fault3 = env3.getFault(); + TEST_FAILED("We retrieved a non-existant fault"); + } catch (XmlRpcFault const& fault) { + TEST_PASSED(); + TEST(fault.getFaultCode() == XMLRPC_INTERNAL_ERROR); + } +} + +void test_value (void) { + XmlRpcEnv env; + + // Test basic reference counting behavior. + xmlrpc_value *v = xmlrpc_build_value(env, "i", (xmlrpc_int32) 1); + env.throwIfFaultOccurred(); + XmlRpcValue val1 = XmlRpcValue(v, XmlRpcValue::CONSUME_REFERENCE); + v = xmlrpc_build_value(env, "i", (xmlrpc_int32) 2); + env.throwIfFaultOccurred(); + XmlRpcValue val2 = v; + xmlrpc_DECREF(v); + + // Borrow a reference. + v = xmlrpc_build_value(env, "i", (xmlrpc_int32) 3); + env.throwIfFaultOccurred(); + XmlRpcValue val3 = XmlRpcValue(v, XmlRpcValue::CONSUME_REFERENCE); + xmlrpc_value *borrowed = val3.borrowReference(); + TEST(borrowed == v); + + // Make a reference. + v = xmlrpc_build_value(env, "i", (xmlrpc_int32) 4); + env.throwIfFaultOccurred(); + XmlRpcValue val4 = XmlRpcValue(v, XmlRpcValue::CONSUME_REFERENCE); + xmlrpc_value *made = val4.makeReference(); + TEST(made == v); + xmlrpc_DECREF(made); + + // Test our default constructor. + XmlRpcValue val5; + TEST(val5.getBool() == false); + + // Test our type introspection. + TEST(XmlRpcValue::makeInt(0).getType() == XMLRPC_TYPE_INT); + + // Test our basic data types. + TEST(XmlRpcValue::makeInt(30).getInt() == 30); + TEST(XmlRpcValue::makeInt(-30).getInt() == -30); + TEST(XmlRpcValue::makeBool(true).getBool() == true); + TEST(XmlRpcValue::makeBool(false).getBool() == false); + TEST(XmlRpcValue::makeDateTime("19980717T14:08:55").getRawDateTime() == + "19980717T14:08:55"); + TEST(XmlRpcValue::makeString("foo").getString() == "foo"); + TEST(XmlRpcValue::makeString("bar", 3).getString() == "bar"); + TEST(XmlRpcValue::makeString("bar", 3).getString() == "bar"); + TEST(XmlRpcValue::makeString("a\0b").getString() == string("a\0b")); + XmlRpcValue::makeArray().getArray(); + XmlRpcValue::makeStruct().getStruct(); + + // Test byte string values. + const unsigned char *b64_data; + size_t b64_len; + XmlRpcValue val6 = XmlRpcValue::makeBase64((unsigned char*) "a\0\0b", 4); + val6.getBase64(b64_data, b64_len); + TEST(b64_len == 4); + TEST(memcmp(b64_data, "a\0\0b", 4) == 0); + + // Test arrays. + XmlRpcValue array = XmlRpcValue::makeArray(); + TEST(array.arraySize() == 0); + array.arrayAppendItem(XmlRpcValue::makeString("foo")); + TEST(array.arraySize() == 1); + array.arrayAppendItem(XmlRpcValue::makeString("bar")); + TEST(array.arraySize() == 2); + TEST(array.arrayGetItem(0).getString() == "foo"); + TEST(array.arrayGetItem(1).getString() == "bar"); + + // Test structs. + XmlRpcValue strct = XmlRpcValue::makeStruct(); + TEST(strct.structSize() == 0); + strct.structSetValue("foo", XmlRpcValue::makeString("fooval")); + TEST(strct.structSize() == 1); + strct.structSetValue("bar", XmlRpcValue::makeString("barval")); + TEST(strct.structSize() == 2); + TEST(strct.structHasKey("bar")); + TEST(!strct.structHasKey("nosuch")); + for (int i = 0; i < (int)strct.structSize(); ++i) { + string key; + XmlRpcValue value; + strct.structGetKeyAndValue(i, key, value); + TEST(key + "val" == value.getString()); + } +} + + + +static void +testXmlRpcCpp() { +/*---------------------------------------------------------------------------- + Test the legacy XmlRpcCpp.cpp library +-----------------------------------------------------------------------------*/ + cout << "Testing XmlRpcCpp library..." << endl; + + test_fault(); + test_env(); + test_value(); +} + + + +static void +buildParamListWithAdd(paramList * const paramListP, + time_t const timeFuture) { + + paramListP->add(value_int(7)); + paramListP->add(value_boolean(true)).add(value_double(3.14)); + time_t const timeZero(0); + paramListP->add(value_datetime(timeZero)); + paramListP->add(value_datetime(timeFuture)); + paramListP->add(value_string("hello world")); + unsigned char bytestringArray[] = {0x10, 0x11, 0x12, 0x13, 0x14}; + vector + bytestringData(&bytestringArray[0], &bytestringArray[4]); + paramListP->add(value_bytestring(bytestringData)); + vector arrayData; + arrayData.push_back(value_int(7)); + arrayData.push_back(value_double(2.78)); + arrayData.push_back(value_string("hello world")); + paramListP->add(value_array(arrayData)); + map structData; + pair member("the_integer", value_int(9)); + structData.insert(member); + paramListP->add(value_struct(structData)); + paramListP->add(value_nil()); + paramListP->add(value_i8((xmlrpc_int64)UINT_MAX + 1)); +} + + + +static void +verifyParamList(paramList const& paramList, + time_t const timeFuture) { + + TEST(paramList.size() == 11); + + TEST(paramList.getInt(0) == 7); + TEST(paramList.getInt(0, 7) == 7); + TEST(paramList.getInt(0, -5, 7) == 7); + TEST(paramList.getBoolean(1) == true); + TEST(paramList.getDouble(2) == 3.14); + TEST(paramList.getDouble(2, 1) == 3.14); + TEST(paramList.getDouble(2, 1, 4) == 3.14); + time_t const timeZero(0); + TEST(paramList.getDatetime_sec(3) == timeZero); + TEST(paramList.getDatetime_sec(3, paramList::TC_ANY) == timeZero); + TEST(paramList.getDatetime_sec(3, paramList::TC_NO_FUTURE) + == timeZero); + TEST(paramList.getDatetime_sec(4, paramList::TC_NO_PAST) + == timeFuture); + TEST(paramList.getString(5) == "hello world"); + TEST(paramList.getBytestring(6)[0] == 0x10); + TEST(paramList.getArray(7).size() == 3); + TEST(paramList.getArray(7, 3).size() == 3); + TEST(paramList.getArray(7, 1, 3).size() == 3); + paramList.getStruct(8)["the_integer"]; + paramList.getNil(9); + TEST(paramList.getI8(10) == (xmlrpc_int64)UINT_MAX + 1); + paramList.verifyEnd(11); +} + + + +class paramListTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "paramListTestSuite"; + } + virtual void runtests(unsigned int const) { + + time_t const timeFuture(time(NULL)+100); + + paramList paramList1; + TEST(paramList1.size() == 0); + + buildParamListWithAdd(¶mList1, timeFuture); + + verifyParamList(paramList1, timeFuture); + + paramList paramList2(5); + TEST(paramList2.size() == 0); + + paramList2.addc(7); + paramList2.addc(true).addc(3.14); + TEST(paramList2.size() == 3); + TEST(paramList2.getInt(0) == 7); + TEST(paramList2.getBoolean(1) == true); + TEST(paramList2.getDouble(2) == 3.14); + } +}; + +//========================================================================= +// Test Driver +//========================================================================= + +int +main(int argc, char**) { + + int retval; + + if (argc-1 > 0) { + cout << "Program takes no arguments" << endl; + exit(1); + } + + bool testsPassed; + + try { + // Add your test suites here. + base64TestSuite().run(0); + xmlTestSuite().run(0); + valueTestSuite().run(0); + paramListTestSuite().run(0); + registryTestSuite().run(0); + serverAbyssTestSuite().run(0); + serverPstreamTestSuite().run(0); + clientTestSuite().run(0); + abyssTestSuite().run(0); + + testXmlRpcCpp(); + + testsPassed = true; + } catch (error const& error) { + cout << "Unexpected error thrown: " << error.what() << endl; + testsPassed = false; + } catch (XmlRpcFault const& fault) { + cout << "Unexpected XML-RPC fault when running test suites." << endl + << "Fault #" << fault.getFaultCode() + << ": " << fault.getFaultString() << endl; + testsPassed = false; + } catch (...) { + cout << "Unexpected exception when running test suites." << endl; + testsPassed = false; + } + + if (testsPassed) { + cout << "PASSED" << endl; + retval = 0; + } else { + cout << "FAILED" << endl; + retval = 1; + } + return retval; +} diff --git a/trunk/test/cpp/testclient.cpp b/trunk/test/cpp/testclient.cpp new file mode 100644 index 000000000..7ad3eeef7 --- /dev/null +++ b/trunk/test/cpp/testclient.cpp @@ -0,0 +1,953 @@ +/*============================================================================= + testclient +=============================================================================== + Test the client C++ facilities of XML-RPC for C/C++. + + Contrary to what you might expect, we use the server facilities too + because we test much of the client using a simulated server, via the + "direct" client XML transport we define herein. +=============================================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "transport_config.h" +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/registry.hpp" +#include "xmlrpc-c/client.hpp" +#include "xmlrpc-c/client_simple.hpp" + +#include "tools.hpp" +#include "testclient.hpp" + +using namespace xmlrpc_c; +using namespace std; + + + +namespace { + +class sampleAddMethod : public method { +public: + sampleAddMethod() { + this->_signature = "i:ii"; + this->_help = "This method adds two integers together"; + } + void + execute(xmlrpc_c::paramList const& paramList, + value * const retvalP) { + + int const addend(paramList.getInt(0)); + int const adder(paramList.getInt(1)); + + paramList.verifyEnd(2); + + *retvalP = value_int(addend + adder); + } +}; + + + +class testApacheDialectMethod : public method { +public: + void + execute(xmlrpc_c::paramList const& paramList, + value * const retvalP) { + + paramList.getNil(0); + + paramList.verifyEnd(1); + + *retvalP = value_i8(7ll); + } +}; + + + +class carriageParm_direct : public carriageParm { +public: + carriageParm_direct(registry * const registryP) : registryP(registryP) {} + + registry * registryP; +}; + + +class clientXmlTransport_direct : public clientXmlTransport { +/*---------------------------------------------------------------------------- + Though this fills the shoes of a client XML transport, it's really a + simulation, because it doesn't transport anything anywhere. The call() + method, which is supposed to transport a call to a server and then + transport the response back, actually just executes the method itself. + + Part of a carriage parameter for a transport of this class is the handle + of a method registry, so the transport knows how to execute the method. +-----------------------------------------------------------------------------*/ +public: + void + call(xmlrpc_c::carriageParm * const carriageParmP, + string const& callXml, + string * const responseXmlP) { + + carriageParm_direct * const parmP = + dynamic_cast(carriageParmP); + + if (parmP == NULL) + throw(error("Carriage parameter passed to the direct " + "transport is not type carriageParm_direct")); + + parmP->registryP->processCall(callXml, responseXmlP); + } +}; + + + +class clientDirectAsyncTestSuite : public testSuite { +/*---------------------------------------------------------------------------- + See clientDirectTestSuite for a description of how we use a + clientXmlTransport_direct object to test client functions. + + The object of this class tests the async client functions. With + clientXmlTransport_direct, these are pretty simple because the + transport doesn't even implement an asynchronous interface; it + relies on the base class' emulation of start() using call(). + + Some day, we should add true asynchronous capability to + clientXmlTransport_direct and really test things. +-----------------------------------------------------------------------------*/ +public: + virtual string suiteName() { + return "clientDirectAsyncTestSuite"; + } + virtual void runtests(unsigned int const) { + + registry myRegistry; + + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + + carriageParm_direct carriageParmDirect(&myRegistry); + clientXmlTransport_direct transportDirect; + client_xml clientDirect(&transportDirect); + paramList paramListSampleAdd1; + paramListSampleAdd1.add(value_int(5)); + paramListSampleAdd1.add(value_int(7)); + paramList paramListSampleAdd2; + paramListSampleAdd2.add(value_int(30)); + paramListSampleAdd2.add(value_int(-10)); + + rpcPtr const rpcSampleAdd1P("sample.add", paramListSampleAdd1); + rpcSampleAdd1P->start(&clientDirect, &carriageParmDirect); + rpcPtr const rpcSampleAdd2P("sample.add", paramListSampleAdd2); + rpcSampleAdd2P->start(&clientDirect, &carriageParmDirect); + + // Note that for clientXmlTransport_direct, start() and call() are + // the same thing. I.e. the RPC is guaranteed finished as soon + // as it is started. + + + clientDirect.finishAsync(timeout()); + clientDirect.finishAsync(timeout(50)); + + TEST(rpcSampleAdd1P->isFinished()); + TEST(rpcSampleAdd1P->isSuccessful()); + value_int const result1(rpcSampleAdd1P->getResult()); + TEST(static_cast(result1) == 12); + + TEST(rpcSampleAdd2P->isFinished()); + TEST(rpcSampleAdd1P->isSuccessful()); + value_int const result2(rpcSampleAdd2P->getResult()); + TEST(static_cast(result2) == 20); + } +}; + + + +class MyRpc : public rpc { + +public: + MyRpc(std::string const methodName, + paramList const& paramList) : + rpc(methodName, paramList) {} + + void + progress(struct xmlrpc_progress_data const& data) const { + + // The way the tests are currently written, this never actually + // runs; we're just testing for ability to compile. + + cout << "Progress of " << this << ": " + << data.call.total << " " + << data.call.now << " " + << data.response.total << " " + << data.response.now + << endl; + } +}; + + + +class clientDerivedRpcTestSuite : public testSuite { +/*---------------------------------------------------------------------------- + The object of this class tests the ability to derive a class + from xmlrpc_c::rpc in order to override certain methods. +-----------------------------------------------------------------------------*/ +public: + virtual string suiteName() { + return "clientDerivedRpcTestSuite"; + } + virtual void runtests(unsigned int const ) { + registry myRegistry; + + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + + carriageParm_direct carriageParmDirect(&myRegistry); + clientXmlTransport_direct transportDirect; + client_xml clientDirect(&transportDirect); + paramList paramListSampleAdd; + paramListSampleAdd.add(value_int(5)); + paramListSampleAdd.add(value_int(7)); + { + /* Test a successful RPC */ + rpcPtr rpcSampleAddP(new MyRpc("sample.add", paramListSampleAdd)); + rpcSampleAddP->call(&clientDirect, &carriageParmDirect); + TEST(rpcSampleAddP->isFinished()); + TEST(rpcSampleAddP->isSuccessful()); + value_int const resultDirect(rpcSampleAddP->getResult()); + TEST(static_cast(resultDirect) == 12); + } + } +}; + + + +class clientDirectTestSuite : public testSuite { +/*---------------------------------------------------------------------------- + The object of this class tests the client facilities by using a + special client XML transport defined above and an XML-RPC server we + build ourselves and run inline. We build the server out of a + xmlrpc_c::registry object and our transport just delivers XML + directly to the registry object and gets the response XML from it + and delivers that back. There's no network or socket or pipeline or + anything -- the transport actually executes the XML-RPC method. +-----------------------------------------------------------------------------*/ +public: + virtual string suiteName() { + return "clientDirectTestSuite"; + } + virtual void runtests(unsigned int const indentation) { + registry myRegistry; + + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + + carriageParm_direct carriageParmDirect(&myRegistry); + clientXmlTransport_direct transportDirect; + client_xml clientDirect(&transportDirect); + paramList paramListSampleAdd; + paramListSampleAdd.add(value_int(5)); + paramListSampleAdd.add(value_int(7)); + paramList paramListEmpty; + { + /* Test a successful RPC */ + rpcPtr rpcSampleAddP("sample.add", paramListSampleAdd); + rpcSampleAddP->call(&clientDirect, &carriageParmDirect); + TEST(rpcSampleAddP->isFinished()); + TEST(rpcSampleAddP->isSuccessful()); + value_int const resultDirect(rpcSampleAddP->getResult()); + TEST(static_cast(resultDirect) == 12); + } + { + /* Test a failed RPC */ + rpcPtr const rpcSampleAddP("sample.add", paramListEmpty); + rpcSampleAddP->call(&clientDirect, &carriageParmDirect); + TEST(rpcSampleAddP->isFinished()); + TEST(!rpcSampleAddP->isSuccessful()); + fault const fault0(rpcSampleAddP->getFault()); + TEST(fault0.getCode() == fault::CODE_TYPE); + } + + { + /* Test with an auto object transport */ + client_xml clientDirect( + clientXmlTransportPtr(new clientXmlTransport_direct)); + rpcPtr rpcSampleAddP("sample.add", paramListSampleAdd); + rpcSampleAddP->call(&clientDirect, &carriageParmDirect); + TEST(rpcSampleAddP->isFinished()); + TEST(rpcSampleAddP->isSuccessful()); + EXPECT_ERROR(fault fault0(rpcSampleAddP->getFault());); + value_int const resultDirect(rpcSampleAddP->getResult()); + TEST(static_cast(resultDirect) == 12); + } + { + /* Test with implicit RPC -- success */ + rpcOutcome outcome; + clientDirect.call(&carriageParmDirect, "sample.add", + paramListSampleAdd, &outcome); + TEST(outcome.succeeded()); + value_int const result(outcome.getResult()); + TEST(static_cast(result) == 12); + } + { + /* Test with implicit RPC - failure */ + rpcOutcome outcome; + clientDirect.call(&carriageParmDirect, "nosuchmethod", + paramList(), &outcome); + TEST(!outcome.succeeded()); + TEST(outcome.getFault().getCode() == fault::CODE_NO_SUCH_METHOD); + TEST(outcome.getFault().getDescription().size() > 0); + } + + int interruptFlag(0); + EXPECT_ERROR(transportDirect.setInterrupt(&interruptFlag);); + // This transport class isn't interruptible + EXPECT_ERROR(clientDirect.setInterrupt(&interruptFlag);); + // Same as above + + clientDirectAsyncTestSuite().run(indentation+1); + + clientDerivedRpcTestSuite().run(indentation+1); + } +}; + + + +class curlTransportTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "curlTransportTestSuite"; + } + virtual void runtests(unsigned int const) { +#if MUST_BUILD_CURL_CLIENT + clientXmlTransport_curl transport0; + clientXmlTransport_curl transport1("eth0"); + clientXmlTransport_curl transport2("eth0", true); + clientXmlTransport_curl transport3("eth0", true, true); + clientXmlTransport_curl transport4( + clientXmlTransport_curl::constrOpt() + .network_interface("eth0") + .dont_advertise(true) + .user_agent("my user agent") + .referer("my referer") + .no_ssl_verifypeer(true) + .no_ssl_verifyhost(true) + .ssl_cert("/etc/sslcert") + .sslcerttype("PEM") + .sslcertpasswd("mypass") + .sslkey("/etc/sslkey") + .sslkeytype("DER") + .sslkeypasswd("mykeypass") + .sslengine("mysslengine") + .sslengine_default(true) + .sslversion(XMLRPC_SSLVERSION_SSLv2) + .cainfo("/etc/cainfo") + .capath("/etc/cadir") + .randomfile("/dev/random") + .egdsocket("/tmp/egdsocket") + .ssl_cipher_list("RC4-SHA:DEFAULT") + .proxy("example.com") + .proxy_port(8080) + .proxy_userpwd("password") + .proxy_type(XMLRPC_HTTPPROXY_SOCKS5) + .proxy_auth(XMLRPC_HTTPAUTH_BASIC) + .proxy_userpwd("mypassword") + .gssapi_delegation(true) + .timeout(0) + .connect_timeout(0) + ); + + clientXmlTransport_curl transport5( + clientXmlTransport_curl::constrOpt() + .no_ssl_verifypeer(false)); + + clientXmlTransport_curl transport6( + clientXmlTransport_curl::constrOpt()); + + clientXmlTransportPtr transport1P(new clientXmlTransport_curl); + clientXmlTransportPtr transport2P; + transport2P = transport1P; + + time_t nowtime = time(NULL); + transport2P->finishAsync(timeout()); + transport2P->finishAsync(timeout(2000)); + transport2P->finishAsync(2000); + TEST(time(NULL) <= nowtime + 1); + + int interruptFlag; + transport2P->setInterrupt(&interruptFlag); + interruptFlag = 0; + transport2P->finishAsync(2000); + transport2P->finishAsync(timeout()); +#else + EXPECT_ERROR(clientXmlTransport_curl transport0;); + EXPECT_ERROR(clientXmlTransport_curl transport1("eth0");); + EXPECT_ERROR(clientXmlTransport_curl transport0("eth0", true);); + EXPECT_ERROR(clientXmlTransport_curl transport0("eth0", true, true);); +#endif + } +}; + + + +class libwwwTransportTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "libwwwTransportTestSuite"; + } + virtual void runtests(unsigned int const) { +#if MUST_BUILD_LIBWWW_CLIENT + clientXmlTransport_libwww transport0; + clientXmlTransport_libwww transport1("getbent"); + clientXmlTransport_libwww transport2("getbent", "1.0"); + clientXmlTransportPtr transport1P(new clientXmlTransport_libwww); + clientXmlTransportPtr transport2P; + transport2P = transport1P; +#else + EXPECT_ERROR(clientXmlTransport_libwww transport0;); + EXPECT_ERROR(clientXmlTransport_libwww transport1("getbent");); + EXPECT_ERROR(clientXmlTransport_libwww transport2("getbent", "1.0");); +#endif + } +}; + + + +class wininetTransportTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "wininetTransportTestSuite"; + } + virtual void runtests(unsigned int const) { +#if MUST_BUILD_WININET_CLIENT + clientXmlTransport_wininet transport0; + clientXmlTransport_wininet transport1(true); + clientXmlTransportPtr transport1P(new clientXmlTransport_wininet); + clientXmlTransportPtr transport2P; + transport2P = transport1P; +#else + EXPECT_ERROR(clientXmlTransport_wininet transport0;); + EXPECT_ERROR(clientXmlTransport_wininet transport1(true);); +#endif + } +}; + + + +class ambivalentHttpTransportTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "ambivalentHttpTransportTestSuite"; + } + virtual void runtests(unsigned int const) { + vector const typeList( + clientXmlTransport_http::availableTypes()); + + TEST(typeList.size() > 0); + + clientXmlTransportPtr const transportP( + clientXmlTransport_http::create()); + carriageParm_http0 carriageParm0("http://whatsamatta.edux"); + client_xml client0(transportP); + + rpcOutcome outcome; + + // Fails because there's no such server + EXPECT_ERROR( + client0.call(&carriageParm0, "nosuchmethod", paramList(), + &outcome); + ); + } +}; + + + +class pstreamTransportTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "pstreamTransportTestSuite"; + } + virtual void runtests(unsigned int const) { + int const devNullFd(open("/dev/null", 0)); + + if (devNullFd < 0) + throw error("Failed to open /dev/null, needed for test."); + + EXPECT_ERROR(clientXmlTransport_pstream transport1( + clientXmlTransport_pstream::constrOpt() + .fd(37) + );); // ERROR: no such file descriptor + + carriageParm_pstream carriageParm0; + + { + clientXmlTransport_pstream transport2( + clientXmlTransport_pstream::constrOpt() + .fd(devNullFd) + ); + + string callXml("hello"); + string responseXml; + EXPECT_ERROR(transport2.call(NULL, callXml, &responseXml);); + // Error: carriage parm not of type carriageParm_pstream + EXPECT_ERROR(transport2.call(&carriageParm0, callXml, + &responseXml);); + // Error: no response + } + { + clientXmlTransport_pstream transport2( + clientXmlTransport_pstream::constrOpt() + .fd(devNullFd) + .useBrokenConnEx(true) + ); + } + clientXmlTransportPtr transport1P(new clientXmlTransport_pstream( + clientXmlTransport_pstream::constrOpt() + .fd(devNullFd) + )); + clientXmlTransportPtr transport2P; + transport2P = transport1P; + + close(devNullFd); + } +}; + + + +class clientXmlTransportTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "clientXmlTransportTestSuite"; + } + virtual void runtests(unsigned int const indentation) { + curlTransportTestSuite().run(indentation + 1); + libwwwTransportTestSuite().run(indentation + 1); + wininetTransportTestSuite().run(indentation + 1); + ambivalentHttpTransportTestSuite().run(indentation + 1); + pstreamTransportTestSuite().run(indentation + 1); + } +}; + + + +class clientSimpleTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "clientSimpleTestSuite"; + } + virtual void runtests(unsigned int const) { + + clientSimple clientS0; + paramList paramList0; + + value result0; + + // These will fail because there's no such server + EXPECT_ERROR(clientS0.call("http://mf.comm", "biteme", &result0);); + + EXPECT_ERROR( + clientS0.call("http://mf.comm", "biteme", "s", &result0, "hard"); + ); + + EXPECT_ERROR( + clientS0.call("http://mf.comm", "biteme", paramList0, &result0); + ); + } +}; + + + +class clientCurlIntTestSuite : public testSuite { +/*---------------------------------------------------------------------------- + The object of this class tests interruptibility functions of the + combination of a client with Curl transport. + + We don't have an HTTP server, so we test only superficially. +-----------------------------------------------------------------------------*/ +public: + virtual string suiteName() { + return "clientCurlIntTestSuite"; + } + virtual void runtests(unsigned int) { +#if MUST_BUILD_CURL_CLIENT + clientXmlTransport_curl transportc0; + client_xml client0(&transportc0); + carriageParm_curl0 carriageParmCurl("http://nosuchserver8677.com"); + + paramList paramList0; + + rpcOutcome outcome0; + + int interruptFlag; + client0.setInterrupt(&interruptFlag); + + interruptFlag = 1; + // This fails because the call gets immediately interrupted + EXPECT_ERROR( + client0.call(&carriageParmCurl, "blowme", paramList0, &outcome0); + ); + interruptFlag = 0; + // This fails because server doesn't exist + EXPECT_ERROR( + client0.call(&carriageParmCurl, "blowme", paramList0, &outcome0); + ); +#endif + } +}; + + + +class clientCurlTestSuite : public testSuite { +/*---------------------------------------------------------------------------- + The object of this class tests the combination of a client with + Curl transport. We assume Curl transports themselves have already + been tested and clients with direct transports have already been tested. + + We don't have an HTTP server, so we test only superficially. + + In the future, we could either start a server or use some server that's + normally avaailble on the Internet. +-----------------------------------------------------------------------------*/ +public: + virtual string suiteName() { + return "clientCurlTestSuite"; + } + virtual void runtests(unsigned int const indentation) { +#if MUST_BUILD_CURL_CLIENT + clientXmlTransport_curl transportc0; + client_xml client0(&transportc0); + carriageParm_http0 carriageParmHttp("http://nosuchserver8677.com"); + carriageParm_curl0 carriageParmCurl("http://nosuchserver8677.com"); + connection connection0(&client0, &carriageParmHttp); + + paramList paramList0; + + rpcOutcome outcome0; + + // This fails because server doesn't exist + EXPECT_ERROR( + client0.call(&carriageParmHttp, "blowme", paramList0, &outcome0); + ); + + // This fails because server doesn't exist + EXPECT_ERROR( + client0.call(&carriageParmCurl, "blowme", paramList0, &outcome0); + ); + + rpcPtr rpc0P("blowme", paramList0); + + // This fails because server doesn't exist + EXPECT_ERROR(rpc0P->call(&client0, &carriageParmCurl);); + + rpcPtr rpc1P("blowme", paramList0); + // This fails because server doesn't exist + EXPECT_ERROR(rpc1P->call(connection0);); + + rpcPtr rpc2P("blowme", paramList0); + + // This RPC fails to execute because the server doesn't exist, + // But libcurl "starts" it just fine. + rpc2P->start(&client0, &carriageParmCurl); + + transportc0.finishAsync(5000); + + TEST(rpc2P->isFinished()); + + TEST(!rpc2P->isSuccessful()); + + // Because the RPC did not return an XML-RPC failure (because the + // server doesn't exist), this throws: + EXPECT_ERROR(rpc2P->getFault();); + + rpcPtr rpc3P("blowme", paramList0); + // This RPC fails to execute because the server doesn't exist + rpc3P->start(connection0); + + transportc0.finishAsync(5000); + TEST(rpc2P->isFinished()); + TEST(!rpc2P->isSuccessful()); + + clientCurlIntTestSuite().run(indentation+1); +#else + // This fails because there is no Curl transport in the library. + EXPECT_ERROR(clientXmlTransport_curl transportc0;); +#endif + } +}; + + + +class carriageParmTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "carriageParmTestSuite"; + } + virtual void runtests(unsigned int) { + carriageParm_http0 carriageParm1("http://suckthis.com"); + carriageParm_curl0 carriageParm2("http://suckthis.com"); + carriageParm_libwww0 carriageParm3("http://suckthis.com"); + carriageParm_wininet0 carriageParm4("http://suckthis.com"); + + carriageParm_http0Ptr carriageParm_http1P( + new carriageParm_http0("http://suckthis.com")); + + carriageParm_http1P->setBasicAuth("bryanh", "12345"); + + carriageParm_curl0Ptr carriageParm_curl1P( + new carriageParm_curl0("http://suckthis.com")); + + carriageParm_curl1P->setBasicAuth("bryanh", "12345"); + + carriageParm_curl1P->setUser("bryanh", "12345"); + carriageParm_curl1P->allowAuthBasic(); + carriageParm_curl1P->disallowAuthBasic(); + carriageParm_curl1P->allowAuthDigest(); + carriageParm_curl1P->disallowAuthDigest(); + carriageParm_curl1P->allowAuthNegotiate(); + carriageParm_curl1P->disallowAuthNegotiate(); + carriageParm_curl1P->allowAuthNtlm(); + carriageParm_curl1P->disallowAuthNtlm(); + + carriageParm_libwww0Ptr carriageParm_libwww1P( + new carriageParm_libwww0("http://suckthis.com")); + + carriageParm_libwww1P->setUser("bryanh", "12345"); + carriageParm_libwww1P->allowAuthBasic(); + + carriageParm_wininet0Ptr carriageParm_wininet1P( + new carriageParm_wininet0("http://suckthis.com")); + + carriageParm_wininet1P->setUser("bryanh", "12345"); + carriageParm_wininet1P->allowAuthBasic(); + } +}; + + + +class clientRpcTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "clientRpcTestSuite"; + } + virtual void runtests(unsigned int) { + + registry myRegistry; + + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + + carriageParm_direct carriageParm0(&myRegistry); + clientXmlTransport_direct transportDirect; + client_xml client0(&transportDirect); + paramList paramListSampleAdd; + paramListSampleAdd.add(value_int(5)); + paramListSampleAdd.add(value_int(7)); + paramList paramListEmpty; + + { + /* Test a successful RPC */ + rpcPtr rpcSampleAddP("sample.add", paramListSampleAdd); + TEST(!rpcSampleAddP->isFinished()); + // This fails because RPC has not been executed + EXPECT_ERROR(value result(rpcSampleAddP->getResult());); + + rpcSampleAddP->call(&client0, &carriageParm0); + + TEST(rpcSampleAddP->isFinished()); + TEST(rpcSampleAddP->isSuccessful()); + value_int const resultDirect(rpcSampleAddP->getResult()); + TEST(static_cast(resultDirect) == 12); + // This fails because the RPC succeeded + EXPECT_ERROR(fault fault0(rpcSampleAddP->getFault());); + // This fails because the RPC has already been executed + EXPECT_ERROR( + rpcSampleAddP->call(&client0, &carriageParm0);); + // This fails because the RPC has already been executed + EXPECT_ERROR( + rpcSampleAddP->start(&client0, &carriageParm0);); + } + { + /* Test a failed RPC */ + rpcPtr const rpcSampleAddP("sample.add", paramListEmpty); + rpcSampleAddP->call(&client0, &carriageParm0); + TEST(rpcSampleAddP->isFinished()); + TEST(!rpcSampleAddP->isSuccessful()); + fault const fault0(rpcSampleAddP->getFault()); + TEST(fault0.getCode() == fault::CODE_TYPE); + // This fails because the RPC failed + EXPECT_ERROR(value result(rpcSampleAddP->getResult());); + // This fails because the RPC has already been executed + EXPECT_ERROR( + rpcSampleAddP->call(&client0, &carriageParm0);); + // This fails because the RPC has already been executed + EXPECT_ERROR( + rpcSampleAddP->start(&client0, &carriageParm0);); + } + { + /* Test with a connection */ + + connection connection0(&client0, &carriageParm0); + + rpcPtr const rpcSampleAddP("sample.add", paramListSampleAdd); + + rpcSampleAddP->call(connection0); + + TEST(rpcSampleAddP->isFinished()); + value_int const resultDirect(rpcSampleAddP->getResult()); + TEST(static_cast(resultDirect) == 12); + } + } +}; + + + +class clientPtrTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "clientPtrTestSuite"; + } + virtual void runtests(unsigned int) { + registry myRegistry; + + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + carriageParm_direct carriageParmDirect(&myRegistry); + clientXmlTransport_direct transportDirect; + + clientPtr clientP(new client_xml(&transportDirect)); + + clientPtr client2P(clientP); + + { + clientPtr client3P; + client3P = client2P; + } + rpcOutcome outcome; + + clientP->call(&carriageParmDirect, "nosuchmethod", + paramList(), &outcome); + TEST(!outcome.succeeded()); + TEST(outcome.getFault().getCode() == fault::CODE_NO_SUCH_METHOD); + } +}; + + + +class serverAccessorTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "serverAccessorTestSuite"; + } + virtual void runtests(unsigned int) { + clientXmlTransportPtr const transportP(new clientXmlTransport_direct); + clientPtr const clientP(new client_xml(transportP)); + registry myRegistry; + carriageParmPtr const carriageParmP( + new carriageParm_direct(&myRegistry)); + + serverAccessor server1(clientP, carriageParmP); + + rpcOutcome outcome; + server1.call("nosuchmethod", paramList(), &outcome); + TEST(!outcome.succeeded()); + TEST(outcome.getFault().getCode() == fault::CODE_NO_SUCH_METHOD); + TEST(outcome.getFault().getDescription().size() > 0); + } +}; + + + +class xmlTestSuite : public testSuite { +/*---------------------------------------------------------------------------- + This test suite tests the generation an interpretation of XML-RPC + XML, by doing RPCs via an XML client and server. Each complete RPC + involves generating XML and interpreting it, so this is a handy way + to test. + + A stronger test would be to make an XML transport that actually verifies + the XML. We're too lazy for that. +-----------------------------------------------------------------------------*/ +public: + virtual string suiteName() { + return "xmlTestSuite"; + } + virtual void runtests(unsigned int) { + registry myRegistry; + myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod)); + myRegistry.addMethod("apache", methodPtr(new testApacheDialectMethod)); + carriageParm_direct carriageParmDirect(&myRegistry); + clientXmlTransport_direct transportDirect; + client_xml clientDirect(&transportDirect, xmlrpc_dialect_apache); + + paramList paramListSampleAdd; + paramListSampleAdd.add(value_int(5)); + paramListSampleAdd.add(value_int(7)); + + { + rpcPtr rpcSampleAddP("sample.add", paramListSampleAdd); + rpcSampleAddP->call(&clientDirect, &carriageParmDirect); + TEST(rpcSampleAddP->isFinished()); + TEST(rpcSampleAddP->isSuccessful()); + value_int const result(rpcSampleAddP->getResult()); + TEST(static_cast(result) == 12); + } + paramList paramListApache; + paramListApache.add(value_nil()); + + { + rpcPtr rpcApacheP("apache", paramListApache); + rpcApacheP->call(&clientDirect, &carriageParmDirect); + TEST(rpcApacheP->isFinished()); + TEST(rpcApacheP->isSuccessful()); + value_i8 const result(rpcApacheP->getResult()); + TEST(static_cast(result) == 7ll); + } + } +}; + + + +} // unnamed namespace + + + +string +clientTestSuite::suiteName() { + return "clientTestSuite"; +} + + + +void +clientTestSuite::runtests(unsigned int const indentation) { + + clientDirectTestSuite().run(indentation+1); + + clientXmlTransportTestSuite().run(indentation+1); + + carriageParmTestSuite().run(indentation+1); + + clientCurlTestSuite().run(indentation+1); + + clientRpcTestSuite().run(indentation+1); + + clientPtrTestSuite().run(indentation+1); + + clientSimpleTestSuite().run(indentation+1); + + serverAccessorTestSuite().run(indentation+1); + + xmlTestSuite().run(indentation+1); +} diff --git a/trunk/test/cpp/testclient.hpp b/trunk/test/cpp/testclient.hpp new file mode 100644 index 000000000..20c1b9f39 --- /dev/null +++ b/trunk/test/cpp/testclient.hpp @@ -0,0 +1,9 @@ +#include "tools.hpp" + +class clientTestSuite : public testSuite { + +public: + virtual std::string suiteName(); + virtual void runtests(unsigned int const indentation); +}; + diff --git a/trunk/test/cpp/testclient_dummy.cpp b/trunk/test/cpp/testclient_dummy.cpp new file mode 100644 index 000000000..5bf3018df --- /dev/null +++ b/trunk/test/cpp/testclient_dummy.cpp @@ -0,0 +1,29 @@ +/*============================================================================= + testclient_dummy +=============================================================================== + This is a substitute for testclient.cpp, for use in a test program that is + not linked with the client libraries. + + It simply passes the test. +=============================================================================*/ + +#include +#include + +#include "tools.hpp" +#include "testclient.hpp" + +using namespace std; + +string +clientTestSuite::suiteName() { + return "clientTestSuite"; +} + + +void +clientTestSuite::runtests(unsigned int const indentation) { + + cout << string((indentation+1)*2, ' ') + << "Running dummy test." << endl; +} diff --git a/trunk/test/cpp/tools.cpp b/trunk/test/cpp/tools.cpp new file mode 100644 index 000000000..5709eff0c --- /dev/null +++ b/trunk/test/cpp/tools.cpp @@ -0,0 +1,87 @@ +#include +#include +#include +#ifdef _WIN32 +# include +# include +#else +# include +#endif + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; + +#include "tools.hpp" + +using namespace std; + +testSuite::~testSuite() { +} + + + +void +testSuite::run(unsigned int const indentation) { + try { + cout << string(indentation*2, ' ') + << "Running " << suiteName() << endl; + this->runtests(indentation); + } catch (error const& error) { + throwf("%s failed. %s", suiteName().c_str(), error.what()); + } catch (...) { + throw(error(suiteName() + string(" failed. ") + + string("It threw an unexpected type of object"))); + } + cout << string(indentation*2, ' ') + << suiteName() << " tests passed." << endl; +} + + + +// This is a good place to set a breakpoint. +void +logFailedTest(const char * const fileName, + unsigned int const lineNum, + const char * const statement) { + + ostringstream msg; + + msg << endl + << fileName << ":" << lineNum + << ": expected (" << statement << ")" << endl; + + throw(error(msg.str())); +} + + +error +fileLineError(string const filename, + unsigned int const lineNumber, + string const description) { + + ostringstream combined; + + combined << filename << ":" << lineNumber << " " << description; + + return error(combined.str()); +} + + + +struct in_addr +test_ipAddrFromDecimal(unsigned int const byte0, + unsigned int const byte1, + unsigned int const byte2, + unsigned int const byte3) { + + struct in_addr retval; + + retval.s_addr = + htonl((byte0 << 24) + (byte1 << 16) + (byte2 << 8) + (byte3 << 0)); + + return retval; +} + + + diff --git a/trunk/test/cpp/tools.hpp b/trunk/test/cpp/tools.hpp new file mode 100644 index 000000000..fc8c2da7a --- /dev/null +++ b/trunk/test/cpp/tools.hpp @@ -0,0 +1,85 @@ +#ifndef TEST_HPP_INCLUDED +#define TEST_HPP_INCLUDED + +#ifdef _WIN32 +# include /* For XMLRPC_SOCKET (= SOCKET) */ +# include +#else +#include +#endif + +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; + +class testSuite { +/*---------------------------------------------------------------------------- + This is a base class for a test suite. Give the suite a name + (to be used in messages about it) and some test code via + virtual methods suiteName() and runtests(), respectively. + + runtests() should throw either an 'error' object or an 'XmlRpcFault' + object if the test fails. It should throw something else if the + test can't run. It should throw nothing if the tests pass. + + You don't normally keep an object of this class around. You don't + even give it a name. You simply refer to a literal object, like so: + + myTestSuite().run(0) +-----------------------------------------------------------------------------*/ +public: + virtual ~testSuite(); + + void run(unsigned int const indentation); + + virtual void runtests(unsigned int const) { + throw(error("test suite does not have a runtests() method")); + }; + virtual std::string suiteName() { + return "unnamed test suite"; + } +}; + + + +void +logFailedTest(const char * const fileName, + unsigned int const lineNum, + const char * const statement); + +error +fileLineError(std::string const filename, + unsigned int const lineNumber, + std::string const description); + +struct in_addr +test_ipAddrFromDecimal(unsigned int const byte0, + unsigned int const byte1, + unsigned int const byte2, + unsigned int const byte3); + +#define TEST(statement) \ + do { \ + if (!(statement)) \ + logFailedTest(__FILE__, __LINE__, #statement); \ + } while (0) + + +#define TEST_PASSED() \ + do { } while (0) + +#define TEST_FAILED(reason) \ + do { \ + logFailedTest(__FILE__, __LINE__, (reason)); \ + } while (0) + +#define EXPECT_ERROR(statement) \ + do { try { statement } catch (error const&) {break;} \ + throw(fileLineError(__FILE__, __LINE__, "Expected error; didn't get one")); \ + } while (0) + +#define trickToStraightenOutEmacsIndentation \ +; + +#endif diff --git a/trunk/test/cpp/value.cpp b/trunk/test/cpp/value.cpp new file mode 100644 index 000000000..3e403c9c1 --- /dev/null +++ b/trunk/test/cpp/value.cpp @@ -0,0 +1,544 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/oldcppwrapper.hpp" +#include "xmlrpc-c/registry.hpp" +#include "c_util.h" + +#include "tools.hpp" + +#include "value.hpp" + +using namespace xmlrpc_c; +using namespace std; + + + +namespace { + +class intTestSuite : public testSuite { +public: + virtual string suiteName() { + return "intTestSuite"; + } + virtual void runtests(unsigned int const) { + value_int int1(7); + TEST(static_cast(int1) == 7); + value_int int2(-7); + TEST(static_cast(int2) == -7); + value val1(int1); + TEST(val1.type() == value::TYPE_INT); + value_int int3(val1); + TEST(static_cast(int3) == 7); + try { + value_int int4(value_double(3.7)); + TEST_FAILED("invalid cast double-int suceeded"); + } catch (error const&) {} + + value const int1x(toValue(7)); + TEST(int1x.type() == value::TYPE_INT); + TEST(static_cast(value_int(int1x)) == 7); + + int test1x; + fromValue(test1x, int1x); + TEST(test1x == 7); + } +}; + + + +class doubleTestSuite : public testSuite { +public: + virtual string suiteName() { + return "doubleTestSuite"; + } + virtual void runtests(unsigned int const) { + value_double double1(3.14); + TEST(static_cast(double1) == 3.14); + value val1(double1); + TEST(val1.type() == value::TYPE_DOUBLE); + value_double double2(val1); + TEST(static_cast(double2) == 3.14); + try { + value_double double4(value_int(4)); + TEST_FAILED("invalid cast int-double suceeded"); + } catch (error const&) {} + + value const double1x(toValue(3.14)); + TEST(double1x.type() == value::TYPE_DOUBLE); + TEST(static_cast(value_double(double1x)) == 3.14); + + double test1x; + fromValue(test1x, double1x); + TEST(test1x == 3.14); + } +}; + + + +class booleanTestSuite : public testSuite { +public: + virtual string suiteName() { + return "booleanTestSuite"; + } + virtual void runtests(unsigned int const) { + value_boolean boolean1(true); + TEST(static_cast(boolean1) == true); + value_boolean boolean2(false); + TEST(static_cast(boolean2) == false); + value val1(boolean1); + TEST(val1.type() == value::TYPE_BOOLEAN); + value_boolean boolean3(val1); + TEST(static_cast(boolean3) == true); + try { + value_boolean boolean4(value_int(4)); + TEST_FAILED("invalid cast int-boolean suceeded"); + } catch (error const&) {} + + value const boolean1x(toValue(true)); + TEST(boolean1x.type() == value::TYPE_BOOLEAN); + TEST(static_cast(value_boolean(boolean1x)) == true); + + bool test1x; + fromValue(test1x, boolean1x); + TEST(test1x == true); + } +}; + + + +#if XMLRPC_HAVE_TIMEVAL + +static struct timeval +makeTv(time_t const secs, + unsigned int const usecs) { + + struct timeval retval; + + retval.tv_sec = secs; + retval.tv_usec = usecs; + + return retval; +} + +static bool +tvIsEqual(struct timeval const comparand, + struct timeval const comparator) { + return + comparand.tv_sec == comparator.tv_sec && + comparand.tv_usec == comparator.tv_usec; +} +#endif + + + +#if XMLRPC_HAVE_TIMESPEC + +static struct timespec +makeTs(time_t const secs, + unsigned int const usecs) { + + struct timespec retval; + + retval.tv_sec = secs; + retval.tv_nsec = usecs * 1000; + + return retval; +} + +static bool +tsIsEqual(struct timespec const comparand, + struct timespec const comparator) { + return + comparand.tv_sec == comparator.tv_sec && + comparand.tv_nsec == comparator.tv_nsec; +} +#endif + +static xmlrpc_datetime const +makeXd(time_t const secs, + unsigned int const usecs) { + + struct tm const tm = *gmtime(&secs); + + xmlrpc_datetime retval; + + retval.Y = 1900 + tm.tm_year; + retval.M = 1 + tm.tm_mon; + retval.D = tm.tm_mday; + retval.h = tm.tm_hour; + retval.m = tm.tm_min; + retval.s = tm.tm_sec; + retval.u = usecs; + + return retval; +} + +static bool +xdIsEqual(xmlrpc_datetime const comparand, + xmlrpc_datetime const comparator) { + return + comparand.Y == comparator.Y && + comparand.M == comparator.M && + comparand.D == comparator.D && + comparand.h == comparator.h && + comparand.m == comparator.m && + comparand.s == comparator.s && + comparand.u == comparator.u; +} + + + +class datetimeTestSuite : public testSuite { +public: + virtual string suiteName() { + return "datetimeTestSuite"; + } + virtual void runtests(unsigned int const) { + time_t const testTime(900684535); + string const testTime8601("19980717T140855,000000Z"); + value_datetime datetime1("19980717T14:08:55"); + TEST(static_cast(datetime1) == testTime); + value_datetime datetime2(testTime); + TEST(static_cast(datetime2) == testTime); + value val1(datetime1); + TEST(val1.type() == value::TYPE_DATETIME); + value_datetime datetime3(val1); + TEST(static_cast(datetime3) == testTime); +#if XMLRPC_HAVE_TIMEVAL + struct timeval const testTimeTv(makeTv(testTime, 0)); + value_datetime datetime4(testTimeTv); + TEST(static_cast(datetime4) == testTime); + TEST(tvIsEqual(static_cast(datetime4), testTimeTv)); +#endif +#if XMLRPC_HAVE_TIMESPEC + struct timespec const testTimeTs(makeTs(testTime, 0)); + value_datetime datetime5(testTimeTs); + TEST(static_cast(datetime5) == testTime); + TEST(tsIsEqual(static_cast(datetime5), testTimeTs)); +#endif + xmlrpc_datetime const testTimeXd(makeXd(testTime, 5)); + value_datetime datetime6(testTimeXd); + TEST(static_cast(datetime6) == testTime); + TEST(xdIsEqual(static_cast(datetime6), testTimeXd)); + + string const iso8601Value(datetime1.iso8601Value()); + TEST(iso8601Value == testTime8601); + + try { + value_datetime datetime4(value_int(4)); + TEST_FAILED("invalid cast int-datetime suceeded"); + } catch (error const&) {} + } +}; + + + +class stringTestSuite : public testSuite { +public: + virtual string suiteName() { + return "stringTestSuite"; + } + virtual void runtests(unsigned int const) { + value_string string1("hello world"); + TEST(static_cast(string1) == "hello world"); + value_string string2("embedded\0null"); + TEST(static_cast(string2) == "embedded\0null"); + value val1(string1); + TEST(val1.type() == value::TYPE_STRING); + value_string string3(val1); + TEST(static_cast(string3) == "hello world"); + try { + value_string string4(value_int(4)); + TEST_FAILED("invalid cast int-string succeeded"); + } catch (error const&) {} + value_string string5("hello world", value_string::nlCode_all); + TEST(static_cast(string5) == "hello world"); + value_string string6("hello\nthere\rworld\r\n\n", + value_string::nlCode_all); + TEST(static_cast(string6) == "hello\nthere\nworld\n\n"); + TEST(string6.crlfValue() == "hello\r\nthere\r\nworld\r\n\r\n"); + value_string string7("hello\nthere\rworld\r\n\n", + value_string::nlCode_lf); + TEST(static_cast(string7) == "hello\nthere\rworld\r\n\n"); + + value const string1x(toValue("hello world")); + TEST(string1x.type() == value::TYPE_STRING); + TEST(static_cast(value_string(string1x)) == "hello world"); + + string test1x; + fromValue(test1x, string1x); + TEST(test1x == "hello world"); + + value const string2x(toValue(string("hello world"))); + TEST(string2x.type() == value::TYPE_STRING); + TEST(static_cast(value_string(string2x)) == "hello world"); + + string1.validate(); + + value_string badString("hello \x18 there"); + + try { + badString.validate(); + TEST_FAILED("'validate' of string containging a control " + "character succeeded"); + } catch (error const&) {} + } +}; + + + +class bytestringTestSuite : public testSuite { +public: + virtual string suiteName() { + return "bytestringTestSuite"; + } + virtual void runtests(unsigned int const) { + unsigned char bytestringArray[] = {0x10, 0x11, 0x12, 0x13, 0x14}; + cbytestring + bytestringData(&bytestringArray[0], &bytestringArray[4]); + value_bytestring bytestring1(bytestringData); + + cbytestring const dataReadBack1(bytestring1.vectorUcharValue()); + TEST(dataReadBack1 == bytestringData); + value val1(bytestring1); + TEST(val1.type() == value::TYPE_BYTESTRING); + value_bytestring bytestring2(val1); + vector const dataReadBack2( + bytestring2.vectorUcharValue()); + TEST(dataReadBack2 == bytestringData); + try { + value_bytestring bytestring4(value_int(4)); + TEST_FAILED("invalid cast int-bytestring suceeded"); + } catch (error const&) {} + + value const bytestring1x(toValue(bytestringData)); + TEST(bytestring1x.type() == value::TYPE_BYTESTRING); + vector const dataReadBack1x( + value_bytestring(bytestring1x).vectorUcharValue()); + TEST(dataReadBack1x == bytestringData); + + vector test1x; + fromValue(test1x, bytestring1x); + TEST(test1x == bytestringData); + + } +}; + + + +class nilTestSuite : public testSuite { +public: + virtual string suiteName() { + return "nilTestSuite"; + } + virtual void runtests(unsigned int const) { + value_nil nil1; + value val1(nil1); + TEST(val1.type() == value::TYPE_NIL); + value_nil nil2(val1); + try { + value_nil nil4(value_int(4)); + TEST_FAILED("invalid cast int-nil suceeded"); + } catch (error const&) {} + } +}; + + + +class i8TestSuite : public testSuite { +public: + virtual string suiteName() { + return "i8TestSuite"; + } + virtual void runtests(unsigned int const) { + value_i8 int1(7); + TEST(static_cast(int1) == 7); + value_i8 int2(-7); + TEST(static_cast(int2) == -7); + value_i8 int5(1ull << 40); + TEST(static_cast(int5) == (1ull << 40)); + value val1(int1); + TEST(val1.type() == value::TYPE_I8); + value_i8 int3(val1); + TEST(static_cast(int3) == 7); + try { + value_i8 int4(value_double(3.7)); + TEST_FAILED("invalid cast double-i8 suceeded"); + } catch (error const&) {} + + value const int1x(toValue((xmlrpc_int64)7)); + TEST(int1x.type() == value::TYPE_I8); + TEST(static_cast(value_i8(int1x)) == 7); + + xmlrpc_int64 test1x; + fromValue(test1x, int1x); + TEST(test1x == 7); + } +}; + + + +class structTestSuite : public testSuite { +public: + virtual string suiteName() { + return "structTestSuite"; + } + virtual void runtests(unsigned int const) { + cstruct structData; + pair member("the_integer", value_int(9)); + structData.insert(member); + + value_struct struct1(structData); + + map dataReadBack(struct1); + + TEST(static_cast(value_int(dataReadBack["the_integer"])) == 9); + + value val1(struct1); + TEST(val1.type() == value::TYPE_STRUCT); + value_struct struct2(val1); + try { + value_struct struct4(value_int(4)); + TEST_FAILED("invalid cast int-struct suceeded"); + } catch (error const&) {} + + map structDatax; + structDatax["one"] = 1; + structDatax["two"] = 2; + + value const struct5(toValue(structDatax)); + TEST(struct5.type() == value::TYPE_STRUCT); + map dataReadBackx; + dataReadBackx = value_struct(struct5); + + TEST(static_cast(value_int(dataReadBackx["two"])) == 2); + + map test5x; + fromValue(test5x, struct5); + TEST(test5x["two"] == 2); + } +}; + + + +class arrayTestSuite : public testSuite { +public: + virtual string suiteName() { + return "arrayTestSuite"; + } + virtual void runtests(unsigned int const) { + carray arrayData; + arrayData.push_back(value_int(7)); + arrayData.push_back(value_double(2.78)); + arrayData.push_back(value_string("hello world")); + value_array array1(arrayData); + + TEST(array1.size() == 3); + vector dataReadBack1(array1.vectorValueValue()); + TEST(dataReadBack1[0].type() == value::TYPE_INT); + TEST(static_cast(value_int(dataReadBack1[0])) == 7); + TEST(dataReadBack1[1].type() == value::TYPE_DOUBLE); + TEST(static_cast(value_double(dataReadBack1[1])) == 2.78); + TEST(dataReadBack1[2].type() == value::TYPE_STRING); + TEST(static_cast(value_string(dataReadBack1[2])) == + "hello world"); + + value val1(array1); + TEST(val1.type() == value::TYPE_ARRAY); + value_array array2(val1); + TEST(array2.size() == 3); + try { + value_array array4(value_int(4)); + TEST_FAILED("invalid cast int-array suceeded"); + } catch (error const&) {} + + int const arrayDatax[] = {7, 4}; + + value const array5( + arrayValueArray(arrayDatax, ARRAY_SIZE(arrayDatax))); + TEST(array5.type() == value::TYPE_ARRAY); + TEST(value_array(array5).size() == 2); + vector dataReadBackx(value_array(array5).vectorValueValue()); + + TEST(dataReadBackx.size() == 2); + TEST(static_cast(value_int(dataReadBackx[0])) == 7); + vector test5x; + fromValue(test5x, array5); + TEST(test5x[1] == 4); + + vector arrayDataVec; + arrayDataVec.push_back("hello world"); + value const array6(toValue(arrayDataVec)); + TEST(array6.type() == value::TYPE_ARRAY); + TEST(value_array(array6).size() == 1); + } +}; + + +class arrayArrayTestSuite : public testSuite { +public: + virtual string suiteName() { + return "arrayArrayTestSuite"; + } + virtual void runtests(unsigned int const) { + + /* Empty array of arrays */ + vector > arrayArrayDataVec; + + value const arrayArray1(toValue(arrayArrayDataVec)); + TEST(arrayArray1.type() == value::TYPE_ARRAY); + TEST(value_array(arrayArray1).size() == 0); + + /* Array of 1 empty array */ + vector innerArray; + arrayArrayDataVec.push_back(innerArray); + value const arrayArray2(toValue(arrayArrayDataVec)); + + TEST(arrayArray2.type() == value::TYPE_ARRAY); + TEST(value_array(arrayArray2).size() == 1); + vector dataReadBackx( + value_array(arrayArray2).vectorValueValue()); + TEST(dataReadBackx.size() == 1); + TEST(dataReadBackx[0].type() == value::TYPE_ARRAY); + vector dataReadBackx2( + value_array(dataReadBackx[0]).vectorValueValue()); + TEST(dataReadBackx2.size() == 0); + } +}; + + +} // unnamed namespace + + +string +valueTestSuite::suiteName() { + return "valueTestSuite"; +} + + + +void +valueTestSuite::runtests(unsigned int const indentation) { + + intTestSuite().run(indentation+1); + doubleTestSuite().run(indentation+1); + booleanTestSuite().run(indentation+1); + datetimeTestSuite().run(indentation+1); + stringTestSuite().run(indentation+1); + bytestringTestSuite().run(indentation+1); + nilTestSuite().run(indentation+1); + i8TestSuite().run(indentation+1); + structTestSuite().run(indentation+1); + arrayTestSuite().run(indentation+1); + arrayArrayTestSuite().run(indentation+1); +} diff --git a/trunk/test/cpp/value.hpp b/trunk/test/cpp/value.hpp new file mode 100644 index 000000000..65d0d9088 --- /dev/null +++ b/trunk/test/cpp/value.hpp @@ -0,0 +1,9 @@ +#include "tools.hpp" + +class valueTestSuite : public testSuite { + +public: + virtual std::string suiteName(); + virtual void runtests(unsigned int const indentation); +}; + diff --git a/trunk/test/cpp/xml.cpp b/trunk/test/cpp/xml.cpp new file mode 100644 index 000000000..0a73e24ee --- /dev/null +++ b/trunk/test/cpp/xml.cpp @@ -0,0 +1,100 @@ +/*============================================================================= + xml +=============================================================================== + Test the XML generator and parser C++ facilities of XML-RPC for C/C++. + +=============================================================================*/ + +#include + +#include "xmlrpc-c/girerr.hpp" +using girerr::error; +using girerr::throwf; +#include "xmlrpc-c/base.hpp" +#include "xmlrpc-c/xml.hpp" + +#include "tools.hpp" +#include "xml.hpp" + +using namespace xmlrpc_c; +using namespace std; + + +namespace { + +class callTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "callTestSuite"; + } + virtual void runtests(unsigned int const) { + + string callXml; + + string const methodName0("myMethod"); + paramList const paramList0; + + xml::generateCall(methodName0, paramList(), &callXml); + + string methodName; + paramList paramList; + + xml::parseCall(callXml, &methodName, ¶mList); + + TEST(methodName == methodName0); + TEST(paramList.size() == paramList0.size()); + } +}; + + + +class responseTestSuite : public testSuite { + +public: + virtual string suiteName() { + return "responseTestSuite"; + } + virtual void runtests(unsigned int const) { + + string respXml; + + rpcOutcome outcome0(value_int(7)); + + xml::generateResponse(outcome0, &respXml); + + rpcOutcome outcome; + + xml::parseResponse(respXml, &outcome); + + TEST((int)value_int(outcome.getResult()) == + (int)value_int(outcome0.getResult())); + + value result; + + xml::parseSuccessfulResponse(respXml, &result); + + TEST((int)value_int(result) == (int)value_int(outcome0.getResult())); + } +}; + + + +} // unnamed namespace + + + +string +xmlTestSuite::suiteName() { + return "XMLTestSuite"; +} + + + +void +xmlTestSuite::runtests(unsigned int const indentation) { + + callTestSuite().run(indentation+1); + + responseTestSuite().run(indentation+1); +} diff --git a/trunk/test/cpp/xml.hpp b/trunk/test/cpp/xml.hpp new file mode 100644 index 000000000..3946f46a3 --- /dev/null +++ b/trunk/test/cpp/xml.hpp @@ -0,0 +1,9 @@ +#include "tools.hpp" + +class xmlTestSuite : public testSuite { + +public: + virtual std::string suiteName(); + virtual void runtests(unsigned int const indentation); +}; + diff --git a/trunk/test/data/req_no_params.xml b/trunk/test/data/req_no_params.xml new file mode 100644 index 000000000..6ed51a4fa --- /dev/null +++ b/trunk/test/data/req_no_params.xml @@ -0,0 +1,9 @@ + + + + + + foo + diff --git a/trunk/test/data/req_out_of_order.xml b/trunk/test/data/req_out_of_order.xml new file mode 100644 index 000000000..8b078a4bb --- /dev/null +++ b/trunk/test/data/req_out_of_order.xml @@ -0,0 +1,12 @@ + + + + + 2 + + + 2 + + + add + diff --git a/trunk/test/data/req_value_name.xml b/trunk/test/data/req_value_name.xml new file mode 100644 index 000000000..b55d4f0e1 --- /dev/null +++ b/trunk/test/data/req_value_name.xml @@ -0,0 +1,14 @@ + + + foo + + + + + 0 + child elements reversed! + + + + + diff --git a/trunk/test/data/sample_add_call.xml b/trunk/test/data/sample_add_call.xml new file mode 100644 index 000000000..b11336a70 --- /dev/null +++ b/trunk/test/data/sample_add_call.xml @@ -0,0 +1,8 @@ + + +sample.add + +5 +7 + + diff --git a/trunk/test/eftest_wrapper.sh b/trunk/test/eftest_wrapper.sh new file mode 100644 index 000000000..31606b74c --- /dev/null +++ b/trunk/test/eftest_wrapper.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +echo "*** Testing for heap block overruns..." +efrpctest +if ! test $?; then exit 1; fi + +echo "*** Testing for heap block underruns..." +EF_PROTECT_BELOW=1 efrpctest +if ! test $?; then exit 1; fi + +echo "*** Testing for access to freed heap blocks..." +EF_PROTECT_FREE=1 efrpctest +if ! test $?; then exit 1; fi + +echo "*** Testing for single-byte overruns..." +EF_ALIGNMENT=0 efrpctest +if ! test $?; then exit 1; fi diff --git a/trunk/test/http-req-simple.txt b/trunk/test/http-req-simple.txt new file mode 100644 index 000000000..00db6a0a0 --- /dev/null +++ b/trunk/test/http-req-simple.txt @@ -0,0 +1,11 @@ +POST /cgi-bin/sample-cgi.cgi 1.0 +Host: localhost +Content-Type: text/xml +Content-Length: 141 + + + + system.listMethods + + + diff --git a/trunk/test/memblock.c b/trunk/test/memblock.c new file mode 100644 index 000000000..781afb4f6 --- /dev/null +++ b/trunk/test/memblock.c @@ -0,0 +1,237 @@ +#include + +#include "xmlrpc_config.h" +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/string_int.h" + +#include "testtool.h" + + +#include "memblock.h" + + + +static char* test_string_1 = "foo"; +static int test_int_array_1[5] = {1, 2, 3, 4, 5}; +static int test_int_array_2[3] = {6, 7, 8}; +static int test_int_array_3[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + + + +static void +testMemBlock(void) { + + xmlrpc_env env; + xmlrpc_mem_block * blockP; + + xmlrpc_mem_block * typedHeapBlockP; + void ** typedContents; + + xmlrpc_env_init(&env); + + /* Allocate a zero-size block. */ + blockP = xmlrpc_mem_block_new(&env, 0); + TEST_NO_FAULT(&env); + TEST(blockP != NULL); + TEST(xmlrpc_mem_block_size(blockP) == 0); + + /* Grow the block a little bit. */ + xmlrpc_mem_block_resize(&env, blockP, strlen(test_string_1) + 1); + TEST_NO_FAULT(&env); + TEST(xmlrpc_mem_block_size(blockP) == strlen(test_string_1) + 1); + + /* Insert a string into the block, and resize it by large amount. + ** We want to cause a reallocation and copy of the block contents. */ + strcpy(xmlrpc_mem_block_contents(blockP), test_string_1); + xmlrpc_mem_block_resize(&env, blockP, 10000); + TEST_NO_FAULT(&env); + TEST(xmlrpc_mem_block_size(blockP) == 10000); + TEST(xmlrpc_streq(xmlrpc_mem_block_contents(blockP), test_string_1)); + + /* Test growing beyond a megabyte */ + xmlrpc_mem_block_resize(&env, blockP, 1024*1024+1); + TEST_NO_FAULT(&env); + TEST(xmlrpc_mem_block_size(blockP) == 1024*1024+1); + TEST(xmlrpc_streq(xmlrpc_mem_block_contents(blockP), test_string_1)); + + /* Test shrinking */ + xmlrpc_mem_block_resize(&env, blockP, 2); + TEST_NO_FAULT(&env); + TEST(xmlrpc_mem_block_size(blockP) == 2); + TEST(xmlrpc_memeq(xmlrpc_mem_block_contents(blockP), test_string_1, 2)); + + /* Test cleanup code (with help from memprof). */ + xmlrpc_mem_block_free(blockP); + + /* Allocate a bigger block. */ + blockP = xmlrpc_mem_block_new(&env, 128); + TEST_NO_FAULT(&env); + TEST(blockP != NULL); + TEST(xmlrpc_mem_block_size(blockP) == 128); + + /* Test cleanup code (with help from memprof). */ + xmlrpc_mem_block_free(blockP); + + /* Allocate a "typed" memory block. */ + typedHeapBlockP = XMLRPC_TYPED_MEM_BLOCK_NEW(void *, &env, 20); + TEST_NO_FAULT(&env); + TEST(typedHeapBlockP != NULL); + TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(void*, typedHeapBlockP) == 20); + typedContents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(void*, typedHeapBlockP); + TEST(typedContents != NULL); + + /* Resize a typed memory block. */ + XMLRPC_TYPED_MEM_BLOCK_RESIZE(void*, &env, typedHeapBlockP, 100); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(void*, typedHeapBlockP) == 100); + + /* Test cleanup code (with help from memprof). */ + XMLRPC_TYPED_MEM_BLOCK_FREE(void*, typedHeapBlockP); + + /* Test xmlrpc_mem_block_append. */ + blockP = XMLRPC_TYPED_MEM_BLOCK_NEW(int, &env, 5); + TEST_NO_FAULT(&env); + memcpy(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(int, blockP), + test_int_array_1, sizeof(test_int_array_1)); + XMLRPC_TYPED_MEM_BLOCK_APPEND(int, &env, blockP, test_int_array_2, 3); + TEST(XMLRPC_TYPED_MEM_BLOCK_SIZE(int, blockP) == 8); + TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(int, blockP), + test_int_array_3, sizeof(test_int_array_3)) == 0); + XMLRPC_TYPED_MEM_BLOCK_FREE(int, blockP); + + xmlrpc_env_clean(&env); +} + + + +static void +testMemPool(void) { + + xmlrpc_env env; + + xmlrpc_mem_pool * poolP; + + xmlrpc_env_init(&env); + + poolP = xmlrpc_mem_pool_new(&env, 1); + TEST_NO_FAULT(&env); + TEST(poolP != NULL); + + xmlrpc_mem_pool_free(poolP); + + poolP = xmlrpc_mem_pool_new(&env, 10); + TEST_NO_FAULT(&env); + TEST(poolP != NULL); + + xmlrpc_mem_pool_alloc(&env, poolP, 1); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_release(poolP, 1); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_alloc(&env, poolP, 5); + TEST_NO_FAULT(&env); + + { + xmlrpc_env env2; + xmlrpc_env_init(&env2); + xmlrpc_mem_pool_alloc(&env2, poolP, 6); + TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env2); + } + + xmlrpc_mem_pool_alloc(&env, poolP, 5); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_release(poolP, 5); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_release(poolP, 5); + TEST_NO_FAULT(&env); + + xmlrpc_mem_pool_free(poolP); + + xmlrpc_env_clean(&env); +} + + + +static void +testMemBlockPool(void) { + + xmlrpc_env env; + + xmlrpc_mem_pool * poolP; + xmlrpc_mem_block * block1P; + + xmlrpc_env_init(&env); + + /* The memory block facility often allocates more memory that we request, + anticipating the future (e.g. if we create a 1-byte block, it allocates + 16), so we work in large numbers. + */ + + poolP = xmlrpc_mem_pool_new(&env, 1000); + TEST_NO_FAULT(&env); + TEST(poolP != NULL); + + block1P = xmlrpc_mem_block_new_pool(&env, 1000, poolP); + TEST_NO_FAULT(&env); + TEST(block1P != NULL); + + xmlrpc_mem_block_free(block1P); + + block1P = xmlrpc_mem_block_new_pool(&env, 200, poolP); + + { + xmlrpc_env env2; + xmlrpc_env_init(&env2); + xmlrpc_mem_block_new_pool(&env2, 900, poolP); + TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env2); + } + + xmlrpc_mem_block_resize(&env, block1P, 500); + TEST_NO_FAULT(&env); + + { + xmlrpc_env env2; + xmlrpc_env_init(&env2); + xmlrpc_mem_block_resize(&env2, block1P, 1100); + TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env2); + } + + { + xmlrpc_env env2; + xmlrpc_env_init(&env2); + xmlrpc_mem_block_new_pool(&env2, 600, poolP); + TEST_FAULT(&env2, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env2); + } + + xmlrpc_mem_block_free(block1P); + + xmlrpc_mem_pool_free(poolP); + + xmlrpc_env_clean(&env); +} + + + +void +test_memBlock() { + + printf("Running memory manager tests..."); + + testMemBlock(); + + testMemPool(); + + testMemBlockPool(); + + printf("\n"); + printf("Memory manager tests done.\n"); +} + + diff --git a/trunk/test/memblock.h b/trunk/test/memblock.h new file mode 100644 index 000000000..30ed9fc71 --- /dev/null +++ b/trunk/test/memblock.h @@ -0,0 +1,7 @@ +#ifndef TEST_MEMBLOCK_H_INCLUDED +#define TEST_MEMBLOCK_H_INCLUDED + +void +test_memBlock(void); + +#endif diff --git a/trunk/test/method_registry.c b/trunk/test/method_registry.c new file mode 100644 index 000000000..af88bb8aa --- /dev/null +++ b/trunk/test/method_registry.c @@ -0,0 +1,1126 @@ +#include +#include + +#include "int.h" +#include "casprintf.h" +#include "girstring.h" + +#include "xmlrpc_config.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" + +#include "testtool.h" +#include "xml_data.h" +#include "method_registry.h" + + +#define FOO_SERVERINFO ((void*) 0xF00) +#define FOO_CALLINFO ((void*) 0xFC0) +#define BAR_SERVERINFO ((void*) 0xBAF) +#define BAR_CALLINFO ((void*) 0xBAC) +#define MULTI_CALLINFO ((void*) 0xFFF) +#define DEFAULT_SERVERINFO ((void*) 0xD00) +#define DEFAULT_CALLINFO ((void*) 0xDC0) + +static const char * const barHelp = "This is the help for Method test.bar."; + + + +static void +testVersion(void) { + + unsigned int major, minor, point; + + xmlrpc_server_version(&major, &minor, &point); + +#ifndef _WIN32 + /* xmlrpc_server_version_major, etc. are not exported from a Windows DLL */ + + TEST(major == xmlrpc_server_version_major); + TEST(minor == xmlrpc_server_version_minor); + TEST(point == xmlrpc_server_version_point); +#endif +} + + + +static xmlrpc_value * +test_foo(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo) { + + xmlrpc_int32 x, y; + + TEST_NO_FAULT(envP); + TEST(paramArrayP != NULL); + TEST(serverInfo == FOO_SERVERINFO); + TEST(callInfo == FOO_CALLINFO || callInfo == MULTI_CALLINFO); + + xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); + TEST_NO_FAULT(envP); + TEST(x == 25); + TEST(y == 17); + + return xmlrpc_build_value(envP, "i", (xmlrpc_int32) x + y); +} + + + +static xmlrpc_value * +test_foo_type1(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo) { + + xmlrpc_int32 x, y; + + TEST_NO_FAULT(envP); + TEST(paramArrayP != NULL); + TEST(serverInfo == FOO_SERVERINFO); + + xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); + TEST_NO_FAULT(envP); + TEST(x == 25); + TEST(y == 17); + + return xmlrpc_build_value(envP, "i", (xmlrpc_int32) x + y); +} + + + +static xmlrpc_value * +test_bar(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP, + void * const serverInfo, + void * const callInfo) { + + xmlrpc_int32 x, y; + + TEST_NO_FAULT(envP); + TEST(paramArrayP != NULL); + TEST(serverInfo == BAR_SERVERINFO); + TEST(callInfo == BAR_CALLINFO || callInfo == MULTI_CALLINFO); + + xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); + TEST_NO_FAULT(envP); + TEST(x == 25); + TEST(y == 17); + + xmlrpc_env_set_fault(envP, 123, "Test fault"); + + return NULL; +} + + + +static xmlrpc_value * +test_default(xmlrpc_env * const envP, + const char * const callInfo, + const char * const methodName, + xmlrpc_value * const paramArrayP, + void * const serverInfo) { + + xmlrpc_int32 x, y; + + TEST_NO_FAULT(envP); + TEST(paramArrayP != NULL); + TEST(serverInfo == DEFAULT_SERVERINFO); + + TEST(streq(methodName, "test.nosuch") || + streq(methodName, "test.nosuch.old")); + + if (streq(methodName, "nosuch.method")) + TEST(callInfo == DEFAULT_CALLINFO); + else if (streq(methodName, "nosuch.method.old")) + TEST(callInfo == NULL); + + xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y); + TEST_NO_FAULT(envP); + TEST(x == 25); + TEST(y == 17); + + return xmlrpc_build_value(envP, "i", 2 * (x + y)); +} + + + +static xmlrpc_value * +test_exttype(xmlrpc_env * const envP, + xmlrpc_value * const paramArrayP ATTR_UNUSED, + void * const serverInfo ATTR_UNUSED, + void * const callInfo ATTR_UNUSED) { + + return xmlrpc_build_value(envP, "(In)", (xmlrpc_int64)8); +} + + + +static void +doRpc(xmlrpc_env * const envP, + xmlrpc_registry * const registryP, + const char * const methodName, + xmlrpc_value * const argArrayP, + void * const callInfo, + xmlrpc_value ** const resultPP) { +/*---------------------------------------------------------------------------- + Do what an XML-RPC server would do -- pass an XML call to the registry + and get XML back. + + Actually to our caller, we look more like an Xmlrpc-c client. We're + both the client and the server all bound together. +-----------------------------------------------------------------------------*/ + xmlrpc_mem_block * callP; + xmlrpc_mem_block * responseP; + + /* Build a call, and tell the registry to handle it. */ + callP = xmlrpc_mem_block_new(envP, 0); + TEST_NO_FAULT(envP); + xmlrpc_serialize_call(envP, callP, methodName, argArrayP); + TEST_NO_FAULT(envP); + + if (callInfo) + xmlrpc_registry_process_call2( + envP, registryP, + xmlrpc_mem_block_contents(callP), + xmlrpc_mem_block_size(callP), + callInfo, &responseP); + else + responseP = xmlrpc_registry_process_call( + envP, registryP, NULL, + xmlrpc_mem_block_contents(callP), + xmlrpc_mem_block_size(callP)); + + TEST_NO_FAULT(envP); + TEST(responseP != NULL); + + /* Parse the response. */ + *resultPP = xmlrpc_parse_response(envP, + xmlrpc_mem_block_contents(responseP), + xmlrpc_mem_block_size(responseP)); + + xmlrpc_mem_block_free(callP); + xmlrpc_mem_block_free(responseP); +} + + + +static const char * const validSigString[] = { + "i:", + "s:d", + "n:iIbds86SA", + "i:,i:", + "i:dd,s:,A:A", + "i:,", + "b:i,", + "b:i,b:,", + NULL +}; + +static const char * const invalidSigString[] = { + "", + "i", + "q", + "i:q", + "i:ddq", + ",", + ",i:", + "i,", + "b:i,,b:i", + "ii:", + "ii:ii", + NULL +}; + + + +static void +test_system_methodSignature(xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Test system.methodSignature system method. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xmlrpc_value * argArrayP; + xmlrpc_value * resultP; + const char * type0; + const char * type1; + const char * type2; + const char * type3; + const char * type4; + const char * type5; + const char * type6; + const char * type7; + const char * type8; + const char * type9; + const char * nosigstring; + + xmlrpc_env_init(&env); + + argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosuchmethod"); + doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, + &resultP); + TEST_FAULT(&env, XMLRPC_NO_SUCH_METHOD_ERROR); + xmlrpc_DECREF(argArrayP); + + argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosig0"); + + doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, + &resultP); + TEST_NO_FAULT(&env); + + xmlrpc_read_string(&env, resultP, &nosigstring); + TEST_NO_FAULT(&env); + + TEST(streq(nosigstring, "undef")); + strfree(nosigstring); + xmlrpc_DECREF(resultP); + xmlrpc_DECREF(argArrayP); + + argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig0"); + doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, + &resultP); + TEST_NO_FAULT(&env); + + xmlrpc_decompose_value(&env, resultP, "((s))", &type0); + TEST_NO_FAULT(&env); + TEST(streq(type0, "int")); + strfree(type0); + xmlrpc_DECREF(resultP); + xmlrpc_DECREF(argArrayP); + + argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig2"); + doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, + &resultP); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, resultP, "((ssssssssss))", + &type0, &type1, &type2, &type3, + &type4, &type5, &type6, &type7, + &type8, &type9); + TEST_NO_FAULT(&env); + TEST(streq(type0, "nil")); + TEST(streq(type1, "int")); + TEST(streq(type2, "i8")); + TEST(streq(type3, "boolean")); + TEST(streq(type4, "double")); + TEST(streq(type5, "string")); + TEST(streq(type6, "dateTime.iso8601")); + TEST(streq(type7, "base64")); + TEST(streq(type8, "struct")); + TEST(streq(type9, "array")); + strfree(type0); strfree(type1); strfree(type2); strfree(type3); + strfree(type4); strfree(type5); strfree(type6); strfree(type7); + strfree(type8); strfree(type9); + xmlrpc_DECREF(resultP); + xmlrpc_DECREF(argArrayP); + + argArrayP = xmlrpc_build_value(&env, "(s)", "test.validsig3"); + doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, + &resultP); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, resultP, "((s)(s))", &type0, &type1); + + TEST_NO_FAULT(&env); + TEST(streq(type0, "int")); + TEST(streq(type1, "int")); + strfree(type0); + strfree(type1); + xmlrpc_DECREF(resultP); + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); +} + + + +static void +test_signature(void) { + + xmlrpc_env env; + xmlrpc_registry * registryP; + unsigned int i; + + xmlrpc_env_init(&env); + + printf(" Running signature tests."); + + registryP = xmlrpc_registry_new(&env); + TEST_NO_FAULT(&env); + + xmlrpc_registry_add_method2(&env, registryP, "test.nosig0", + test_foo, NULL, NULL, FOO_SERVERINFO); + TEST_NO_FAULT(&env); + + xmlrpc_registry_add_method2(&env, registryP, "test.nosig1", + test_foo, "?", NULL, FOO_SERVERINFO); + TEST_NO_FAULT(&env); + + for (i = 0; validSigString[i]; ++i) { + const char * methodName; + casprintf(&methodName, "test.validsig%u", i); + xmlrpc_registry_add_method2(&env, registryP, methodName, + test_foo, + validSigString[i], NULL, FOO_SERVERINFO); + TEST_NO_FAULT(&env); + strfree(methodName); + } + + for (i = 0; invalidSigString[i]; ++i) { + const char * methodName; + casprintf(&methodName, "test.invalidsig%u", i); + xmlrpc_registry_add_method2(&env, registryP, methodName, + test_foo, + invalidSigString[i], NULL, FOO_SERVERINFO); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + strfree(methodName); + } + + xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, "test.old", + test_foo_type1, FOO_SERVERINFO, + NULL, NULL); + TEST_NO_FAULT(&env); + + xmlrpc_registry_add_method_w_doc(&env, registryP, NULL, "test.old.invalid", + test_foo_type1, FOO_SERVERINFO, + invalidSigString[0], NULL); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + test_system_methodSignature(registryP); + + xmlrpc_registry_free(registryP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +static void +test_disable_introspection(void) { + + xmlrpc_env env; + xmlrpc_registry * registryP; + xmlrpc_value * argArrayP; + xmlrpc_value * resultP; + + xmlrpc_env_init(&env); + + printf(" Running disable introspection tests."); + + registryP = xmlrpc_registry_new(&env); + TEST_NO_FAULT(&env); + + xmlrpc_registry_add_method2(&env, registryP, "test.nosig0", + test_foo, NULL, NULL, FOO_SERVERINFO); + TEST_NO_FAULT(&env); + + xmlrpc_registry_disable_introspection(registryP); + + argArrayP = xmlrpc_build_value(&env, "(s)", "test.nosig0"); + doRpc(&env, registryP, "system.methodSignature", argArrayP, NULL, + &resultP); + TEST_FAULT(&env, XMLRPC_INTROSPECTION_DISABLED_ERROR); + xmlrpc_DECREF(argArrayP); + + xmlrpc_registry_free(registryP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +static const char * const expectedMethodName[] = { +/*---------------------------------------------------------------------------- + The list we expect back from system.listMethods. +-----------------------------------------------------------------------------*/ + "system.listMethods", + "system.methodExist", + "system.methodHelp", + "system.methodSignature", + "system.multicall", + "system.shutdown", + "system.capabilities", + "system.getCapabilities", + "test.foo", + "test.bar" +}; + + + +static void +test_system_listMethods(xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Test system.listMethods +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xmlrpc_value * resultP; + xmlrpc_value * argArrayP; + const char * methodName[ARRAY_SIZE(expectedMethodName)]; + unsigned int size; + unsigned int i; + + xmlrpc_env_init(&env); + + printf(" Running system.listMethods tests."); + + argArrayP = xmlrpc_array_new(&env); + TEST_NO_FAULT(&env); + + doRpc(&env, registryP, "system.listMethods", argArrayP, NULL, &resultP); + TEST_NO_FAULT(&env); + + TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_ARRAY); + + size = xmlrpc_array_size(&env, resultP); + + TEST_NO_FAULT(&env); + + TEST(size == ARRAY_SIZE(expectedMethodName)); + + xmlrpc_decompose_value(&env, resultP, "(ssssssssss)", + &methodName[0], &methodName[1], + &methodName[2], &methodName[3], + &methodName[4], &methodName[5], + &methodName[6], &methodName[7], + &methodName[8], &methodName[9]); + + TEST_NO_FAULT(&env); + + for (i = 0; i < ARRAY_SIZE(expectedMethodName); ++i) { + TEST(streq(methodName[i], expectedMethodName[i])); + strfree(methodName[i]); + } + + xmlrpc_DECREF(resultP); + + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +static void +test_system_methodExist(xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Test system.methodExist +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xmlrpc_value * resultP; + xmlrpc_value * argArrayP; + xmlrpc_bool exists; + + xmlrpc_env_init(&env); + + printf(" Running system.methodExist tests."); + + argArrayP = xmlrpc_build_value(&env, "(s)", "test.foo"); + TEST_NO_FAULT(&env); + + doRpc(&env, registryP, "system.methodExist", argArrayP, NULL, &resultP); + TEST_NO_FAULT(&env); + + TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_BOOL); + + xmlrpc_read_bool(&env, resultP, &exists); + TEST_NO_FAULT(&env); + + TEST(exists); + + xmlrpc_DECREF(resultP); + + xmlrpc_DECREF(argArrayP); + + + argArrayP = xmlrpc_build_value(&env, "(s)", "nosuchmethod"); + TEST_NO_FAULT(&env); + + doRpc(&env, registryP, "system.methodExist", argArrayP, NULL, &resultP); + TEST_NO_FAULT(&env); + + TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_BOOL); + + xmlrpc_read_bool(&env, resultP, &exists); + TEST_NO_FAULT(&env); + + TEST(!exists); + + xmlrpc_DECREF(resultP); + + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +static void +testNoHelp(xmlrpc_registry * const registryP) { + + xmlrpc_env env; + xmlrpc_value * resultP; + xmlrpc_value * argArrayP; + const char * helpString; + + xmlrpc_env_init(&env); + + argArrayP = xmlrpc_build_value(&env, "(s)", "test.foo"); + TEST_NO_FAULT(&env); + + doRpc(&env, registryP, "system.methodHelp", argArrayP, NULL, &resultP); + TEST_NO_FAULT(&env); + + TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_STRING); + + xmlrpc_read_string(&env, resultP, &helpString); + TEST_NO_FAULT(&env); + + TEST(streq(helpString, "No help is available for this method.")); + + strfree(helpString); + + xmlrpc_DECREF(resultP); + + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); +} + + + +static void +testExistentHelp(xmlrpc_registry * const registryP) { + + xmlrpc_env env; + xmlrpc_value * resultP; + xmlrpc_value * argArrayP; + const char * helpString; + + xmlrpc_env_init(&env); + + argArrayP = xmlrpc_build_value(&env, "(s)", "test.bar"); + TEST_NO_FAULT(&env); + + doRpc(&env, registryP, "system.methodHelp", argArrayP, NULL, &resultP); + TEST_NO_FAULT(&env); + + TEST(xmlrpc_value_type(resultP) == XMLRPC_TYPE_STRING); + + xmlrpc_read_string(&env, resultP, &helpString); + TEST_NO_FAULT(&env); + + TEST(streq(helpString, barHelp)); + + strfree(helpString); + + xmlrpc_DECREF(resultP); + + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); +} + + + +static void +test_system_methodHelp(xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Test system.methodHelp +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + + xmlrpc_env_init(&env); + + printf(" Running system.methodHelp tests."); + + testNoHelp(registryP); + + testExistentHelp(registryP); + + printf("\n"); +} + + + +static void +test_system_capabilities(xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Test system.capabilities +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xmlrpc_value * resultP; + xmlrpc_value * argArrayP; + const char * facility; + xmlrpc_int version_major, version_minor, version_point; + xmlrpc_int protocol_version; + + xmlrpc_env_init(&env); + + printf(" Running system.capabilities tests."); + + argArrayP = xmlrpc_array_new(&env); + TEST_NO_FAULT(&env); + + doRpc(&env, registryP, "system.capabilities", argArrayP, NULL, &resultP); + TEST_NO_FAULT(&env); + + xmlrpc_decompose_value(&env, resultP, "{s:s,s:i,s:i,s:i,s:i,*}", + "facility", &facility, + "version_major", &version_major, + "version_minor", &version_minor, + "version_point", &version_point, + "protocol_version", &protocol_version); + TEST_NO_FAULT(&env); + + TEST(streq(facility, "xmlrpc-c")); + TEST(protocol_version == 2); + + strfree(facility); + + xmlrpc_DECREF(resultP); + + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +static void +test_system_getCapabilities(xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Test system.getCapabilities +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xmlrpc_value * resultP; + xmlrpc_value * argArrayP; + const char * specUrl; + int specVersion; + + xmlrpc_env_init(&env); + + printf(" Running system.getCapabilities tests."); + + argArrayP = xmlrpc_array_new(&env); + TEST_NO_FAULT(&env); + + doRpc(&env, registryP, "system.getCapabilities", argArrayP, NULL, + &resultP); + TEST_NO_FAULT(&env); + + xmlrpc_decompose_value(&env, resultP, "{s:{s:s,s:i,*},*}", + "introspect", + "specUrl", &specUrl, + "specVersion", &specVersion); + TEST_NO_FAULT(&env); + + TEST(streq(specUrl, + "http://xmlrpc-c.sourceforge.net/xmlrpc-c/introspection.html")); + TEST(specVersion == 1); + + strfree(specUrl); + + xmlrpc_DECREF(resultP); + + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +static void +test_system_multicall(xmlrpc_registry * const registryP) { +/*---------------------------------------------------------------------------- + Test system.multicall +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xmlrpc_value * multiP; + xmlrpc_int32 foo1_result, foo2_result; + xmlrpc_int32 bar_code, nosuch_code; + char *bar_string, *nosuch_string; + xmlrpc_value * valueP; + xmlrpc_value * argArrayP; + + xmlrpc_env_init(&env); + + printf(" Running multicall tests."); + + /* Build an argument array for our calls. */ + argArrayP = xmlrpc_build_value(&env, "(ii)", + (xmlrpc_int32) 25, (xmlrpc_int32) 17); + TEST_NO_FAULT(&env); + + multiP = xmlrpc_build_value(&env, + "((" + "{s:s,s:A}" /* test.foo */ + "{s:s,s:A}" /* test.bar */ + "{s:s,s:A}" /* test.nosuch */ + "{s:s,s:A}" /* test.foo */ + "))", + "methodName", "test.foo", + "params", argArrayP, + "methodName", "test.bar", + "params", argArrayP, + "methodName", "test.nosuch", + "params", argArrayP, + "methodName", "test.foo", + "params", argArrayP); + TEST_NO_FAULT(&env); + doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, + &valueP); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, valueP, + "(" + "(i)" /* result of test.foo */ + "{s:i,s:s,*}" /* result of test.bar */ + "{s:i,s:s,*}" /* result of test.nosuch */ + "(i)" /* result of test.foo #2 */ + ")", + &foo1_result, + "faultCode", &bar_code, + "faultString", &bar_string, + "faultCode", &nosuch_code, + "faultString", &nosuch_string, + &foo2_result); + xmlrpc_DECREF(valueP); + TEST_NO_FAULT(&env); + TEST(foo1_result == 42); + TEST(bar_code == 123); + TEST(streq(bar_string, "Test fault")); + TEST(nosuch_code == XMLRPC_NO_SUCH_METHOD_ERROR); + TEST(foo2_result == 42); + xmlrpc_DECREF(multiP); + free(bar_string); + free(nosuch_string); + + + /* Now for some invalid multi calls */ + + multiP = xmlrpc_build_value(&env, + "(({s:s,s:V}{s:s,s:()}{s:s,s:V}))", + "methodName", "test.foo", + "params", argArrayP, + "methodName", "system.multicall", + "params", + "methodName", "test.foo", + "params", argArrayP); + TEST_NO_FAULT(&env); + doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, + &valueP); + TEST_FAULT(&env, XMLRPC_REQUEST_REFUSED_ERROR); + + xmlrpc_DECREF(multiP); + + multiP = xmlrpc_build_value(&env, + "(({s:s,s:V}d))", + "methodName", "test.foo", + "params", argArrayP, + 5.0); + + TEST_NO_FAULT(&env); + doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, + &valueP); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + xmlrpc_DECREF(multiP); + + multiP = xmlrpc_build_value(&env, + "({s:s,s:V})", + "methodName", "test.foo", + "params", argArrayP); + + TEST_NO_FAULT(&env); + doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, + &valueP); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + xmlrpc_DECREF(multiP); + + multiP = xmlrpc_build_value(&env, "(({}))"); + TEST_NO_FAULT(&env); + doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, + &valueP); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_DECREF(multiP); + + multiP = xmlrpc_build_value(&env, "(({s:s}))", + "methodName", "test.foo"); + TEST_NO_FAULT(&env); + doRpc(&env, registryP, "system.multicall", multiP, MULTI_CALLINFO, + &valueP); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_DECREF(multiP); + + + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +static void +testCall(xmlrpc_registry * const registryP) { + + xmlrpc_env env; + xmlrpc_env env2; + xmlrpc_value * argArrayP; + xmlrpc_value * valueP; + xmlrpc_int32 i; + + printf(" Running call tests."); + + xmlrpc_env_init(&env); + + /* Build an argument array for our calls. */ + argArrayP = xmlrpc_build_value(&env, "(ii)", + (xmlrpc_int32) 25, (xmlrpc_int32) 17); + TEST_NO_FAULT(&env); + + /* Call test.foo and check the result. */ + doRpc(&env, registryP, "test.foo", argArrayP, FOO_CALLINFO, &valueP); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + xmlrpc_decompose_value(&env, valueP, "i", &i); + xmlrpc_DECREF(valueP); + TEST_NO_FAULT(&env); + TEST(i == 42); + + /* Call test.bar and check the result. */ + xmlrpc_env_init(&env2); + doRpc(&env2, registryP, "test.bar", argArrayP, BAR_CALLINFO, &valueP); + TEST(env2.fault_occurred); + TEST(env2.fault_code == 123); + TEST(env2.fault_string && streq(env2.fault_string, "Test fault")); + xmlrpc_env_clean(&env2); + + /* Call a non-existant method and check the result. */ + xmlrpc_env_init(&env2); + doRpc(&env2, registryP, "test.nosuch", argArrayP, FOO_CALLINFO, &valueP); + TEST(valueP == NULL); + TEST_FAULT(&env2, XMLRPC_NO_SUCH_METHOD_ERROR); + xmlrpc_env_clean(&env2); + + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +static void +testDefaultMethod(xmlrpc_registry * const registryP) { + + xmlrpc_env env; + xmlrpc_value * argArrayP; + xmlrpc_value * valueP; + xmlrpc_int32 i; + + xmlrpc_env_init(&env); + + printf(" Running default method tests."); + + /* Build an argument array for our calls. */ + argArrayP = xmlrpc_build_value(&env, "(ii)", + (xmlrpc_int32) 25, (xmlrpc_int32) 17); + + xmlrpc_registry_set_default_method(&env, registryP, &test_default, + DEFAULT_SERVERINFO); + TEST_NO_FAULT(&env); + doRpc(&env, registryP, "test.nosuch", argArrayP, DEFAULT_CALLINFO, + &valueP); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + xmlrpc_decompose_value(&env, valueP, "i", &i); + xmlrpc_DECREF(valueP); + TEST_NO_FAULT(&env); + TEST(i == 84); + + /* Now try it with old method interface */ + + doRpc(&env, registryP, "test.nosuch.old", argArrayP, NULL, &valueP); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + xmlrpc_read_int(&env, valueP, &i); + TEST_NO_FAULT(&env); + xmlrpc_DECREF(valueP); + TEST(i == 84); + + /* Change the default method. */ + xmlrpc_registry_set_default_method(&env, registryP, &test_default, + BAR_SERVERINFO); + TEST_NO_FAULT(&env); + + xmlrpc_DECREF(argArrayP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +static void +test_apache_dialect(void) { + + char const expectedResp[] = + XML_PROLOGUE + "\r\n" + "\r\n" + "\r\n" + "8\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n"; + + xmlrpc_env env; + xmlrpc_registry * registryP; + xmlrpc_value * argArrayP; + xmlrpc_mem_block * callP; + xmlrpc_mem_block * responseP; + + xmlrpc_env_init(&env); + + printf(" Running apache dialect tests."); + + registryP = xmlrpc_registry_new(&env); + TEST_NO_FAULT(&env); + + xmlrpc_registry_set_dialect(&env, registryP, xmlrpc_dialect_i8); + TEST_NO_FAULT(&env); + + xmlrpc_registry_set_dialect(&env, registryP, 100); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_registry_set_dialect(&env, registryP, xmlrpc_dialect_apache); + TEST_NO_FAULT(&env); + + xmlrpc_registry_add_method2(&env, registryP, "test_exttype", + test_exttype, NULL, NULL, FOO_SERVERINFO); + TEST_NO_FAULT(&env); + + argArrayP = xmlrpc_array_new(&env); + TEST_NO_FAULT(&env); + + callP = xmlrpc_mem_block_new(&env, 0); + TEST_NO_FAULT(&env); + xmlrpc_serialize_call(&env, callP, "test_exttype", argArrayP); + TEST_NO_FAULT(&env); + + xmlrpc_registry_process_call2( + &env, registryP, + xmlrpc_mem_block_contents(callP), + xmlrpc_mem_block_size(callP), + NULL, &responseP); + + TEST_NO_FAULT(&env); + + TEST(XMLRPC_MEMBLOCK_SIZE(char, responseP) == strlen(expectedResp)); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, responseP), + expectedResp, + XMLRPC_MEMBLOCK_SIZE(char, responseP))); + + xmlrpc_DECREF(argArrayP); + xmlrpc_mem_block_free(callP); + xmlrpc_mem_block_free(responseP); + xmlrpc_registry_free(registryP); + + xmlrpc_env_clean(&env); + + printf("\n"); +} + + + +void +test_method_registry(void) { + + xmlrpc_env env, env2; + xmlrpc_value * valueP; + xmlrpc_registry * registryP; + xmlrpc_mem_block * responseP; + + xmlrpc_env_init(&env); + + testVersion(); + + printf("Running method registry tests."); + + /* Create a new registry. */ + registryP = xmlrpc_registry_new(&env); + TEST_NO_FAULT(&env); + TEST(registryP != NULL); + + /* Add some test methods. */ + xmlrpc_registry_add_method(&env, registryP, NULL, "test.foo", + test_foo_type1, FOO_SERVERINFO); + TEST_NO_FAULT(&env); + xmlrpc_registry_add_method2(&env, registryP, "test.bar", + test_bar, NULL, barHelp, BAR_SERVERINFO); + TEST_NO_FAULT(&env); + + printf("\n"); + testCall(registryP); + + test_system_multicall(registryP); + + xmlrpc_env_init(&env2); + xmlrpc_registry_process_call2(&env, registryP, + expat_error_data, + strlen(expat_error_data), + NULL, + &responseP); + TEST_NO_FAULT(&env); + TEST(responseP != NULL); + valueP = xmlrpc_parse_response(&env2, xmlrpc_mem_block_contents(responseP), + xmlrpc_mem_block_size(responseP)); + TEST(valueP == NULL); + TEST_FAULT(&env2, XMLRPC_PARSE_ERROR); + xmlrpc_mem_block_free(responseP); + xmlrpc_env_clean(&env2); + + printf("\n"); + + testDefaultMethod(registryP); + + test_system_listMethods(registryP); + + test_system_methodExist(registryP); + + test_system_methodHelp(registryP); + + test_system_capabilities(registryP); + + test_system_getCapabilities(registryP); + + test_signature(); + + test_disable_introspection(); + + test_apache_dialect(); + + /* Test cleanup code (w/memprof). */ + xmlrpc_registry_free(registryP); + + printf("\n"); + + xmlrpc_env_clean(&env); +} diff --git a/trunk/test/method_registry.h b/trunk/test/method_registry.h new file mode 100644 index 000000000..bdc325bdb --- /dev/null +++ b/trunk/test/method_registry.h @@ -0,0 +1,7 @@ +#ifndef TEST_METHOD_REGISTRY_H_INCLUDED +#define TEST_METHOD_REGISTRY_H_INCLUDED + +void +test_method_registry(void); + +#endif diff --git a/trunk/test/parse_xml.c b/trunk/test/parse_xml.c new file mode 100644 index 000000000..d6abe5904 --- /dev/null +++ b/trunk/test/parse_xml.c @@ -0,0 +1,529 @@ +#include +#include + +#include "xmlrpc_config.h" + +#include "girstring.h" +#include "casprintf.h" +#include "xmlrpc-c/base.h" + +#include "testtool.h" +#include "xml_data.h" +#include "parse_xml.h" + + + +static void +testParseNumberValue(void) { + +char const xmldata[] = + XML_PROLOGUE + "\r\n" + "test\r\n" + "\r\n" + "2147483647\r\n" \ + "-2147483648\r\n" \ + "10\r\n" + "10\r\n" + "10\r\n" + "10\r\n" + "10\r\n" + "10\r\n" + "10.1\r\n" + "-10.1\r\n" + "+10.1\r\n" + "0\r\n" + ".01\r\n" + "5.\r\n" + "5.3E6\r\n" + " 1\r\n" + "\r\n" + "\r\n"; + + xmlrpc_env env; + xmlrpc_value * paramArrayP; + const char * methodName; + int arraySize; + xmlrpc_int int_max, int_min; + xmlrpc_int32 i_i1, i_i2, i_i4; + xmlrpc_int64 i_i8, i_ex_i8; + double d1, d2, d3, d4, d5, d6, d7, d8, d9; + + xmlrpc_env_init(&env); + + xmlrpc_parse_call(&env, xmldata, strlen(xmldata), + &methodName, ¶mArrayP); + TEST_NO_FAULT(&env); + + arraySize = xmlrpc_array_size(&env, paramArrayP); + TEST_NO_FAULT(&env); + + TEST(arraySize == 16); + + xmlrpc_decompose_value( + &env, paramArrayP, "(iiiiiIIddddddddd)", + &int_max, &int_min, &i_i1, &i_i2, &i_i4, &i_i8, &i_ex_i8, + &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9); + + TEST_NO_FAULT(&env); + + TEST(int_max == INT_MAX); + TEST(int_min == INT_MIN); + TEST(i_i1 == 10); + TEST(i_i2 == 10); + TEST(i_i4 == 10); + TEST(i_i8 == 10); + TEST(i_ex_i8 == 10); + TESTFLOATEQUAL(d1, 10.0); + TESTFLOATEQUAL(d2, 10.1); + TESTFLOATEQUAL(d3, -10.1); + TESTFLOATEQUAL(d4, +10.1); + TESTFLOATEQUAL(d5, 0.0); + TESTFLOATEQUAL(d6, 0.01); + TESTFLOATEQUAL(d7, 5.0); + TESTFLOATEQUAL(d8, 5.3E6); + TESTFLOATEQUAL(d9, 1.0); + + xmlrpc_DECREF(paramArrayP); + strfree(methodName); + + xmlrpc_env_clean(&env); +} + + + +static void +testParseMiscSimpleValue(void) { + +char const xmldata[] = + XML_PROLOGUE + "\r\n" + "test\r\n" + "\r\n" + "hello\r\n" + "0\r\n" + "1\r\n" + "19980717T14:08:55" + "\r\n" + "" + "19980717T14:08:55.123456" + "\r\n" + "YmFzZTY0IGRhdGE=\r\n" + "\r\n" + "\r\n" + "\r\n" + "\r\n"; + + xmlrpc_env env; + xmlrpc_value * paramArrayP; + const char * methodName; + int arraySize; + const char * str_hello; + xmlrpc_bool b_false, b_true; + const char * datetime_sec; + const char * datetime_usec; + unsigned char * b64_data; + size_t b64_len; + + xmlrpc_env_init(&env); + + xmlrpc_parse_call(&env, xmldata, strlen(xmldata), + &methodName, ¶mArrayP); + TEST_NO_FAULT(&env); + + arraySize = xmlrpc_array_size(&env, paramArrayP); + TEST_NO_FAULT(&env); + + TEST(arraySize == 8); + + xmlrpc_decompose_value( + &env, paramArrayP, "(sbb886nn)", + &str_hello, &b_false, &b_true, &datetime_sec, &datetime_usec, + &b64_data, &b64_len); + + TEST_NO_FAULT(&env); + + TEST(streq(str_hello, "hello")); + TEST(!b_false); + TEST(b_true); + TEST(streq(datetime_sec, "19980717T14:08:55")); + TEST(streq(datetime_usec, "19980717T14:08:55.123456")); + TEST(b64_len == 11); + TEST(memcmp(b64_data, "base64 data", b64_len) == 0); + + free(b64_data); + strfree(str_hello); + strfree(datetime_sec); + strfree(datetime_usec); + xmlrpc_DECREF(paramArrayP); + strfree(methodName); + + xmlrpc_env_clean(&env); +} + + + +static void +validateParseResponseResult(xmlrpc_value * const valueP) { + + xmlrpc_env env; + + xmlrpc_value * s; + xmlrpc_int32 int_max; + xmlrpc_int32 int_min; + xmlrpc_int32 int_one; + xmlrpc_bool bool_false; + xmlrpc_bool bool_true; + char * str_hello; + char * str_untagged; + char * datetime; + unsigned char * b64_data; + size_t b64_len; + double negone; + double zero; + double one; + + xmlrpc_env_init(&env); + + xmlrpc_decompose_value( + &env, valueP, "((iibbs68())idddSs)", + &int_max, &int_min, + &bool_false, &bool_true, &str_hello, + &b64_data, &b64_len, &datetime, + &int_one, &negone, &zero, &one, &s, &str_untagged); + + TEST_NO_FAULT(&env); + TEST(int_max == INT_MAX); + TEST(int_min == INT_MIN); + TEST(!bool_false); + TEST(bool_true); + TEST(strlen(str_hello) == strlen("Hello, world! <&>")); + TEST(streq(str_hello, "Hello, world! <&>")); + TEST(b64_len == 11); + TEST(memcmp(b64_data, "base64 data", b64_len) == 0); + TEST(streq(datetime, "19980717T14:08:55")); + TEST(int_one == 1); + TEST(negone == -1.0); + TEST(zero == 0.0); + TEST(one == 1.0); + TEST(streq(str_untagged, "Untagged string")); + free(str_hello); + free(b64_data); + free(datetime); + free(str_untagged); + + { + /* Analyze the contents of our struct. */ + + xmlrpc_value * sval; + int size, sval_int; + + TEST(s != NULL); + size = xmlrpc_struct_size(&env, s); + TEST_NO_FAULT(&env); + TEST(size == 2); + sval = xmlrpc_struct_get_value(&env, s, "ten <&>"); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, sval, "i", &sval_int); + TEST_NO_FAULT(&env); + TEST(sval_int == 10); + sval = xmlrpc_struct_get_value(&env, s, "twenty"); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, sval, "i", &sval_int); + TEST_NO_FAULT(&env); + TEST(sval_int == 20); + xmlrpc_DECREF(s); + } + + xmlrpc_env_clean(&env); +} + + + +static void +testParseGoodResponse(void) { + + xmlrpc_env env; + xmlrpc_value * valueP; + int faultCode; + const char * faultString; + + xmlrpc_env_init(&env); + + xmlrpc_parse_response2(&env, good_response_xml, strlen(good_response_xml), + &valueP, &faultCode, &faultString); + + TEST_NO_FAULT(&env); + TEST(faultString == NULL); + + validateParseResponseResult(valueP); + + xmlrpc_DECREF(valueP); + + /* Try it again with old interface */ + + valueP = xmlrpc_parse_response(&env, + good_response_xml, + strlen(good_response_xml)); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + + validateParseResponseResult(valueP); + + xmlrpc_DECREF(valueP); + + xmlrpc_env_clean(&env); + +} + + + +static void +testParseBadResponseXml(void) { +/*---------------------------------------------------------------------------- + Test parsing of data that is supposed to be a response, but in not + even valid XML. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + xmlrpc_value * valueP; + int faultCode; + const char * faultString; + + xmlrpc_env_init(&env); + + xmlrpc_parse_response2(&env, + unparseable_value, strlen(unparseable_value), + &valueP, &faultCode, &faultString); + + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); + xmlrpc_env_clean(&env); + + xmlrpc_env_init(&env); + + /* And again with the old interface */ + valueP = xmlrpc_parse_response(&env, unparseable_value, + strlen(unparseable_value)); + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); + xmlrpc_env_clean(&env); + TEST(valueP == NULL); +} + + + +static void +testParseBadResponseXmlRpc(void) { +/*---------------------------------------------------------------------------- + Test parsing of data that is supposed to be a response, and is valid + XML, but is not valid XML-RPC. +-----------------------------------------------------------------------------*/ + unsigned int i; + + /* For this test, we test up to but not including the in a + successful RPC response. + */ + + /* Next, check for bogus responses. These are all well-formed XML, but + ** they aren't legal XML-RPC. */ + for (i = 15; bad_responses[i] != NULL; ++i) { + const char * const bad_resp = bad_responses[i]; + xmlrpc_env env; + xmlrpc_value * v; + + xmlrpc_env_init(&env); + + /* Now, make sure the higher-level routine barfs appropriately. */ + v = xmlrpc_parse_response(&env, bad_resp, strlen(bad_resp)); + TEST(env.fault_occurred); + TEST(env.fault_code != 0); /* We use 0 as a code in our bad faults. */ + TEST(v == NULL); + xmlrpc_env_clean(&env); + } +} + + + +static void +testParseBadResult(void) { +/*---------------------------------------------------------------------------- + Test parsing of data that is supposed to be a response, but is not + valid. It looks like a valid success response, but the result value + is not valid XML-RPC. +-----------------------------------------------------------------------------*/ + unsigned int i; + + for (i = 0; bad_values[i] != NULL; ++i) { + const char * const bad_resp = bad_values[i]; + xmlrpc_env env; + xmlrpc_value * valueP; + int faultCode; + const char * faultString; + + xmlrpc_env_init(&env); + + xmlrpc_parse_response2(&env, bad_resp, strlen(bad_resp), + &valueP, &faultCode, &faultString); + + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); + xmlrpc_env_clean(&env); + + xmlrpc_env_init(&env); + + /* And again with the old interface */ + + valueP = xmlrpc_parse_response(&env, bad_resp, strlen(bad_resp)); + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); + TEST(valueP == NULL); + xmlrpc_env_clean(&env); + } +} + + + +static void +testParseBadResponse(void) { +/*---------------------------------------------------------------------------- + Test parsing of data that is supposed to be a response, but is not + valid. Either not valid XML or not valid XML-RPC. +-----------------------------------------------------------------------------*/ + testParseBadResponseXml(); + + testParseBadResponseXmlRpc(); + + testParseBadResult(); +} + + + +static void +testParseFaultResponse(void) { +/*---------------------------------------------------------------------------- + Test parsing of a valid response that indicates the RPC failed. +-----------------------------------------------------------------------------*/ + xmlrpc_env env; + + xmlrpc_env_init(&env); + + { + xmlrpc_value * resultP; + int faultCode; + const char * faultString; + + xmlrpc_parse_response2(&env, + serialized_fault, strlen(serialized_fault), + &resultP, &faultCode, &faultString); + + TEST_NO_FAULT(&env); + TEST(faultString != NULL); + TEST(faultCode == 6); + TEST(streq(faultString, "A fault occurred")); + strfree(faultString); + } + /* Now with the old interface */ + { + xmlrpc_env fault; + + /* Parse a valid fault. */ + xmlrpc_env_init(&fault); + xmlrpc_parse_response(&fault, serialized_fault, + strlen(serialized_fault)); + + TEST(fault.fault_occurred); + TEST(fault.fault_code == 6); + TEST(streq(fault.fault_string, "A fault occurred")); + xmlrpc_env_clean(&fault); + } + + xmlrpc_env_clean(&env); +} + + + +static void +testParseXmlCall(void) { + + xmlrpc_env env; + const char *method_name; + xmlrpc_value *params; + int i1, i2; + const char **bad_call; + + xmlrpc_env_init(&env); + + /* Parse a valid call. */ + xmlrpc_parse_call(&env, serialized_call, strlen(serialized_call), + &method_name, ¶ms); + TEST_NO_FAULT(&env); + TEST(params != NULL); + xmlrpc_decompose_value(&env, params, "(ii)", &i1, &i2); + xmlrpc_DECREF(params); + TEST_NO_FAULT(&env); + TEST(streq(method_name, "gloom&doom")); + TEST(i1 == 10 && i2 == 20); + strfree(method_name); + + /* Test some poorly-formed XML data. */ + xmlrpc_parse_call(&env, unparseable_value, strlen(unparseable_value), + &method_name, ¶ms); + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); + TEST(method_name == NULL && params == NULL); + + /* Next, check for bogus values. These are all well-formed XML, but + they aren't legal XML-RPC. + */ + for (bad_call = bad_calls; *bad_call != NULL; ++bad_call) { + xmlrpc_parse_call(&env, *bad_call, strlen(*bad_call), + &method_name, ¶ms); + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); + TEST(method_name == NULL && params == NULL); + } + xmlrpc_env_clean(&env); +} + + + +static void +testParseXmlValue(void) { + + const char * const xmlInt7 = "7"; + const char * const xmlBadVal1 = "hello"; + const char * const xmlBadVal2 = ""; + + xmlrpc_value * valueP; + + xmlrpc_env env; + + xmlrpc_env_init(&env); + + xmlrpc_parse_value_xml(&env, xmlInt7, strlen(xmlInt7), &valueP); + + TEST_NO_FAULT(&env); + + xmlrpc_DECREF(valueP); + + xmlrpc_parse_value_xml(&env, xmlBadVal1, strlen(xmlBadVal1), &valueP); + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); + xmlrpc_env_clean(&env); + + xmlrpc_env_init(&env); + xmlrpc_parse_value_xml(&env, xmlBadVal2, strlen(xmlBadVal2), &valueP); + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); + + xmlrpc_env_clean(&env); +} + + + +void +test_parse_xml(void) { + + printf("Running XML parsing tests.\n"); + testParseNumberValue(); + testParseMiscSimpleValue(); + testParseGoodResponse(); + testParseFaultResponse(); + testParseBadResponse(); + testParseXmlCall(); + testParseXmlValue(); + printf("\n"); + printf("XML parsing tests done.\n"); +} diff --git a/trunk/test/parse_xml.h b/trunk/test/parse_xml.h new file mode 100644 index 000000000..c3928862b --- /dev/null +++ b/trunk/test/parse_xml.h @@ -0,0 +1,2 @@ +void +test_parse_xml(void); diff --git a/trunk/test/req_no_params.xml b/trunk/test/req_no_params.xml new file mode 100644 index 000000000..6ed51a4fa --- /dev/null +++ b/trunk/test/req_no_params.xml @@ -0,0 +1,9 @@ + + + + + + foo + diff --git a/trunk/test/serialize.c b/trunk/test/serialize.c new file mode 100644 index 000000000..275aa784e --- /dev/null +++ b/trunk/test/serialize.c @@ -0,0 +1,316 @@ +#include +#include +#include + +#include "xmlrpc_config.h" + +#include "xmlrpc-c/base.h" + +#include "testtool.h" +#include "xml_data.h" +#include "girstring.h" +#include "serialize_value.h" + +#include "serialize.h" + + +static void +test_serialize_basic(void) { + + xmlrpc_env env; + xmlrpc_value * v; + xmlrpc_mem_block *output; + size_t size; + + xmlrpc_env_init(&env); + + /* Build a nice, messy value to serialize. We should attempt to use + ** use every data type except double (which doesn't serialize in a + ** portable manner. */ + v = xmlrpc_build_value(&env, "(iibbs68())", + (xmlrpc_int32) INT_MAX, (xmlrpc_int32) INT_MIN, + (xmlrpc_bool) 0, (xmlrpc_bool) 1, + "Hello, world! <&>", + "base64 data", (size_t) 11, + "19980717T14:08:55"); + TEST_NO_FAULT(&env); + + /* Serialize the value. */ + output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); + TEST_NO_FAULT(&env); + xmlrpc_serialize_value(&env, output, v); + TEST_NO_FAULT(&env); + + /* Make sure we serialized the correct value. */ + size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); + TEST(size == strlen(serialized_data)); + TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), + serialized_data, size) == 0); + + /* (Debugging code to display the value.) */ + /* XMLRPC_TYPED_MEM_BLOCK_APPEND(char, &env, output, "\0", 1); + ** TEST_NO_FAULT(&env); + ** printf("%s\n", XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output)); */ + + /* Clean up our value. */ + XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); + xmlrpc_DECREF(v); + + xmlrpc_env_clean(&env); +} + + + +static void +test_serialize_methodResponse(void) { + + /* Serialize a methodResponse. */ + + char const serialized_response[] = + XML_PROLOGUE + "\r\n" + "\r\n" + "30\r\n" + "\r\n" + "\r\n"; + + xmlrpc_env env; + xmlrpc_value * v; + xmlrpc_mem_block *output; + size_t size; + + xmlrpc_env_init(&env); + + output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); + TEST_NO_FAULT(&env); + v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 30); + TEST_NO_FAULT(&env); + xmlrpc_serialize_response(&env, output, v); + TEST_NO_FAULT(&env); + + /* Make sure we serialized the correct value. */ + size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); + TEST(size == strlen(serialized_response)); + TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), + serialized_response, size) == 0); + + /* Clean up our methodResponse. */ + xmlrpc_DECREF(v); + XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); + + xmlrpc_env_clean(&env); +} + + + +static void +test_serialize_methodCall(void) { + + /* Serialize a methodCall. */ + + xmlrpc_env env; + xmlrpc_value * v; + xmlrpc_mem_block *output; + size_t size; + + xmlrpc_env_init(&env); + + output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); + TEST_NO_FAULT(&env); + v = xmlrpc_build_value(&env, "(ii)", (xmlrpc_int32) 10, (xmlrpc_int32) 20); + TEST_NO_FAULT(&env); + xmlrpc_serialize_call(&env, output, "gloom&doom", v); + TEST_NO_FAULT(&env); + + /* Make sure we serialized the correct value. */ + size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); + TEST(size == strlen(serialized_call)); + TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), + serialized_call, size) == 0); + + /* Clean up our methodCall. */ + xmlrpc_DECREF(v); + XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); + + xmlrpc_env_clean(&env); +} + + + +static void +test_serialize_fault(void) { + /* Serialize a fault. */ + + xmlrpc_env env; + xmlrpc_env fault; + xmlrpc_mem_block *output; + size_t size; + + xmlrpc_env_init(&env); + + output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); + TEST_NO_FAULT(&env); + xmlrpc_env_init(&fault); + xmlrpc_env_set_fault(&fault, 6, "A fault occurred"); + xmlrpc_serialize_fault(&env, output, &fault); + TEST_NO_FAULT(&env); + + /* Make sure we serialized the correct value. */ + size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); + TEST(size == strlen(serialized_fault)); + TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), + serialized_fault, size) == 0); + + /* Clean up our fault. */ + xmlrpc_env_clean(&fault); + XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); + + xmlrpc_env_clean(&env); +} + + + +static void +test_serialize_apache_value(void) { + + char const serializedData[] = + "\r\n" + "7\r\n" + "8\r\n" + "\r\n" + ""; + + xmlrpc_env env; + xmlrpc_value * valueP; + xmlrpc_mem_block * outputP; + size_t size; + + xmlrpc_env_init(&env); + + valueP = xmlrpc_build_value(&env, "(iIn)", 7, (xmlrpc_int64)8); + TEST_NO_FAULT(&env); + + outputP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + TEST_NO_FAULT(&env); + xmlrpc_serialize_value2(&env, outputP, valueP, xmlrpc_dialect_apache); + TEST_NO_FAULT(&env); + + size = XMLRPC_MEMBLOCK_SIZE(char, outputP); + + TEST(size == strlen(serializedData)); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, outputP), serializedData, size)); + + XMLRPC_MEMBLOCK_FREE(char, outputP); + xmlrpc_DECREF(valueP); + + xmlrpc_env_clean(&env); +} + + + +static void +test_serialize_apache_params(void) { + + char const serializedData[] = + "\r\n" + "7\r\n" + "8\r\n" + "\r\n"; + + xmlrpc_env env; + xmlrpc_value * paramArrayP; + xmlrpc_mem_block * outputP; + size_t size; + + xmlrpc_env_init(&env); + + paramArrayP = xmlrpc_build_value(&env, "(iI)", 7, (xmlrpc_int64)8); + TEST_NO_FAULT(&env); + + outputP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + TEST_NO_FAULT(&env); + xmlrpc_serialize_params2(&env, outputP, paramArrayP, + xmlrpc_dialect_apache); + TEST_NO_FAULT(&env); + + size = XMLRPC_MEMBLOCK_SIZE(char, outputP); + + TEST(size == strlen(serializedData)); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, outputP), serializedData, size)); + + XMLRPC_MEMBLOCK_FREE(char, outputP); + xmlrpc_DECREF(paramArrayP); + + xmlrpc_env_clean(&env); +} + + + +static void +test_serialize_apache_response(void) { + + char const serializedData[] = + XML_PROLOGUE + "\r\n" + "\r\n" + "8\r\n" + "\r\n" + "\r\n"; + + xmlrpc_env env; + xmlrpc_value * resultP; + xmlrpc_mem_block * outputP; + size_t size; + + xmlrpc_env_init(&env); + + resultP = xmlrpc_i8_new(&env, 8); + TEST_NO_FAULT(&env); + + outputP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + TEST_NO_FAULT(&env); + xmlrpc_serialize_response2(&env, outputP, resultP, + xmlrpc_dialect_apache); + TEST_NO_FAULT(&env); + + size = XMLRPC_MEMBLOCK_SIZE(char, outputP); + + TEST(size == strlen(serializedData)); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, outputP), serializedData, size)); + + XMLRPC_MEMBLOCK_FREE(char, outputP); + xmlrpc_DECREF(resultP); + + xmlrpc_env_clean(&env); +} + + + +static void +test_serialize_apache(void) { + + /* Serialize various things using the Apache dialect of XML-RPC */ + + test_serialize_apache_value(); + test_serialize_apache_params(); + test_serialize_apache_response(); +} + + + +void +test_serialize(void) { + + printf("Running serialize tests."); + + test_serialize_basic(); + printf("\n"); + test_serialize_value(); + test_serialize_methodResponse(); + test_serialize_methodCall(); + test_serialize_fault(); + test_serialize_apache(); + + printf("\n"); + printf("Serialize tests done.\n"); +} diff --git a/trunk/test/serialize.h b/trunk/test/serialize.h new file mode 100644 index 000000000..f01ef588d --- /dev/null +++ b/trunk/test/serialize.h @@ -0,0 +1,2 @@ +void +test_serialize(void); diff --git a/trunk/test/serialize_value.c b/trunk/test/serialize_value.c new file mode 100644 index 000000000..a8d17a3be --- /dev/null +++ b/trunk/test/serialize_value.c @@ -0,0 +1,241 @@ +#include +#include +#include + +#include "xmlrpc_config.h" + +#include "xmlrpc-c/base.h" + +#include "testtool.h" +#include "girstring.h" + +#include "serialize_value.h" + + +static void +test_serialize_string(void) { + + /* Test serialize of a string, including all the line ending + complexity. + */ + + xmlrpc_env env; + xmlrpc_value * v; + xmlrpc_mem_block * xmlP; /* Serialized result */ + + xmlrpc_env_init(&env); + + TEST_NO_FAULT(&env); + + v = xmlrpc_string_new(&env, "hello world"); + TEST_NO_FAULT(&env); + + xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + xmlrpc_serialize_value(&env, xmlP, v); + TEST_NO_FAULT(&env); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), + "hello world", + XMLRPC_MEMBLOCK_SIZE(char, xmlP))); + XMLRPC_MEMBLOCK_FREE(char, xmlP); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new(&env, ""); + TEST_NO_FAULT(&env); + xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + xmlrpc_serialize_value(&env, xmlP, v); + TEST_NO_FAULT(&env); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), + "", + XMLRPC_MEMBLOCK_SIZE(char, xmlP))); + XMLRPC_MEMBLOCK_FREE(char, xmlP); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new_lp(&env, 7, "foo\0bar"); + TEST_NO_FAULT(&env); + xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + xmlrpc_serialize_value(&env, xmlP, v); + TEST_NO_FAULT(&env); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), + "foo\0bar", + XMLRPC_MEMBLOCK_SIZE(char, xmlP))); + XMLRPC_MEMBLOCK_FREE(char, xmlP); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new_lp(&env, 7, "foo\nbar"); + TEST_NO_FAULT(&env); + xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + xmlrpc_serialize_value(&env, xmlP, v); + TEST_NO_FAULT(&env); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), + "foo\nbar", + XMLRPC_MEMBLOCK_SIZE(char, xmlP))); + XMLRPC_MEMBLOCK_FREE(char, xmlP); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new_lp(&env, 8, "foo\r\nbar"); + TEST_NO_FAULT(&env); + xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + xmlrpc_serialize_value(&env, xmlP, v); + TEST_NO_FAULT(&env); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), + "foo\nbar", + XMLRPC_MEMBLOCK_SIZE(char, xmlP))); + XMLRPC_MEMBLOCK_FREE(char, xmlP); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new_lp(&env, 7, "foo\rbar"); + TEST_NO_FAULT(&env); + xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + xmlrpc_serialize_value(&env, xmlP, v); + TEST_NO_FAULT(&env); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), + "foo\nbar", + XMLRPC_MEMBLOCK_SIZE(char, xmlP))); + XMLRPC_MEMBLOCK_FREE(char, xmlP); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new_lp_cr(&env, 7, "foo\rbar"); + TEST_NO_FAULT(&env); + xmlP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + xmlrpc_serialize_value(&env, xmlP, v); + TEST_NO_FAULT(&env); + TEST(memeq(XMLRPC_MEMBLOCK_CONTENTS(char, xmlP), + "foo bar", + XMLRPC_MEMBLOCK_SIZE(char, xmlP))); + XMLRPC_MEMBLOCK_FREE(char, xmlP); + xmlrpc_DECREF(v); + + xmlrpc_env_clean(&env); +} + + + +static void +testOneDouble(double const value) { + + /* Test serialize of a double. */ + + xmlrpc_env env; + xmlrpc_value * valueP; + xmlrpc_mem_block * serializedP; + char * result; + /* serialized result, as asciiz string */ + size_t resultLength; + /* Length in characters of the serialized result */ + double serializedValue; + char nextChar; + int itemsMatched; + + xmlrpc_env_init(&env); + + /* Build a double to serialize */ + valueP = xmlrpc_double_new(&env, value); + TEST_NO_FAULT(&env); + + /* Serialize the value. */ + serializedP = XMLRPC_MEMBLOCK_NEW(char, &env, 0); + TEST_NO_FAULT(&env); + xmlrpc_serialize_value(&env, serializedP, valueP); + TEST_NO_FAULT(&env); + + /* Make sure we serialized the correct value. Note that because + doubles aren't precise, this might serialize as 3.1415899999 + or something like that. So we check it arithmetically. + */ + resultLength = XMLRPC_MEMBLOCK_SIZE(char, serializedP); + result = malloc(resultLength + 1); + + memcpy(result, XMLRPC_MEMBLOCK_CONTENTS(char, serializedP), resultLength); + result[resultLength] = '\0'; + + itemsMatched = sscanf(result, + "%lf\r\n%c", + &serializedValue, &nextChar); + + TEST(itemsMatched == 1); + TESTFLOATEQUAL(serializedValue, value); + + free(result); + + /* Clean up our value. */ + XMLRPC_TYPED_MEM_BLOCK_FREE(char, serializedP); + xmlrpc_DECREF(valueP); + + xmlrpc_env_clean(&env); +} + + + +static void +test_serialize_double(void) { + + testOneDouble(0); + testOneDouble(1); + testOneDouble(0.3); + testOneDouble(4.9); + testOneDouble(9.9999999); + testOneDouble(-8); + testOneDouble(-.7); + testOneDouble(-2.5); + testOneDouble(3.14159); + testOneDouble(1.2E37); + testOneDouble(1.2E-37); + testOneDouble(-5E200); +} + + + +static void +test_serialize_struct(void) { + + /* Serialize a simple struct. */ + + char const serialized_struct[] = + "\r\n" \ + "<&>\r\n" \ + "10\r\n" \ + ""; + + xmlrpc_env env; + xmlrpc_value * v; + xmlrpc_mem_block *output; + size_t size; + + xmlrpc_env_init(&env); + + v = xmlrpc_build_value(&env, "{s:i}", "<&>", (xmlrpc_int32) 10); + TEST_NO_FAULT(&env); + output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0); + TEST_NO_FAULT(&env); + xmlrpc_serialize_value(&env, output, v); + TEST_NO_FAULT(&env); + + /* Make sure we serialized the correct value. */ + size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); + TEST(size == strlen(serialized_struct)); + TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), + serialized_struct, size) == 0); + + /* Clean up our struct. */ + XMLRPC_TYPED_MEM_BLOCK_FREE(char, output); + xmlrpc_DECREF(v); + + xmlrpc_env_clean(&env); +} + + + +void +test_serialize_value(void) { + + printf(" Running serialize value tests."); + + test_serialize_string(); + + test_serialize_double(); + + test_serialize_struct(); + + printf("\n"); + printf(" Serialize value tests done.\n"); +} diff --git a/trunk/test/serialize_value.h b/trunk/test/serialize_value.h new file mode 100644 index 000000000..d976d076a --- /dev/null +++ b/trunk/test/serialize_value.h @@ -0,0 +1,7 @@ +#ifndef SERIALIZE_VALUE_H_INCLUDED +#define SERIALIZE_VALUE_H_INCLUDED + +void +test_serialize_value(void); + +#endif diff --git a/trunk/test/server_abyss.c b/trunk/test/server_abyss.c new file mode 100644 index 000000000..591a9880d --- /dev/null +++ b/trunk/test/server_abyss.c @@ -0,0 +1,277 @@ +#define WIN32_LEAN_AND_MEAN /* required by xmlrpc-c/abyss.h */ + +#include "unistdx.h" +#include +#include "bool.h" + +#include "xmlrpc_config.h" + +#include "girstring.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "xmlrpc-c/abyss.h" +#include "xmlrpc-c/server_abyss.h" + +#include "testtool.h" + +#include "server_abyss.h" + + +static xmlrpc_call_processor myXmlProcessor; + +static void +myXmlProcessor(xmlrpc_env * const envP ATTR_UNUSED, + void * const processorArg ATTR_UNUSED, + const char * const callXml ATTR_UNUSED, + size_t const callXmlLen ATTR_UNUSED, + TSession * const abyssSessionP ATTR_UNUSED, + xmlrpc_mem_block ** const responseXmlPP ATTR_UNUSED) { + + printf("XML processor running\n"); +} + + + +static void +testSetHandlers(TServer * const abyssServerP) { + + xmlrpc_env env; + xmlrpc_registry * registryP; + xmlrpc_server_abyss_handler_parms parms; + + xmlrpc_env_init(&env); + + registryP = xmlrpc_registry_new(&env); + TEST_NO_FAULT(&env); + TEST(registryP != NULL); + + parms.xml_processor = &myXmlProcessor; + parms.xml_processor_arg = NULL; + parms.xml_processor_max_stack = 512; + parms.uri_path = "/RPC6"; + parms.chunk_response = true; + parms.allow_origin = "*"; + + xmlrpc_server_abyss_set_handler3( + &env, abyssServerP, &parms, XMLRPC_AHPSIZE(xml_processor_arg)); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* Parms too short */ + xmlrpc_server_abyss_set_handler3( + &env, abyssServerP, &parms, XMLRPC_AHPSIZE(allow_origin)); + TEST_NO_FAULT(&env); + + xmlrpc_server_abyss_set_handler2(abyssServerP, "/RPC5", + &myXmlProcessor, NULL, 512, true); + + xmlrpc_server_abyss_set_handler(&env, abyssServerP, "/RPC3", registryP); + TEST_NO_FAULT(&env); + + xmlrpc_server_abyss_set_handlers2(abyssServerP, "/RPC4", registryP); + + xmlrpc_server_abyss_set_handlers(abyssServerP, registryP); + + xmlrpc_server_abyss_set_default_handler(abyssServerP); + + xmlrpc_registry_free(registryP); + + { + xmlrpc_registry * registryP; + registryP = xmlrpc_registry_new(&env); + xmlrpc_server_abyss_set_handlers(abyssServerP, registryP); + xmlrpc_registry_free(registryP); + } + xmlrpc_env_clean(&env); +} + + + +static void +testServerParms(void) { + xmlrpc_server_abyss_parms parms; + + struct sockaddr sockaddr; + + parms.config_file_name = NULL; + parms.registryP = NULL; + parms.port_number = 1000; + parms.max_conn = 10; + parms.max_conn_backlog = 10; + parms.keepalive_timeout = 5; + parms.keepalive_max_conn = 4; + parms.timeout = 50; + parms.dont_advertise = true; + parms.uri_path = "/RPC9"; + parms.chunk_response = true; + parms.allow_origin = "*"; + parms.access_ctl_expires = true; + parms.access_ctl_max_age = 5; + parms.sockaddr_p = &sockaddr; + parms.sockaddrlen = sizeof(sockaddr); + parms.log_file_name = "/tmp/xmlrpc_logfile"; + + if (parms.config_file_name) {} // Defeat set-but-unused compiler warning +}; + + + +static void +testObjectParm(void) { + + xmlrpc_env env; + + xmlrpc_server_abyss_parms parms; + xmlrpc_registry * registryP; + xmlrpc_server_abyss_t * serverP; + + xmlrpc_env_init(&env); + + xmlrpc_server_abyss_global_init(&env); + TEST_NO_FAULT(&env); + + registryP = xmlrpc_registry_new(&env); + TEST_NO_FAULT(&env); + + MEMSZERO(&parms); + + parms.registryP = registryP; + + xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(sockaddrlen), + &serverP); + + TEST_NO_FAULT(&env); + TEST(serverP != NULL); + + xmlrpc_server_abyss_destroy(serverP); + + xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(sockaddr_p), + &serverP); + + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* sockaddr_p w/o sockaddrlen */ + + parms.port_number = 100000; + + xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(sockaddrlen), + &serverP); + + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* port number too large */ + + xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(port_number), + &serverP); + + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* port number too large */ + { + struct sockaddr_in localhost; + localhost.sin_family = AF_INET; + localhost.sin_port = htons(8080); + localhost.sin_addr = test_ipAddrFromDecimal(127, 0, 0, 1); + + parms.sockaddr_p = (const struct sockaddr *)&localhost; + parms.sockaddrlen = sizeof(localhost); + + xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(sockaddrlen), + &serverP); + + TEST_NO_FAULT(&env); + TEST(serverP != NULL); + + xmlrpc_server_abyss_destroy(serverP); + } + xmlrpc_server_abyss_global_term(); + + xmlrpc_env_clean(&env); +} + + + +static void +testObject(void) { + + xmlrpc_env env; + xmlrpc_server_abyss_parms parms; + xmlrpc_server_abyss_t * serverP; + xmlrpc_registry * registryP; + xmlrpc_server_abyss_sig * oldHandlersP; + + xmlrpc_env_init(&env); + + registryP = xmlrpc_registry_new(&env); + TEST_NO_FAULT(&env); + + parms.config_file_name = NULL; + parms.registryP = registryP; + + serverP = NULL; + + xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(registryP), + &serverP); + + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* Global init not done */ + + xmlrpc_server_abyss_global_init(&env); + TEST_NO_FAULT(&env); + + xmlrpc_server_abyss_create(&env, &parms, XMLRPC_APSIZE(registryP), + &serverP); + + TEST_NO_FAULT(&env); + TEST(serverP != NULL); + + xmlrpc_server_abyss_terminate(&env, serverP); + TEST_NO_FAULT(&env); + + xmlrpc_server_abyss_reset_terminate(&env, serverP); + TEST_NO_FAULT(&env); + + xmlrpc_server_abyss_setup_sig(&env, serverP, &oldHandlersP); + TEST_NO_FAULT(&env); + + xmlrpc_server_abyss_use_sigchld(serverP); + + xmlrpc_server_abyss_restore_sig(oldHandlersP); + TEST_NO_FAULT(&env); + + free(oldHandlersP); + + xmlrpc_server_abyss_destroy(serverP); + + xmlrpc_registry_free(registryP); + + xmlrpc_server_abyss_global_term(); + + xmlrpc_server_abyss_setup_sig(&env, serverP, &oldHandlersP); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* Not globally initialized */ + + testObjectParm(); + + xmlrpc_env_clean(&env); +} + + + +void +test_server_abyss(void) { + + TServer abyssServer; + + printf("Running Abyss XML-RPC server tests...\n"); + + ServerCreate(&abyssServer, "testserver", 8080, NULL, NULL); + + testSetHandlers(&abyssServer); + + ServerSetMaxConn(&abyssServer, 10); + ServerSetMaxConnBacklog(&abyssServer, 10); + ServerSetMaxSessionMem(&abyssServer, 64*1024); + ServerSetKeepaliveTimeout(&abyssServer, 60); + ServerSetKeepaliveMaxConn(&abyssServer, 10); + ServerSetTimeout(&abyssServer, 0); + ServerSetAdvertise(&abyssServer, false); + + ServerFree(&abyssServer); + + testServerParms(); + + testObject(); + + printf("\n"); + printf("Abyss XML-RPC server tests done.\n"); +} diff --git a/trunk/test/server_abyss.h b/trunk/test/server_abyss.h new file mode 100644 index 000000000..2cd527923 --- /dev/null +++ b/trunk/test/server_abyss.h @@ -0,0 +1,2 @@ +void +test_server_abyss(void); diff --git a/trunk/test/server_abyss_dummy.c b/trunk/test/server_abyss_dummy.c new file mode 100644 index 000000000..8394728e6 --- /dev/null +++ b/trunk/test/server_abyss_dummy.c @@ -0,0 +1,14 @@ +#include + +#include "server_abyss.h" + + + +void +test_server_abyss(void) { + + printf("Running dummy Abyss XML-RPC server test\n"); + + printf("\n"); + printf("Abyss XML-RPC server tests done.\n"); +} diff --git a/trunk/test/test.c b/trunk/test/test.c new file mode 100644 index 000000000..d130a733a --- /dev/null +++ b/trunk/test/test.c @@ -0,0 +1,740 @@ +/* Copyright information is at the end of the file. */ + +#ifdef _WIN32 +# include +#else +# include +#endif +#include +#include +#include +#include +#include + +#include "casprintf.h" + +#include "xmlrpc_config.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server.h" +#include "xmlrpc-c/string_int.h" + +#include "bool.h" +#include "testtool.h" +#include "value.h" +#include "serialize.h" +#include "parse_xml.h" +#include "cgi.h" +#include "xml_data.h" +#include "client.h" +#include "abyss.h" +#include "server_abyss.h" +#include "method_registry.h" +#include "memblock.h" + +/*========================================================================= +** Test Harness +**========================================================================= +** This is a super light-weight test harness. It's vaguely inspired by +** Kent Beck's book on eXtreme Programming (XP)--the output is succinct, +** new tests can be coded quickly, and the whole thing runs in a few +** second's time. +** +** To run the tests, type './rpctest'. +** To check for memory leaks, install RedHat's 'memprof' utility, and +** type 'memprof rpctest'. +** +** If you add new tests to this file, please deallocate any data +** structures you use in the appropriate fashion. This allows us to test +** various destructor code for memory leaks. +*/ + +int total_tests = 0; +int total_failures = 0; + +bool const runningUnderWindows = +#ifdef _WIN32 + true; +#else + false; +#endif + + +/*========================================================================= +** Test Data +**========================================================================= +** Some common test data which need to be allocated at a fixed address, +** or which are inconvenient to allocate inline. +*/ + +static char* test_string_1 = "foo"; +static char* test_string_2 = "bar"; + +/*========================================================================= +** Test Suites +**========================================================================= +*/ + +static void +testVersion(void) { + + unsigned int major, minor, point; + + xmlrpc_version(&major, &minor, &point); + +#ifndef _WIN32 + /* xmlrpc_version_major, etc. are not exported from a Windows DLL */ + + TEST(major == xmlrpc_version_major); + TEST(minor == xmlrpc_version_minor); + TEST(point == xmlrpc_version_point); +#endif +} + + + +static void +testEnv(void) { + xmlrpc_env env, env2; + + /* Test xmlrpc_env_init. */ + xmlrpc_env_init(&env); + TEST(!env.fault_occurred); + TEST(env.fault_code == 0); + TEST(env.fault_string == NULL); + + /* Test xmlrpc_set_fault. */ + xmlrpc_env_set_fault(&env, 1, test_string_1); + TEST(env.fault_occurred); + TEST(env.fault_code == 1); + TEST(env.fault_string != test_string_1); + TEST(xmlrpc_streq(env.fault_string, test_string_1)); + + /* Change an existing fault. */ + xmlrpc_env_set_fault(&env, 2, test_string_2); + TEST(env.fault_occurred); + TEST(env.fault_code == 2); + TEST(xmlrpc_streq(env.fault_string, test_string_2)); + + /* Set a fault with a format string. */ + xmlrpc_env_set_fault_formatted(&env, 3, "a%s%d", "bar", 9); + TEST(env.fault_occurred); + TEST(env.fault_code == 3); + TEST(xmlrpc_streq(env.fault_string, "abar9")); + + /* Test cleanup code (with help from memprof). */ + xmlrpc_env_clean(&env); + + /* Test cleanup code on in absence of xmlrpc_env_set_fault. */ + xmlrpc_env_init(&env2); + xmlrpc_env_clean(&env2); +} + + + +static char *(base64_triplets[]) = { + "", "", "\r\n", + "a", "YQ==", "YQ==\r\n", + "aa", "YWE=", "YWE=\r\n", + "aaa", "YWFh", "YWFh\r\n", + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", + "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY" + "2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=", + "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY" + "2Rl\r\n" + "ZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=\r\n", + NULL}; + + + +static void +testBase64Conversion(void) { + + xmlrpc_env env; + char ** triplet; + + xmlrpc_env_init(&env); + + for (triplet = base64_triplets; *triplet != NULL; triplet += 3) { + char * bin_data; + char * nocrlf_ascii_data; + char * ascii_data; + xmlrpc_mem_block * output; + + bin_data = *triplet; + nocrlf_ascii_data = *(triplet + 1); + ascii_data = *(triplet + 2); + + /* Test our encoding routine. */ + output = xmlrpc_base64_encode(&env, + (unsigned char*) bin_data, + strlen(bin_data)); + TEST_NO_FAULT(&env); + TEST(output != NULL); + TEST(xmlrpc_mem_block_size(output) == strlen(ascii_data)); + TEST(memcmp(xmlrpc_mem_block_contents(output), ascii_data, + strlen(ascii_data)) == 0); + xmlrpc_mem_block_free(output); + + /* Test our newline-free encoding routine. */ + output = + xmlrpc_base64_encode_without_newlines(&env, + (unsigned char*) bin_data, + strlen(bin_data)); + TEST_NO_FAULT(&env); + TEST(output != NULL); + TEST(xmlrpc_mem_block_size(output) == strlen(nocrlf_ascii_data)); + TEST(memcmp(xmlrpc_mem_block_contents(output), nocrlf_ascii_data, + strlen(nocrlf_ascii_data)) == 0); + xmlrpc_mem_block_free(output); + + /* Test our decoding routine. */ + output = xmlrpc_base64_decode(&env, ascii_data, strlen(ascii_data)); + TEST_NO_FAULT(&env); + TEST(output != NULL); + TEST(xmlrpc_mem_block_size(output) == strlen(bin_data)); + TEST(memcmp(xmlrpc_mem_block_contents(output), bin_data, + strlen(bin_data)) == 0); + xmlrpc_mem_block_free(output); + } + + /* Now for something broken... */ + { + xmlrpc_env env2; + xmlrpc_mem_block * output; + + xmlrpc_env_init(&env2); + output = xmlrpc_base64_decode(&env2, "====", 4); + TEST(output == NULL); + TEST_FAULT(&env2, XMLRPC_PARSE_ERROR); + xmlrpc_env_clean(&env2); + } + /* Now for something broken in a really sneaky way... */ + { + xmlrpc_env env2; + xmlrpc_mem_block * output; + xmlrpc_env_init(&env2); + output = xmlrpc_base64_decode(&env2, "a==", 4); + TEST(output == NULL); + TEST_FAULT(&env2, XMLRPC_PARSE_ERROR); + xmlrpc_env_clean(&env2); + } + xmlrpc_env_clean(&env); +} + + + +static void +testBoundsChecks(void) { + + xmlrpc_env env; + xmlrpc_value *array; + int i1, i2, i3, i4; + + /* Get an array to work with. */ + xmlrpc_env_init(&env); + array = xmlrpc_build_value(&env, "(iii)", 100, 200, 300); + TEST_NO_FAULT(&env); + xmlrpc_env_clean(&env); + + /* Test xmlrpc_decompose_value with too few values. */ + xmlrpc_env_init(&env); + xmlrpc_decompose_value(&env, array, "(iiii)", &i1, &i2, &i3, &i4); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + xmlrpc_env_clean(&env); + + /* Test xmlrpc_decompose_value with too many values. */ + xmlrpc_env_init(&env); + xmlrpc_decompose_value(&env, array, "(ii)", &i1, &i2, &i3, &i4); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + xmlrpc_env_clean(&env); + + /* Dispose of our array. */ + xmlrpc_DECREF(array); +} + + + +static void +testNestingLimit(void) { + + xmlrpc_env env; + xmlrpc_value *val; + + xmlrpc_env_init(&env); + + /* Test with an adequate limit for a result value which is an + array which contains an element which is a struct, whose values + are simple: 3. + */ + xmlrpc_limit_set(XMLRPC_NESTING_LIMIT_ID, 3); + val = xmlrpc_parse_response(&env, + good_response_xml, strlen(good_response_xml)); + TEST_NO_FAULT(&env); + TEST(val != NULL); + xmlrpc_DECREF(val); + + /* Test with an inadequate limit. */ + xmlrpc_limit_set(XMLRPC_NESTING_LIMIT_ID, 2); + val = xmlrpc_parse_response(&env, + good_response_xml, strlen(good_response_xml)); + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); /* BREAKME - Will change. */ + TEST(val == NULL); + + /* Reset the default limit. */ + xmlrpc_limit_set(XMLRPC_NESTING_LIMIT_ID, XMLRPC_NESTING_LIMIT_DEFAULT); + TEST(xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID) + == XMLRPC_NESTING_LIMIT_DEFAULT); + + xmlrpc_env_clean(&env); +} + + + +static void +testXmlSizeLimit(void) { + + xmlrpc_env env; + const char * methodName; + xmlrpc_value * paramsP; + + /* NOTE - This test suite only verifies the last-ditch size-checking + code. There should also be matching code in all server (and + preferably all client) modules as well. + */ + + /* Set our XML size limit to something ridiculous. */ + xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, 6); + + /* Attempt to parse a call. */ + xmlrpc_env_init(&env); + xmlrpc_parse_call(&env, serialized_call, strlen(serialized_call), + &methodName, ¶msP); + TEST_FAULT(&env, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env); + + { + xmlrpc_value * resultP; + int faultCode; + const char * faultString; + + /* Attempt to parse a response. */ + xmlrpc_env_init(&env); + xmlrpc_parse_response2(&env, + good_response_xml, strlen(good_response_xml), + &resultP, &faultCode, &faultString); + TEST_FAULT(&env, XMLRPC_LIMIT_EXCEEDED_ERROR); + xmlrpc_env_clean(&env); + } + /* Reset the default limit. */ + xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, XMLRPC_XML_SIZE_LIMIT_DEFAULT); +} + + + +/*========================================================================= +** test_sample_files +**========================================================================= +** Read in a bunch of sample test files and make sure we get plausible +** results. +** +** We use these files to test strange-but-legal encodings, illegal-but- +** allowed-by-Xmlrpc-c encodings, etc. +*/ + +/* The test program is designed to be run with the 'test' source directory + (which also contains the test program itself) as the current + directory. Except on Windows, where the Bin directory (which also contains + the test program itself) is supposed to be the current directory. +*/ +#define TESTDATA_DIR "data" + +static const char * goodRequests[] = { + TESTDATA_DIR DIRECTORY_SEPARATOR "req_out_of_order.xml", + TESTDATA_DIR DIRECTORY_SEPARATOR "req_no_params.xml", + TESTDATA_DIR DIRECTORY_SEPARATOR "req_value_name.xml", + NULL +}; + +#define MAX_SAMPLE_FILE_LEN (16 * 1024) + + + +static void +reportFileOpenError(const char * const path, + int const openErrno) { + + if (runningUnderWindows) { + char cwdname[1024]; + char * succeeded; + + succeeded = getcwd(cwdname, sizeof(cwdname)); + if (succeeded) + fprintf(stderr, "Running in current work directory '%s'\n", + cwdname); + } + fprintf(stderr, "Could not open file '%s'. errno=%d (%s)\n", + path, openErrno, strerror(openErrno)); +} + + + +static void +readFile(const char * const path, + const char ** const outDataP, + size_t * const outSizeP) { + + static char fileBuff[MAX_SAMPLE_FILE_LEN]; + + FILE * fileP; + size_t bytesRead; + + fileP = fopen(path, "r"); + + if (fileP == NULL) { + /* Since this error is fairly likely to happen, give an + informative error message... + */ + reportFileOpenError(path, errno); + exit(1); + } + + /* Read in one buffer full of data, and make sure that everything + fit. (We perform a lazy error/no-eof/zero-length-file test using + 'bytesRead'.) + */ + bytesRead = fread(fileBuff, sizeof(char), MAX_SAMPLE_FILE_LEN, fileP); + TEST(0 < bytesRead && bytesRead < MAX_SAMPLE_FILE_LEN); + + fclose(fileP); + + *outDataP = fileBuff; + *outSizeP = bytesRead; +} + + + +static void +testSampleFiles(void) { + + xmlrpc_env env; + const char ** pathP; + + xmlrpc_env_init(&env); + + /* Test our good requests. */ + + for (pathP = goodRequests; *pathP != NULL; ++pathP) { + const char * const path = *pathP; + + const char * data; + size_t dataLen; + const char * methodName; + xmlrpc_value * params; + + readFile(path, &data, &dataLen); + + xmlrpc_parse_call(&env, data, dataLen, &methodName, ¶ms); + + TEST_NO_FAULT(&env); + + strfree(methodName); + xmlrpc_DECREF(params); + } + + xmlrpc_env_clean(&env); +} + + +/*========================================================================= +** test_utf8_coding +**========================================================================= +** We need to test our UTF-8 decoder thoroughly. Most of these test +** cases are taken from the UTF-8-test.txt file by Markus Kuhn +** : +** http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt +*/ + +#if HAVE_UNICODE_WCHAR + +typedef struct { + char *utf8; + wchar_t wcs[16]; +} utf8_and_wcs; + +static utf8_and_wcs good_utf8[] = { + + /* Greek 'kosme'. */ + {"\316\272\341\275\271\317\203\316\274\316\265", + {0x03BA, 0x1F79, 0x03C3, 0x03BC, 0x03B5, 0}}, + + /* First sequences of a given length. */ + /* '\000' is not a legal C string. */ + {"\302\200", {0x0080, 0}}, + {"\340\240\200", {0x0800, 0}}, + + /* Last sequences of a given length. */ + {"\177", {0x007F, 0}}, + {"\337\277", {0x07FF, 0}}, + /* 0xFFFF is not a legal Unicode character. */ + + /* Other boundry conditions. */ + {"\001", {0x0001, 0}}, + {"\355\237\277", {0xD7FF, 0}}, + {"\356\200\200", {0xE000, 0}}, + {"\357\277\275", {0xFFFD, 0}}, + + /* Other random test cases. */ + {"", {0}}, + {"abc", {0x0061, 0x0062, 0x0063, 0}}, + {"[\302\251]", {0x005B, 0x00A9, 0x005D, 0}}, + + {NULL, {0}} +}; + +static char *(bad_utf8[]) = { + + /* Continuation bytes. */ + "\200", "\277", + + /* Lonely start characters. */ + "\300", "\300x", "\300xx", + "\340", "\340x", "\340xx", "\340xxx", + + /* Last byte missing. */ + "\340\200", "\340\200x", "\340\200xx", + "\357\277", "\357\277x", "\357\277xx", + + /* Illegal bytes. */ + "\376", "\377", + + /* Overlong '/'. */ + "\300\257", "\340\200\257", + + /* Overlong ASCII NUL. */ + "\300\200", "\340\200\200", + + /* Maximum overlong sequences. */ + "\301\277", "\340\237\277", + + /* Illegal code positions. */ + "\357\277\276", /* U+FFFE */ + "\357\277\277", /* U+FFFF */ + + /* UTF-16 surrogates (unpaired and paired). */ + "\355\240\200", + "\355\277\277", + "\355\240\200\355\260\200", + "\355\257\277\355\277\277", + + /* Valid UCS-4 characters (we don't handle these yet). + ** On systems with UCS-4 or UTF-16 wchar_t values, we + ** may eventually handle these in some fashion. */ + "\360\220\200\200", + "\370\210\200\200\200", + "\374\204\200\200\200\200", + + NULL +}; +#endif /* HAVE_UNICODE_WCHAR */ + +/* This routine is missing on certain platforms. This implementation +** *appears* to be correct. */ +#if 0 +#ifndef HAVE_WCSNCMP +int wcsncmp(wchar_t *wcs1, wchar_t* wcs2, size_t len) +{ + size_t i; + /* XXX - 'unsigned long' should be 'uwchar_t'. */ + unsigned long c1, c2; + for (i=0; i < len; i++) { + c1 = wcs1[i]; + c2 = wcs2[i]; + /* This clever comparison borrowed from the GNU C Library. */ + if (c1 == 0 || c1 != c2) + return c1 - c2; + } + return 0; +} +#endif /* HAVE_WCSNCMP */ +#endif + +static void +test_utf8_coding(void) { + +#if HAVE_UNICODE_WCHAR + xmlrpc_env env, env2; + utf8_and_wcs *good_data; + char **bad_data; + char *utf8; + wchar_t *wcs; + xmlrpc_mem_block *output; + + xmlrpc_env_init(&env); + + /* Test each of our valid UTF-8 sequences. */ + for (good_data = good_utf8; good_data->utf8 != NULL; good_data++) { + utf8 = good_data->utf8; + wcs = good_data->wcs; + + /* Attempt to validate the UTF-8 string. */ + xmlrpc_validate_utf8(&env, utf8, strlen(utf8)); + TEST_NO_FAULT(&env); + + /* Attempt to decode the UTF-8 string. */ + output = xmlrpc_utf8_to_wcs(&env, utf8, strlen(utf8)); + TEST_NO_FAULT(&env); + TEST(output != NULL); + TEST(wcslen(wcs) == XMLRPC_TYPED_MEM_BLOCK_SIZE(wchar_t, output)); + TEST(0 == + wcsncmp(wcs, XMLRPC_TYPED_MEM_BLOCK_CONTENTS(wchar_t, output), + wcslen(wcs))); + xmlrpc_mem_block_free(output); + + /* Test the UTF-8 encoder, too. */ + output = xmlrpc_wcs_to_utf8(&env, wcs, wcslen(wcs)); + TEST_NO_FAULT(&env); + TEST(output != NULL); + TEST(strlen(utf8) == XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output)); + TEST(xmlrpc_strneq(utf8, XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), + strlen(utf8))); + xmlrpc_mem_block_free(output); + } + + /* Test each of our illegal UTF-8 sequences. */ + for (bad_data = bad_utf8; *bad_data != NULL; bad_data++) { + utf8 = *bad_data; + + /* Attempt to validate the UTF-8 string. */ + xmlrpc_env_init(&env2); + xmlrpc_validate_utf8(&env2, utf8, strlen(utf8)); + TEST_FAULT(&env2, XMLRPC_INVALID_UTF8_ERROR); + /* printf("Fault: %s\n", env2.fault_string); --Hand-checked */ + xmlrpc_env_clean(&env2); + + /* Attempt to decode the UTF-8 string. */ + xmlrpc_env_init(&env2); + output = xmlrpc_utf8_to_wcs(&env2, utf8, strlen(utf8)); + TEST_FAULT(&env2, XMLRPC_INVALID_UTF8_ERROR); + TEST(output == NULL); + xmlrpc_env_clean(&env2); + } + xmlrpc_env_clean(&env); +#endif /* HAVE_UNICODE_WCHAR */ +} + + + +static void +test_server_cgi_maybe(void) { + +#ifndef _WIN32 + + test_server_cgi(); + +#endif +} + + + +static void +test_client_maybe(void) { + +#ifndef _WIN32 /* Must get Windows Curl transport working for this to work */ + + test_client(); + +#endif +} + + + +int +main(int argc, + char ** argv ATTR_UNUSED) { + + int retval; + + if (argc-1 > 0) { + fprintf(stderr, "There are no arguments.\n"); + retval = 1; + } else { + xmlrpc_env env; + xmlrpc_env_init(&env); + xmlrpc_init(&env); + testVersion(); + testEnv(); + printf("\n"); + test_memBlock(); + testBase64Conversion(); + printf("\n"); + test_value(); + testBoundsChecks(); + printf("\n"); + test_serialize(); + test_parse_xml(); + test_method_registry(); + testNestingLimit(); + testXmlSizeLimit(); + testSampleFiles(); + printf("\n"); + test_server_cgi_maybe(); + test_abyss(); + test_server_abyss(); + + test_utf8_coding(); + + printf("\n"); + + test_client_maybe(); + + printf("\n"); + + xmlrpc_term(); + + /* Summarize our test run. */ + printf("Ran %d tests, %d failed, %.1f%% passed\n", + total_tests, total_failures, + 100.0 - (100.0 * total_failures) / total_tests); + + /* Print the final result. */ + if (total_failures == 0) { + printf("OK\n"); + retval = 0; + } else { + retval = 1; + printf("FAILED\n"); + } + xmlrpc_env_clean(&env); + } + return retval; +} + + + + +/* 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. */ diff --git a/trunk/test/testtool.c b/trunk/test/testtool.c new file mode 100644 index 000000000..5aeca8af4 --- /dev/null +++ b/trunk/test/testtool.c @@ -0,0 +1,88 @@ +#include +#include +#ifdef _WIN32 +# include +# include +#else +# include +#endif + +#include "xmlrpc_config.h" +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/util_int.h" + +#include "testtool.h" + /* Defines global variable, 'total_tests', 'total_failures' */ + + +/* This is a good place to set a breakpoint. */ +void +test_failure(const char * const file, + unsigned int const line, + const char * const label, + const char * const statement) { + + ++total_failures; + printf("\n%s:%u: test failure: %s (%s)\n", file, line, label, statement); + + /* We abort rather than exit so one can tell from a dump or debug session + who called us. + */ + abort(); +} + + + +void +test_fault(xmlrpc_env * const envP, + int const expectedCode, + const char * const fileName, + unsigned int const lineNumber) { + + ++total_tests; + + if (!envP->fault_occurred) + test_failure(fileName, lineNumber, "no fault occurred", ""); + else if (envP->fault_code != expectedCode) + test_failure(fileName, lineNumber, "wrong fault occurred", + envP->fault_string); + else + printf("."); + + xmlrpc_env_clean(envP); + xmlrpc_env_init(envP); +} + + + +void +test_null_string(const char * const string, + const char * const fileName, + unsigned int const lineNumber) { + + ++total_tests; + + if (string != NULL) + test_failure(fileName, lineNumber, "string not null", string); + else + printf("."); +} + + + +struct in_addr +test_ipAddrFromDecimal(unsigned int const byte0, + unsigned int const byte1, + unsigned int const byte2, + unsigned int const byte3) { + + struct in_addr retval; + + retval.s_addr = + htonl((byte0 << 24) + (byte1 << 16) + (byte2 << 8) + (byte3 << 0)); + + return retval; +} + + + diff --git a/trunk/test/testtool.h b/trunk/test/testtool.h new file mode 100644 index 000000000..abf5a42ec --- /dev/null +++ b/trunk/test/testtool.h @@ -0,0 +1,93 @@ +#ifndef TESTTOOL_H_INCLUDED +#define TESTTOOL_H_INCLUDED + +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +#include +#endif + +#include "xmlrpc-c/util.h" +#include "xmlrpc-c/util_int.h" + +extern int total_tests; +extern int total_failures; + + +void +test_failure(const char * const file, + unsigned int const line, + const char * const label, + const char * const statement); + +void +test_fault(xmlrpc_env * const envP, + int const expectedCode, + const char * const fileName, + unsigned int const lineNumber); + +void +test_null_string(const char * const string, + const char * const fileName, + unsigned int const lineNumber); + +#define TEST(statement) \ +do { \ + ++total_tests; \ + if ((statement)) { \ + printf("."); \ + } else { \ + test_failure(__FILE__, __LINE__, "expected", #statement); \ + } \ + } while (0) + +#define TEST_NO_FAULT(env) \ + do { \ + ++total_tests; \ + if (!(env)->fault_occurred) { \ + printf("."); \ + } else { \ + test_failure(__FILE__, __LINE__, "fault occurred", \ + (env)->fault_string); \ + } \ + } while (0) + +#define TEST_EPSILON 1E-5 + +#define FORCENONZERO(x) (MAX(fabs(x), TEST_EPSILON)) + +#define FLOATEQUAL(comparand, comparator) \ + ((fabs((comparand)-(comparator)))/FORCENONZERO(comparand) < TEST_EPSILON) +#define TESTFLOATEQUAL(comparand, comparator) \ + TEST(FLOATEQUAL(comparand, comparator)) + +#define TEST_FAULT(envP, code) \ + do { test_fault(envP, code, __FILE__, __LINE__); } while(0) + +; + +#define TEST_NULL_STRING(string) \ + do { test_null_string(string, __FILE__, __LINE__); } while(0) + +; + +#define TEST_ERROR(reason) \ +do { \ + printf("Unable to test at %s/%u. %s", __FILE__, __LINE__, reason); \ + abort(); \ + } while (0) + +; + +struct in_addr +test_ipAddrFromDecimal(unsigned int const byte0, + unsigned int const byte1, + unsigned int const byte2, + unsigned int const byte3); + +#endif diff --git a/trunk/test/value.c b/trunk/test/value.c new file mode 100644 index 000000000..8c786058f --- /dev/null +++ b/trunk/test/value.c @@ -0,0 +1,2043 @@ +/* Copyright information is at the end of the file. */ + +#include +#include +#include +#include + +#include "casprintf.h" +#include "girstring.h" + +#include "xmlrpc_config.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/string_int.h" + +#include "testtool.h" +#include "value_datetime.h" + +#include "value.h" + + +#if HAVE_UNICODE_WCHAR + +static bool +wcsneq(const wchar_t * const comparand, + const wchar_t * const comparator, + size_t const length) { + + return(wcsncmp(comparand, comparator, length) == 0); +} + +#endif /* HAVE_UNICODE_WCHAR */ + +static void +test_value_alloc_dealloc(void) { + + xmlrpc_value * v; + xmlrpc_env env; + + xmlrpc_env_init(&env); + + /* Test allocation and deallocation (w/memprof). */ + v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 5); + TEST_NO_FAULT(&env); + TEST(v != NULL); + xmlrpc_INCREF(v); + xmlrpc_DECREF(v); + xmlrpc_DECREF(v); + + xmlrpc_env_clean(&env); +} + + +static void +test_value_int(void) { + + xmlrpc_value * v; + xmlrpc_value * v2; + xmlrpc_env env; + xmlrpc_int32 i; + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_INT), "INT")); + + v = xmlrpc_int_new(&env, (xmlrpc_int32) 25); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_INT); + xmlrpc_read_int(&env, v, &i); + TEST_NO_FAULT(&env); + TEST(i == 25); + xmlrpc_DECREF(v); + + v = xmlrpc_int_new(&env, (xmlrpc_int32) -25); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_INT); + xmlrpc_read_int(&env, v, &i); + TEST_NO_FAULT(&env); + TEST(i == -25); + xmlrpc_DECREF(v); + + v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 10); + TEST_NO_FAULT(&env); + TEST(v != NULL); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_INT); + xmlrpc_decompose_value(&env, v, "i", &i); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(i == 10); + + v = xmlrpc_int_new(&env, (xmlrpc_int32) 25); + TEST_NO_FAULT(&env); + v2 = xmlrpc_value_new(&env, v); + TEST_NO_FAULT(&env); + xmlrpc_DECREF(v); + TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_INT); + xmlrpc_read_int(&env, v2, &i); + TEST_NO_FAULT(&env); + TEST(i == 25); + xmlrpc_DECREF(v2); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_bool(void) { + + xmlrpc_value * v; + xmlrpc_value * v2; + xmlrpc_env env; + xmlrpc_bool b; + + /* Test booleans. */ + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_BOOL), "BOOL")); + + v = xmlrpc_bool_new(&env, (xmlrpc_bool) 1); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v)); + xmlrpc_read_bool(&env, v, &b); + TEST_NO_FAULT(&env); + TEST(b); + xmlrpc_DECREF(v); + + v = xmlrpc_build_value(&env, "b", (xmlrpc_bool) 0); + TEST_NO_FAULT(&env); + TEST(v != NULL); + TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v)); + xmlrpc_decompose_value(&env, v, "b", &b); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(!b); + + v = xmlrpc_bool_new(&env, (xmlrpc_bool) 1); + TEST_NO_FAULT(&env); + v2 = xmlrpc_value_new(&env, v); + TEST_NO_FAULT(&env); + xmlrpc_DECREF(v); + TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v2)); + xmlrpc_read_bool(&env, v2, &b); + TEST_NO_FAULT(&env); + TEST(b); + xmlrpc_DECREF(v2); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_double(void) { + + xmlrpc_value * v; + xmlrpc_value * v2; + xmlrpc_env env; + double d; + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_DOUBLE), "DOUBLE")); + + v = xmlrpc_double_new(&env, -3.25); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v)); + xmlrpc_read_double(&env, v, &d); + TEST_NO_FAULT(&env); + TEST(d == -3.25); + xmlrpc_DECREF(v); + + v = xmlrpc_build_value(&env, "d", 1.0); + TEST_NO_FAULT(&env); + TEST(v != NULL); + TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v)); + xmlrpc_decompose_value(&env, v, "d", &d); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(d == 1.0); + + v = xmlrpc_double_new(&env, -3.25); + TEST_NO_FAULT(&env); + v2 = xmlrpc_value_new(&env, v); + xmlrpc_DECREF(v); + TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v2)); + xmlrpc_read_double(&env, v2, &d); + TEST_NO_FAULT(&env); + TEST(d == -3.25); + xmlrpc_DECREF(v2); + + /* Older compilers don't have INFINITY and NAN, so we compute them here. + But newer compilers recognize an error if they see you dividing by + zero, so we have to make it nonobvious that we're doing that. + */ + double const zero = sin(0); + + v = xmlrpc_double_new(&env, 1.0/zero); /* +INFINITY */ + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + v = xmlrpc_double_new(&env, -1.0/zero); /* -INFINITY */ + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + v = xmlrpc_double_new(&env, 0.0/zero); /* NAN */ + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_env_clean(&env); +} + + + +static xmlrpc_value * +test_string_new_va(xmlrpc_env * const envP, + const char * const format, + ...) { + + va_list args; + + xmlrpc_value * v; + + va_start(args, format); + + v = xmlrpc_string_new_va(envP, format, args); + + va_end(args); + + return v; +} + + + +static void +test_value_string_no_null(void) { + + /* Test strings (without '\0' bytes). */ + + xmlrpc_value * v; + xmlrpc_env env; + const char * str; + size_t len; + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_STRING), "STRING")); + + { + const char * const simpleAsciiString = "foo"; + v = xmlrpc_string_new(&env, simpleAsciiString); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_STRING); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, simpleAsciiString)); + xmlrpc_DECREF(v); + strfree(str); + } + { + const char * const utf8String = "KOŚĆ"; + v = xmlrpc_string_new(&env, utf8String); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_STRING); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, utf8String)); + xmlrpc_DECREF(v); + strfree(str); + } + v = xmlrpc_string_new_f(&env, "String %s, number %d", "xyz", 7); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_STRING); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "String xyz, number 7")); + xmlrpc_DECREF(v); + strfree(str); + + v = test_string_new_va(&env, "String %s, number %d", "xyz", 7); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_STRING); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "String xyz, number 7")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_build_value(&env, "s", "foo"); + + TEST_NO_FAULT(&env); + TEST(v != NULL); + TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v)); + + xmlrpc_decompose_value(&env, v, "s", &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo")); + strfree(str); + + xmlrpc_decompose_value(&env, v, "s#", &str, &len); + TEST_NO_FAULT(&env); + TEST(len == strlen("foo")); + TEST(xmlrpc_streq(str, "foo")); + TEST(strlen(str) == strlen("foo")); + strfree(str); + + xmlrpc_DECREF(v); + + { + const char * const simpleAsciiString = "foo"; + xmlrpc_value * v2; + v = xmlrpc_string_new(&env, simpleAsciiString); + TEST_NO_FAULT(&env); + v2 = xmlrpc_value_new(&env, v); + TEST_NO_FAULT(&env); + xmlrpc_DECREF(v); + TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_STRING); + xmlrpc_read_string(&env, v2, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, simpleAsciiString)); + xmlrpc_DECREF(v2); + strfree(str); + } + xmlrpc_env_clean(&env); +} + + + +static void +test_value_string_null(void) { + + xmlrpc_value * v; + xmlrpc_env env; + xmlrpc_env env2; + const char * str; + size_t len; + + /* Test a string with a '\0' byte. */ + + xmlrpc_env_init(&env); + + v = xmlrpc_string_new_lp(&env, 7, "foo\0bar"); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v)); + xmlrpc_read_string_lp(&env, v, &len, &str); + TEST_NO_FAULT(&env); + TEST(len == 7); + TEST(memeq(str, "foo\0bar", 7)); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_build_value(&env, "s#", "foo\0bar", (size_t) 7); + TEST_NO_FAULT(&env); + TEST(v != NULL); + TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v)); + + xmlrpc_decompose_value(&env, v, "s#", &str, &len); + TEST_NO_FAULT(&env); + TEST(memeq(str, "foo\0bar", 7)); + TEST(len == 7); + strfree(str); + + /* Test for type error when decoding a string with a zero byte to a + ** regular C string. */ + xmlrpc_env_init(&env2); + xmlrpc_decompose_value(&env2, v, "s", &str); + TEST_FAULT(&env2, XMLRPC_TYPE_ERROR); + xmlrpc_env_clean(&env2); + xmlrpc_DECREF(v); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_string_multiline(void) { + + xmlrpc_env env; + xmlrpc_value * v; + const char * str; + size_t len; + + xmlrpc_env_init(&env); + + /* LF line ending */ + + v = xmlrpc_string_new(&env, "foo\n"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\n")); + strfree(str); + xmlrpc_read_string_crlf(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\r\n")); + strfree(str); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new(&env, "foo\n\n"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\n\n")); + strfree(str); + xmlrpc_read_string_crlf(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\r\n\r\n")); + strfree(str); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new(&env, "foo\nbar"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\nbar")); + strfree(str); + xmlrpc_read_string_crlf(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\r\nbar")); + strfree(str); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new(&env, "foo\nbar\n"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\nbar\n")); + strfree(str); + xmlrpc_read_string_crlf(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\r\nbar\r\n")); + strfree(str); + xmlrpc_DECREF(v); + + v = xmlrpc_string_new(&env, "foo\nbar\nbaz"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\nbar\nbaz")); + strfree(str); + xmlrpc_read_string_crlf(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\r\nbar\r\nbaz")); + strfree(str); + xmlrpc_DECREF(v); + + /* CR line ending */ + + v = xmlrpc_string_new(&env, "foo\r"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\n")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_string_new(&env, "foo\r\r"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\n\n")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_string_new(&env, "foo\rbar"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\nbar")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_string_new(&env, "foo\rbar\r"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\nbar\n")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_string_new(&env, "foo\rbar\rbaz"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\nbar\nbaz")); + xmlrpc_DECREF(v); + strfree(str); + + /* CRLF line ending */ + + v = xmlrpc_string_new(&env, "foo\r\n"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\n")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_string_new(&env, "foo\r\n\r\n"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\n\n")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_string_new(&env, "foo\r\nbar"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\nbar")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_string_new(&env, "foo\r\nbar\r\n"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\nbar\n")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_string_new(&env, "foo\r\nbar\r\nbaz"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\nbar\nbaz")); + xmlrpc_DECREF(v); + strfree(str); + + /* Embedded null */ + + v = xmlrpc_string_new_lp(&env, 14, "foo\r\n\0bar\r\nbaz"); + TEST_NO_FAULT(&env); + xmlrpc_read_string_lp(&env, v, &len, &str); + TEST_NO_FAULT(&env); + TEST(len == 12); + TEST(memeq(str, "foo\n\0bar\nbaz", len)); + strfree(str); + xmlrpc_read_string_lp_crlf(&env, v, &len, &str); + TEST_NO_FAULT(&env); + TEST(len == 14); + TEST(memeq(str, "foo\r\n\0bar\r\nbaz", len)); + strfree(str); + xmlrpc_DECREF(v); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_string_cr(void) { + + xmlrpc_env env; + xmlrpc_value * v; + const char * str; + size_t len; + + xmlrpc_env_init(&env); + v = xmlrpc_string_new_cr(&env, "foo\r\nbar\r\nbaz"); + TEST_NO_FAULT(&env); + xmlrpc_read_string(&env, v, &str); + TEST_NO_FAULT(&env); + TEST(streq(str, "foo\r\nbar\r\nbaz")); + xmlrpc_DECREF(v); + strfree(str); + + v = xmlrpc_string_new_lp_cr(&env, 7, "\0foo\rbar"); + TEST_NO_FAULT(&env); + xmlrpc_read_string_lp(&env, v, &len, &str); + TEST_NO_FAULT(&env); + TEST(len == 7); + TEST(memeq(str, "\0foo\rbar", len)); + xmlrpc_DECREF(v); + strfree(str); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_string_ctlchar(void) { + + xmlrpc_env env; + xmlrpc_value * vCtl; + xmlrpc_value * vNoCtl; + + xmlrpc_env_init(&env); + vNoCtl = xmlrpc_string_new(&env, "foo bar"); + TEST_NO_FAULT(&env); + + xmlrpc_string_validate(&env, vNoCtl); + TEST_NO_FAULT(&env); + + xmlrpc_env_init(&env); + vCtl = xmlrpc_string_new(&env, "foo\x18 bar"); + TEST_NO_FAULT(&env); + + xmlrpc_string_validate(&env, vCtl); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_DECREF(vNoCtl); + xmlrpc_DECREF(vCtl); + + xmlrpc_env_clean(&env); +} + + + +#if HAVE_UNICODE_WCHAR + +/* Here is a 3-character, NUL-terminated string, once in UTF-8 chars, + and once in UTF-16 wchar_ts. Note that 2 of the UTF-16 characters + translate directly to UTF-8 bytes because only the lower 7 bits of + each is nonzero, but the middle UTF-16 character translates to two + UTF-8 bytes. +*/ +static char utf8_data[] = "[\xC2\xA9]"; +static wchar_t wcs_data[] = {'[', 0x00A9, ']', 0x0000}; + +static void +test_value_string_wide_build(void) { + + xmlrpc_env env; + xmlrpc_value * valueP; + const wchar_t * wcs; + size_t len; + + xmlrpc_env_init(&env); + + /* Build with build_value w# */ + valueP = xmlrpc_build_value(&env, "w#", wcs_data, (size_t)3); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + + /* Verify it */ + xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(wcs != NULL); + TEST(len == 3); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_data, len)); + free((void*)wcs); + + xmlrpc_DECREF(valueP); + + /* Build with build_value w */ + valueP = xmlrpc_build_value(&env, "w", wcs_data); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + + /* Verify it */ + xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(wcs != NULL); + TEST(len == 3); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_data, len)); + free((void*)wcs); + + xmlrpc_DECREF(valueP); +} +#endif /* HAVE_UNICODE_WCHAR */ + + +static void +test_value_string_wide_line(void) { + /* Test with various line delimiters */ + +#if HAVE_UNICODE_WCHAR + xmlrpc_env env; + xmlrpc_value * valueP; + const wchar_t * wcs; + size_t len; + + wchar_t const wcs_lines[] = {'\n', '\r', '\r', '\n', '\0'}; + wchar_t const wcs_lines_lf[] = {'\n', '\n', '\n'}; + wchar_t const wcs_lines_crlf[] = { + '\r', '\n', '\r', '\n', '\r', '\n' }; + + xmlrpc_env_init(&env); + + valueP = xmlrpc_string_w_new(&env, wcs_lines); + TEST_NO_FAULT(&env); + + xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(len == 3); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_lines_lf, len)); + free((void*)wcs); + + xmlrpc_read_string_w_lp_crlf(&env, valueP, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(len == 6); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_lines_crlf, len)); + free((void*)wcs); + + xmlrpc_DECREF(valueP); + + valueP = xmlrpc_string_w_new_cr(&env, wcs_lines); + TEST_NO_FAULT(&env); + + xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(len == 4); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_lines, len)); + free((void*)wcs); + + xmlrpc_DECREF(valueP); + + xmlrpc_env_clean(&env); +#endif /* HAVE_UNICODE_WCHAR */ +} + + + +static void +test_value_string_wide(void) { + +#if HAVE_UNICODE_WCHAR + xmlrpc_env env; + xmlrpc_value * valueP; + xmlrpc_value * value2P; + const wchar_t * wcs; + size_t len; + + xmlrpc_env_init(&env); + + /* Build a string from wchar_t data. */ + valueP = xmlrpc_string_w_new_lp(&env, 3, wcs_data); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + + /* Extract it as a wchar_t string. */ + xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(wcs != NULL); + TEST(len == 3); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_data, len)); + free((void*)wcs); + + xmlrpc_read_string_w(&env, valueP, &wcs); + TEST_NO_FAULT(&env); + TEST(wcs != NULL); + TEST(wcs[3] == '\0'); + TEST(wcsneq(wcs, wcs_data, 3)); + free((void*)wcs); + + xmlrpc_decompose_value(&env, valueP, "w#", &wcs, &len); + TEST_NO_FAULT(&env); + TEST(wcs != NULL); + TEST(len == 3); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_data, len)); + free((void*)wcs); + + { + /* Extract it as a UTF-8 string. */ + const char * str; + size_t len; + + xmlrpc_read_string_lp(&env, valueP, &len, &str); + TEST_NO_FAULT(&env); + TEST(str != NULL); + TEST(len == 4); + TEST(str[len] == '\0'); + TEST(xmlrpc_strneq(str, utf8_data, len)); + free((void*)str); + } + + xmlrpc_DECREF(valueP); + + /* Build from null-terminated wchar_t string */ + valueP = xmlrpc_string_w_new(&env, wcs_data); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + + /* Verify it */ + xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(wcs != NULL); + TEST(len == 3); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_data, len)); + free((void*)wcs); + + xmlrpc_DECREF(valueP); + + test_value_string_wide_build(); + + /* Build a string from UTF-8 data. */ + valueP = xmlrpc_string_new(&env, utf8_data); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + + /* Extract it as a wchar_t string. */ + xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(wcs != NULL); + TEST(len == 3); + TEST(wcs[len] == 0x0000); + TEST(wcsneq(wcs, wcs_data, len)); + free((void*)wcs); + xmlrpc_DECREF(valueP); + + /* Test with embedded NUL. We use a length of 4 so that the terminating + NUL actually becomes part of the string. + */ + valueP = xmlrpc_string_w_new_lp(&env, 4, wcs_data); + TEST_NO_FAULT(&env); + TEST(valueP != NULL); + + /* Extract it as a wchar_t string. */ + xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(wcs != NULL); + TEST(len == 4); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_data, len)); + free((void*)wcs); + + xmlrpc_read_string_w(&env, valueP, &wcs); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + value2P = xmlrpc_value_new(&env, valueP); + TEST_NO_FAULT(&env); + + xmlrpc_read_string_w_lp(&env, value2P, &len, &wcs); + TEST_NO_FAULT(&env); + TEST(wcs != NULL); + TEST(len == 4); + TEST(wcs[len] == '\0'); + TEST(wcsneq(wcs, wcs_data, len)); + free((void*)wcs); + xmlrpc_DECREF(value2P); + + xmlrpc_DECREF(valueP); + + test_value_string_wide_line(); + + xmlrpc_env_clean(&env); +#endif /* HAVE_UNICODE_WCHAR */ +} + + + +static void +test_value_base64(void) { + + /* Test data. */ + + unsigned char const data1[5] = {'a', '\0', 'b', '\n', 'c'}; + unsigned char const data2[3] = {'a', '\0', 'b'}; + + xmlrpc_value * v; + xmlrpc_value * v2; + xmlrpc_env env; + const unsigned char * data; + size_t len; + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_BASE64), "BASE64")); + + v = xmlrpc_base64_new(&env, sizeof(data1), data1); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v)); + xmlrpc_read_base64(&env, v, &len, &data); + TEST_NO_FAULT(&env); + TEST(memeq(data, data1, sizeof(data1))); + TEST(len == sizeof(data1)); + xmlrpc_DECREF(v); + free((void*)data); + + v = xmlrpc_build_value(&env, "6", data2, sizeof(data2)); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v)); + xmlrpc_decompose_value(&env, v, "6", &data, &len); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(len == sizeof(data2)); + TEST(memeq(data, data1, sizeof(data2))); + free((void *)data); + + v = xmlrpc_base64_new(&env, sizeof(data1), data1); + TEST_NO_FAULT(&env); + v2 = xmlrpc_value_new(&env, v); + TEST_NO_FAULT(&env); + xmlrpc_DECREF(v); + TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v2)); + xmlrpc_read_base64(&env, v2, &len, &data); + TEST_NO_FAULT(&env); + TEST(memeq(data, data1, sizeof(data1))); + TEST(len == sizeof(data1)); + xmlrpc_DECREF(v2); + free((void*)data); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_value(void) { + + xmlrpc_value *v, *v2, *v3; + xmlrpc_env env; + + /* Test 'V' with building and parsing. */ + + xmlrpc_env_init(&env); + + v2 = xmlrpc_int_new(&env, (xmlrpc_int32) 5); + TEST_NO_FAULT(&env); + v = xmlrpc_build_value(&env, "V", v2); + TEST_NO_FAULT(&env); + TEST(v == v2); + xmlrpc_decompose_value(&env, v2, "V", &v3); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(v2 == v3); + xmlrpc_DECREF(v3); + xmlrpc_DECREF(v2); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_array(void) { + + xmlrpc_value * v; + xmlrpc_value * v2; + xmlrpc_env env; + size_t len; + xmlrpc_value * itemP; + + /* Basic array-building test. */ + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_ARRAY), "ARRAY")); + + v = xmlrpc_array_new(&env); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); + len = xmlrpc_array_size(&env, v); + TEST_NO_FAULT(&env); + TEST(len == 0); + + itemP = xmlrpc_int_new(&env, 7); + TEST_NO_FAULT(&env); + xmlrpc_array_append_item(&env, v, itemP); + TEST_NO_FAULT(&env); + len = xmlrpc_array_size(&env, v); + TEST_NO_FAULT(&env); + TEST(len == 1); + xmlrpc_DECREF(itemP); + + v2 = xmlrpc_value_new(&env, v); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); + len = xmlrpc_array_size(&env, v); + TEST_NO_FAULT(&env); + TEST(len == 1); + xmlrpc_DECREF(v2); + + xmlrpc_DECREF(v); + + v = xmlrpc_build_value(&env, "()"); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v)); + len = xmlrpc_array_size(&env, v); + TEST_NO_FAULT(&env); + TEST(len == 0); + xmlrpc_DECREF(v); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_AS(void) { + + xmlrpc_value *v; + xmlrpc_value *v2; + xmlrpc_value *v3; + xmlrpc_env env; + size_t len; + + /* Test parsing of 'A' and 'S'. */ + + xmlrpc_env_init(&env); + + v = xmlrpc_build_value(&env, "((){})"); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, v, "(AS)", &v2, &v3); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v2)); + TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(v3)); + len = xmlrpc_array_size(&env, v2); + TEST_NO_FAULT(&env); + TEST(len == 0); + len = xmlrpc_struct_size(&env, v3); + TEST_NO_FAULT(&env); + TEST(len == 0); + xmlrpc_DECREF(v2); + xmlrpc_DECREF(v3); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_AS_typecheck(void) { + + xmlrpc_env env; + xmlrpc_env env2; + xmlrpc_value *v; + xmlrpc_value *v2; + + /* Test typechecks for 'A' and 'S'. */ + + xmlrpc_env_init(&env); + xmlrpc_env_init(&env2); + + v = xmlrpc_build_value(&env, "s", "foo"); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env2, v, "A", &v2); + TEST_FAULT(&env2, XMLRPC_TYPE_ERROR); + + xmlrpc_decompose_value(&env2, v, "S", &v2); + TEST_FAULT(&env2, XMLRPC_TYPE_ERROR); + xmlrpc_DECREF(v); + xmlrpc_env_clean(&env2); + xmlrpc_env_clean(&env); +} + + + +static void +test_value_array2(void) { + + xmlrpc_value * arrayP; + xmlrpc_env env; + xmlrpc_int32 i, i1, i2, i3, i4, i5; + xmlrpc_value * itemP; + xmlrpc_value * subarrayP; + size_t len; + + /* A more complex array. */ + + xmlrpc_env_init(&env); + + arrayP = xmlrpc_build_value(&env, "(i(ii)i)", + (xmlrpc_int32) 10, (xmlrpc_int32) 20, + (xmlrpc_int32) 30, (xmlrpc_int32) 40); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP)); + + len = xmlrpc_array_size(&env, arrayP); + TEST_NO_FAULT(&env); + TEST(len == 3); + + xmlrpc_array_read_item(&env, arrayP, 1, &subarrayP); + TEST_NO_FAULT(&env); + + len = xmlrpc_array_size(&env, subarrayP); + TEST_NO_FAULT(&env); + TEST(len == 2); + + xmlrpc_array_read_item(&env, subarrayP, 0, &itemP); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, itemP, "i", &i); + xmlrpc_DECREF(itemP); + TEST_NO_FAULT(&env); + TEST(i == 20); + + xmlrpc_DECREF(subarrayP); + + itemP = xmlrpc_array_get_item(&env, arrayP, 0); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, itemP, "i", &i); + TEST_NO_FAULT(&env); + TEST(i == 10); + + xmlrpc_decompose_value(&env, arrayP, "(i(ii)i)", &i1, &i2, &i3, &i4); + TEST_NO_FAULT(&env); + TEST(i1 == 10 && i2 == 20 && i3 == 30 && i4 == 40); + + xmlrpc_decompose_value(&env, arrayP, "(i(i*)i)", &i1, &i2, &i3); + TEST_NO_FAULT(&env); + TEST(i1 == 10 && i2 == 20 && i3 == 40); + + xmlrpc_decompose_value(&env, arrayP, "(i(ii*)i)", &i1, &i2, &i3, &i4); + TEST_NO_FAULT(&env); + + xmlrpc_decompose_value(&env, arrayP, "(i(iii)i)", &i1, &i2, &i3, &i4, &i5); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_decompose_value(&env, arrayP, "(i(i)i)", &i1, &i2, &i3, &i4, &i5); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_decompose_value(&env, arrayP, "(i(ii)i*i)", + &i1, &i2, &i3, &i4, &i5); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, arrayP, "(i(iiQ)i*i)", + &i1, &i2, &i3, &i4, &i5); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, arrayP, "(", + &i1, &i2, &i3, &i4, &i5); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, arrayP, "(i", + &i1, &i2, &i3, &i4, &i5); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, arrayP, "(i*", + &i1, &i2, &i3, &i4, &i5); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + + /* Test bounds check on xmlrpc_array_get_item. */ + xmlrpc_array_read_item(&env, arrayP, 3, &itemP); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_array_get_item(&env, arrayP, 3); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_array_get_item(&env, arrayP, -1); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_DECREF(arrayP); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_array_nil(void) { + + xmlrpc_value * arrayP; + xmlrpc_env env; + xmlrpc_int32 i1, i2; + xmlrpc_value * itemP; + size_t len; + + xmlrpc_env_init(&env); + + arrayP = xmlrpc_build_value(&env, "(nini)", + (xmlrpc_int32) 10, (xmlrpc_int32) 20); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP)); + + len = xmlrpc_array_size(&env, arrayP); + TEST_NO_FAULT(&env); + TEST(len == 4); + + itemP = xmlrpc_array_get_item(&env, arrayP, 0); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, itemP, "n"); + TEST_NO_FAULT(&env); + + itemP = xmlrpc_array_get_item(&env, arrayP, 1); + TEST_NO_FAULT(&env); + { + int i; + xmlrpc_decompose_value(&env, itemP, "i", &i); + TEST_NO_FAULT(&env); + TEST(i == 10); + } + xmlrpc_decompose_value(&env, arrayP, "(nini)", &i1, &i2); + TEST_NO_FAULT(&env); + TEST(i1 == 10 && i2 == 20); + + /* Test bounds check on xmlrpc_array_get_item. */ + xmlrpc_array_read_item(&env, arrayP, 4, &itemP); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_array_get_item(&env, arrayP, 4); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_DECREF(arrayP); + + xmlrpc_env_clean(&env); +} + + + +static void +destroyMyCptr(void * const context, + void * const objectP) { +/*---------------------------------------------------------------------------- + This is a xmlrpc_cptr_dtor_fn. +-----------------------------------------------------------------------------*/ + int * const destroyConfirmationP = context; + int * const objectIntP = objectP; + + *destroyConfirmationP = *objectIntP; +} + + + +static void +test_value_cptr(void) { + + int destroyConfirmation; + + xmlrpc_value * v; + xmlrpc_value * v2; + xmlrpc_env env; + void * ptr; + int myObject; + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_C_PTR), "C_PTR")); + + myObject = 7; + + v = xmlrpc_cptr_new(&env, &myObject); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_C_PTR); + xmlrpc_DECREF(v); + + v = xmlrpc_cptr_new_dtor(&env, &myObject, + &destroyMyCptr, &destroyConfirmation); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_C_PTR); + destroyConfirmation = 3; + xmlrpc_DECREF(v); + TEST(destroyConfirmation == 7); // the destructor has set this + + v = xmlrpc_build_value(&env, "p", (void*) 0x00000017); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_C_PTR == xmlrpc_value_type(v)); + xmlrpc_decompose_value(&env, v, "p", &ptr); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(ptr == (void*) 0x00000017); + + v = xmlrpc_cptr_new(&env, &myObject); + TEST_NO_FAULT(&env); + v2 = xmlrpc_value_new(&env, v); + xmlrpc_DECREF(v); + TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_C_PTR); + xmlrpc_DECREF(v2); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_nil(void) { + + xmlrpc_value * v; + xmlrpc_value * v2; + xmlrpc_env env; + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_NIL), "NIL")); + + v = xmlrpc_nil_new(&env); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_NIL); + xmlrpc_DECREF(v); + + v = xmlrpc_build_value(&env, "n"); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_NIL == xmlrpc_value_type(v)); + xmlrpc_decompose_value(&env, v, "n"); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + + v = xmlrpc_nil_new(&env); + TEST_NO_FAULT(&env); + v2 = xmlrpc_value_new(&env, v); + TEST_NO_FAULT(&env); + xmlrpc_DECREF(v); + TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_NIL); + xmlrpc_DECREF(v2); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_i8(void) { + + xmlrpc_value * v; + xmlrpc_value * v2; + xmlrpc_env env; + xmlrpc_int64 i; + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_I8), "I8")); + + v = xmlrpc_i8_new(&env, (xmlrpc_int64) 25); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_I8); + xmlrpc_read_i8(&env, v, &i); + TEST_NO_FAULT(&env); + TEST(i == 25); + xmlrpc_DECREF(v); + + v = xmlrpc_i8_new(&env, (xmlrpc_int64) -25); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_I8); + xmlrpc_read_i8(&env, v, &i); + TEST_NO_FAULT(&env); + TEST(i == -25); + xmlrpc_DECREF(v); + + v = xmlrpc_i8_new(&env, (xmlrpc_int64)1 << 40); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_I8); + xmlrpc_read_i8(&env, v, &i); + TEST_NO_FAULT(&env); + TEST(i == (xmlrpc_int64)1 << 40); + xmlrpc_DECREF(v); + + v = xmlrpc_build_value(&env, "I", (xmlrpc_int64) 10); + TEST_NO_FAULT(&env); + TEST(v != NULL); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_I8); + xmlrpc_decompose_value(&env, v, "I", &i); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(i == 10); + + v = xmlrpc_i8_new(&env, (xmlrpc_int64) 25); + TEST_NO_FAULT(&env); + v2 = xmlrpc_value_new(&env, v); + TEST_NO_FAULT(&env); + xmlrpc_DECREF(v); + TEST(xmlrpc_value_type(v2) == XMLRPC_TYPE_I8); + xmlrpc_read_i8(&env, v2, &i); + TEST_NO_FAULT(&env); + TEST(i == 25); + xmlrpc_DECREF(v2); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_type_mismatch(void) { + + xmlrpc_value * v; + xmlrpc_env env; + xmlrpc_env env2; + char * str; + + /* Test for one, simple kind of type mismatch error. We assume that + if one of these typechecks works, the rest work fine. + */ + + xmlrpc_env_init(&env); + xmlrpc_env_init(&env2); + + v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 5); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env2, v, "s", &str); + xmlrpc_DECREF(v); + TEST_FAULT(&env2, XMLRPC_TYPE_ERROR); + + xmlrpc_env_clean(&env2); + xmlrpc_env_clean(&env); +} + + + +static void +test_value_invalid_type(void) { + + xmlrpc_env env; + + /* Test invalid type specifier in format string */ + + xmlrpc_env_init(&env); + + xmlrpc_build_value(&env, "Q"); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_missing_array_delim(void) { + + xmlrpc_env env; + + /* Test missing close parenthesis on array */ + + xmlrpc_env_init(&env); + + xmlrpc_build_value(&env, "("); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_build_value(&env, "(i"); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_missing_struct_delim(void) { + + xmlrpc_env env; + + /* Test missing closing brace on struct */ + + xmlrpc_env_init(&env); + + xmlrpc_build_value(&env, "{"); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_build_value(&env, "{s:i", "key1", 7); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_build_value(&env, "{s:i,s:i", "key1", 9, "key2", -4); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_invalid_struct(void) { + + xmlrpc_env env; + + /* Note that even though the format strings are invalid, we have + to supply the variable arguments that xmlrpc_build_value() will + be looking for as it tries to parse it. Otherwise, we get wild + memory references and consequent Valgrind flags. + */ + + xmlrpc_env_init(&env); + + xmlrpc_build_value(&env, "{s:ii", "key1", 9, 9); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_build_value(&env, "{si:", "key1", 9); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_build_value(&env, "{s", "key1"); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_env_clean(&env); +} + + + +static void +testFailedParseValue(void) { + + xmlrpc_env env; + xmlrpc_value * valueP; + const char * stringval; + int integerval; + + + xmlrpc_env_init(&env); + + valueP = xmlrpc_build_value(&env, "{s:s}", "string", "stringval"); + + TEST_NO_FAULT(&env); + + /* Fail because "integer" member is missing */ + xmlrpc_parse_value(&env, valueP, "{s:s,s:i,*}", + "string", &stringval, "integer", &integerval); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_DECREF(valueP); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_parse_value(void) { + + xmlrpc_env env; + xmlrpc_value * valueP; + const char * base64_data = "base64 data"; + size_t base64_data_length = strlen(base64_data); + const char * datestring = "19980717T14:08:55"; + + xmlrpc_env_init(&env); + + valueP = xmlrpc_build_value(&env, "(idb8ss#6(i){s:i}np(i))", + 7, 3.14, (xmlrpc_bool)1, datestring, + "hello world", "a\0b", (size_t)3, + base64_data, base64_data_length, + 15, "member9", 9, &valueP, -5); + + TEST_NO_FAULT(&env); + + { + xmlrpc_int32 i; + xmlrpc_double d; + xmlrpc_bool b; + const char * dt_str; + const char * s1; + const char * s2; + size_t s2_len; + const unsigned char * b64; + size_t b64_len; + xmlrpc_value * arrayP; + xmlrpc_value * structP; + void * cptr; + xmlrpc_value * subvalP; + + xmlrpc_parse_value(&env, valueP, "(idb8ss#6ASnpV)", + &i, &d, &b, &dt_str, &s1, &s2, &s2_len, + &b64, &b64_len, + &arrayP, &structP, &cptr, &subvalP); + + TEST_NO_FAULT(&env); + + TEST(i == 7); + TEST(d == 3.14); + TEST(b == (xmlrpc_bool)1); + TEST(streq(dt_str, datestring)); + TEST(streq(s1, "hello world")); + TEST(s2_len == 3); + TEST(memeq(s2, "a\0b", 3)); + TEST(b64_len == strlen("base64 data")); + TEST(memeq(b64, "base64 data", b64_len)); + TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP)); + TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(structP)); + TEST(cptr == &valueP); + TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(subvalP)); + + xmlrpc_DECREF(valueP); + } + testFailedParseValue(); + + xmlrpc_env_clean(&env); +} + + + +static void +test_struct_get_element(xmlrpc_value * const structP, + xmlrpc_value * const fooValueP, + xmlrpc_value * const weirdValueP, + const char * const weirdKey, + unsigned int const weirdKeyLen) { + + xmlrpc_env env; + xmlrpc_value * valueP; + xmlrpc_value * fooStringP; + xmlrpc_value * bogusKeyStringP; + + xmlrpc_env_init(&env); + + /* build test tools */ + + fooStringP = xmlrpc_build_value(&env, "s", "foo"); + TEST_NO_FAULT(&env); + + bogusKeyStringP = xmlrpc_build_value(&env, "s", "doesn't_exist"); + TEST_NO_FAULT(&env); + + /* "find" interface */ + + xmlrpc_struct_find_value(&env, structP, "foo", &valueP); + TEST_NO_FAULT(&env); + TEST(valueP == fooValueP); + xmlrpc_DECREF(valueP); + + xmlrpc_struct_find_value(&env, structP, "doesn't_exist", &valueP); + TEST_NO_FAULT(&env); + TEST(valueP == NULL); + + xmlrpc_struct_find_value_v(&env, structP, fooStringP, &valueP); + TEST_NO_FAULT(&env); + TEST(valueP == fooValueP); + xmlrpc_DECREF(valueP); + + xmlrpc_struct_find_value_v(&env, structP, bogusKeyStringP, &valueP); + TEST_NO_FAULT(&env); + TEST(valueP == NULL); + + xmlrpc_struct_find_value(&env, fooValueP, "foo", &valueP); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + /* "read" interface */ + + xmlrpc_struct_read_value(&env, structP, "foo", &valueP); + TEST_NO_FAULT(&env); + TEST(valueP == fooValueP); + xmlrpc_DECREF(valueP); + + xmlrpc_struct_read_value(&env, structP, "doesn't_exist", &valueP); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_struct_read_value_v(&env, structP, fooStringP, &valueP); + TEST_NO_FAULT(&env); + TEST(valueP == fooValueP); + xmlrpc_DECREF(valueP); + + xmlrpc_struct_read_value_v(&env, structP, bogusKeyStringP, &valueP); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + xmlrpc_struct_read_value(&env, fooValueP, "foo", &valueP); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + /* obsolete "get" interface. Note that it does not update the + reference count of the xmlrpc_value it returns. + */ + + valueP = xmlrpc_struct_get_value(&env, structP, "foo"); + TEST_NO_FAULT(&env); + TEST(valueP == fooValueP); + + valueP = xmlrpc_struct_get_value(&env, structP, "doesn't_exist"); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + valueP = xmlrpc_struct_get_value(&env, fooValueP, "foo"); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + valueP = xmlrpc_struct_get_value_n(&env, structP, weirdKey, weirdKeyLen); + TEST_NO_FAULT(&env); + TEST(valueP == weirdValueP); + + /* Clean up */ + + xmlrpc_DECREF(fooStringP); + xmlrpc_DECREF(bogusKeyStringP); + + xmlrpc_env_clean(&env); +} + + + +static void +testStructReadout(xmlrpc_value * const structP, + unsigned int const expectedSize) { + + xmlrpc_env env; + xmlrpc_value * keyP; + xmlrpc_value * valueP; + + unsigned int index; + + xmlrpc_env_init(&env); + + for (index = 0; index < expectedSize; ++index) { + xmlrpc_struct_read_member(&env, structP, index, &keyP, &valueP); + TEST_NO_FAULT(&env); + xmlrpc_DECREF(keyP); + xmlrpc_DECREF(valueP); + } + + xmlrpc_struct_read_member(&env, structP, expectedSize, &keyP, &valueP); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + for (index = 0; index < expectedSize; ++index) { + xmlrpc_struct_get_key_and_value(&env, structP, index, &keyP, &valueP); + TEST_NO_FAULT(&env); + } + xmlrpc_env_clean(&env); +} + + + +static void +test_struct_decompose_invalid_format_string( + xmlrpc_value * const testStructP) { + + xmlrpc_env env; + xmlrpc_int32 ival; + xmlrpc_bool bval; + char * sval; + + xmlrpc_env_init(&env); + + /* Premature end of format string: */ + + xmlrpc_decompose_value(&env, testStructP, "{"); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, testStructP, "{s", "baz"); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, testStructP, "{s:", "baz"); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, testStructP, "{s:", "baz"); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, testStructP, "{s:b", "baz", &bval); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, testStructP, "{s:b,", "baz", &bval); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_decompose_value(&env, testStructP, "{s:b,*", "baz", &bval); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + /* Key not 's' */ + xmlrpc_decompose_value(&env, testStructP, "{i:s,s:i,*}", + "baz", &sval, + "foo", &ival); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + /* Missing colon */ + xmlrpc_decompose_value(&env, testStructP, "{is,s:i,*}", + "baz", &sval, + "foo", &ival); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + /* Missing comma */ + xmlrpc_decompose_value(&env, testStructP, "{i:ss:i,*}", + "baz", &sval, + "foo", &ival); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + /* Undefined format specifier */ + xmlrpc_decompose_value(&env, testStructP, "{s:Q,*}", + "baz", &sval); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + /* No * at end */ + xmlrpc_decompose_value(&env, testStructP, "{s:b,s:s,s:i}", + "baz", &bval, + "foo", &sval, + "bar", &ival); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_env_clean(&env); +} + + + +static void +test_struct_decompose(xmlrpc_value * const testStructP) { + + xmlrpc_env env; + + xmlrpc_int32 ival; + xmlrpc_bool bval; + char * sval; + xmlrpc_value * topStructP; + xmlrpc_value * value1P; + + xmlrpc_env_init(&env); + + /* Make a test struct */ + topStructP = xmlrpc_build_value(&env, "{s:S,s:s}", + "key1", testStructP, + "key2", "my_string_value"); + TEST_NO_FAULT(&env); + + test_struct_decompose_invalid_format_string(testStructP); + + /* Decompose a struct */ + xmlrpc_decompose_value(&env, testStructP, "{s:b,s:s,s:i,*}", + "baz", &bval, + "foo", &sval, + "bar", &ival); + TEST_NO_FAULT(&env); + TEST(ival == 1); + TEST(!bval); + TEST(streq(sval, "Hello!")); + free(sval); + + /* Decompose a deep struct */ + + xmlrpc_decompose_value(&env, topStructP, "{s:S,*}", "key1", &value1P); + TEST_NO_FAULT(&env); + TEST(xmlrpc_value_type(value1P) == XMLRPC_TYPE_STRUCT); + xmlrpc_DECREF(value1P); + + xmlrpc_decompose_value(&env, topStructP, "{s:{s:b,s:s,s:i,*},*}", + "key1", + "baz", &bval, + "foo", &sval, + "bar", &ival); + TEST_NO_FAULT(&env); + TEST(ival == 1); + TEST(!bval); + TEST(streq(sval, "Hello!")); + free(sval); + + /* First value of wrong type */ + xmlrpc_decompose_value(&env, testStructP, "{s:b,s:i,*}", + "baz", &sval, + "foo", &ival); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + /* Subsequent value of wrong type */ + xmlrpc_decompose_value(&env, testStructP, "{s:s,s:i,*}", + "foo", &sval, + "baz", &bval); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + /* Nonexistent key */ + xmlrpc_decompose_value(&env, testStructP, "{s:b,s:i,*}", + "baz", &bval, + "nosuch", &sval); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + + /* Error subsequent to nested value */ + xmlrpc_decompose_value(&env, topStructP, "{s:{s:s,*},s:i,*}", + "key1", + "foo", &sval, + "key2", &ival); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + xmlrpc_DECREF(topStructP); + + xmlrpc_env_clean(&env); +} + + + +static void +test_struct (void) { + + xmlrpc_env env; + xmlrpc_value * value1P; + xmlrpc_value *s, *i, *i1, *i2, *i3, *key, *value; + size_t size; + int present; + xmlrpc_bool bval; + char const weirdKey[] = {'f', 'o', 'o', '\0', 'b', 'a', 'r'}; + + xmlrpc_env_init(&env); + + /* Create a struct. */ + s = xmlrpc_struct_new(&env); + TEST_NO_FAULT(&env); + TEST(s != NULL); + TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s)); + size = xmlrpc_struct_size(&env, s); + TEST_NO_FAULT(&env); + TEST(size == 0); + + /* Create some elements to insert into our struct. */ + i1 = xmlrpc_build_value(&env, "s", "Item #1"); + TEST_NO_FAULT(&env); + i2 = xmlrpc_build_value(&env, "s", "Item #2"); + TEST_NO_FAULT(&env); + i3 = xmlrpc_build_value(&env, "s", "Item #3"); + TEST_NO_FAULT(&env); + + /* Insert a single item. */ + xmlrpc_struct_set_value(&env, s, "foo", i1); + TEST_NO_FAULT(&env); + size = xmlrpc_struct_size(&env, s); + TEST_NO_FAULT(&env); + TEST(size == 1); + + /* Insert an item whose key has the same hash value as "foo". */ + xmlrpc_struct_set_value(&env, s, "qmdebdw", i2); + TEST_NO_FAULT(&env); + size = xmlrpc_struct_size(&env, s); + TEST_NO_FAULT(&env); + TEST(size == 2); + i = xmlrpc_struct_get_value(&env, s, "foo"); + TEST_NO_FAULT(&env); + TEST(i == i1); + i = xmlrpc_struct_get_value(&env, s, "qmdebdw"); + TEST_NO_FAULT(&env); + TEST(i == i2); + + /* Replace an existing element with a different element. */ + xmlrpc_struct_set_value(&env, s, "foo", i3); + TEST_NO_FAULT(&env); + size = xmlrpc_struct_size(&env, s); + TEST_NO_FAULT(&env); + TEST(size == 2); + i = xmlrpc_struct_get_value(&env, s, "foo"); + TEST_NO_FAULT(&env); + TEST(i == i3); + + /* Insert an item with a NUL in the key */ + xmlrpc_struct_set_value_n(&env, s, weirdKey, sizeof(weirdKey), i2); + TEST_NO_FAULT(&env); + size = xmlrpc_struct_size(&env, s); + TEST_NO_FAULT(&env); + TEST(size == 3); + + test_struct_get_element(s, i3, i2, weirdKey, sizeof(weirdKey)); + + /* Replace an existing element with the same element (tricky). */ + xmlrpc_struct_set_value(&env, s, "foo", i3); + TEST_NO_FAULT(&env); + size = xmlrpc_struct_size(&env, s); + TEST_NO_FAULT(&env); + TEST(size == 3); + i = xmlrpc_struct_get_value(&env, s, "foo"); + TEST_NO_FAULT(&env); + TEST(i == i3); + + /* Test for the presence and absence of elements. */ + present = xmlrpc_struct_has_key(&env, s, "foo"); + TEST_NO_FAULT(&env); + TEST(present); + present = xmlrpc_struct_has_key(&env, s, "qmdebdw"); + TEST_NO_FAULT(&env); + TEST(present); + present = xmlrpc_struct_has_key(&env, s, "bogus"); + TEST_NO_FAULT(&env); + TEST(!present); + + /* Make sure our typechecks work correctly. */ + xmlrpc_struct_size(&env, i1); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + xmlrpc_struct_has_key(&env, i1, "foo"); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + xmlrpc_struct_set_value(&env, i1, "foo", i2); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + xmlrpc_struct_set_value_v(&env, s, s, i2); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + + /* Test cleanup code (w/memprof). */ + xmlrpc_DECREF(s); + + s = xmlrpc_build_value(&env, "{s:s,s:i,s:b}", + "foo", "Hello!", + "bar", (xmlrpc_int32) 1, + "baz", (xmlrpc_bool) 0); + TEST_NO_FAULT(&env); + TEST(s != NULL); + TEST(xmlrpc_value_type(s) == XMLRPC_TYPE_STRUCT); + size = xmlrpc_struct_size(&env, s); + TEST_NO_FAULT(&env); + TEST(size == 3); + present = xmlrpc_struct_has_key(&env, s, "foo"); + TEST_NO_FAULT(&env); + TEST(present); + present = xmlrpc_struct_has_key(&env, s, "bar"); + TEST_NO_FAULT(&env); + TEST(present); + present = xmlrpc_struct_has_key(&env, s, "baz"); + TEST_NO_FAULT(&env); + TEST(present); + xmlrpc_struct_read_value(&env, s, "baz", &value1P); + TEST_NO_FAULT(&env); + xmlrpc_read_bool(&env, value1P, &bval); + TEST_NO_FAULT(&env); + TEST(!bval); + xmlrpc_DECREF(value1P); + + testStructReadout(s, 3); + + test_struct_decompose(s); + + /* Test type check. */ + xmlrpc_struct_get_key_and_value(&env, i1, 0, &key, &value); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + TEST(key == NULL && value == NULL); + + /* Test bounds checks. */ + xmlrpc_struct_get_key_and_value(&env, s, -1, &key, &value); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + TEST(key == NULL && value == NULL); + + xmlrpc_struct_get_key_and_value(&env, s, 3, &key, &value); + TEST_FAULT(&env, XMLRPC_INDEX_ERROR); + TEST(key == NULL && value == NULL); + + /* Test cleanup code (w/memprof). */ + xmlrpc_DECREF(s); + + xmlrpc_DECREF(i1); + xmlrpc_DECREF(i2); + xmlrpc_DECREF(i3); + xmlrpc_env_clean(&env); +} + + + +void +test_value(void) { + + printf("Running value tests."); + + test_value_alloc_dealloc(); + test_value_int(); + test_value_bool(); + test_value_double(); + test_value_datetime(); + printf("\n Running string value tests."); + test_value_string_no_null(); + test_value_string_null(); + test_value_string_multiline(); + test_value_string_cr(); + test_value_string_wide(); + test_value_string_ctlchar(); + printf("\n String value tests done.\n"); + test_value_base64(); + test_value_array(); + test_value_array2(); + test_value_array_nil(); + test_value_value(); + test_value_AS(); + test_value_AS_typecheck(); + test_value_cptr(); + test_value_nil(); + test_value_i8(); + test_value_type_mismatch(); + test_value_invalid_type(); + test_value_missing_array_delim(); + test_value_missing_struct_delim(); + test_value_invalid_struct(); + test_value_parse_value(); + test_struct(); + + printf("\n"); + printf("Value tests done.\n"); +} diff --git a/trunk/test/value.h b/trunk/test/value.h new file mode 100644 index 000000000..2789defb6 --- /dev/null +++ b/trunk/test/value.h @@ -0,0 +1,2 @@ +void +test_value(void); diff --git a/trunk/test/value_datetime.c b/trunk/test/value_datetime.c new file mode 100644 index 000000000..ff48456ce --- /dev/null +++ b/trunk/test/value_datetime.c @@ -0,0 +1,448 @@ +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include +#include + +#include "casprintf.h" +#include "girstring.h" + +#include "xmlrpc_config.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/string_int.h" + +#include "testtool.h" + +#include "value_datetime.h" + + + +static const char * +truncateFracSec(const char * const datestring) { +/*---------------------------------------------------------------------------- + Return 'datestring', but with any fractional seconds chopped off. + E.g. if 'datestring' is "20000301T00:00:00.654321", + we return "20000301T00:00:00". +-----------------------------------------------------------------------------*/ + char * buffer; + unsigned int i; + + buffer = strdup(datestring); + + for (i = 0; i < strlen(buffer); ++i) { + if (buffer[i] == '.') + buffer[i] = '\0'; + } + return buffer; +} + + + +#if XMLRPC_HAVE_TIMEVAL + +static struct timeval +makeTv(time_t const secs, + unsigned int const usecs) { + + struct timeval retval; + + retval.tv_sec = secs; + retval.tv_usec = usecs; + + return retval; +} + +static bool +tvIsEqual(struct timeval const comparand, + struct timeval const comparator) { + return + comparand.tv_sec == comparator.tv_sec && + comparand.tv_usec == comparator.tv_usec; +} +#endif + + + +#if XMLRPC_HAVE_TIMESPEC + +static struct timespec +makeTs(time_t const secs, + unsigned int const usecs) { + + struct timespec retval; + + retval.tv_sec = secs; + retval.tv_nsec = usecs * 1000; + + return retval; +} + +static bool +tsIsEqual(struct timespec const comparand, + struct timespec const comparator) { + return + comparand.tv_sec == comparator.tv_sec && + comparand.tv_nsec == comparator.tv_nsec; +} +#endif + + + +static const char * +make8601(time_t const seconds, + unsigned int const usec) { + + struct tm const tm = *gmtime(&seconds); + + const char * retval; + + xmlrpc_asprintf(&retval, "%04u%02u%02uT%02u%02u%02u,%06uZ", + 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, + usec); + + return retval; +} + + + +static void +test_value_datetime_varytime(const char * const datestring, + time_t const datetime, + unsigned int const usec) { + + xmlrpc_value * v; + xmlrpc_env env; + const char * readBackString; + time_t readBackDt; + unsigned int readBackUsec; + const char * datestringSec; +#if XMLRPC_HAVE_TIMEVAL + struct timeval const dtTimeval = makeTv(datetime, usec); + struct timeval readBackTv; +#endif +#if XMLRPC_HAVE_TIMESPEC + struct timespec const dtTimespec = makeTs(datetime, usec); + struct timespec readBackTs; +#endif + const char * const dt8601 = make8601(datetime, usec); + const char * readBack8601; + + datestringSec = truncateFracSec(datestring); + + xmlrpc_env_init(&env); + + /* Test xmlrpc_datetime_new_str and time read functions*/ + v = xmlrpc_datetime_new_str(&env, datestring); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); + + xmlrpc_read_datetime_sec(&env, v, &readBackDt); + TEST_NO_FAULT(&env); + TEST(readBackDt == datetime); + + xmlrpc_read_datetime_usec(&env, v, &readBackDt, &readBackUsec); + TEST_NO_FAULT(&env); + TEST(readBackDt == datetime); + TEST(readBackUsec == usec); + +#if XMLRPC_HAVE_TIMEVAL + xmlrpc_read_datetime_timeval(&env, v, &readBackTv); + TEST_NO_FAULT(&env); + TEST(tvIsEqual(dtTimeval, readBackTv)); +#endif + +#if XMLRPC_HAVE_TIMESPEC + xmlrpc_read_datetime_timespec(&env, v, &readBackTs); + TEST_NO_FAULT(&env); + TEST(tsIsEqual(dtTimespec, readBackTs)); +#endif + + xmlrpc_read_datetime_8601(&env, v, &readBack8601); + TEST_NO_FAULT(&env); + TEST(xmlrpc_streq(dt8601, readBack8601)); + strfree(readBack8601); + + xmlrpc_DECREF(v); + + /* Test xmlrpc_datetime_new_sec */ + v = xmlrpc_datetime_new_sec(&env, datetime); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); + + xmlrpc_read_datetime_str(&env, v, &readBackString); + TEST_NO_FAULT(&env); + TEST(streq(readBackString, datestringSec)); + strfree(readBackString); + + xmlrpc_DECREF(v); + + /* Test xmlrpc_datetime_new_usec */ + v = xmlrpc_datetime_new_usec(&env, datetime, usec); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); + + xmlrpc_read_datetime_str(&env, v, &readBackString); + TEST_NO_FAULT(&env); + TEST(streq(readBackString, datestring)); + strfree(readBackString); + + xmlrpc_DECREF(v); + +#if XMLRPC_HAVE_TIMEVAL + /* Test xmlrpc_datetime_new_timeval */ + v = xmlrpc_datetime_new_timeval(&env, dtTimeval); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); + + xmlrpc_read_datetime_str(&env, v, &readBackString); + TEST_NO_FAULT(&env); + TEST(streq(readBackString, datestring)); + strfree(readBackString); + + xmlrpc_DECREF(v); +#endif + +#if XMLRPC_HAVE_TIMESPEC + /* Test xmlrpc_datetime_new_timespec */ + v = xmlrpc_datetime_new_timespec(&env, dtTimespec); + TEST_NO_FAULT(&env); + TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v)); + + xmlrpc_read_datetime_str(&env, v, &readBackString); + TEST_NO_FAULT(&env); + TEST(streq(readBackString, datestring)); + strfree(readBackString); + + xmlrpc_DECREF(v); +#endif + + xmlrpc_env_clean(&env); + strfree(datestringSec); +} + + + +static void +test_value_datetime_not_unix(const char * const datestring) { + + xmlrpc_value * v; + xmlrpc_env env; + time_t dt; + + xmlrpc_env_init(&env); + + v = xmlrpc_datetime_new_str(&env, datestring); + TEST_NO_FAULT(&env); + + xmlrpc_read_datetime_sec(&env, v, &dt); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_DECREF(v); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_datetime_str_invalid1(const char * const datestring) { + + /* Ideally, xmlrpc_datetime_new_str() would fail on these, but + the code doesn't implement that today. However, + xmlrpc_read_datetime_sec() does catch many cases, so we + use that. + + Note that xmlrpc_read_datetime_sec() doesn't catch them all. + Sometimes it just returns garbage, e.g. returns July 1 for + June 31. + */ + + xmlrpc_value * v; + xmlrpc_env env; + time_t dt; + + xmlrpc_env_init(&env); + + v = xmlrpc_datetime_new_str(&env, datestring); + TEST_NO_FAULT(&env); + + xmlrpc_read_datetime_sec(&env, v, &dt); + TEST_FAULT(&env, XMLRPC_PARSE_ERROR); + + xmlrpc_DECREF(v); + + xmlrpc_env_clean(&env); +} + + + +static void +test_value_datetime_str_invalid2(const char * const datestring) { + + xmlrpc_env env; + + xmlrpc_env_init(&env); + + xmlrpc_datetime_new_str(&env, datestring); + TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); + + xmlrpc_env_clean(&env); +} + + + +static void +test_build_decomp_datetime(void) { + + const char * datestring = "19980717T14:08:55"; + time_t const datetime = 900684535; + + xmlrpc_env env; + xmlrpc_value * v; + time_t dt; + const char * ds; + + xmlrpc_env_init(&env); + + v = xmlrpc_build_value(&env, "t", datetime); + TEST_NO_FAULT(&env); + TEST(v != NULL); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_DATETIME); + + dt = 0; + xmlrpc_read_datetime_sec(&env, v, &dt); + TEST(dt == datetime); + + dt = 0; + xmlrpc_decompose_value(&env, v, "t", &dt); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(dt == datetime); + + v = xmlrpc_int_new(&env, 9); + TEST_NO_FAULT(&env); + xmlrpc_decompose_value(&env, v, "t", &dt); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + xmlrpc_env_clean(&env); + xmlrpc_env_init(&env); + xmlrpc_decompose_value(&env, v, "8", &ds); + TEST_FAULT(&env, XMLRPC_TYPE_ERROR); + xmlrpc_env_clean(&env); + xmlrpc_env_init(&env); + xmlrpc_DECREF(v); + + v = xmlrpc_build_value(&env, "8", datestring); + TEST_NO_FAULT(&env); + TEST(v != NULL); + TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_DATETIME); + xmlrpc_decompose_value(&env, v, "8", &ds); + xmlrpc_DECREF(v); + TEST_NO_FAULT(&env); + TEST(streq(ds, datestring)); + strfree(ds); + + xmlrpc_env_clean(&env); +} + + + + +static void +test_value_datetime_basic(void) { + + xmlrpc_value * v; + xmlrpc_env env; + xmlrpc_datetime dt; + xmlrpc_datetime readBackDt; + + xmlrpc_env_init(&env); + + dt.Y = 2001; + dt.M = 12; + dt.D = 25; + dt.h = 1; + dt.m = 2; + dt.s = 3; + dt.u = 4; + + v = xmlrpc_datetime_new(&env, dt); + + xmlrpc_read_datetime(&env, v, &readBackDt); + TEST_NO_FAULT(&env); + TEST(readBackDt.Y = dt.Y); + TEST(readBackDt.M = dt.M); + TEST(readBackDt.D = dt.D); + TEST(readBackDt.h = dt.h); + TEST(readBackDt.m = dt.m); + TEST(readBackDt.s = dt.s); + TEST(readBackDt.u = dt.u); + + xmlrpc_env_clean(&env); +} + + + +void +test_value_datetime(void) { + + const char * datestring = "19980717T14:08:55"; + time_t const datetime = 900684535; + + xmlrpc_env env; + + printf("\n Running datetime value tests"); + + xmlrpc_env_init(&env); + + TEST(streq(xmlrpc_type_name(XMLRPC_TYPE_DATETIME), "DATETIME")); + + test_value_datetime_basic(); + + /* Valid datetime, generated from XML-RPC string, time_t, and + time_t + microseconds + */ + + test_value_datetime_varytime(datestring, datetime, 0); + + /* test microseconds */ + test_value_datetime_varytime("20000301T00:00:00.654321", + 951868800, 654321); + test_value_datetime_varytime("20040229T23:59:59.123000", + 1078099199, 123000); + test_value_datetime_varytime("20000229T23:59:59.000123", + 951868799, 123); + + /* Leap years */ + test_value_datetime_varytime("20000229T23:59:59", 951868799, 0); + test_value_datetime_varytime("20000301T00:00:00", 951868800, 0); + test_value_datetime_varytime("20010228T23:59:59", 983404799, 0); + test_value_datetime_varytime("20010301T00:00:00", 983404800, 0); + test_value_datetime_varytime("20040229T23:59:59", 1078099199, 0); + test_value_datetime_varytime("20040301T00:00:00", 1078099200, 0); + + /* Datetimes that can't be represented as time_t */ + test_value_datetime_not_unix("19691231T23:59:59"); + + /* Invalid datetimes */ + /* Note that the code today does a pretty weak job of validating datetimes, + so we test only the validation that we know is implemented. + */ + test_value_datetime_str_invalid1("19700101T25:00:00"); + test_value_datetime_str_invalid1("19700101T10:61:01"); + test_value_datetime_str_invalid1("19700101T10:59:61"); + test_value_datetime_str_invalid1("19700001T10:00:00"); + test_value_datetime_str_invalid1("19701301T10:00:00"); + test_value_datetime_str_invalid1("19700132T10:00:00"); + test_value_datetime_str_invalid2("19700132T10:00:00."); + test_value_datetime_str_invalid2("19700132T10:00:00,123"); + + test_build_decomp_datetime(); + + xmlrpc_env_clean(&env); + + printf("\n"); + printf(" datetime value tests done.\n"); +} diff --git a/trunk/test/value_datetime.h b/trunk/test/value_datetime.h new file mode 100644 index 000000000..5a26f60a2 --- /dev/null +++ b/trunk/test/value_datetime.h @@ -0,0 +1,7 @@ +#ifndef VALUE_DATETIME_H_INCLUDED +#define VALUE_DATETIME_H_INCLUDED + +void +test_value_datetime(void); + +#endif diff --git a/trunk/test/xml_data.c b/trunk/test/xml_data.c new file mode 100644 index 000000000..a06854e67 --- /dev/null +++ b/trunk/test/xml_data.c @@ -0,0 +1,200 @@ +#include + +#include "xml_data.h" + +#define RAW_STRING_DATA \ + "\r\n" \ + "2147483647\r\n" \ + "-2147483648\r\n" \ + "0\r\n" \ + "1\r\n" \ + "Hello, world! <&>\r\n" \ + "\r\n" \ + "YmFzZTY0IGRhdGE=\r\n" \ + "\r\n" \ + "" \ + "19980717T14:08:55" \ + "\r\n" \ + "\r\n" \ + "\r\n" \ + "" + +char const serialized_data[] = RAW_STRING_DATA; + +char const serialized_call[] = + XML_PROLOGUE + "\r\n" + "gloom&doom\r\n" + "\r\n" + "10\r\n" + "20\r\n" + "\r\n" + "\r\n"; + +char const serialized_fault[] = + XML_PROLOGUE + "\r\n" + "\r\n" + "\r\n" + "faultCode\r\n" + "6\r\n" + "faultString\r\n" + "A fault occurred\r\n" + "\r\n" + "\r\n" + "\r\n"; + +char const expat_data[] = XML_PROLOGUE RAW_STRING_DATA "\r\n"; +char const expat_error_data[] = + XML_PROLOGUE \ + "abc\r\n"; + /* Invalid because there's no closing */ + + +char const good_response_xml[] = + XML_PROLOGUE + "\r\n" + "\r\n" + RAW_STRING_DATA "\r\n" + "1\r\n" + "-1.0\r\n" + "0.0\r\n" + "1.0\r\n" + "\r\n" + "ten <&>\r\n" + "10\r\n" + "twenty\r\n" + "20\r\n" + "\r\n" + "Untagged string\r\n" + "\r\n" + "\r\n"; + +#define VALUE_HEADER \ + XML_PROLOGUE"\r\n" +#define VALUE_FOOTER \ + "\r\n" + +#define MEMBER_HEADER \ + VALUE_HEADER"" +#define MEMBER_FOOTER \ + ""VALUE_FOOTER +#define ARBITRARY_VALUE \ + "0" + +char const unparseable_value[] = VALUE_HEADER""VALUE_FOOTER; + +const char * bad_values[] = { + VALUE_HEADER"00"VALUE_FOOTER, + VALUE_HEADER""VALUE_FOOTER, + VALUE_HEADER"4"VALUE_FOOTER, + VALUE_HEADER"2147483648"VALUE_FOOTER, + VALUE_HEADER"-2147483649"VALUE_FOOTER, + VALUE_HEADER" 0"VALUE_FOOTER, + VALUE_HEADER"0 "VALUE_FOOTER, + VALUE_HEADER"2"VALUE_FOOTER, + VALUE_HEADER"-1"VALUE_FOOTER, + VALUE_HEADER""VALUE_FOOTER, + VALUE_HEADER"0.0 "VALUE_FOOTER, + VALUE_HEADER"a"VALUE_FOOTER, + VALUE_HEADER"1.1.1"VALUE_FOOTER, + VALUE_HEADER"1a"VALUE_FOOTER, + VALUE_HEADER"1.1a"VALUE_FOOTER, + VALUE_HEADER""VALUE_FOOTER, + VALUE_HEADER""VALUE_FOOTER, + VALUE_HEADER""VALUE_FOOTER, + VALUE_HEADER""VALUE_FOOTER, + VALUE_HEADER""VALUE_FOOTER, + MEMBER_HEADER MEMBER_FOOTER, + MEMBER_HEADER"a"MEMBER_FOOTER, + MEMBER_HEADER"a"ARBITRARY_VALUE""MEMBER_FOOTER, + MEMBER_HEADER""ARBITRARY_VALUE MEMBER_FOOTER, + MEMBER_HEADER"a"MEMBER_FOOTER, + MEMBER_HEADER""ARBITRARY_VALUE MEMBER_FOOTER, + NULL +}; + +#define RESPONSE_HEADER \ + XML_PROLOGUE"\r\n" +#define RESPONSE_FOOTER \ + "\r\n" + +#define PARAMS_RESP_HEADER \ + RESPONSE_HEADER"" +#define PARAMS_RESP_FOOTER \ + ""RESPONSE_FOOTER + +#define FAULT_HEADER \ + RESPONSE_HEADER"" +#define FAULT_FOOTER \ + ""RESPONSE_FOOTER + +#define FAULT_STRUCT_HEADER \ + FAULT_HEADER"" +#define FAULT_STRUCT_FOOTER \ + ""FAULT_FOOTER + +const char * bad_responses[] = { + XML_PROLOGUE"\r\n", + RESPONSE_HEADER RESPONSE_FOOTER, + RESPONSE_HEADER""RESPONSE_FOOTER, + RESPONSE_HEADER""RESPONSE_FOOTER, + + /* Make sure we insist on only one parameter in a response. */ + PARAMS_RESP_HEADER PARAMS_RESP_FOOTER, + PARAMS_RESP_HEADER + "0" + "0" + PARAMS_RESP_FOOTER, + + /* Test other sorts of bad parameters. */ + PARAMS_RESP_HEADER""PARAMS_RESP_FOOTER, + PARAMS_RESP_HEADER""PARAMS_RESP_FOOTER, + PARAMS_RESP_HEADER""PARAMS_RESP_FOOTER, + PARAMS_RESP_HEADER + ""ARBITRARY_VALUE ARBITRARY_VALUE"" + PARAMS_RESP_FOOTER, + + /* Basic fault tests. */ + FAULT_HEADER FAULT_FOOTER, + FAULT_HEADER""FAULT_FOOTER, + FAULT_HEADER""FAULT_FOOTER, + FAULT_HEADER"1"FAULT_FOOTER, + + /* Make sure we insist on the proper members within the fault struct. */ + FAULT_STRUCT_HEADER + "faultString" + "foo" + FAULT_STRUCT_FOOTER, + FAULT_STRUCT_HEADER + "faultCode" + "0" + FAULT_STRUCT_FOOTER, + FAULT_STRUCT_HEADER + "faultCode" + "0" + "faultString" + "0" + FAULT_STRUCT_FOOTER, + FAULT_STRUCT_HEADER + "faultCode" + "0" + "faultString" + "foo" + FAULT_STRUCT_FOOTER, + NULL}; + +#define CALL_HEADER \ + XML_PROLOGUE"\r\n" +#define CALL_FOOTER \ + "\r\n" + +const char * bad_calls[] = { + XML_PROLOGUE"\r\n", + CALL_HEADER CALL_FOOTER, + CALL_HEADER"m"CALL_FOOTER, + CALL_HEADER""CALL_FOOTER, + CALL_HEADER""CALL_FOOTER, + NULL}; + + diff --git a/trunk/test/xml_data.h b/trunk/test/xml_data.h new file mode 100644 index 000000000..89b5e4938 --- /dev/null +++ b/trunk/test/xml_data.h @@ -0,0 +1,28 @@ +#ifndef XML_DATA_H_INCLUDED +#define XML_DATA_H_INCLUDED + +#define XML_PROLOGUE "\r\n" + +#define APACHE_URL "http://ws.apache.org/xmlrpc/namespaces/extensions" +#define XMLNS_APACHE "xmlns:ex=\"" APACHE_URL "\"" + +extern char const serialized_data[]; + +extern char const serialized_call[]; + +extern char const serialized_fault[]; + +extern char const expat_data[]; +extern char const expat_error_data[]; + +extern char const good_response_xml[]; + +extern char const unparseable_value[]; + +extern const char *(bad_values[]); + +extern const char *(bad_responses[]); + +extern const char *(bad_calls[]); + +#endif diff --git a/trunk/tools/Makefile b/trunk/tools/Makefile new file mode 100644 index 000000000..7cd2e5f5f --- /dev/null +++ b/trunk/tools/Makefile @@ -0,0 +1,48 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + SRCDIR := $(call updir,$(CURDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools + +include $(BLDDIR)/config.mk + +SUBDIRS = \ + binmode-rpc-kit \ + lib \ + turbocharger \ + xml \ + +ifeq ($(MUST_BUILD_CLIENT),yes) + SUBDIRS += xmlrpc xmlrpc_transport + + ifeq ($(ENABLE_CPLUSPLUS),yes) + SUBDIRS += xml-rpc-api2cpp xml-rpc-api2txt xmlrpc_cpp_proxy + + ifeq ($(BUILD_XMLRPC_PSTREAM),yes) + SUBDIRS += xmlrpc_pstream + endif + endif +endif + +ifeq ($(ENABLE_CPLUSPLUS),yes) + SUBDIRS += xmlrpc_dumpserver +endif + +.PHONY: all clean distclean install uninstall check dep + +all: $(SUBDIRS:%=%/all) + +clean: $(SUBDIRS:%=%/clean) + +distclean: $(SUBDIRS:%=%/distclean) + +install: $(SUBDIRS:%=%/install) + +uninstall: $(SUBDIRS:%=%/uninstall) + +check: + +dep: $(SUBDIRS:%=%/dep) + +include $(SRCDIR)/common.mk diff --git a/trunk/tools/binmode-rpc-kit/COPYING b/trunk/tools/binmode-rpc-kit/COPYING new file mode 100644 index 000000000..9a97cb38b --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/COPYING @@ -0,0 +1,24 @@ +Copyright (C) 2001 by Eric Kidd. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/trunk/tools/binmode-rpc-kit/Makefile b/trunk/tools/binmode-rpc-kit/Makefile new file mode 100644 index 000000000..ea34b1982 --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/Makefile @@ -0,0 +1,6 @@ +all: +clean: +distclean: +install: +uninstall: +dep: diff --git a/trunk/tools/binmode-rpc-kit/README b/trunk/tools/binmode-rpc-kit/README new file mode 100644 index 000000000..029b5b13c --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/README @@ -0,0 +1,31 @@ +Binmode RPC Implementor's Kit +============================= + +Version: 0.1 +Author: Eric Kidd +Date: 31 January 2001 + +The Binmode RPC Implementor's Kit was created as part the xmlrpc-c project. + + http://xmlrpc-c.sourceforge.net/ + +The following files are included: + + README This file + COPYING A standard disclaimer, etc. + binmode-rpc-rfc.txt The current draft of the standard + oct2bin A Perl script for turning the notation used by + the standard into actual binary data. + binmode-rpc2xml-rpc A script which translates a Binmode RPC packet + back into XML. You can use this for dumping wire + messages. (It also catches the most obvious ways + to misimplement the standard, so try it on your + output data.) + examples/ Examples and counter-examples from the standard in + machine-readable format. + +If you have any questions, please ask on the xmlrpc-c-devel mailing list: + + http://xmlrpc-c.sourceforge.net/lists.php + +Thank you for investigating Binmode RPC. Share and enjoy! diff --git a/trunk/tools/binmode-rpc-kit/binmode-rpc-rfc.txt b/trunk/tools/binmode-rpc-kit/binmode-rpc-rfc.txt new file mode 100644 index 000000000..03f026d0c --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/binmode-rpc-rfc.txt @@ -0,0 +1,338 @@ +This is a draft, and subject to change. Please do not implement it +yet. Thank you! + +Examples can be found at the bottom of the file. + +Thank you for your feedback! + +Eric Kidd +eric.kidd@pobox.com +30 January 2001 + + +The Binmode RPC Protocol +======================== + +Binmode RPC is an ultra-lightweight RPC protocol designed for 100% +compatibility with XML-RPC . It emphasizes +simplicity, dynamically-typed data, and extreme ease of implementation. + +Two XML-RPC implementations that implement 'binmode-rpc' may negotiate away +the XML part of XML-RPC, and replace it with a simple binary protocol. + +Design goals: + + * The complete specification should fit in a 350-line text file. :-) + * The protocol should be easy to implement. + * The protocol should provide a high degree of compression. + * The protocol should be very fast--faster than zlib compression. + * The protocol must be implementable in portable ANSI C, with no + './configure' checks. + * The protocol must not contain any options, variant encodings + or similar hair. If you want DCE/RPC, you know where to find it. + * All protocol operations must be performed at the byte level + (except for UTF-8 encoding and decoding). + * The protocol must be semi-readable in a hex dump or Emacs buffer. + * The protocol must efficiently encode boxcarred calls that are + implemented using 'system.multicall'. + * The protocol must enable an efficient encoding for + frequently-repeated string values. + + * The protocol must never be sent to clients or servers which + don't understand it. + * There must be a way for clients and servers to active the protocol + if both ends of the connection understand it. + + +The X-XML-RPC-Extensions Header +------------------------------- + +(First, we'll need a mechanism for unobtrusively announcing the presence of +non-standard capabilities.) + +An XML-RPC implementation MAY advertise additional, non-standard +capabilities using the 'X-XML-RPC-Extensions' header. + +Rationale: The 'X-XML-RPC-Extensions' header should be available to CGI +scripts in the environment variable HTTP_X_XML_RPC_EXTENSIONS. + +If present, this header MUST contain a comma-separated list of +keywords. Parameter information MAY be included, if desired, in the +standard fashion used by HTTP 1.1 'Accept-Encoding' headers. + + X-XML-RPC-Extensions: binmode-rpc + X-XML-RPC-Extensions: binmode-rpc, x-telepathic-transport + X-XML-RPC-Extensions: binmode-rpc,x-telepathic-transport + X-XML-RPC-Extensions: binmode-rpc, x-telepathic-transport;speed=low + +If a client sends the X-XML-RPC-Extensions header in a request, the server +MAY use any of the specified extensions in its response. + +Rationale: No client may be sent non-standard data without first having +advertised the ability to accept it. + +If the server includes the X-XML-RPC-Extensions header in a response, the +client MAY use any of the specified extensions in further requests to that +URL. The client MUST NOT assume that the same extensions are available for +any other URL on the same server. + +Rationale: No server may be sent non-standard data without first having +advertised the ability to accept it. Furthermore, this permission is +URL-specific, since different XML-RPC implementations may be located at +different URLs on a single server. + +The client SHOULD NOT cache extension information about a particular server +for an excessive length of time (typically beyond a single program +invocation). If the client does cache this information indefinitely, it +SHOULD be able to cope if an extension is disabled. + +Rationale: The XML-RPC implementation used on the server may be changed by +the administrator. + + +The 'binmode-rpc' Extension +----------------------- + +A client or server which sends the 'binmode-rpc' extension MUST accept +message bodies of type 'application/x-binmode-rpc' in addition to the +regular 'text/xml'. + +All servers which accept the binmode-rpc extension MUST also accept +standard XML-RPC, as described by . + + +The 'application/x-binmode-rpc' Format +-------------------------------------- + +All documents of the type 'application/x-binmode-rpc' MUST begin with the +following byte sequence (represented here as a C string): + + 'binmode-rpc:' + +This MUST be followed by a Call or a Response, encoded as described below: + + Call := 'C' String Array + +A Call consists of a single octet with the ASCII value 'C', followed by a +String containing the method name and an Array containing the parameters. + + Response := 'R' (Value|Fault) + +A Response MUST contain either a Value or a Fault. + + Fault := 'F' Struct + +A Fault contains a regular Struct (with members as specified by the the +XML-RPC specification). + +Trailing data at the end of an 'application/x-binmode-rpc' document MUST be +ignored. + + +Byte-Order of Integers +---------------------- + +(The following integer types don't correspond directly to XML-RPC +integers--instead, they'll be used to *build* more complicated types.) + + SignedLSB := a four-octet, signed, twos'-complement integer, + least-significant byte (LSB) first + UnsignedLSB := a four-octet, unsigned integer, LSB first + +Raw integer data is encoded in little-endian format. + +Rationale: A fixed, mandatory byte ordering is easier to implement than +approaches which allow multiple byte orderings, and little-endian CPUs +outnumber big-endian CPUs at the time of writing. + + +Values +------ + + Value := (Integer|Boolean|Double|DateTimeISO8601Binary|Array|Struct| + String|Other) + + Integer := 'I' SignedLSB + Boolean := ('t'|'f') + + Double := 'D' SizeOctet AsciiChar... + DateTimeISO8601 := '8' SizeOctet AsciiChar... + +These two types are encoded with an unsigned size octet followed by the +specified number of ASCII characters. The values are encoded in the fashion +described by the XML-RPC specification. + +Rationale: In both these cases, we're punting. Binary floating point +formats are highly non-portable, and cannot be easily manipulated by most +programming languages. XML-RPC values lack timezone +information, and are therefore difficult to convert to a binary format. + + Binary := 'B' UnsignedLSB Octet... + +This corresponds to the XML-RPC type, but without any encoding. +The UnsignedLSB specifies the number of octets of data. + + Array := 'A' UnsignedLSB Value... + +The UnsignedLSB specifies the number of values in the array. + + Struct := 'S' UnsignedLSB (String,Value)... + +The UnsignedLSB specifies the number of String,Value pairs in the struct. +The strings are keys; the values may be of any type. + + Other := 'O' String Binary + +Future XML-RPC types (if any) may be sent a String containing the type name +and a Binary block (as above) containing type-specific data. +Implementations MUST NOT encode any of the standard types using this +construct. Implementations MAY signal an error if data of type Other is +encountered. + +Rationale: This is allowed to cause an error because most applications +won't understand the contents anyway. But if new types are added, dumb +gateways will be able to manipulate them in encapsulated format (if they so +desire). + + +Strings +------- + + String := (RegularString|RecordedString|RecalledString) + +We have three types of strings. + + RegularString := 'U' StringData + StringData := UnsignedLSB Utf8Octet... + +Strings are encoded in UTF-8 format. The UnsignedLSB specifies the number +of UTF-8 octets. Implementations SHOULD raise an error if they encounter +invalid UTF-8 data (e.g., ISO Latin 1 characters). + +Rationale: Technically speaking, XML-RPC is limited to plain ASCII +characters, and may not contain 8-bit or 16-bit characters in any coding +system. But since XML-RPC is based on XML, adding Unicode is a trivial +enhancement to the basic protocol, and *somebody* will make it sooner or +later. When that day arrives, we want to be able to encode Unicode +characters. + +Implements MUST encode UTF-8 characters using the minimum number of octets. +Implementations SHOULD raise an error if they encounter any UTF-8 +characters encoded using more than the minimum number of octets. + +Rationale: Overlong UTF-8 encodings are sometimes used to bypass string +validation in security code. They serve no legitimate purpose, either. So +to improve the overall security of the Universe, we work hard to discourage +them. + +UTF-8 & Unicode FAQ: http://www.cl.cam.ac.uk/~mgk25/unicode.html + + RecordedString := '>' CodebookPosition StringData + RecalledString := '<' CodebookPosition + CodebookPosition := UnsignedOctet + +The 'binmode' format allows a 256-entry "codebook" of strings. At the +start of a data stream, the codebook is empty. When the decoder +encounters a RecordedString, it MUST store it into the specified codebook +position (and then proceed to decode it as a regular string). + +When the decoder encounters a RecalledString, it MUST look it up in the +specified codebook position. If that codebook position has been set, the +implementation MUST use the string value found in the codebook. If the +position has not been set, the implementation MUST stop decoding and raise +an error. It is legal to change a codebook position once it has been set; +the most recent value applies. + +A RecordedString or a RecalledString may be used anywhere a RegularString +may be used. + +Rationale: XML-RPC data tends to contain large numbers of identical +strings. (These are typically the names of members or the names of +methods in a multicall.) To get any kind of reasonable data compression, +it's necessary to have some way of compressing these values. The codebook +mechanism is relatively simple and uncomplicated. + +Implementations MAY choose not to use this feature when encoding data, but +MUST understand it when decoding data. + +Rationale: On the decoding end of things, this feature is trivial to +implement, and must be present for the sake of interoperability. On the +encoding end of things, however, making effective use of this feature is +slightly trickier, so implementations are allowed (but not encouraged) to +omit it. + + +Compliance +---------- + +Implementations MUST implement all features of this protocol correctly, +particularly on the decoding end. In the case of this protocol, a 95% correct +implementation is 100% broken. Yes, this statement is redundant. ;-) + + +Examples +-------- + +Non-ASCII octets are specified as in C strings. Continued lines are +indicated by a trailing '\'; these should be joined together as one +sequence of bytes. + +binmode-rpc:CU\003\0\0\0addA\002\0\0\0I\002\0\0\0I\002\0\0\0 + +binmode-rpc:RI\004\0\0\0 + +binmode-rpc:RFS\002\0\0\0 \ +U\011\0\0\0faultCodeI\001\0\0\0 \ +U\013\0\0\0faultStringU\021\0\0\0An error occurred + +binmode-rpc:RA\006\0\0\0 \ +>\000\003\0\0\0foo \ +>\001\003\0\0\0bar \ +<\000 \ +>\000\003\0\0\0baz \ +<\000 \ +<\001 + +(This deserializes to ['foo', 'bar', 'foo', 'baz', 'baz', 'bar'].) + +binmode-rpc:RU\042\0\0\0Copyright \302\251 1995 J. Random Hacker + +(This is based on an example in the Unicode/UTF-8 FAQ (see above).) + +binmode-rpc:RA\010\0\0\0 \ +I\006\0\0\0 \ +tf \ +D\0042.75 \ +8\02119980717T14:08:55 \ +U\003\0\0\0foo \ +B\003\0\0\0abc \ +S\002\0\0\0U\003\0\0\0runt + +Counter-Examples +---------------- + +The following specimens are illegal, and SHOULD be rejected by a compliant +implementation. Please test your code. + +* A different format name: + + binmode-rpc2:RI\004\0\0\0 + +* A built-in type incorrectly encoded using 'O': + + binmode-rpc:ROU\006\0\0\0stringB\003\0\0\0xyz + +* A recall of an unrecorded string: + + binmode-rpc:R<\002 + +* ISO Latin 1 data in a string. (UTF-8 required!) + + binmode-rpc:RU\041\0\0\0Copyright \251 1995 J. Random Hacker + +* UTF-8 character encoded with too many octets (based on an example in the + Unicode/UTF-8 FAQ): + + binmode-rpc:RU\041\0\0\0Bad linefeed: \300\212 (too many bytes) + +A compliant implementation MUST NOT send any of these sequences. diff --git a/trunk/tools/binmode-rpc-kit/binmode-rpc2xml-rpc b/trunk/tools/binmode-rpc-kit/binmode-rpc2xml-rpc new file mode 100755 index 000000000..2625629bd --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/binmode-rpc2xml-rpc @@ -0,0 +1,552 @@ +#!/usr/bin/perl -w + +use strict; + +# Some constants. +my $crlf = "\015\012"; + +# Try to load our external libraries, but fail gracefully. +eval { + require Frontier::Client; + require MIME::Base64; +}; +if ($@) { + print STDERR <<"EOD"; +This script requires Ken MacLeod\'s Frontier::RPC2 module. You can get this +from CPAN or from his website at http://bitsko.slc.ut.us/~ken/xml-rpc/ . + +For installation instructions, see the XML-RPC HOWTO at: + http://www.linuxdoc.org/HOWTO/XML-RPC-HOWTO/index.html + +This script also requires MIME::Base64. You can get this from CPAN. +EOD + exit 1; +} + +# Parse our command-line arguments. +if (@ARGV != 0) { + print STDERR "Usage: binmode-rpc2xml-rpc < data.binmode > data.xml\n"; + exit 1; +} + +# Perform our I/O in binary mode (hence the name of the protocol). +binmode STDIN; # Because we're reading raw binary data. +binmode STDOUT; # Because we want our XML left unmolested. + +# Just suck all our input into one string and glom it together. +my $binmode_data = join('', ); + +# Check for the mandatory header. +unless ($binmode_data =~ /^binmode-rpc:/) { + die "$0: No 'binmode-rpc:' header present, stopping"; +} + +# Set our decoding-position counter to point just past the header, and +# our end pointer to just beyond the end of the entire message. +my $position = length('binmode-rpc:'); +my $end = length($binmode_data); + +# Set our starting output indentation to zero (for the pretty-printer). +my $indentation = 0; + +# Build an empty codebook of strings. +my @codebook; + +# Begin the hard work. +decode_call_or_response(); + +# Print a warning if there's leftover data. +if ($position != $end) { + printf STDERR "binmode-rpc2xml-rpc: warning: Trailing data ignored\n"; +} + +# We're done! +exit (0); + + +#-------------------------------------------------------------------------- +# Pretty-printing +#-------------------------------------------------------------------------- + +sub escape_string ($) { + my ($string) = @_; + $string =~ s/&/&/g; + $string =~ s/= 0) { + die "Perl can't handle 32-bit unsigned integers portably, stopping"; + } + return $integer; +} + +sub read_signed_lsb () { + die "Unexpected end of input" unless ($position + 4 <= $end); + my $integer = unpack('V', substr($binmode_data, $position, 4)); + $position += 4; + die "Weird error decoding integer" unless (defined $integer); + return $integer; +} + +sub read_data ($) { + my ($length) = @_; + die "Unexpected end of input" unless ($position + $length <= $end); + my $data = unpack("a$length", substr($binmode_data, $position, $length)); + $position += $length; + die "Weird error decoding data" unless (defined $data); + die "Wrong data length" unless (length($data) == $length); + return $data; +} + +sub read_data_w_byte_length () { + my $length = read_byte(); + return read_data($length); +} + +sub read_data_w_unsigned_lsb_length () { + my $length = read_unsigned_lsb(); + return read_data($length) +} + +sub read_string_data () { + my $string = read_data_w_unsigned_lsb_length(); + validate_utf8($string); + return $string; +} + + +#-------------------------------------------------------------------------- +# High-level input routines +#-------------------------------------------------------------------------- +# These use the low-level input routines to read data from the buffer, +# and then convert it into Frontier::RPC2 objects. + +sub read_value () { + my $type = read_character(); + #print STDERR "DEBUG: Reading from '$type'\n"; + if ($type eq 'I') { + return _read_int_value(); + } elsif ($type eq 't') { + return Frontier::RPC2::Boolean->new(1); + } elsif ($type eq 'f') { + return Frontier::RPC2::Boolean->new(0); + } elsif ($type eq 'D') { + return _read_double_value(); + } elsif ($type eq '8') { + return _read_dateTime_value(); + } elsif ($type eq 'B') { + return _read_base64_value(); + } elsif ($type eq 'A') { + return _read_array_value(); + } elsif ($type eq 'S') { + return _read_struct_value(); + } elsif ($type eq 'U') { + return _read_regular_string_value(); + } elsif ($type eq '>') { + return _read_recorded_string_value(); + } elsif ($type eq '<') { + return _read_recalled_string_value(); + } elsif ($type eq 'O') { + die "Type 'O' Binmode RPC data not supported"; + } else { + die "Type '$type' Binmode RPC data does not exist"; + } +} + +sub read_value_and_typecheck ($) { + my ($wanted_type) = @_; + my $value = read_value(); + my $value_type = ref($value); + die "$0: Expected $wanted_type, got $value_type, stopping" + unless ($wanted_type eq $value_type); + return $value; +} + +sub _read_int_value () { + return Frontier::RPC2::Integer->new(read_signed_lsb); +} + +sub _read_double_value () { + return Frontier::RPC2::Double->new(read_data_w_byte_length); +} + +sub _read_dateTime_value () { + return Frontier::RPC2::DateTime::ISO8601->new(read_data_w_byte_length); +} + +sub _read_base64_value () { + my $binary = read_data_w_unsigned_lsb_length; + my $encoded = MIME::Base64::encode_base64($binary, $crlf); + return Frontier::RPC2::Base64->new($encoded); +} + +sub _read_array_value () { + my $size = read_unsigned_lsb; + my @values; + for (my $i = 0; $i < $size; $i++) { + push @values, read_value; + } + return \@values; +} + +sub _read_struct_value () { + my $size = read_unsigned_lsb; + my %struct; + for (my $i = 0; $i < $size; $i++) { + my $key = read_value_and_typecheck('Frontier::RPC2::String'); + $struct{$key->value} = read_value; + } + return \%struct; +} + +sub _read_regular_string_value () { + return Frontier::RPC2::String->new(read_string_data); +} + +sub _read_recorded_string_value () { + my $codebook_entry = read_byte; + my $string = Frontier::RPC2::String->new(read_string_data); + $codebook[$codebook_entry] = $string; + return $string; +} + +sub _read_recalled_string_value () { + my $codebook_entry = read_byte; + my $string = $codebook[$codebook_entry]; + unless (defined $string) { + die "$0: Attempted to use undefined codebook position $codebook_entry"; + } + return $string; +} + + +#-------------------------------------------------------------------------- +# High-level output routines +#-------------------------------------------------------------------------- +# We don't use Frontier::RPC2's output routines, because we're looking +# for maximum readability. This is a debugging tool, after all. + +sub print_xml_header () { + print_xml_line ''; +} + +sub get_escaped_string ($) { + my ($value) = @_; + return escape_string($value->value); +} + +sub print_simple_value ($$) { + my ($tag, $value) = @_; + my $string = get_escaped_string($value); + print_xml_line "<$tag>$string"; +} + +sub print_value ($) { + my ($value) = @_; + my $type = ref($value); + if ($type eq 'Frontier::RPC2::Integer') { + print_simple_value("int", $value); + } elsif ($type eq 'Frontier::RPC2::Double') { + print_simple_value("double", $value); + } elsif ($type eq 'Frontier::RPC2::Boolean') { + print_simple_value("boolean", $value); + } elsif ($type eq 'Frontier::RPC2::String') { + print_simple_value("string", $value); + } elsif ($type eq 'Frontier::RPC2::DateTime::ISO8601') { + print_simple_value("dateTime.iso8601", $value); + } elsif ($type eq 'Frontier::RPC2::Base64') { + print_base64_data($value); + } elsif ($type eq 'ARRAY') { + print_array_value($value); + } elsif ($type eq 'HASH') { + print_struct_value($value); + } else { + die "Unxpected type '$type', stopping"; + } +} + +sub print_params ($) { + my ($params) = @_; + + die "Wanted array" unless (ref($params) eq 'ARRAY'); + + print_xml_line ''; + push_indentation_level; + + foreach my $item (@$params) { + print_xml_line ''; + push_indentation_level; + print_value($item); + pop_indentation_level; + print_xml_line ''; + } + + pop_indentation_level; + print_xml_line ''; +} + +sub print_base64_data ($) { + my ($value) = @_; + print_xml_line ''; + push_indentation_level; + print_xml_line ''; + print $value->value; + print_xml_line ''; + pop_indentation_level; + print_xml_line ''; +} + +sub print_array_value ($) { + my ($array) = @_; + + print_xml_line ''; + push_indentation_level; + print_xml_line ''; + push_indentation_level; + print_xml_line ''; + push_indentation_level; + + foreach my $item (@$array) { + print_value($item); + } + + pop_indentation_level; + print_xml_line ''; + pop_indentation_level; + print_xml_line ''; + pop_indentation_level; + print_xml_line ''; +} + +sub print_struct_value ($) { + my ($struct) = @_; + + print_xml_line ''; + push_indentation_level; + print_xml_line ''; + push_indentation_level; + + for my $key (keys %$struct) { + print_xml_line ''; + push_indentation_level; + + my $name = escape_string($key); + print_xml_line "$name"; + print_value($struct->{$key}); + + pop_indentation_level; + print_xml_line ''; + } + + pop_indentation_level; + print_xml_line ''; + pop_indentation_level; + print_xml_line ''; +} + + +#-------------------------------------------------------------------------- +# High-level decoder routines +#-------------------------------------------------------------------------- +# These routines convert Binmode RPC data into the corresponding XML-RPC +# documents. + +sub decode_call_or_response () { + my $type = read_character(); + if ($type eq 'C') { + decode_call(); + } elsif ($type eq 'R') { + decode_response(); + } else { + die "$0: Unknown binmode-rpc request type '$type', stopping"; + } +} + +sub decode_call () { + my $namevalue = read_value_and_typecheck('Frontier::RPC2::String'); + my $params = read_value_and_typecheck('ARRAY'); + + print_xml_header; + print_xml_line ''; + push_indentation_level; + + my $name = get_escaped_string($namevalue); + print_xml_line "$name"; + + print_params($params); + + pop_indentation_level; + print_xml_line ''; +} + +sub decode_response () { + my $maybe_fault = peek_character; + if ($maybe_fault eq 'F') { + read_character; + my $fault = read_value_and_typecheck('HASH'); + print_xml_header; + + print_xml_line ''; + push_indentation_level; + print_xml_line ''; + push_indentation_level; + + print_value $fault; + + pop_indentation_level; + print_xml_line ''; + pop_indentation_level; + print_xml_line ''; + } else { + my $value = read_value; + print_xml_header; + print_xml_line ''; + push_indentation_level; + print_params [$value]; + pop_indentation_level; + print_xml_line ''; + } +} + + +#-------------------------------------------------------------------------- +# UTF-8 Validation +#-------------------------------------------------------------------------- +# This is based on the UTF-8 section of the Secure Programs HOWTO. +# http://new.linuxnow.com/docs/content/HOWTO/Secure-Programs-HOWTO/ +# This code *hasn't* been stress-tested for correctness yet; please see: +# http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt +# This is not yet good enough to be used as part of a UTF-8 decoder or +# security validator, but it's OK to make sure nobody is sending Latin-1. + +BEGIN { + + use vars qw{@illegal_initial_bytes @sequence_length_info}; + + # Bytes are represented as data/mask pairs. + @illegal_initial_bytes = + (# 10xxxxxx illegal as initial byte of char (80..BF) + [0x80, 0xC0], + # 1100000x illegal, overlong (C0..C1 80..BF) + [0xC0, 0xFE], + # 11100000 100xxxxx illegal, overlong (E0 80..9F) + [0xE0, 0xFF, 0x80, 0xE0], + # 11110000 1000xxxx illegal, overlong (F0 80..8F) + [0xF0, 0xFF, 0x80, 0xF0], + # 11111000 10000xxx illegal, overlong (F8 80..87) + [0xF8, 0xFF, 0x80, 0xF8], + # 11111100 100000xx illegal, overlong (FC 80..83) + [0xFC, 0xFF, 0x80, 0xFC], + # 1111111x illegal; prohibited by spec + [0xFE, 0xFE]); + + # Items are byte, mask, sequence length. + @sequence_length_info = + (# 110xxxxx 10xxxxxx + [0xC0, 0xE0, 2], + # 1110xxxx 10xxxxxx 10xxxxxx + [0xE0, 0xF0, 3], + # 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + [0xF0, 0xF8, 4], + # 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + [0xF8, 0xFC, 5], + # 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + [0xFC, 0xFE, 6]); +} + +sub validate_utf8 ($) { + my ($string) = @_; + my $end = length($string); + + my $i = 0; + while ($i < $end) { + my $byte = ord(substr($string, $i, 1)); + #print STDERR "Checking byte $byte\n"; + + # Check for illegal bytes at the start of this sequence. + NEXT_CANDIDATE: + foreach my $illegal_byte_info (@illegal_initial_bytes) { + my $offset = 0; + for (my $j = 0; $j < @$illegal_byte_info; $j += 2) { + my $pattern = $illegal_byte_info->[$j]; + my $mask = $illegal_byte_info->[$j+1]; + my $data = ord(substr($string, $i+$offset, 1)); + #print STDERR " B: $byte P: $pattern M: $mask D: $data\n"; + next NEXT_CANDIDATE unless ($data & $mask) == $pattern; + $offset++; + } + die "Illegal UTF-8 sequence (" . substr($string, $i, 2) . ")"; + } + + # Find the length of the sequence, and make sure we have enough data. + my $length = 1; + foreach my $length_info (@sequence_length_info) { + my ($pattern, $mask, $length_candidate) = @$length_info; + if (($byte & $mask) == $pattern) { + $length = $length_candidate; + last; + } + } + die "$0: Unexpected end of UTF-8 sequence, stopping" + unless $i + $length <= $end; + + # Verify the sequence is well-formed. + $i++, $length--; + while ($length > 0) { + die "$0: Malformed UTF-8 sequence, stopping" + unless (ord(substr($string, $i, 1)) & 0xC0) == 0x80; + $i++, $length--; + } + } + #printf STDERR "DEBUG: Verified $i bytes\n"; +} diff --git a/trunk/tools/binmode-rpc-kit/examples/good-1.binmode b/trunk/tools/binmode-rpc-kit/examples/good-1.binmode new file mode 100644 index 0000000000000000000000000000000000000000..53c57403f0ee1f99275b5f73d4271ab0f75dc541 GIT binary patch literal 80 zcmYew%*)MBN!2YXNVW=ciyB>>_P5YYet literal 0 HcmV?d00001 diff --git a/trunk/tools/binmode-rpc-kit/examples/good-1.xml b/trunk/tools/binmode-rpc-kit/examples/good-1.xml new file mode 100644 index 000000000..3f9feaa01 --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/examples/good-1.xml @@ -0,0 +1,32 @@ + + + + + + + + 6 + 1 + 0 + 2.75 + 19980717T14:08:55 + foo + + +YWJj + + + + + + run + 1 + + + + + + + + + diff --git a/trunk/tools/binmode-rpc-kit/examples/good-2.binmode b/trunk/tools/binmode-rpc-kit/examples/good-2.binmode new file mode 100644 index 0000000000000000000000000000000000000000..8fd69ef786cf153bc0e10e1ef57125ad9125c1eb GIT binary patch literal 36 icmYew%*)MBN!2YXNVakgWoBStNK8p_WCGHjZ~_3f3I`|v literal 0 HcmV?d00001 diff --git a/trunk/tools/binmode-rpc-kit/examples/good-2.xml b/trunk/tools/binmode-rpc-kit/examples/good-2.xml new file mode 100644 index 000000000..ab1db1ad6 --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/examples/good-2.xml @@ -0,0 +1,12 @@ + + + add + + + 2 + + + 2 + + + diff --git a/trunk/tools/binmode-rpc-kit/examples/good-3.binmode b/trunk/tools/binmode-rpc-kit/examples/good-3.binmode new file mode 100644 index 0000000000000000000000000000000000000000..a0633e8bebffd4e7599104b7106bf87e03264a24 GIT binary patch literal 18 ZcmYew%*)MBN!2YXNVW>{WMN=n002FH1u6gl literal 0 HcmV?d00001 diff --git a/trunk/tools/binmode-rpc-kit/examples/good-3.xml b/trunk/tools/binmode-rpc-kit/examples/good-3.xml new file mode 100644 index 000000000..4262551fc --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/examples/good-3.xml @@ -0,0 +1,8 @@ + + + + + 4 + + + diff --git a/trunk/tools/binmode-rpc-kit/examples/good-4.binmode b/trunk/tools/binmode-rpc-kit/examples/good-4.binmode new file mode 100644 index 0000000000000000000000000000000000000000..3d95e779985110d395aed59bba23863553b5b088 GIT binary patch literal 76 zcmYew%*)MBN!2YXNVW=c3ua + + + + + + faultString + An error occurred + + + faultCode + 1 + + + + + diff --git a/trunk/tools/binmode-rpc-kit/examples/good-5.binmode b/trunk/tools/binmode-rpc-kit/examples/good-5.binmode new file mode 100644 index 0000000000000000000000000000000000000000..e869c55d25f5071094ef2ed711c22b51518feba4 GIT binary patch literal 51 xcmYew%*)MBN!2YXNVW=cWMg1puw!5bl4<$*c8nlKQeu$}R4gg6%7(#)5db=K3R3_8 literal 0 HcmV?d00001 diff --git a/trunk/tools/binmode-rpc-kit/examples/good-5.xml b/trunk/tools/binmode-rpc-kit/examples/good-5.xml new file mode 100644 index 000000000..601ff3d22 --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/examples/good-5.xml @@ -0,0 +1,19 @@ + + + + + + + + foo + bar + foo + baz + baz + bar + + + + + + diff --git a/trunk/tools/binmode-rpc-kit/examples/good-6.binmode b/trunk/tools/binmode-rpc-kit/examples/good-6.binmode new file mode 100644 index 0000000000000000000000000000000000000000..8a7c6214e77f9493a124c79abdab8c611fb54772 GIT binary patch literal 52 zcmYew%*)MBN!2YXNVW + + + + Copyright © 1995 J. Random Hacker + + + diff --git a/trunk/tools/binmode-rpc-kit/examples/invalid-1.binmode b/trunk/tools/binmode-rpc-kit/examples/invalid-1.binmode new file mode 100644 index 0000000000000000000000000000000000000000..4076dbb69a1f31f25e7378dfe56bc3a089dc0d9a GIT binary patch literal 19 acmYew%*)MBN!2YXNH($x@?>FPU;qF^Uj{4`pLuU??sr%FIi5Vg@oRDysmr$O+B> literal 0 HcmV?d00001 diff --git a/trunk/tools/binmode-rpc-kit/examples/invalid-3.binmode b/trunk/tools/binmode-rpc-kit/examples/invalid-3.binmode new file mode 100644 index 000000000..ad5e88399 --- /dev/null +++ b/trunk/tools/binmode-rpc-kit/examples/invalid-3.binmode @@ -0,0 +1 @@ +binmode-rpc:R< \ No newline at end of file diff --git a/trunk/tools/binmode-rpc-kit/examples/invalid-4.binmode b/trunk/tools/binmode-rpc-kit/examples/invalid-4.binmode new file mode 100644 index 0000000000000000000000000000000000000000..69aa2f464d31fc15b046650c42c766ffba2a497b GIT binary patch literal 51 zcmYew%*)MBN!2YXNVW out.binmode". + +binmode STDOUT; + +while (<>) { + s/\\(\d\d\d)/chr(oct($1))/ge; + s/\\0/chr(0)/ge; + s/\\\\/\\/g; + print $_; +} diff --git a/trunk/tools/common.mk b/trunk/tools/common.mk new file mode 100644 index 000000000..1218e18cb --- /dev/null +++ b/trunk/tools/common.mk @@ -0,0 +1,49 @@ +CLIENT_LDLIBS = $(shell cat blddir/src/libxmlrpc_client.ldflags) $(LDLIBS_XML) + +CLIENT_LIBS_DEP = \ + $(LIBXMLRPC_CLIENT) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_XML) \ + $(LIBXMLRPC_UTIL) \ + $(BLDDIR)/src/libxmlrpc_client.ldflags \ + +CLIENTPP_LDLIBS = \ + -Lblddir/src/cpp \ + -lxmlrpc_client++ \ + -lxmlrpc_packetsocket \ + -lxmlrpc++ \ + -Lblddir/lib/libutil++ \ + -lxmlrpc_util++ \ + +SERVER_ABYSS_LDLIBS = \ + $(LIBXMLRPC_SERVER_ABYSS) \ + $(LIBXMLRPC_ABYSS) \ + $(LIBXMLRPC_SERVER) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_XML) \ + $(LIBXMLRPC_UTIL) \ + $(LDLIBS_XML) \ + +SERVER_ABYSS_LIBS_DEP = \ + $(LIBXMLRPC_SERVER_ABYSS) \ + $(LIBXMLRPC_ABYSS) \ + $(LIBXMLRPC_SERVER) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_XML) \ + $(LIBXMLRPC_UTIL) \ + +include $(SRCDIR)/common.mk + +ifneq ($(OMIT_LIB_RULE),Y) +blddir/tools/lib/dumpvalue.o: FORCE + $(MAKE) -C $(dir $@) -f $(SRCDIR)/tools/lib/Makefile $(notdir $@) +endif + +.PHONY: install +install: install-common + +.PHONY: check +check: + +.PHONY: FORCE +FORCE: diff --git a/trunk/tools/interop-server/interop-cgi.c b/trunk/tools/interop-server/interop-cgi.c new file mode 100644 index 000000000..d07926716 --- /dev/null +++ b/trunk/tools/interop-server/interop-cgi.c @@ -0,0 +1,215 @@ +/* A CGI which implements all of the test functions need for an interop +** endpoint. */ + +#include +#include +#include + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/cgi.h" + +#include "version.h" + +#include "config.h" /* information about this build environment */ + + +/*========================================================================= +** Toolkit Identification +**========================================================================= +*/ + +static xmlrpc_value * +whichToolkit(xmlrpc_env * const env, + xmlrpc_value * const param_array, + void * const user_data ATTR_UNUSED) { + + xmlrpc_value * retval; + + /* Parse our argument array. */ + xmlrpc_parse_value(env, param_array, "()"); + if (env->fault_occurred) + retval = NULL; + else { + struct utsname utsname; + + int rc; + rc = uname(&utsname); + if (rc != 0) { + xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, + "uname() failed. errno=%d (%s)", + errno, strerror(errno)); + retval = NULL; + } else { + /* Assemble our result. */ + retval = xmlrpc_build_value(env, "{s:s,s:s,s:s,s:s}", + "toolkitDocsUrl", + "http://xmlrpc-c.sourceforge.net/", + "toolkitName", PACKAGE, + "toolkitVersion", XMLRPC_C_VERSION"+", + "toolkitOperatingSystem", + utsname.sysname); + } + } + return retval; +} + + + +static char whichToolkit_help[] = +"Identify the toolkit used to implement this server. The operating system " +"information is based on where the toolkit was compiled, not where it's " +"currently running."; + + +/*========================================================================= +** noInParams +**========================================================================= +** Test a method with no parameters. +*/ + +static xmlrpc_value * +noInParams(xmlrpc_env * const env, + xmlrpc_value * const param_array, + void * const user_data ATTR_UNUSED) { + + /* Parse our argument array. */ + xmlrpc_parse_value(env, param_array, "()"); + if (env->fault_occurred) + return NULL; + + /* Assemble our result. */ + return xmlrpc_build_value(env, "i", (xmlrpc_int32) 0); +} + +static char noInParams_help[] = +"A method with no parameters. Returns an arbitrary int."; + + +/*========================================================================= +** Echo Tests +**========================================================================= +** We're lazy--we only implement one actual echo method, but we hook it +** up to lots of different names. +*/ + +static xmlrpc_value * +echoValue(xmlrpc_env * const env, + xmlrpc_value * const param_array, + void * const user_data ATTR_UNUSED) { + + xmlrpc_value *val; + + /* Parse our argument array. */ + xmlrpc_parse_value(env, param_array, "(V)", &val); + if (env->fault_occurred) + return NULL; + + /* Create a new reference (because both our parameter list and our + ** return value will be DECREF'd when we return). */ + xmlrpc_INCREF(val); + + /* Return our result. */ + return val; +} + +static char echoValue_help[] = +"Echo an arbitrary XML-RPC value of any type."; + +static char echoString_help[] = +"Echo an arbitrary XML-RPC string."; + +static char echoInteger_help[] = +"Echo an arbitrary XML-RPC integer."; + +static char echoBoolean_help[] = +"Echo an arbitrary XML-RPC boolean value."; + +static char echoFloat_help[] = +"Echo an arbitrary XML-RPC float."; + +static char echoStruct_help[] = +"Echo an arbitrary XML-RPC struct."; + +static char echoDate_help[] = +"Echo an arbitrary XML-RPC date/time value."; + +static char echoBase64_help[] = +"Echo an arbitrary XML-RPC Base64 value."; + +static char echoStringArray_help[] = +"Echo an array of arbitrary XML-RPC strings."; + +static char echoIntegerArray_help[] = +"Echo an array of arbitrary XML-RPC integers."; + +static char echoFloatArray_help[] = +"Echo an array of arbitrary XML-RPC floats."; + +static char echoStructArray_help[] = +"Echo an array of arbitrary XML-RPC structs."; + + +/*========================================================================= +** Server Setup +**========================================================================= +** Set up and run our server. +*/ + +int +main(int const argc ATTR_UNUSED, + char ** const argv ATTR_UNUSED) { + + /* Process our request. */ + xmlrpc_cgi_init(XMLRPC_CGI_NO_FLAGS); + + /* Add a method to identify our toolkit. */ + xmlrpc_cgi_add_method_w_doc("interopEchoTests.whichToolkit", + &whichToolkit, NULL, + "S:", whichToolkit_help); + + /* Add a whole bunch of test methods. */ + xmlrpc_cgi_add_method_w_doc("interopEchoTests.noInParams", + &noInParams, NULL, + "i:", noInParams_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoValue", + &echoValue, NULL, + "?", echoValue_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoString", + &echoValue, NULL, + "s:s", echoString_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoInteger", + &echoValue, NULL, + "i:i", echoInteger_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoBoolean", + &echoValue, NULL, + "b:b", echoBoolean_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoFloat", + &echoValue, NULL, + "d:d", echoFloat_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoStruct", + &echoValue, NULL, + "S:S", echoStruct_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoDate", + &echoValue, NULL, + "8:8", echoDate_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoBase64", + &echoValue, NULL, + "6:6", echoBase64_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoStringArray", + &echoValue, NULL, + "A:A", echoStringArray_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoIntegerArray", + &echoValue, NULL, + "A:A", echoIntegerArray_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoFloatArray", + &echoValue, NULL, + "A:A", echoFloatArray_help); + xmlrpc_cgi_add_method_w_doc("interopEchoTests.echoStructArray", + &echoValue, NULL, + "A:A", echoStructArray_help); + + xmlrpc_cgi_process_call(); + xmlrpc_cgi_cleanup(); + + return 0; +} diff --git a/trunk/tools/lib/Makefile b/trunk/tools/lib/Makefile new file mode 100644 index 000000000..39d34b844 --- /dev/null +++ b/trunk/tools/lib/Makefile @@ -0,0 +1,46 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/lib + +default: all + +include $(BLDDIR)/config.mk + +OMIT_LIB_RULE = Y + +include $(SRCDIR)/tools/common.mk + +INCLUDES = \ + -Isrcdir/$(SUBDIR)/include \ + -Iblddir \ + -Isrcdir/include \ + -Isrcdir/lib/util/include \ + +LIBOBJS = \ + dumpvalue.o \ + +.PHONY: all +all: $(LIBOBJS) + +%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h + $(CC) -c $(CFLAGS_ALL) $< + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: dep +dep: dep-common + +.PHONY: clean +clean: clean-common + +.PHONY: distclean +distclean: clean distclean-common diff --git a/trunk/tools/lib/dumpvalue.c b/trunk/tools/lib/dumpvalue.c new file mode 100644 index 000000000..ddb52662d --- /dev/null +++ b/trunk/tools/lib/dumpvalue.c @@ -0,0 +1,497 @@ +/* dumpvalue() service, which prints to Standard Output the value of + an xmlrpc_value. + + We've put this in a separate module in hopes that it eventually can be + used for debugging purposes in other places. +*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include + +#include "xmlrpc_config.h" /* information about this build environment */ +#include "int.h" +#include "casprintf.h" +#include "mallocvar.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/string_int.h" + +#include "dumpvalue.h" + + + +static void +dumpInt(const char * const prefix, + xmlrpc_value * const valueP) { + + xmlrpc_env env; + xmlrpc_int value; + + xmlrpc_env_init(&env); + + xmlrpc_read_int(&env, valueP, &value); + + if (env.fault_occurred) + printf("Internal error: unable to extract value of " + "integer xmlrpc_value %lx. %s\n", + (unsigned long)valueP, env.fault_string); + else + printf("%sInteger: %d\n", prefix, value); + + xmlrpc_env_clean(&env); +} + + + +static void +dumpBool(const char * const prefix, + xmlrpc_value * const valueP) { + + xmlrpc_env env; + xmlrpc_bool value; + + xmlrpc_env_init(&env); + + xmlrpc_read_bool(&env, valueP, &value); + + if (env.fault_occurred) + printf("Internal error: Unable to extract value of " + "boolean xmlrpc_value %lx. %s\n", + (unsigned long)valueP, env.fault_string); + else + printf("%sBoolean: %s\n", prefix, value ? "TRUE" : "FALSE"); + + xmlrpc_env_clean(&env); +} + + + +static void +dumpDouble(const char * const prefix, + xmlrpc_value * const valueP) { + + xmlrpc_env env; + xmlrpc_double value; + + xmlrpc_env_init(&env); + + xmlrpc_read_double(&env, valueP, &value); + + if (env.fault_occurred) + printf("Internal error: Unable to extract value from " + "floating point number xmlrpc_value %lx. %s\n", + (unsigned long)valueP, env.fault_string); + else + printf("%sFloating Point: %f\n", prefix, value); + + xmlrpc_env_clean(&env); +} + + + +static void +dumpDatetime(const char * const prefix, + xmlrpc_value * const valueP) { + + xmlrpc_env env; + xmlrpc_datetime value; + + xmlrpc_env_init(&env); + + xmlrpc_read_datetime(&env, valueP, &value); + + if (env.fault_occurred) + printf("Internal error: Unable to extract value from " + "datetime xmlrpc_value %lx. %s\n", + (unsigned long)valueP, env.fault_string); + else + printf("%sDatetime: %u.%02u.%02u %02u:%02u:%02u.%06u\n", + prefix, + value.Y, + value.M, + value.D, + value.h, + value.m, + value.s, + value.u + ); + + xmlrpc_env_clean(&env); +} + + + +static size_t +nextLineSize(const char * const string, + size_t const startPos, + size_t const stringSize) { +/*---------------------------------------------------------------------------- + Return the length of the line that starts at offset 'startPos' in the + string 'string', which is 'stringSize' characters long. + + 'string' in not NUL-terminated. + + A line begins at beginning of string or after a newline character and + runs through the next newline character or end of string. The line + includes the newline character at the end, if any. +-----------------------------------------------------------------------------*/ + size_t i; + + for (i = startPos; i < stringSize && string[i] != '\n'; ++i); + + if (i < stringSize) + ++i; /* Include the newline */ + + return i - startPos; +} + + + +static void +dumpMultilineString(const char * const prefix, + const char * const value, + size_t const length) { + + size_t cursor; /* Index into value[] */ + + for (cursor = 0; cursor < length; ) { + /* Print one line of buffer */ + + size_t const lineSize = nextLineSize(value, cursor, length); + const char * const printableLine = + xmlrpc_makePrintable_lp(&value[cursor], lineSize); + + printf("%s%s\n", prefix, printableLine); + + cursor += lineSize; + + strfree(printableLine); + } +} + + + +static void +dumpSimpleString(const char * const value, + size_t const length) { + + const char * const printable = xmlrpc_makePrintable_lp(value, length); + + printf("'%s'\n", printable); + + strfree(printable); +} + + + +static void +dumpString(const char * const prefix, + xmlrpc_value * const valueP) { + + xmlrpc_env env; + size_t length; + const char * value; + + xmlrpc_env_init(&env); + + xmlrpc_read_string_lp(&env, valueP, &length, &value); + + if (env.fault_occurred) + printf("Internal error: Unable to extract value from " + "string xmlrpc_value %lx. %s\n", + (unsigned long)valueP, env.fault_string); + else { + printf("%sString: ", prefix); + if (strlen(value) == length && strchr(value, '\n')) { + const char * prefix2; + casprintf(&prefix2, "%s ", prefix); + printf("\n"); + dumpMultilineString(prefix2, value, length); + strfree(prefix2); + } else + dumpSimpleString(value, length); + + strfree(value); + } + xmlrpc_env_clean(&env); +} + + + +static void +dumpBase64(const char * const prefix, + xmlrpc_value * const valueP) { + + xmlrpc_env env; + const unsigned char * value; + size_t length; + + xmlrpc_env_init(&env); + + xmlrpc_read_base64(&env, valueP, &length, &value); + + if (env.fault_occurred) + printf("Unable to parse base64 bit string xmlrpc_value %lx. %s\n", + (unsigned long)valueP, env.fault_string); + else { + unsigned int i; + + printf("%sBit string: ", prefix); + for (i = 0; i < length; ++i) + printf("%02x", value[i]); + + free((void*)value); + } + xmlrpc_env_clean(&env); +} + + + +static void +dumpArray(const char * const prefix, + xmlrpc_value * const arrayP) { + + xmlrpc_env env; + unsigned int arraySize; + + xmlrpc_env_init(&env); + + XMLRPC_ASSERT_ARRAY_OK(arrayP); + + arraySize = xmlrpc_array_size(&env, arrayP); + if (env.fault_occurred) + printf("Unable to get array size. %s\n", env.fault_string); + else { + int const spaceCount = strlen(prefix); + + unsigned int i; + const char * blankPrefix; + + printf("%sArray of %u items:\n", prefix, arraySize); + + casprintf(&blankPrefix, "%*s", spaceCount, ""); + + for (i = 0; i < arraySize; ++i) { + xmlrpc_value * valueP; + + xmlrpc_array_read_item(&env, arrayP, i, &valueP); + + if (env.fault_occurred) + printf("Unable to get array item %u\n", i); + else { + const char * prefix2; + + casprintf(&prefix2, "%s Index %2u ", blankPrefix, i); + dumpValue(prefix2, valueP); + strfree(prefix2); + + xmlrpc_DECREF(valueP); + } + } + strfree(blankPrefix); + } + xmlrpc_env_clean(&env); +} + + + +static void +dumpStructMember(const char * const prefix, + xmlrpc_value * const structP, + unsigned int const index) { + + xmlrpc_env env; + + xmlrpc_value * keyP; + xmlrpc_value * valueP; + + xmlrpc_env_init(&env); + + xmlrpc_struct_read_member(&env, structP, index, &keyP, &valueP); + + if (env.fault_occurred) + printf("Unable to get struct member %u\n", index); + else { + int const blankCount = strlen(prefix); + const char * prefix2; + const char * blankPrefix; + + casprintf(&blankPrefix, "%*s", blankCount, ""); + + casprintf(&prefix2, "%s Key: ", blankPrefix); + dumpValue(prefix2, keyP); + strfree(prefix2); + + casprintf(&prefix2, "%s Value: ", blankPrefix); + dumpValue(prefix2, valueP); + strfree(prefix2); + + strfree(blankPrefix); + + xmlrpc_DECREF(keyP); + xmlrpc_DECREF(valueP); + } + xmlrpc_env_clean(&env); +} + + + +static void +dumpStruct(const char * const prefix, + xmlrpc_value * const structP) { + + xmlrpc_env env; + unsigned int structSize; + + xmlrpc_env_init(&env); + + structSize = xmlrpc_struct_size(&env, structP); + if (env.fault_occurred) + printf("Unable to get struct size. %s\n", env.fault_string); + else { + unsigned int i; + + printf("%sStruct of %u members:\n", prefix, structSize); + + for (i = 0; i < structSize; ++i) { + const char * prefix1; + + if (i == 0) + prefix1 = strdup(prefix); + else { + int const blankCount = strlen(prefix); + casprintf(&prefix1, "%*s", blankCount, ""); + } + dumpStructMember(prefix1, structP, i); + + strfree(prefix1); + } + } + xmlrpc_env_clean(&env); +} + + + +static void +dumpCPtr(const char * const prefix, + xmlrpc_value * const valueP) { + + xmlrpc_env env; + void * value; + + xmlrpc_env_init(&env); + + xmlrpc_read_cptr(&env, valueP, &value); + + if (env.fault_occurred) + printf("Unable to parse C pointer xmlrpc_value %lx. %s\n", + (unsigned long)valueP, env.fault_string); + else + printf("%sC pointer: '%lux'\n", prefix, (unsigned long)value); + + xmlrpc_env_clean(&env); +} + + + +static void +dumpNil(const char * const prefix, + xmlrpc_value * const valueP) { + + xmlrpc_env env; + + xmlrpc_env_init(&env); + + xmlrpc_read_nil(&env, valueP); + + if (env.fault_occurred) + printf("Internal error: nil value xmlrpc_value %lx " + "is not valid. %s\n", + (unsigned long)valueP, env.fault_string); + else + printf("%sNil\n", prefix); + + xmlrpc_env_clean(&env); +} + + + +static void +dumpI8(const char * const prefix, + xmlrpc_value * const valueP) { + + xmlrpc_env env; + xmlrpc_int64 value; + + xmlrpc_env_init(&env); + + xmlrpc_read_i8(&env, valueP, &value); + + if (env.fault_occurred) + printf("Internal error: unable to extract value of " + "64-bit integer xmlrpc_value %lx. %s\n", + (unsigned long)valueP, env.fault_string); + else + printf("%s64-bit integer: %" XMLRPC_PRId64 "\n", prefix, value); + + xmlrpc_env_clean(&env); +} + + + +static void +dumpUnknown(const char * const prefix, + xmlrpc_value * const valueP) { + + printf("%sDon't recognize value type %u of xmlrpc_value %lx.\n", + prefix, xmlrpc_value_type(valueP), (unsigned long)valueP); + printf("%sCan't print it.\n", prefix); +} + + + +void +dumpValue(const char * const prefix, + xmlrpc_value * const valueP) { + + switch (xmlrpc_value_type(valueP)) { + case XMLRPC_TYPE_INT: + dumpInt(prefix, valueP); + break; + case XMLRPC_TYPE_BOOL: + dumpBool(prefix, valueP); + break; + case XMLRPC_TYPE_DOUBLE: + dumpDouble(prefix, valueP); + break; + case XMLRPC_TYPE_DATETIME: + dumpDatetime(prefix, valueP); + break; + case XMLRPC_TYPE_STRING: + dumpString(prefix, valueP); + break; + case XMLRPC_TYPE_BASE64: + dumpBase64(prefix, valueP); + break; + case XMLRPC_TYPE_ARRAY: + dumpArray(prefix, valueP); + break; + case XMLRPC_TYPE_STRUCT: + dumpStruct(prefix, valueP); + break; + case XMLRPC_TYPE_C_PTR: + dumpCPtr(prefix, valueP); + break; + case XMLRPC_TYPE_NIL: + dumpNil(prefix, valueP); + break; + case XMLRPC_TYPE_I8: + dumpI8(prefix, valueP); + break; + default: + dumpUnknown(prefix, valueP); + } +} diff --git a/trunk/tools/lib/include/dumpvalue.h b/trunk/tools/lib/include/dumpvalue.h new file mode 100644 index 000000000..84be00972 --- /dev/null +++ b/trunk/tools/lib/include/dumpvalue.h @@ -0,0 +1,10 @@ +#ifndef DUMPVALUE_H_INCLUDED +#define DUMPVALUE_H_INCLUDED + +struct _xmlrpc_value; + +void +dumpValue(const char * const prefix, + struct _xmlrpc_value * const valueP); + +#endif diff --git a/trunk/tools/perl_packetsocket/PacketSocket.pm b/trunk/tools/perl_packetsocket/PacketSocket.pm new file mode 100644 index 000000000..37abd986d --- /dev/null +++ b/trunk/tools/perl_packetsocket/PacketSocket.pm @@ -0,0 +1,186 @@ +############################################################################### +# +# This Perl module provides a "packet socket" of the kind that +# XML-RPC For C/C++ uses for its "packet stream" variation on XML-RPC. +# +# This module does not use the XML-RPC For C/C++ libraries. It is +# pure Perl and layers on top of IO::Socket. +# +# By Bryan Henderson, San Jose CA 08.03.12. +# +# Contributed to the public domain by author. +# +############################################################################### + +package IO::PacketSocket; + +use strict; +use warnings; +use Exporter; +use Carp; +use vars qw(@ISA $VERSION @EXPORT); +use Errno qw(:POSIX); +use English; +use IO::Socket::INET + + +$VERSION = 1.00; +@ISA = qw(Exporter IO); + +my ($TRUE, $FALSE) = (1,0); + +my $ESC = chr(0x1B); # ASCII Escape + +my $startDelim = $ESC . 'PKT'; +my $endDelim = $ESC . 'END'; +my $escapedEsc = $ESC . 'ESC'; + + +sub createObject { + my ($class, %args) = @_; + + my $errorRet; + # Description of why we can't create the object. Undefined if + # we haven't given up yet. + + my $packetSocket; + + $packetSocket = {}; + + bless ($packetSocket, $class); + + if (defined($args{STREAMSOCKET})) { + $packetSocket->{STREAMSOCKET} = $args{STREAMSOCKET}; + } else { + $errorRet = "You must specify STREAMSOCKET"; + } + + $packetSocket->{RECEIVE_BUFFER} = ''; + + if ($errorRet && !$args{ERROR}) { + carp("Failed to create PacketSocket object. $errorRet"); + } + if ($args{ERROR}) { + $ {$args{ERROR}} = $errorRet; + } + if ($args{HANDLE}) { + $ {$args{HANDLE}} = $packetSocket; + } +} + + + +sub new { + + my ($class, %args) = @_; + + $args{HANDLE} = \my $retval; + $args{ERROR} = undef; + + $class->createObject(%args); + + return $retval; +} + + + +sub escaped($) { + my ($x) = @_; +#----------------------------------------------------------------------------- +# Return $x, but properly escaped to be inside a packet socket +# packet. +#----------------------------------------------------------------------------- + + $x =~ s{$ESC}{$escapedEsc}g; + + return $x; +} + + + +sub unescaped($) { + my ($x) = @_; +#----------------------------------------------------------------------------- +# Inverse of escaped() +#----------------------------------------------------------------------------- + + $x =~ s{$escapedEsc}{$ESC}g; + + return $x; +} + + + +sub send() { + my($this, $payload) = @_; + + my $retval; + + my $packet = $startDelim . escaped($payload) . $endDelim; + + $retval = $this->{STREAMSOCKET}->send($packet); + + return $retval; +} + + + +sub havePacket() { + + my ($this) = @_; + + return ($this->{RECEIVE_BUFFER} =~ m{$endDelim}); +} + + + +sub validatePacketStart($) { + + my ($packetR) = @_; + + my $delim = substr($$packetR, 0, 4); + + if ($startDelim !~ m{^$delim}) { + die("Received bytes '$delim' are not in any packet. " . + "Sender is probably not using a packet socket"); + } +} + + + +sub recv() { + my ($this, $payloadR) = @_; + + my $gotPacket; + my $eof; + my $escapedPacket; + + $gotPacket = $FALSE; + $eof = $FALSE; + + while (!$gotPacket && !$eof) { + validatePacketStart(\$this->{RECEIVE_BUFFER}); + + $this->{STREAMSOCKET}->recv(my $buffer, 4096, 0); + + if ($buffer eq '') { + $eof = $TRUE; + } else { + $this->{RECEIVE_BUFFER} .= $buffer; + } + + validatePacketStart(\$this->{RECEIVE_BUFFER}); + + if ($this->{RECEIVE_BUFFER} =~ + m{^($startDelim)(.*?)($endDelim)(.*)}s) { + + ($escapedPacket, $this->{RECEIVE_BUFFER}) = ($2, $3); + + $gotPacket = $TRUE; + } + } + + $$payloadR = $eof ? '' : unescaped($escapedPacket); +} + +1; diff --git a/trunk/tools/turbocharger/Makefile b/trunk/tools/turbocharger/Makefile new file mode 100644 index 000000000..ff09f9741 --- /dev/null +++ b/trunk/tools/turbocharger/Makefile @@ -0,0 +1,6 @@ +all: +clean: +distclean: +install: +uninstall: +dep: \ No newline at end of file diff --git a/trunk/tools/turbocharger/README b/trunk/tools/turbocharger/README new file mode 100644 index 000000000..4613bfd20 --- /dev/null +++ b/trunk/tools/turbocharger/README @@ -0,0 +1,37 @@ +XML-RPC Turbocharger (Experimental) +=================================== + +This a hacked copy of mod_gzip. In addition to the usual "gzip" encoding, +it also handles "deflate" encoding. + +When used in conjuction with the xmlrpc-c client, this should reduce your +outbound XML-RPC network traffic by an amazing amount--compression ratios +of 10:1 and 30:1 are not unheard of. If you're clever, you should be able +to use this with just about any Apache-based XML-RPC server. + +You can find the standard distribution of mod_gzip here: + + http://www.remotecommunications.com/apache/mod_gzip/ + +The hacked distribution is installed and used in exactly the same fashion +as the regular distribution. There's one extra logging directive available: + + %{mod_gzip_compression_format}n Compression format chosen by client. + +Go read the mod_gzip documentation; it should all make sense. + +If you want to discuss the XML-RPC Turbocharger, please sign up for the +xmlrpc-c-devel mailing list at: + + http://xmlrpc-c.sourceforge.net/ + +This code is highly experimental, and may do some strange things. You'll +probably need to screw around with mod_gzip for a while until you get +everything to work. Don't run this on your production web server, OK? + +Eric Kidd +eric.kidd@pobox.com + +P.S. The Turbocharger appears to dump core in mod_gzip decides to serialize +a large response to disk. Do you see what I mean by "experimental" and +"don't run this on your production web server"? :-) diff --git a/trunk/tools/turbocharger/mod_gzip.c b/trunk/tools/turbocharger/mod_gzip.c new file mode 100644 index 000000000..3d74553a3 --- /dev/null +++ b/trunk/tools/turbocharger/mod_gzip.c @@ -0,0 +1,9843 @@ +/* ==================================================================== + * Copyright (c) 1995-2000 The Apache Group. 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. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * 4. The names "Apache Server" and "Apache Group" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY + * EXPRESSED 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 APACHE GROUP OR + * ITS 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Group and was originally based + * on public domain software written at the National Center for + * Supercomputing Applications, University of Illinois, Urbana-Champaign. + * For more information on the Apache Group and the Apache HTTP server + * project, please see . + * + */ + +/* + * mod_gzip.c + * + * Apache gzip compression module. + * + * This module adds 'on the fly' compression of HTTP content to + * any Apache Web Server. It uses the IETF Content-encoding standard(s). + * + * It will compress both static files and the output of any CGI + * program inclding shell scripts, perl scripts, executables, + * PHP used as CGI, etc. + * + * There is NO client-side software required for using this module + * other than any fully HTTP 1.1 compliant user agent. + * + * Any fully HTTP 1.1 compliant user agent will be able to receive and + * automatically decode the compressed content. + * + * All fully HTTP 1.1 compliant user agents that are capable of receiving + * gzip encoded data will indicate their ability to do so by adding the + * standard "Accept-Encoding: gzip" field to the inbound request header. + * + * This module may be compiled as a stand-alone external 'plug-in' + * or be compiled into the Apache core server as a 'built-in' module. + * + * Sponsor: Remote Communications, Inc. http://www.RemoteCommunications.com/ + * Authors: Konstantin Balashov, Alex Kosobrukhov and Kevin Kiley. + * Contact: info@RemoteCommunications.com + * + * Initial public release date: 13-Oct-2000 + * + * Miscellaneous release notes: + * + * THIS IS A COMPLETELY SELF-CONTAINED MODULE. MOD_GZIP.C IS THE + * ONY SOURCE CODE FILE THERE IS AND THERE ARE NO MODULE SPECIFIC + * HEADER FILES OR THE NEED FOR ANY 3RD PARTY COMPRESSION LIBRARIES. + * ALL OF THE COMPRESSION CODE NEEDED BY THIS MODULE IS CONTAINED + * WITHIN THIS SINGLE SOURCE FILE. + * + * Many standard compression libraries are not designed or optimized + * for use as real-time compression codecs nor are they guaranteed + * to be 'thread-safe'. The internal compression code used by mod_gzip + * is all of those things. It is a highly-optimized and thread-safe + * implementation of the standard LZ77 + Huffman compression + * technique that has come to be known as GZIP. + * + * MOD_GZIP LOG FORMATS... + * + * mod_gzip makes a number of statistical items for each transaction + * available through the use of Apache's 'LogFormat' directives which + * can be specified in the httpd.conf Apache config file + * + * mod_gzip uses the standard Apache NOTES interface to allow compression + * information to be added to the Apache Web Server log files. + * + * Standard NOTES may be added to Apache logs using the following syntax + * in any LogFormat directive... + * * %...{Foobar}n: The contents of note "Foobar" from another module. + * + * Additional notes about logging compression information... + * + * The Apache LogFormat directive is unable to actually display + * the 'percent' symbol since it is used exclusively as a 'pickup' + * character in the formatting string and cannot be 'escaped' so + * all logging of compression ratios cannot use the PERCENT symbol. + * Use ASCII 'pct.' designation instead for all PERCENTAGE values. + * + * Example: This will display the compression ratio percentage along + * with the standard CLF ( Common Log Format ) information... + * + * Available 'mod_gzip' compression information 'notes'... + * + * %{mod_gzip_result}n - A short 'result' message. Could be OK or DECLINED, etc. + * %{mod_gzip_input_size}n - The size ( in bytes ) of the requested object. + * %{mod_gzip_output_size}n - The size ( in bytes ) of the compressed version. + * %{mod_gzip_compression_ration}n - The compression rate achieved. + * + * LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info1 + * LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_result}n In:%{mod_gzip_input_size}n Out:%{mod_gzip_output_size}n:%{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info2 + * + * If you create your own custom 'LogFormat' lines don't forget that + * the entire LogFormat line must be encased in quote marks or you + * won't get the right results. The visible effect of there not being + * and end-quote on a LogFormat line is that the NAME you are choosing + * for the LogFormat line is the only thing that will appear in the + * log file that tries to use the unbalanced line. + * + * Also... when using the %{mod_gzip_xxxxx}n note references in your + * LogFormat line don't forget to add the lowercase letter 'n' after + * the closing bracket to indicate that this is a module 'note' value. + * + * Once a LogFormat directive has been added to your httpd.conf file + * which displays whatever level of compression information desired + * simply use the 'name' associated with that LogFormat line in + * the 'CustomLog' directive for 'access.log'. + * + * Example: The line below simply changes the default access.log format + * for Apache to the special mog_gzip information record defined above... + * CustomLog logs/access.log common + * + * CustomLog logs/access.log common_with_mod_gzip_info2 + * + * Using the 'common_with_mod_gzip_info1' LogFormat line for Apache's + * normal access.log file produces the following results in the access.log + * file when a gigantic 679,188 byte online CD music collection HTML + * document called 'music.htm' is requested and the Server delivers the + * file via mod_gzip compressed 93 percent down to only 48,951 bytes... + * + * 216.20.10.1 [12/Oct...] "GET /music.htm HTTP/1.1" 200 48951 mod_gzip: 93pct. + * + * The line below shows what will appear in the Apache access.log file + * if the more detailed 'common_with_mod_gzip_info2' LogFormat line is used. + * The line has been intentionally 'wrapped' for better display below + * but would normally appear as a single line entry in access.log. + * + * 216.20.10.1 [12/Oct...] "GET /music.htm HTTP/1.1" 200 48951 + * mod_gzip: OK In:679188 Out:48951:93pct. + * + * The 'OK' result string shows that the compression was successful. + * The 'In:' value is the size (in bytes) of the requested file and + * the 'Out:' value is the size (in bytes) after compression followed + * by a colon and a number showing that the document was compressed + * 93 percent before being returned to the user. + * + * Please NOTE that if you add any ASCII strings to your LogFormat + * string then they will appear in your log file regardless of + * whether this module was actually 'called' to process the + * transaction or not. If the module was not called to handle the + * transaction then the places where the statistical information + * associated with the 'NOTES' references would normally appear + * will be filled in with 'dashes' to denote 'no value available'. + * + * MOD_GZIP RUNTIME DEBUG... + * + * If you set your default Apache logging level to 'LogLevel debug' + * in your httpd.conf file then this module will add certain + * diagnostic debug messages to your error log for each and every + * transaction that is actually passed to the module. + * + * If Apache does not 'call' this module to handle a particular + * transaction then no special log information will appear in + * your error log(s) for that transaction. + * + * MOD_GZIP CONFIGURATION DIRECTIVES... + * + * The section that follows is a sample mod_gzip configuration + * section that will provide basic compression of all static + * TEXT and HTML files as well as dynamic compression of most + * standard CGI including Shell scripts, Perl, PHP, etc. + * + * The configuration directives themselves are documented in more + * detail in the README and INSTALL files that accompany this module. + * + * You should be able to simply 'cut and paste' the follwing section + * directly into the BOTTOM of your current httpd.conf Apache + * configuration file and be able to start using mod_gzip immediately. + * + +# +# MOD_GZIP Configuration Directives +# +# All you should have to do to get up and running using +# mod_gzip with some basic STATIC and DYNAMIC compression +# capabilites is copy the mod_gzip dynamic library to your +# ../modules directory and then add this entire example +# configuration section to the BOTTOM of your httpd.conf file. +# +# Add this entire section including all lines down to where +# it says '# End of MOD_GZIP Configuration Directives'. +# +# The LoadModule command is included here for clarity +# but you may want to move it the the BOTTOM of your +# current LoadModule list in httpd.conf. +# +# Change the 'mod_gzip_temp_dir' to the name of a directory +# on your machine where temporary workfiles can be created +# and destroyed. This directory MUST be readable/writable +# by the Server itself while it is running. If the directory +# does not exist you must create it yourself with the right +# permissions before running the Server. +# +# If no 'mod_gzip_temp_dir' is specified then the default location +# for temporary workfiles will be 'ServerRoot' directory. +# +# The special mod_gzip log formats are, of course, optional. +# +# You must, of course, load the right module name for your OS +# so make sure the correct 'LoadModule' command is uncommented +# directly below... + +# Load Win32 module... +LoadModule gzip_module modules/ApacheModuleGzip.dll + +# Load UNIX module... +# LoadModule gzip_module modules/mod_gzip.so + +LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info1 +LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_result}n In:%{mod_gzip_input_size}n Out:%{mod_gzip_output_size}n:%{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info2 + +# NOTE: This 'CustomLog' directive shows how to set your access.log file +# to use the mod_gzip format but please remember that for every 'CustomLog' +# directive that Apache finds in httpd.conf there will be corresponding +# line of output in the access.log file. If you only want ONE line of +# results in access.log for each transaction then be sure to comment out +# any other 'CustomLog' directives so that this is the only one. + +CustomLog logs/access.log common_with_mod_gzip_info2 + +# Runtime control directives... + +mod_gzip_on Yes +mod_gzip_do_cgi Yes +mod_gzip_do_static_files Yes +mod_gzip_minimum_file_size 300 +mod_gzip_maximum_inmem_size 60000 +mod_gzip_keep_workfiles No +mod_gzip_temp_dir "C:/Program Files/Apache Group/Apache/temp" + +# Item lists... +# +# Item names can be any one of the following... +# +# cgi-script - A valid 'handler' name +# text/* - A valid MIME type name ( '*' wildcard allowed ) +# .phtml - A valid file type extension + +# Dynamic items... +# +# NOTE: FOR NOW ALL DYNAMIC ITEMS SHOULD BE +# DECLARED BEFORE ANY STATIC ITEMS TO PREVENT +# PICKUP CONFLICTS. IF YOU USE !cgi-script +# BE SURE IT IS DECLARED BEFORE ANY text/* +# MIME TYPE ENTRIES. +# +# The items listed here are the types of dynamic +# output that will be compressed... +# +# Dynamic items MUST have the "!" BANG character +# on the front of the item name. +# +mod_gzip_item_include !cgi-script +mod_gzip_item_include !.php +mod_gzip_item_include !.php3 +mod_gzip_item_include !.phtml + +# Static items... +# +# The items listed here are the types of static +# files that will be compressed... +# +# NOTE: FOR NOW ALL STATIC INCLUDES MUST +# COME AFTER DYNAMIC INCLUDES TO PREVENT +# PICKUP CONFLICTS +# +mod_gzip_item_include text/* + +# Uncomment this line to compress graphics +# when graphics compression is allowed... +#mod_gzip_item_include image/* + + +# Exclusions... MIME types and FILE types... +# +# The items listed here will be EXCLUDED from +# any attempt to apply compression... +# +mod_gzip_item_exclude .js +mod_gzip_item_exclude .css + +# Exclusions... HTTP support levels... +# +# By specifying a certain minimum level of HTTP support +# certain older user agents ( browsers ) can be +# automatically excluded from receiving compressed data. +# +# The item value should be in the same HTTP numeric format +# that Apache uses to designate HTTP version levels. +# +# 1001 = HTTP/1.1 +# +# So 'mod_gzip_min_http 1001' means that a requesting +# user agent ( browser ) must report a minimum HTTP support +# level of 1.1 or it will not receive any compressed data. +# +mod_gzip_min_http 1001 + +# Debugging... +# +# If your Apache 'LogLevel' is set to 'debug' then +# mod_gzip will add some diagnostic and compression +# information to your error.log file for each request +# that is processed by mod_gzip. +# +# LogLevel debug + +# End of MOD_GZIP Configuration Directives + + * End of inline comments + */ + +#include +/* + * Apache headers... + */ + +#define CORE_PRIVATE + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_main.h" +#include "http_protocol.h" +#include "util_script.h" + +/* + * Add this header for ap_server_root[ MAX_STRING_LEN ] global... + * + * #include "http_conf_globals.h" + * + * ...or just include what we need from http_conf_globals.h + * since that is, in fact, only 1 item at this time. + */ +extern API_VAR_EXPORT char ap_server_root[ MAX_STRING_LEN ]; + +/* + * Add this header to get 'ap_update_mtime()' prototype... + * + * #include "http_request.h" + * + * ...or just include what we need from http_request.h since + * that is, in fact, only 1 item at this time. + */ +extern API_EXPORT(time_t) +ap_update_mtime(request_rec *r, time_t dependency_mtime); + +/* + * Version information... + * + * Since this product is 'married' to the ASF Apache Web Server + * the version numbers should always 'match' the changing + * version numbers of Apache itself so users can be sure + * they have the 'right' module. This allows us to move the + * version numbers either backwards or forwards in case issues + * arise which require specific versions of mod_gzip for + * specific versions of Apache. + * + * The original code was first tested against the Apache 1.3.14 + * release but should be compatible with the entire 1.3.x series. + * If earlier 1.3.x versions of Apache required special versions + * then the mod_gzip version number will still match the Apache + * version number ( As in... mod_gzip v1.3.12.1, if needed ). + * + * If a special version is required for Apache 2.0 then the + * version number(s) will change to match release numbers in + * that series. ( As in... mod_gzip v 2.0.1.1, etc. ). + * + * The first 3 numbers of the version are always the equivalent + * Apache release numbers. The fourth number is always the actual + * mod_gzip 'build' number for that version of Apache. + */ + +char mod_gzip_version[] = "1.3.14.5"; /* Global version string */ + +/* + * Declare the NAME by which this module will be known. + * This is the NAME that will be used in LoadModule command(s). + */ +extern module MODULE_VAR_EXPORT gzip_module; + +/* + * Allow this module to 'read' config information from + * ( and interact with ) the 'real' mod_cgi module... + */ +extern module cgi_module; + +/* + * Some compile-time code inclusion switches... + */ + +/* + * Turn MOD_GZIP_ALLOWS_INTERNAL_COMMANDS switch ON to allow + * information requests to be sent via any standard browser. + */ + +#define MOD_GZIP_ALLOWS_INTERNAL_COMMANDS + +/* + * Turn MOD_GZIP_USES_APACHE_LOGS switch ON to include the + * code that can update Apache logs with compression information. + */ + +#define MOD_GZIP_USES_APACHE_LOGS + + /* + * Turn MOD_GZIP_USES_AP_SEND_MMAP switch ON to use the + * ap_send_mmap() method for transmitting data. If this + * switch is OFF then the default is to use ap_rwrite(). + * This might need to be platform specific at some point. + */ + +#define MOD_GZIP_USES_AP_SEND_MMAP + +/* + * Turn MOD_GZIP_DEBUG1 switch ON for verbose diags. + * This is normally OFF by default and should only be + * used for diagnosing problems. The log output is + * VERY detailed and the log files will be HUGE. + */ + +/* +#define MOD_GZIP_DEBUG1 +*/ + +/* + * Some useful instance globals... + */ + +#ifndef MOD_GZIP_MAX_PATH_LEN +#define MOD_GZIP_MAX_PATH_LEN 512 +#endif + +char mod_gzip_temp_dir[ MOD_GZIP_MAX_PATH_LEN + 2 ]; + +long mod_gzip_iusn = 0; /* Instance Unique Sequence Number */ + +long mod_gzip_maximum_inmem_size = 60000L; +long mod_gzip_minimum_file_size = 300L; + +#ifdef _WIN32 +char mod_gzip_dirsep[]="\\"; /* Dir separator is a backslash for Windows */ +#else /* !_WIN32 */ +char mod_gzip_dirsep[]="/"; /* Dir separator is a forward slash for UNIX */ +#endif /* _WIN32 */ + +/* + * The Compressed Object Cache control structure... + */ + +#define MOD_GZIP_SEC_ONE_DAY 86400 /* Total seconds in one day */ +#define MOD_GZIP_SEC_ONE_HR 3600 /* Total seconds in one hour */ + +#define MOD_GZIP_DEFAULT_CACHE_SPACE 5 +#define MOD_GZIP_DEFAULT_CACHE_MAXEXPIRE MOD_GZIP_SEC_ONE_DAY +#define MOD_GZIP_DEFAULT_CACHE_EXPIRE MOD_GZIP_SEC_ONE_HR +#define MOD_GZIP_DEFAULT_CACHE_LMFACTOR (0.1) +#define MOD_GZIP_DEFAULT_CACHE_COMPLETION (0.9) + +struct mod_gzip_cache_conf { + + const char *root; /* The location of the cache directory */ + off_t space; /* Maximum cache size (in 1024 bytes) */ + char space_set; + time_t maxexpire; /* Maximum time to keep cached files (secs) */ + char maxexpire_set; + time_t defaultexpire; /* Default time to keep cached file (secs) */ + char defaultexpire_set; + double lmfactor; /* Factor for estimating expires date */ + char lmfactor_set; + time_t gcinterval; /* Garbage collection interval (secs) */ + char gcinterval_set; + int dirlevels; /* Number of levels of subdirectories */ + char dirlevels_set; + int dirlength; /* Length of subdirectory names */ + char dirlength_set; +}; + +/* + * The Inclusion/Exclusion map item structure... + */ + +#define MOD_GZIP_IMAP_MAXNAMES 256 +#define MOD_GZIP_IMAP_MAXNAMELEN 90 + +#define MOD_GZIP_IMAP_ISMIME 1 +#define MOD_GZIP_IMAP_ISEXT 2 +#define MOD_GZIP_IMAP_ISHANDLER 3 + +#define MOD_GZIP_IMAP_STATIC1 9001 +#define MOD_GZIP_IMAP_DYNAMIC1 9002 +#define MOD_GZIP_IMAP_DECLINED1 9003 + +typedef struct { + + int include; /* 1=Include 0=Exclude */ + int type; /* _ISMIME, _ISEXT, _ISHANDLER, etc. */ + int action; /* _STATIC1, _DYNAMIC1, etc. */ + + char name[ MOD_GZIP_IMAP_MAXNAMELEN + 2 ]; + +} mod_gzip_imap; + +/* + * The primary module configuration record... + */ + +typedef struct { + + struct mod_gzip_cache_conf cache; /* Compressed Object Cache control */ + + int req; /* 1=mod_gzip handles requests 0=No */ + char req_set; /* Mirrors the 'req' flag */ + int do_static_files; /* 1=Yes 0=No */ + int do_cgi; /* 1=Yes 0=No */ + int keep_workfiles; /* 1=Keep workfiles 0=No */ + int min_http; /* Minimum HTTP level ( 1001=HTTP/1.1 ) */ + long minimum_file_size; /* Minimum size in bytes for compression attempt */ + long maximum_inmem_size; /* Maximum size in bytes for im-memory compress */ + + /* Inclusion/Exclusion list(s)... */ + + int imap_total_entries; + + mod_gzip_imap imap[ MOD_GZIP_IMAP_MAXNAMES + 1 ]; + +} mod_gzip_conf; + +/* + * The GZP request control structure... + */ + +#define GZIP_FORMAT (0) +#define DEFLATE_FORMAT (1) + +typedef struct _GZP_CONTROL { + + int decompress; /* 0=Compress 1=Decompress */ + + int compression_format; /* GZIP_FORMAT or DEFLATE_FORMAT */ + + /* Input control... */ + + int input_ismem; /* Input source is memory buffer, not file */ + char *input_ismem_ibuf; /* Pointer to input memory buffer */ + long input_ismem_ibuflen; /* Total length of input data */ + + char input_filename[ MOD_GZIP_MAX_PATH_LEN + 2 ]; /* Input file name */ + + /* Output control... */ + + int output_ismem; /* Output source is memory buffer, not file */ + char *output_ismem_obuf; /* Pointer to output memory buffer */ + long output_ismem_obuflen; /* Maximum length of output data buffer */ + + char output_filename[ MOD_GZIP_MAX_PATH_LEN + 2 ]; /* Output file name */ + + /* Results... */ + + int result_code; /* Result code */ + long bytes_out; /* Total number of compressed output bytes */ + +} GZP_CONTROL; + +/* + * Forward prototypes for internal routines... + */ + +int gzp_main( GZP_CONTROL *gzp ); /* Primary GZP API entry point */ + +int mod_gzip_request_handler( request_rec *r ); +int mod_gzip_cgi_handler( request_rec *r ); +int mod_gzip_static_file_handler( request_rec *r ); +int mod_gzip_prepare_for_dynamic_call( request_rec *r ); +int mod_gzip_imap_show_items( mod_gzip_conf *mgc ); +int mod_gzip_get_action_flag( request_rec *r, mod_gzip_conf *conf ); +int mod_gzip_ismatch( char *s1, char *s2, int len1, int haswilds ); + +FILE *mod_gzip_open_output_file( +request_rec *r, +char *output_filename, +int *rc +); + +int mod_gzip_create_unique_filename( +mod_gzip_conf *mgc, +char *target, +int targetmaxlen +); + +int mod_gzip_encode_and_transmit( +request_rec *r, +char *source, +int source_is_a_file, +long input_size, +int nodecline +); + + +#ifdef MOD_GZIP_ALLOWS_INTERNAL_COMMANDS + +int mod_gzip_send_html_command_response( +request_rec *r, /* Request record */ +char *tmp, /* Response to send */ +char *ctype /* Content type string */ +); + +#endif /* MOD_GZIP_ALLOWS_INTERNAL_COMMANDS */ + +/* + * Module routines... + */ + +#ifdef MOD_GZIP_DEBUG1 + +void mod_gzip_printf( const char *fmt, ... ) +{ + int l; + FILE *log; + + va_list ap; + + char logname[256]; + char log_line[4096]; + + /* Start... */ + + /* If UNIX then mod_gzip_dirsep = '/' Backward slash */ + /* If _WIN32 then mod_gzip_dirsep = '\' Forward slash */ + + #ifdef FUTURE_USE + /* + For now we need both startup and runtime diags in the same + log so it all goes to ServerRoot. 'mod_gzip_temp_dir' name + isn't even valid until late in the startup process so we + have to write to ServerRoot anyway until temp dir is known. + */ + if ( strlen(mod_gzip_temp_dir) ) /* Use temp directory ( if specified )... */ + { + sprintf( logname, "%s%smod_gzip.log", mod_gzip_temp_dir, mod_gzip_dirsep ); + } + else /* Just use 'ap_server_root' Apache ServerRoot directory... */ + { + sprintf( logname, "%s%smod_gzip.log", ap_server_root, mod_gzip_dirsep ); + } + #endif /* FUTURE_USE */ + + /* Just use ServerRoot for now... */ + sprintf( logname, "%s%smod_gzip.log", ap_server_root, mod_gzip_dirsep ); + + log = fopen( logname,"a" ); + + if ( !log ) /* Log file did not open... */ + { + /* Just turn and burn... */ + + return; /* Void return */ + } + + /* Get the variable parameter list... */ + + va_start( ap, fmt ); + + l = vsprintf(log_line, fmt, ap); + + /* See if we need to add LF... */ + + if ( l > 0 ) + { + if ( log_line[l-1] != '\n' ) + { + log_line[l]='\n'; + l++; + } + + log_line[l+1] = 0; + } + + fprintf( log, "%s", log_line ); + + fclose( log ); + + va_end(ap); /* End session */ + + return; /* Void return */ + +}/* End of log_d() */ + +void mod_gzip_hexdump( char *buffer, int buflen ) +{ + int i,o1,o2,o3; + + int len1; + int len2; + + char ch1; + char ch2; + char s[40]; + char l1[129]; + char l2[129]; + char l3[300]; + + long offset1=0L; + + /* Start... */ + + o1=0; + o2=0; + o3=0; + + l1[0] = 0; + l2[0] = 0; + l3[0] = 0; + + offset1 = 0; + + for ( i=0; i 126) ch2 = DUMPIT_LAPOSTROPHE; + else if ( ch1 == 37 ) ch2 = DUMPIT_ASTERISK; /* Mask PERCENT for UNIX */ + else if ( ch1 == 92 ) ch2 = DUMPIT_ASTERISK; /* Mask BACKSLASH for UNIX */ + else ch2 = ch1; + + /* ENDIF on MASK_ALL_NON_PRINTABLE_CHARS */ + #endif + + l2[o2++] = ch2; + + sprintf( s, "%02X", ch1 ); + + if ( strlen(s) > 2 ) s[2]=0; /* Prevent overflow */ + + len1 = strlen(s); + len2 = strlen(l1); + + if ( strlen(l1) < (sizeof(l1) - (len1+1)) ) + { + strcat( l1, s ); + strcat( l1, " " ); + } + + if ( o2 >= 16 ) + { + l2[o2]=0; + + mod_gzip_printf( "%6lu| %-49.49s| %-16.16s |\n", offset1, l1, l2 ); + + offset1 += o2; + + o1=0; + o2=0; + o3=0; + + l1[0] = 0; + l2[0] = 0; + l3[0] = 0; + } + + }/* End 'for( i=0; i 0 ) + { + l2[o2]=0; + + mod_gzip_printf( "%6lu| %-49.49s| %-16.16s |\n", offset1, l1, l2 ); + + offset1 += o2; + + o1 = o2 = o3 = 0; + + l1[0] = 0; + l2[0] = 0; + l3[0] = 0; + } + +}/* End of mod_gzip_hexdump() */ + +#endif /* MOD_GZIP_DEBUG1 */ + +static void mod_gzip_init( server_rec *server, pool *p ) +{ + /* + * The module initialization procedure... + */ + + FILE *fh1; + char filename[ 512 ]; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_init()"; + #endif + + mod_gzip_conf *mgc; + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry...\n", cn ); + #endif + + /* + * Set some instance specific globals... + * + * The default 'temp' dir, lacking an httpd.conf config file + * override, is the Apache 'ServerRoot'. Don't assume that /logs + * dir exists because some Apache installations just use syslog + * or stderr as their log output target. + * + * On most Apache installations 'ServerRoot' is automatically + * readable/writable by the Server while it is running. + * + * On systems where it is not there MUST be an override + * in the httpd.conf file. + * + * See the comments regarding the 'mod_gzip_temp_dir' directive + * in the httpd.conf configuration file. + */ + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(server->module_config, &gzip_module); + + /* Make sure we can read/write the temp directory... */ + + sprintf( filename, "%s%smod_gzip.id", mgc->cache.root, mod_gzip_dirsep ); + + fh1 = fopen( filename, "wb" ); + + if ( !fh1 ) /* Write an ERROR to console and to log(s)... */ + { + fprintf( stderr, "mod_gzip: Cannot read/write dir/file [%s]\n",filename); + fprintf( stderr, "mod_gzip: Make sure the directory exists and that the Server\n"); + fprintf( stderr, "mod_gzip: has read/write permission(s) for the directory.\n"); + fprintf( stderr, "mod_gzip: See the 'mod_gzip_temp_dir' configuration notes.\n"); + + /* This is a startup ERROR and has to be fixed... */ + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_ERR, server, + "mod_gzip: Cannot read/write dir/file [%s]", filename); + ap_log_error( "",0,APLOG_NOERRNO|APLOG_ERR, server, + "mod_gzip: Make sure the directory exists and that the Server"); + ap_log_error( "",0,APLOG_NOERRNO|APLOG_ERR, server, + "mod_gzip: has read/write permission(s) for the directory."); + ap_log_error( "",0,APLOG_NOERRNO|APLOG_ERR, server, + "mod_gzip: See the 'mod_gzip_temp_dir' configuration notes."); + } + else /* File opened OK... just add some data and close it... */ + { + /* + * Since this is just a MARK file we could simply wipe + * it out but might as well print the actual version + * number into it and leave it there in case there is + * any question about which version is actually running. + */ + + fprintf( fh1, "mod_gzip version %s\n", mod_gzip_version ); + fclose( fh1 ); + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_imap_show_items( (mod_gzip_conf *) mgc ); /* Show item list */ + mod_gzip_printf( "%s: Exit > return( void ) >\n", cn ); + mod_gzip_printf( "\n" ); /* Separator for log file */ + #endif + +}/* End of mod_gzip_init() */ + +int mod_gzip_strnicmp( char *s1, char *s2, int len1 ) +{ + /* Behaves just like strnicmp() but IGNORES differences */ + /* between FORWARD or BACKWARD slashes in a STRING... */ + /* Also uses straight pointers and avoids stdlib calls. */ + + int i; + char ch1; + char ch2; + + /* WARNING! We MUST have a check for 'NULL' on the pointer(s) */ + /* themselves or we might GP ( like NETSCAPE does ) */ + /* if a 'NULL' pointer is passed to this routine... */ + + if ( ( s1 == 0 ) || ( s2 == 0 ) ) + { + /* SAFETY! If pointer itself if NULL */ + /* don't enter LOOP or NETSCAPE will GP... */ + + return( 1 ); /* Return '1' for NOMATCH... */ + } + + for ( i=0; i 96 ) ch1 -= 32; + if ( ch2 > 96 ) ch2 -= 32; + + if ( ch1 == '/' ) ch1 = '\\'; + if ( ch2 == '/' ) ch2 = '\\'; + + if ( ch1 != ch2 ) return( 1 ); /* No match! */ + + s1++; + s2++; + + }/* End 'i' loop */ + + /* If we make it to here then everything MATCHED! */ + + return( 0 ); /* MATCH! */ + +}/* End mod_gzip_strnicmp() */ + +extern API_VAR_EXPORT module *top_module; + +struct _table { + array_header a; +#ifdef MAKE_TABLE_PROFILE + void *creator; +#endif +}; +typedef struct _table _table; + +const char *mod_gzip_isscript( request_rec *r, _table *t, const char *key) +{ + /* + * Get a 'handler' name for a MIME type right out of + * the Apache 'Action' table(s)... + * + * Example: + * + * If "key" is "applications/x-httpd-php3" + * then this search will return "/php3/php.exe" + * or whatever the equivalent PHP executable + * pathname is as specified by an 'Action' statement + * in the httpd.conf configuration file. + * + * This pathname might still have 'aliases' in it + * so we will have to consult with mod_alias + * following this call and get any aliases converted. + */ + + table_entry *elts = + (table_entry *) t->a.elts; + int i; + + char cn[]="mod_gzip_isscript()"; + + /* + * Start... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry...\n",cn); + mod_gzip_printf( "%s: key=[%s]\n",cn,key ); + #endif + + if ( key == NULL ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 'key' has no length\n",cn); + mod_gzip_printf( "%s: Exit > return( NULL ) >\n",cn); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: Search key is NULL.",cn); + } + + return NULL; + } + + for (i = 0; i < t->a.nelts; ++i) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( + "%s: i=%4.4d Comparing [%s] with elts.key[%s].val[%s]\n", + cn, i, key, elts[i].key, elts[i].val ); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: i=%4.4d Comparing [%s] with elts.key[%s].val[%s]", + cn, i, key, elts[i].key, elts[i].val ); + } + + if (!strcasecmp(elts[i].key, key)) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: MATCH FOUND!",cn); + mod_gzip_printf( "%s: Exit > return(%s) >\n",cn,elts[i].val); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: MATCH FOUND...",cn); + } + + return elts[i].val; + } + + }/* End 'i' loop */ + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: NO MATCH FOUND...",cn); + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: NO MATCH FOUND!\n",cn); + mod_gzip_printf( "%s: Exit > return( NULL ) >\n",cn); + #endif + + return NULL; + +}/* End of 'mod_gzip_isscript()' */ + +typedef struct { + table *action_types; /* Added with Action... */ + char *scripted[METHODS]; /* Added with Script... */ + array_header *xmethods; /* Added with Script -- extension methods */ +} mod_actions_local_config; + +int mod_gzip_run_mod_action( request_rec *r ) +{ + module *modp; + int count=0; + int pass=0; + + mod_actions_local_config *mod_actions_conf; + + const char *t=0; + const char *action=0; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_run_mod_action()"; + #endif + + #ifdef MOD_GZIP_FUTURE_USE + const handler_rec *handp; + #endif + + /* Currently 9 possible 'event' handlers. */ + /* Actual content handler in a module is 'extra'. */ + #define MOD_GZIP_NMETHODS 9 + + /* + * Start... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry...\n",cn); + mod_gzip_printf( "%s: *IN: r->uri =[%s]\n", cn, r->uri ); + mod_gzip_printf( "%s: *IN: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); + mod_gzip_printf( "%s: *IN: r->filename =[%s]\n", cn, r->filename ); + mod_gzip_printf( "%s: r->content_type =[%s]\n", cn,r->content_type); + mod_gzip_printf( "%s: r->handler =[%s]\n", cn,r->handler); + #endif + + for ( modp = top_module; modp; modp = modp->next ) + { + /* modp->name list will look like this... */ + /*--------------------*/ + /* 00 [mod_gzip.c] */ + /* 01 [mod_isapi.c] */ + /* 02 [mod_setenv.c] */ + /* 02 [mod_actions.c] */ + /* ............... */ + /* ............... */ + /* 18 [mod_so.c] */ + /* 19 [http_core.c] <- Always bottom of list (last one called) */ + /*--------------------*/ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: count=%4.4d modp = %10.10ld modp->name=[%s]\n", + cn,count,(long)modp, modp->name ); + #endif + + if ( mod_gzip_strnicmp( (char *) modp->name, "mod_actions.c", 13 ) == 0 ) + { + + /* Module information... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ++++++++++ MODULE FOUND!...\n",cn); + mod_gzip_printf( "%s: ++++++++++ modp->module_index = %d\n",cn,(int)modp->module_index); + #endif + + /* Get a pointer to the module configuration data... */ + + mod_actions_conf = (mod_actions_local_config *) + ap_get_module_config(r->per_dir_config, modp ); + + /* Get script name... */ + + /* Make 2 passes if necessary. If we don't find a */ + /* program name associated with MIME type first */ + /* then punt and look for a program name associated */ + /* with the r->handler name such as [php-script] */ + + for ( pass = 0; pass < 2; pass++ ) + { + if ( pass == 0 ) /* Check r->content_type first */ + { + /* This is the first pass... */ + + /* Set 'action' search key to 'r->content_type' */ + /* so we search for [application/x-httpd-php3] */ + + action = r->content_type; + } + else if ( pass == 1 ) /* Try r->handler */ + { + /* This is the second pass... */ + + /* Set 'action' search key to 'r->handler' */ + /* so we search for [php-script] */ + + action = r->handler; + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ++++++++++ pass =%d\n", cn,pass); + mod_gzip_printf( "%s: ++++++++++ t =[%s]\n",cn,t); + mod_gzip_printf( "%s: ++++++++++ r->content_type =[%s]\n",cn,r->content_type); + mod_gzip_printf( "%s: ++++++++++ r->handler =[%s]\n",cn,r->handler); + mod_gzip_printf( "%s: ++++++++++ action =[%s]\n",cn,action); + mod_gzip_printf( "%s: ++++++++++ r->filename =[%s]\n",cn,r->filename); + mod_gzip_printf( "%s: ++++++++++ r->uri =[%s]\n",cn,r->uri); + mod_gzip_printf( "%s: ++++++++++ Call mod_gzip_isscript()...\n",cn); + #endif + + t = + mod_gzip_isscript( + r, + (_table *) mod_actions_conf->action_types, + action ? action : ap_default_type(r) + ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ++++++++++ Back mod_gzip_isscript()...\n",cn); + mod_gzip_printf( "%s: ++++++++++ t =[%s]\n",cn,t); + mod_gzip_printf( "%s: ++++++++++ action =[%s]\n",cn,action); + #endif + + if ( t ) + { + /* + * If a program name was found then make it r->filename + * and r->uri will become the input name for the program + */ + + r->filename = ap_pstrdup(r->pool,t); + + break; + } + + }/* End 'for( pass )' loop */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ++++++++++ r->filename=[%s]\n",cn,r->filename); + mod_gzip_printf( "%s: ++++++++++ r->uri =[%s]\n",cn,r->uri); + #endif + + /* If a handler was found we are DONE... */ + + if ( t ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Handler was found...\n",cn); + mod_gzip_printf( "%s: Exit > return( OK ) >\n",cn); + #endif + + return OK; + } + + #ifdef MOD_GZIP_FUTURE_USE + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ++++++++++ METHODS\n",cn); + mod_gzip_printf( "%s: ++++++++++ modp->translate_handler = %ld\n",cn,(long)modp->translate_handler); + mod_gzip_printf( "%s: ++++++++++ modp->ap_check_user_id = %ld\n",cn,(long)modp->ap_check_user_id); + mod_gzip_printf( "%s: ++++++++++ modp->auth_checker = %ld\n",cn,(long)modp->auth_checker); + mod_gzip_printf( "%s: ++++++++++ modp->access_checker = %ld\n",cn,(long)modp->access_checker); + mod_gzip_printf( "%s: ++++++++++ modp->type_checker = %ld\n",cn,(long)modp->type_checker); + mod_gzip_printf( "%s: ++++++++++ modp->fixer_upper = %ld\n",cn,(long)modp->fixer_upper); + mod_gzip_printf( "%s: ++++++++++ modp->logger = %ld\n",cn,(long)modp->logger); + mod_gzip_printf( "%s: ++++++++++ modp->header_parser = %ld\n",cn,(long)modp->header_parser); + mod_gzip_printf( "%s: .......... CONTENT HANDLERS\n",cn); + #endif /* MOD_GZIP_DEBUG1 */ + + if ( !modp->handlers ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: .......... NO CONTENT HANDLERS!\n",cn); + #endif + } + else /* There are some handlers... */ + { + for ( handp = modp->handlers; handp->content_type; ++handp ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: .......... handp->content_type = [%s]\n", + cn,handp->content_type); + mod_gzip_printf( "%s: .......... handp->handler = %ld\n",cn,(long)handp->handler); + #endif + + }/* End 'handp' loop */ + + }/* End 'else' */ + + #endif /* MOD_GZIP_FUTURE_USE */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: No handler was found...\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + return DECLINED; + + }/* 'if ( mod_gzip_strnicmp( (char *) modp->name, "mod_actions.c", 13 ) == 0 )' */ + + count++; + + }/* End 'modp' loop... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: No handler found...\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) > ERROR >\n",cn); + #endif + + return DECLINED; + +}/* End of mod_gzip_run_mod_action() */ + + +int mod_gzip_run_mod_alias( request_rec *r ) +{ + /* + * This calls 'translate_alias_redir()' routine in mod_alias.c + * which will search/replace keywords in the URI with the correct + * 'ScriptAlias' value(s) from the httpd.conf configuration file. + * + * 'translate_alias_redir()' is the name of routine registered + * by mod_alias.c module as the 'translate' hook. + */ + + module *modp; + int count=0; + int rc; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_run_mod_alias()"; + #endif + + const handler_rec *handp; + + /* Currently 9 possible 'event' handlers. */ + /* Actual content handler in a module is 'extra'. */ + #define MOD_GZIP_NMETHODS 9 + + char *save_filename = 0; + char *save_uri = 0; + + char nothing[256]; + + /* + * Start... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry...\n",cn); + mod_gzip_printf( "%s: *IN: r->uri =[%s]\n", cn, r->uri ); + mod_gzip_printf( "%s: *IN: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); + mod_gzip_printf( "%s: *IN: r->filename =[%s]\n", cn, r->filename ); + #endif + + for ( modp = top_module; modp; modp = modp->next ) + { + /* modp->name list will look like this... */ + /*--------------------*/ + /* 00 [mod_gzip.c] */ + /* 01 [mod_isapi.c] */ + /* 02 [mod_setenv.c] */ + /* 02 [mod_actions.c] */ + /* ............... */ + /* ............... */ + /* 18 [mod_so.c] */ + /* 19 [http_core.c] <- Always bottom of list (last one called) */ + /*--------------------*/ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: count=%4.4d modp = %10.10ld modp->name=[%s]\n", + cn,count,(long)modp, modp->name ); + #endif + + /* + There are only 3 modules that normally have + 'translate' handlers registered... + + mod_alias + mod_userdir + http_core + */ + + if ( ( mod_gzip_strnicmp( (char *) modp->name, "mod_alias.c", 11 ) == 0 ) || + ( mod_gzip_strnicmp( (char *) modp->name, "mod_userdir.c", 13 ) == 0 ) || + ( mod_gzip_strnicmp( (char *) modp->name, "http_core.c", 11 ) == 0 ) ) + { + + /* Module information... */ + + #ifdef MOD_GZIP_DEBUG1 + + mod_gzip_printf( "%s: ++++++++++ MODULE FOUND!...\n",cn); + mod_gzip_printf( "%s: ++++++++++ modp->module_index = %d\n",cn,(int)modp->module_index); + + mod_gzip_printf( "%s: ++++++++++ METHODS\n",cn); + mod_gzip_printf( "%s: ++++++++++ modp->translate_handler = %ld\n",cn,(long)modp->translate_handler); + mod_gzip_printf( "%s: ++++++++++ modp->ap_check_user_id = %ld\n",cn,(long)modp->ap_check_user_id); + mod_gzip_printf( "%s: ++++++++++ modp->auth_checker = %ld\n",cn,(long)modp->auth_checker); + mod_gzip_printf( "%s: ++++++++++ modp->access_checker = %ld\n",cn,(long)modp->access_checker); + mod_gzip_printf( "%s: ++++++++++ modp->type_checker = %ld\n",cn,(long)modp->type_checker); + mod_gzip_printf( "%s: ++++++++++ modp->fixer_upper = %ld\n",cn,(long)modp->fixer_upper); + mod_gzip_printf( "%s: ++++++++++ modp->logger = %ld\n",cn,(long)modp->logger); + mod_gzip_printf( "%s: ++++++++++ modp->header_parser = %ld\n",cn,(long)modp->header_parser); + mod_gzip_printf( "%s: .......... CONTENT HANDLERS\n",cn); + + #endif /* MOD_GZIP_DEBUG1 */ + + if ( !modp->handlers ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: .......... NO CONTENT HANDLERS!\n",cn); + #endif + } + else /* There are some handlers... */ + { + for ( handp = modp->handlers; handp->content_type; ++handp ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: .......... handp->content_type = [%s]\n", + cn,handp->content_type); + mod_gzip_printf( "%s: .......... handp->handler = %ld\n",cn,(long)handp->handler); + #endif + + }/* End 'handp' loop */ + + }/* End 'else' */ + + if ( modp->translate_handler ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: modp->translate_handler is VALID...\n",cn); + #endif + + /* + There are only 3 modules that normally have + 'translate' handlers registered... + + mod_alias <- Will translate /php3/xxx to c:/php3017/xx + mod_userdir + http_core + */ + + /* + * This calls 'translate_alias_redir()' routine in mod_alias.c + * which will search/replace keywords in the URI with the correct + * 'ScriptAlias' value(s) from the httpd.conf configuration file. + * + * 'translate_alias_redir()' is the name of routine registered + * by mod_alias.c module as the 'translate' hook. + * + * The 'translate_alias_redir()' function in mod_alias.c + * is really simple. All it does is check to make sure + * that r->uri has some value and, if it does, it calls + * another routine in mod_alias.c named 'try_alias_list()' + * which replaces any 'ScriptAlias' phrases with their + * real values and copies the result to r->filename. + * + * We must make sure the phrase we want translated is + * in r->uri and check for results in r->filename. + */ + + /* + * Calling mod_alias.c translate handler will correctly + * translate 'ScriptAlias' phrases such as... + * + * URI value... + * /php3/php3.exe + * becomes... + * c:/php3017/php3.exe + */ + + save_filename = r->filename; + save_uri = r->uri; + nothing[0] = 0; + + r->filename = nothing; + r->uri = save_filename; /* Phrase to translate */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: r->filename = [%s]\n",cn,r->filename); + mod_gzip_printf( "%s: r->uri = [%s]\n",cn,r->uri); + mod_gzip_printf( "%s: Call (modp->translate_handler)(r)...\n",cn); + #endif + + /* Call the actual translate routine in mod_action module... */ + + rc = (modp->translate_handler)( (request_rec *) r ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back (modp->translate_handler)(r)...\n",cn); + mod_gzip_printf( "%s: r->filename = [%s]\n",cn,r->filename); + mod_gzip_printf( "%s: r->uri = [%s]\n",cn,r->uri); + #endif + + /* + * If there was a successful translation then the return + * code will be OK and the translated URI will be sitting + * in r->filename. If there were no phrase replacements + * then the return code will be DECLINED. + */ + + #ifdef MOD_GZIP_DEBUG1 + + if ( rc == OK ) + { + mod_gzip_printf( "%s: rc = %d = OK\n",cn, rc ); + } + else if ( rc == DECLINED ) + { + mod_gzip_printf( "%s: rc = %d = DECLINED\n",cn, rc ); + } + else if ( rc == DONE ) /* -2 means 'totally done' */ + { + mod_gzip_printf( "%s: rc = %d = DONE\n",cn, rc ); + } + else /* Probably an HTTP ERROR value... */ + { + mod_gzip_printf( "%s: rc = %d = HTTP_ERROR?\n",cn, rc ); + } + + #endif /* MOD_GZIP_DEBUG */ + + /* + * Evaluate the results... + */ + + if ( rc == OK ) /* There was a phrase translation... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: There was a phrase translation...\n",cn ); + mod_gzip_printf( "%s: Keeping new 'r->filename'\n",cn ); + #endif + + /* Do NOT restore 'r->filename' to original value... */ + /* Just fall-through and continue... */ + } + else /* No phrases were replaced... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: There were NO phrases translated...\n",cn ); + mod_gzip_printf( "%s: Restoring 'r->filename' to original value...\n",cn ); + #endif + + /* Restore 'r->filename' to original value... */ + + r->filename = save_filename; + } + + /* Always 'restore' URI to original value... */ + + r->uri = save_uri; + + /* Turn and burn... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( rc=%d ) >\n",cn,rc); + #endif + + return rc; + } + else /* modp->translate_handler is NULL... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: modp->translate_handler is NOT VALID.\n",cn); + #endif + } + + }/* 'if ( mod_gzip_strnicmp( (char *) modp->name, "mod_actions.c", 13 ) == 0 )' */ + + count++; + + }/* End 'modp' loop... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: No handler found...\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) > ERROR >\n",cn); + #endif + + return DECLINED; + +}/* End of mod_gzip_run_mod_alias() */ + + +static int mod_gzip_handler( request_rec *r ) +{ + /* + * The primary module request handler... + */ + + int rc=0; + char cn[]="mod_gzip_handler()"; + int access_status=0; + int access_status2=0; + + /* + * Start... + */ + + if ( r->server->loglevel == APLOG_DEBUG ) + { + /* + * If the user has 'LogLevel debug' set in httpd.conf then + * it's ok to go ahead and strike some diagnostic information + * to the Apache log(s). + * + * APLOG_MARK is what supplies __FILE__ and __LINE__ info and + * it is actually defined in HTTP_LOG.H as... + * + * define APLOG_MARK __FILE__,__LINE__ + * + * Sometimes the original __FILE__ name is very long and is + * fairly useless information cluttering up the logs when + * there is only 1 possible source file name so + * to NOT use it just supply 2 dummy parameters instead. + * + * The first parameter can be a custom message instead of + * the __FILE__ string that would normally be substituted. + */ + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: Entry point...",cn); + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: r->the_request = [%s]",cn,r->the_request); + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: r->protocol = [%s]",cn,r->protocol); + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: r->proto_num = %d",cn,(int)r->proto_num); + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: r->filename = [%s]",cn,r->filename); + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: r->uri = [%s]",cn,r->uri); + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: r->content_type = [%s]",cn,r->content_type); + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: r->handler = [%s]",cn,r->handler); + + }/* End 'if( r->server->loglevel == APLOG_DEBUG )' */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "\n" ); + mod_gzip_printf( "%s: ```` Entry...\n",cn); + mod_gzip_printf( "%s: -------------------------------------------------------------\n",cn); + mod_gzip_printf( "%s: *IN: r->uri =[%s]\n", cn, r->uri ); + mod_gzip_printf( "%s: *IN: r->unparsed_uri =[%s]\n", cn, r->unparsed_uri ); + mod_gzip_printf( "%s: *IN: r->filename =[%s]\n", cn, r->filename ); + mod_gzip_printf( "%s: *IN: r->path_info =[%s]\n", cn, r->path_info ); + mod_gzip_printf( "%s: *IN: r->args =[%s]\n", cn, r->args ); + mod_gzip_printf( "%s: *IN: r->header_only =[%s]\n", cn, r->header_only ); + mod_gzip_printf( "%s: *IN: r->protocol =[%s]\n", cn, r->protocol ); + mod_gzip_printf( "%s: *IN: r->proto_num =%d\n", cn, r->proto_num ); + mod_gzip_printf( "%s: *IN: r->hostname =[%s]\n", cn, r->hostname ); + mod_gzip_printf( "%s: *IN: r->the_request =[%s]\n", cn, r->the_request ); + mod_gzip_printf( "%s: *IN: r->assbackwards =%d\n", cn, r->assbackwards ); + mod_gzip_printf( "%s: *IN: r->status_line =[%s]\n", cn, r->status_line ); + mod_gzip_printf( "%s: *IN: r->status =%d\n", cn, r->status ); + mod_gzip_printf( "%s: *IN: r->method =[%s]\n", cn, r->method ); + mod_gzip_printf( "%s: *IN: r->method_number =%d\n", cn, r->method_number ); + mod_gzip_printf( "%s: *IN: r->content_type =[%s]\n", cn, r->content_type ); + mod_gzip_printf( "%s: *IN: r->handler =[%s]\n", cn, r->handler ); + mod_gzip_printf( "%s: *IN: r->content_encoding =[%s]\n", cn, r->content_encoding ); + mod_gzip_printf( "%s: *IN: r->content_language =[%s]\n", cn, r->content_language ); + mod_gzip_printf( "%s: -------------------------------------------------------------\n",cn); + mod_gzip_printf( "%s: *IN: r->parsed_uri.scheme =[%s]\n", cn, r->parsed_uri.scheme ); + mod_gzip_printf( "%s: *IN: r->parsed_uri.hostinfo =[%s]\n", cn, r->parsed_uri.hostinfo ); + mod_gzip_printf( "%s: *IN: r->parsed_uri.user =[%s]\n", cn, r->parsed_uri.user ); + mod_gzip_printf( "%s: *IN: r->parsed_uri.password =[%s]\n", cn, r->parsed_uri.password ); + mod_gzip_printf( "%s: *IN: r->parsed_uri.hostname =[%s]\n", cn, r->parsed_uri.hostname ); + mod_gzip_printf( "%s: *IN: r->parsed_uri.port_str =[%s]\n", cn, r->parsed_uri.port_str ); + mod_gzip_printf( "%s: *IN: r->parsed_uri.port =%u\n", cn, r->parsed_uri.port ); + mod_gzip_printf( "%s: *IN: r->parsed_uri.path =[%s]\n", cn, r->parsed_uri.path ); + mod_gzip_printf( "%s: *IN: r->parsed_uri.query =[%s]\n", cn, r->parsed_uri.query ); + mod_gzip_printf( "%s: *IN: r->parsed_uri.fragment =[%s]\n", cn, r->parsed_uri.fragment ); + mod_gzip_printf( "%s: -------------------------------------------------------------\n",cn); + + #endif /* MOD_GZIP_DEBUG1 */ + + /* + * Call the real transaction handler.... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call mod_gzip_request_handler()...\n", cn ); + #endif + + rc = mod_gzip_request_handler( (request_rec *) r ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back mod_gzip_request_handler()... rc=%d\n",cn,rc); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + /* + * If LogLevel is 'debug' then show the final return code + * value in the log(s)... + */ + + if ( rc == OK ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: Exit: return( rc = %d = OK )", cn, rc ); + } + else if ( rc == DECLINED ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: Exit: return( rc = %d = DECLINED )", cn, rc ); + } + else /* It's probably an HTTP error code... */ + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "%s: Exit: return( rc = %d = HTTP ERROR CODE? )", cn, rc ); + } + + }/* End 'if( r->server->loglevel == APLOG_DEBUG )' */ + + #ifdef MOD_GZIP_DEBUG1 + + if ( rc == OK ) + { + mod_gzip_printf( "%s: rc = %d OK\n", cn, (int) rc); + } + else if ( rc == DECLINED ) + { + mod_gzip_printf( "%s: rc = %d DECLINED\n", cn, (int) rc ); + } + else /* It's probably an HTTP error code... */ + { + mod_gzip_printf( "%s: rc = %d ( HTTP ERROR CODE? )\n", cn, (int) rc ); + } + + mod_gzip_printf( "%s: Exit > return( rc = %d ) >\n",cn,rc ); + + #endif /* MOD_GZIP_DEBUG1 */ + + return rc; + +}/* End of mod_gzip_handler() */ + +typedef struct { + table *action_types; /* Added with Action... */ + char *scripted[METHODS]; /* Added with Script... */ + array_header *xmethods; /* Added with Script -- extension methods */ +} action_dir_config2; + +extern module action_module; + +int mod_gzip_request_handler( request_rec *r ) +{ + /* + * Process a new request... + */ + + int rc = 0; + int loglevel = 0; + int do_command = 0; + int process = 0; + int action_flag = 0; + long compression_ratio = 0; + + const char* has_encoding = 0; + const char* accept_encoding = 0; + + #ifdef MOD_GZIP_ALLOWS_INTERNAL_COMMANDS + char tmp[4096]; /* Scratch buffer for HTML output */ + #endif + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_request_handler()"; + const char* the_type = 0; + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + char log_info[40]; /* Scratch buffer */ + #endif + + void *modconf = r->server->module_config; + + mod_gzip_conf *conf = 0; /* Pointer to our own config data */ + + /* + * Start... + * + * Establish a local pointer to module configuration data... + */ + + conf = (mod_gzip_conf *) + ap_get_module_config(modconf, &gzip_module); + + /* + * Get the current Apache log level... + */ + + loglevel = r->server->loglevel; + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* + * If the MOD_GZIP_USES_APACHE_LOGS compile-time switch is ON + * then the Apache log module interface code is being included. + * + * Reset the module 'notes' that are used by mod_gzip to + * add entries to Apache standard log files... + * + * See the note farther below about how to add mod_gzip + * compression information to any standard Apache log file. + */ + + /* Default for 'mod_result' message is 'DECLINED:NOP'... */ + + ap_table_setn( r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:NOP")); + + /* Default for in/out size is 'n/a'... 'Not available'...*/ + + sprintf( log_info, "n/a" ); + + ap_table_setn( r->notes,"mod_gzip_input_size",ap_pstrdup(r->pool,log_info)); + ap_table_setn( r->notes,"mod_gzip_output_size",ap_pstrdup(r->pool,log_info)); + + /* Default for compression ratio is '0' percent... */ + + ap_table_setn( r->notes,"mod_gzip_compression_ratio",ap_pstrdup(r->pool,"0")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + #ifdef MOD_GZIP_DEBUG1 + + /* Request info... */ + + mod_gzip_printf( "%s: Entry...\n",cn); + mod_gzip_printf( "%s: mod_gzip_version =[%s]\n", cn, mod_gzip_version); + mod_gzip_printf( "%s: conf->req = %d\n", cn, (int) conf->req); + mod_gzip_printf( "%s: conf->cache.root =[%s]\n", cn, conf->cache.root); + mod_gzip_printf( "%s: *IN: r->uri =[%s]\n", cn, r->uri); + mod_gzip_printf( "%s: *IN: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri); + mod_gzip_printf( "%s: *IN: r->filename =[%s]\n", cn, r->filename); + mod_gzip_printf( "%s: *IN: r->handler =[%s]\n", cn, r->handler); + mod_gzip_printf( "%s: r->finfo.st_size = %ld\n", cn, (long) r->finfo.st_size); + + /* NOTE: The r->headers_out content type value has not normally */ + /* been set at this point but grab a pointer to it and show */ + /* it just to make sure. The r->content_type value, however, */ + /* normally WILL have some value at this point. */ + + the_type = ap_table_get( r->headers_out,"Content-type" ); + + mod_gzip_printf( "%s: r->headers_out, Content-type = [%s]\n",cn,the_type); + mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type ); + + /* The r->handler ASCII name string is the all-important */ + /* jump table name for the module that will handle the */ + /* transaction. If this is a CGI jump then it will normally */ + /* have a value of 'cgi-script' at this point. */ + + mod_gzip_printf( "%s: r->handler = [%s]\n",cn,r->handler ); + + /* Server info... */ + + mod_gzip_printf( "%s: r->server->path = [%s]\n",cn,r->server->path ); + mod_gzip_printf( "%s: r->server->pathlen = %d\n", cn,r->server->pathlen); + mod_gzip_printf( "%s: r->server->server_admin = [%s]\n",cn,r->server->server_admin); + mod_gzip_printf( "%s: r->server->server_hostname = [%s]\n",cn,r->server->server_hostname); + mod_gzip_printf( "%s: r->server->error_fname = [%s]\n",cn,r->server->error_fname); + + /* Environment info... */ + + mod_gzip_printf( "%s: DOCUMENT_ROOT = [%s]\n",cn,ap_document_root(r)); + + #endif /* MOD_GZIP_DEBUG1 */ + + /* + * Check the 'master' request control switch and see if mod_gzip + * is ON (ENABLED) or OFF (DISABLED)... + */ + + if ( conf->req != 1 ) + { + /* mod_gzip is currently DISABLED so DECLINE the processing... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: conf->req = %d = OFF\n",cn,conf->req); + mod_gzip_printf( "%s: The module is currently DISABLED\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:DISABLED")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + + }/* End 'if( conf->req != 1 )' */ + + /* + * Check for a default HTTP support level ( if used ). + * If no value for conf->min_http was supplied in the + * httpd.conf file then the default value will be 0 + * so that ALL levels of HTTP will be OK... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: *HTTP CHECK:conf->min_http = %d\n", cn, conf->min_http ); + mod_gzip_printf( "%s: *HTTP CHECK:r->proto_num = %d\n", cn, r->proto_num ); + mod_gzip_printf( "%s: *HTTP CHECK:r->protocol = [%s]\n", cn, r->protocol ); + #endif + + if ( r->proto_num < conf->min_http ) + { + /* The HTTPx/x version number does not meet the minimum requirement */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Request HTTP level does not meet minimum requirement\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + sprintf( log_info, "DECLINED:%s:%d", r->protocol, r->proto_num ); + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,log_info)); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + + }/* End 'if ( r->proto_num < conf->min_http )' */ + + else /* Protocol level is OK... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Request HTTP level is OK...\n",cn); + #endif + } + + #ifdef MOD_GZIP_ALLOWS_INTERNAL_COMMANDS + + /* + * Internal command pickups... + * + * If this module was compiled with the + * MOD_GZIP_ALLOWS_INTERNAL_COMMANDS switch ON + * then the first thing we do is check for valid + * URL-based internal commands. + * + * Rather than check for all possible commands each time + * just do 1 quick check for the command prefix and set + * a flag to indicate if there is any need to enter the + * actual command handler... + */ + + if ( strstr( r->filename, "mod_gzip_command_" ) ) + { + do_command = 1; /* Process the command */ + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: do_command = %d\n",cn,do_command); + #endif + + if ( do_command ) + { + /* Determine the exact command and respond... */ + + if ( strstr( r->filename, "mod_gzip_command_version" ) ) + { + /*------------------------------------------------------*/ + /* Command: 'mod_gzip_command_version' */ + /* Purpose: Return the current mod_gzip version number. */ + /* Comment: Allows anyone to query any Apache Server at */ + /* any URL with a browser and discover if */ + /* mod_gzip is in use at that site. */ + /*------------------------------------------------------*/ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 'mod_gzip_command_version' seen...\n",cn); + #endif + + /* NOTE: mod_gzip command results are not sent compressed */ + + /* Build the response buffer... */ + + sprintf( tmp, + "
"
+          "mod_gzip is available on this Server\r\n"
+          "mod_gzip version = %s\r\n"
+          "
", + mod_gzip_version + ); + + /* For all mod_gzip commands that are intercepted we */ + /* simply return OK. */ + + return( mod_gzip_send_html_command_response( r, tmp, "text/html" )); + } + else if ( strstr( r->filename, "mod_gzip_command_showstats" ) ) + { + /*------------------------------------------------------*/ + /* Command: 'mod_gzip_command_showstats' */ + /* Purpose: Display compression statistics. */ + /* Comment: Allows anyone to query any Apache Server at */ + /* any URL with a browser and get a report */ + /* about compression results. */ + /*------------------------------------------------------*/ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 'mod_gzip_command_showstats' seen...\n",cn); + #endif + + /* NOTE: mod_gzip command results are not sent compressed */ + + /* Build the response buffer... */ + + /* NOTE: This command has been temporarily removed */ + + sprintf( tmp, + "
"
+          "mod_gzip is available on this Server\r\n"
+          "mod_gzip version = %s\r\n\r\n"
+          "The 'mod_gzip_command_showstats' command has been temporarily removed.\r\n"
+          "
", + mod_gzip_version + ); + + /* For all mod_gzip commands that are intercepted we */ + /* simply return OK. */ + + return( mod_gzip_send_html_command_response( r, tmp, "text/html" )); + } + else if ( strstr( r->filename, "mod_gzip_command_resetstats" ) ) + { + /*------------------------------------------------------*/ + /* Command: 'mod_gzip_command_resetstats' */ + /* Purpose: Resets the compression statistics. */ + /* Comment: Allows the compression statistics to be */ + /* reset using only a browser. */ + /*------------------------------------------------------*/ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 'mod_gzip_command_resetstats' seen...\n",cn); + #endif + + /* NOTE: mod_gzip command results are not sent compressed */ + + /* Build the response buffer... */ + + /* NOTE: This command has been temporarily removed */ + + sprintf( tmp, + "
"
+          "mod_gzip is available on this Server\r\n"
+          "mod_gzip version = %s\r\n\r\n"
+          "The 'mod_gzip_command_resetstats' command has been temporarily removed.\r\n"
+          "
", + mod_gzip_version + ); + + /* For all mod_gzip commands that are intercepted we */ + /* simply return OK. */ + + return( mod_gzip_send_html_command_response( r, tmp, "text/html" )); + } + else /* Unrecognized command... */ + { + /* The command prefix was 'seen' and the 'do_command' flag */ + /* was TRUE but either the command was mis-typed or there */ + /* is no such command available. This is not an ERROR and */ + /* we should simply fall-through and assume that the URL */ + /* is valid for the local Server. A 404 will be returned */ + /* if there is no object that actually matches the name. */ + } + + }/* End 'if( do_command )' */ + + #endif /* MOD_GZIP_ALLOWS_INTERNAL_COMMANDS */ + + /* + * Sanity checks... + */ + + /* + * If the requested file already contains the .gz designation + * then we must assume it is pre-compressed and let the + * default logic take care of sending the file. This module + * doesn't really care if a .gz file was actually requested + * or if it is the source target because of a successful + * Server side 'negotiation'. Doesn't matter. + */ + + if ( ( r->filename ) && ( strstr( r->filename, ".gz" ) ) ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: r->filename already contains '.gz'.\n",cn); + mod_gzip_printf( "%s: Pre-compression is assumed.\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:HAS.GZ")); + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: Files with .gz file extension are skipped."); + } + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + } + else /* r->filename doesn not contain '.gz' designator... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: r->filename does NOT contain '.gz'.\n",cn); + mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); + #endif + } + + /* + * For now just block all attempts to compress 'image/*' MIME + * type even if user is trying to do so. Too many issues with + * broken browsers when it comes to decoding compressed images. + * + * WARNING: Don't submit r->content_type to strstr() it if is + * NULL or the API call will GP fault. Go figure. + */ + + if ( ( r->content_type ) && ( strstr( r->content_type, "image/" ) ) ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: r->content_type contains 'image/'.\n",cn); + mod_gzip_printf( "%s: Image compression is temporaily BLOCKED\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:IMAGE")); + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: Graphics image compression option is temporarily disabled."); + } + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + } + + /* + * Safeguard against situations where some other module or + * filter has gotten to this request BEFORE us and has already + * added the 'Content-encoding: gzip' field to the output header. + * It must be assumed that whoever added the header prior to this + * point also took care of the compression itself. + * + * If the output header already contains "Content-encoding: gzip" + * then simply DECLINE the processing and let the default chain + * take care of it... + */ + + has_encoding = ap_table_get( r->headers_out, "Content-encoding" ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: has_encoding = [%s]\n",cn,has_encoding); + #endif + + if ( has_encoding ) /* 'Content-encoding' field is present... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Output header already contains 'Content-encoding:' field\n",cn); + mod_gzip_printf( "%s: Checking for 'gzip' designator...\n",cn); + #endif + + if ( strstr( has_encoding, "gzip" ) || + strstr( has_encoding, "deflate" ) ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' or 'deflate' designator...\n",cn); + mod_gzip_printf( "%s: Pre-compression is assumed.\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:HAS_CE:GZIP")); + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: Header already has 'Content-encoding: gzip'"); + } + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + } + else /* 'gzip' designator not found... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' or 'deflate' designator...\n",cn); + mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); + #endif + } + + }/* End 'if( has_encoding )' */ + + else /* Output header does NOT contain 'Content-encoding:' field... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Output header does NOT contain 'Content-encoding:' field.\n",cn); + mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); + #endif + } + + /* + * Basic sanity checks completed and we are still here. + * + * Now we must determine if the User-Agent is capable of receiving + * compressed data... + * + * There are, currently, many reasons why it is actually never + * enough to simply trust the 'Accept-encoding: foo, bar' + * request header field when it comes to actually determining + * if a User-agent is capable of receiving content or transfer + * encodings. + * + * Some of them are... + * + * 1. There have been several major releases of popular browsers + * that actually send the 'Accept-encoding:' request field but + * are, in reality, unable to perform the specified decoding(s). + * In some cases the result will be that the browser screen + * simply fills with garbage ( the binary compressed data + * itself ) but in some cases the browser will actually crash. + * + * 2. There have been other major releases of browsers that are + * specifying multiple 'Accept-encoding' techniques with no + * 'Q' values whatsoever and they are actually only able to + * handle one of the multiple types specified. There is no + * way to know which type is 'real' other than by using other + * empiricial data extracted from the 'User-agent' field + * or other inbound request headers. + * + * 3. Same as 1 and 2 but relates to SIZE. Some major browser + * releases can handle the encoded content but only up to + * a certain 'SIZE' limit and then they will fail. There + * is no way for a User-agent to specify this limitation + * via HTTP so empirical header analysis is the only option. + * + * 4. The HTTP specification has no way for a Server to distinguish + * from the 'Accept encoding: foo, bar' input request field + * whether the user agent can only support the specified encodings + * as either a Content-encoding OR a Transfer-encoding, but + * not both. There is also no way of knowing if the user + * agent is able to handle any of the specified types being + * used as both a Content-encoding AND a Transfer-encoding + * for the same message body. All the Server can do is assume + * that the encodings are valid in any/all combinations + * and that the user agent can 'Accept' them as either + * 'Content' encodings and/or 'Transfer' encodings under + * any and all circumstances. This blanket assumption will + * cause problems with some release versions of some browsers + * because the assumed 'do all' capability is simply not a + * reality. + * + * 5. Many browsers ( such as Netscape 4.75 for UNIX ) are unable + * to handle Content-encoding only for specific kinds of HTML + * transactions such as Style Sheets even though the browser + * says it is HTTP 1.1 compliant and is suppying the standard + * 'Accept-encoding: gzip' field. According to the IETF + * specifications any user-agent that says it can accept + * encodings should be able to do so for all types of HTML + * transactions but this is simply not the current reality. + * Some will, some won't... even if they say they can. + * + * This version of this module takes the 'What, me worry' approach + * and simply uses the accepted method of relying solely on the + * 'Accept-encoding: foo, bar' field and also assumes this means + * that the User-agent can accept the specified encodings as + * either Content-encodings (CE) and/or Transfer-encodings (TE) + * under all circumstances and in any combinations that the + * Server decides to send. + * + * It also assumes that the caller has no preference and should + * be able to decode any of the specified encodings equally well. + * Most user-agents sending the 'Accept-encoding:' field do NOT + * supply any 'Q' values to help with determining preferences. + */ + + accept_encoding = ap_table_get( r->headers_in, "Accept-Encoding" ); + + #ifdef MOD_GZIP_DEBUG1 + + if ( accept_encoding ) + { + mod_gzip_printf( "%s: 'Accept Encoding:' field seen.\n",cn); + } + else + { + mod_gzip_printf( "%s: 'Accept Encoding' field NOT seen.\n",cn); + } + + #endif /* MOD_GZIP_DEBUG1 */ + + /* If Accept-Encoding is applicable to this request...*/ + + if ( accept_encoding ) + { + /* ...and if it has the right 'gzip' indicator... */ + /* We record the compression format in a request note, so we + * can get it again later, and so it can potentially be logged. + */ + if ( strstr( accept_encoding, "gzip" ) ) + { + process = 1; /* ...set the 'process' flag TRUE */ + ap_table_setn( r->notes,"mod_gzip_compression_format", + ap_pstrdup(r->pool,"gzip")); + + } + else if ( strstr( accept_encoding, "deflate" ) ) + { + process = 1; /* ...set the 'process' flag TRUE */ + ap_table_setn( r->notes,"mod_gzip_compression_format", + ap_pstrdup(r->pool,"deflate")); + } + + }/* End 'if( accept_encoding )' */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 'process' flag = %d\n",cn,process); + #endif + + if ( !process ) /* Request does not meet criteria for processing... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: No 'gzip' capability specified by user-agent.\n",cn); + mod_gzip_printf( "%s: 'process' flag is FALSE.\n",cn); + mod_gzip_printf( "%s: This request will not be processed.\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:NO_GZIP")); + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: The inbound request header does not have 'Accept-encoding: gzip'"); + } + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + } + else /* 'gzip' designator was seen in 'Accept-Encoding:' field */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 'gzip' or 'deflate' capability specified by user-agent.\n",cn); + mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); + #endif + } + + /* + * Handle the transaction... + * + * At this point the inbound header analysis has been completed + * and we are assuming that the user agent is capable of accepting + * the content encodings we can provide. + * + * We must now 'do the right thing' based on what type of + * request it actually is... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: r->handler = [%s]\n",cn,r->handler); + mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); + mod_gzip_printf( "%s: Call mod_gzip_get_action_flag()...\n",cn); + #endif + + action_flag = + mod_gzip_get_action_flag( + (request_rec *) r, + (mod_gzip_conf *) conf + ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back mod_gzip_get_action_flag()...\n",cn); + mod_gzip_printf( "%s: action_flag = %d\n",cn,action_flag); + mod_gzip_printf( "%s: conf->do_static_files = %d\n",cn,(int)conf->do_static_files); + mod_gzip_printf( "%s: conf->do_cgi = %d\n",cn,(int)conf->do_cgi); + #endif + + /* + * Perform the right 'action' for this transaction... + */ + + if ( action_flag == MOD_GZIP_IMAP_DECLINED1 ) + { + /* + * If the transaction is to be DECLINED then just set the final + * return code to DECLINED, fall through, and return. + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_DECLINED1\n",cn); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: action_flag = MOD_GZIP_IMAP_DECLINED1 "); + } + + rc = DECLINED; + } + else if ( action_flag == MOD_GZIP_IMAP_DYNAMIC1 ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_DYNAMIC1\n",cn); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: action_flag = MOD_GZIP_IMAP_DYNAMIC1 "); + } + + /* + * Check the flag that can control whether or not the + * CGI dynamic output handler is ever called... + */ + + if ( conf->do_cgi != 1 ) /* CGI handler is OFF for now... */ + { + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: Calls to CGI handler currently DISABLED "); + } + + #ifdef MOD_GZIP_USES_APACHE_LOGS + /* Update the result string for Apache log(s)... */ + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:CGI_OFF")); + #endif + + rc = DECLINED; /* Just set final return code and fall through */ + + }/* End 'if( conf->do_cgi == 0 )' */ + + else /* It's OK to call the handler... */ + { + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: Calling cgi_handler for r->uri=[%s]",r->uri); + } + + /* Take care of some business BEFORE calling the */ + /* dynamic handler... */ + + mod_gzip_prepare_for_dynamic_call( r ); + + /* PHP NOTE */ + /* r->path_info must be set before ap_add_cgi_vars() */ + /* is called from within the upcoming hander or we */ + /* won't get PATH_INFO or PATH_TRANSLATED environment */ + /* variables set and PHP.EXE will return 'No input file' */ + /* error message since it depends on both of these being */ + /* set. r->path_info must be set to r->uri */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 1 r->uri = [%s]\n", cn, r->uri ); + mod_gzip_printf( "%s: 1 r->path_info = [%s]\n", cn, r->path_info ); + mod_gzip_printf( "%s: Setting r->path_info to r->uri for CGI...\n", cn ); + #endif + + r->path_info = r->uri; + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 2 r->uri = [%s]\n", cn, r->uri ); + mod_gzip_printf( "%s: 2 r->path_info = [%s]\n", cn, r->path_info ); + #endif + + /* Call the actual handler... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call mod_gzip_cgi_handler()...\n",cn); + #endif + + rc = mod_gzip_cgi_handler( (request_rec *) r ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back mod_gzip_cgi_handler()... rc=%d\n",cn,rc); + #endif + + }/* End 'else' - OK to call handler */ + } + else if ( action_flag == MOD_GZIP_IMAP_STATIC1 ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_STATIC1\n",cn); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: action_flag = MOD_GZIP_IMAP_STATIC1 "); + } + + /* + * Check the flag that can control whether or not the + * static handler is ever called... + */ + + if ( conf->do_static_files != 1 ) /* Static handler is OFF for now... */ + { + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: Calls to static handler currently DISABLED "); + } + + #ifdef MOD_GZIP_USES_APACHE_LOGS + /* Update the result string for Apache log(s)... */ + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:STATIC_OFF")); + #endif + + rc = DECLINED; /* Just set final return code and fall through */ + + }/* End 'if( conf->do_static == 0 )' */ + + else /* It's OK to call the handler... */ + { + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: Calling static_handler for r->uri=[%s]",r->uri); + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call mod_gzip_static_file_handler()...\n",cn); + #endif + + rc = mod_gzip_static_file_handler( (request_rec *) r ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back mod_gzip_static_file_handler()... rc=%d\n",cn,rc); + #endif + + }/* End 'else' - OK to call the handler */ + } + else /* Safety catch... No pickup for the 'action' flag... */ + { + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: action_flag = MOD_GZIP_IMAP_????? Unknown value"); + } + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: No pickup for specified 'action' flag."); + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: action_flag = MOD_GZIP_??? Unknown value\n",cn); + #endif + + rc = DECLINED; + } + + /* + * Record results to logs, if applicable, and return... + * + * The 'r->notes' values that can be used to disply result + * information in the standard Apache log files should have + * already been updated by the handler that was actually + * used to process the transaction. + */ + + #ifdef MOD_GZIP_DEBUG1 + + if ( rc == OK ) + { + mod_gzip_printf( "%s: Exit > return( rc=%d OK ) >\n",cn,rc); + } + else if ( rc == DECLINED ) + { + mod_gzip_printf( "%s: Exit > return( rc=%d DECLINED ) >\n",cn,rc); + } + else /* HTTP ERROR VALUE... */ + { + mod_gzip_printf( "%s: Exit > return( rc=%d HTTP_ERROR ) >\n",cn,rc); + } + + #endif /* MOD_GZIP_DEBUG1 */ + + return rc; /* Could be OK or DECLINED or HTTP_ERROR */ + +}/* End of mod_gzip_request_handler() */ + +int mod_gzip_prepare_for_dynamic_call( request_rec *r ) +{ + int rc; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_prepare_for_dynamic_call()"; + #endif + + /* + * Start... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry...\n",cn); + #endif + + /* + * mod_gzip can run other modules directly... + */ + + /* + * First run mod_action and see it there's a SCRIPT + * for this mime type... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: 1 ***: r->uri =[%s]\n", cn, r->uri ); + mod_gzip_printf( "%s: 1 ***: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); + mod_gzip_printf( "%s: 1 ***: r->filename =[%s]\n", cn, r->filename ); + mod_gzip_printf( "%s: 1 ***: r->content_type=[%s]\n", cn, r->content_type ); + mod_gzip_printf( "%s: 1 ***: r->handler =[%s]\n", cn, r->handler ); + mod_gzip_printf( "%s: Call mod_gzip_run_mod_action(r)...\n",cn); + #endif + + rc = mod_gzip_run_mod_action( (request_rec *) r ); + + #ifdef MOD_GZIP_DEBUG1 + + mod_gzip_printf( "%s: Back mod_gzip_run_mod_action(r)...\n",cn); + + if ( rc == OK ) + { + mod_gzip_printf( "%s: rc = %d = OK\n",cn, rc ); + } + else if ( rc == DECLINED ) + { + mod_gzip_printf( "%s: rc = %d = DECLINED\n",cn, rc ); + } + else if ( rc == DONE ) /* -2 means 'totally done' */ + { + mod_gzip_printf( "%s: rc = %d = DONE\n",cn, rc ); + } + else /* Probably an HTTP ERROR value... */ + { + mod_gzip_printf( "%s: rc = %d = HTTP_ERROR?\n",cn, rc ); + } + + mod_gzip_printf( "%s: 2 ***: r->uri =[%s]\n", cn, r->uri ); + mod_gzip_printf( "%s: 2 ***: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); + mod_gzip_printf( "%s: 2 ***: r->filename =[%s]\n", cn, r->filename ); + mod_gzip_printf( "%s: 2 ***: r->content_type=[%s]\n", cn, r->content_type ); + mod_gzip_printf( "%s: 2 ***: r->handler =[%s]\n", cn, r->handler ); + + #endif /* MOD_GZIP_DEBUG1 */ + + /* + * Now run mod_alias and get any aliases converted + * to real pathnames... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call mod_gzip_run_mod_alias(r)...\n",cn); + #endif + + rc = mod_gzip_run_mod_alias( (request_rec *) r ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back mod_gzip_run_mod_alias(r)...\n",cn); + + if ( rc == OK ) + { + mod_gzip_printf( "%s: rc = %d = OK\n",cn, rc ); + } + else if ( rc == DECLINED ) + { + mod_gzip_printf( "%s: rc = %d = DECLINED\n",cn, rc ); + } + else if ( rc == DONE ) /* -2 means 'totally done' */ + { + mod_gzip_printf( "%s: rc = %d = DONE\n",cn, rc ); + } + else /* Probably an HTTP ERROR value... */ + { + mod_gzip_printf( "%s: rc = %d = HTTP_ERROR?\n",cn, rc ); + } + + mod_gzip_printf( "%s: 3 ***: r->uri =[%s]\n", cn, r->uri ); + mod_gzip_printf( "%s: 3 ***: r->unparsed_uri=[%s]\n", cn, r->unparsed_uri ); + mod_gzip_printf( "%s: 3 ***: r->filename =[%s]\n", cn, r->filename ); + mod_gzip_printf( "%s: 3 ***: r->content_type=[%s]\n", cn, r->content_type ); + mod_gzip_printf( "%s: 3 ***: r->handler =[%s]\n", cn, r->handler ); + + #endif /* MOD_GZIP_DEBUG1 */ + + return OK; + +}/* End of mod_gzip_prepare_for_dynamic_call() */ + + +int mod_gzip_static_file_handler( request_rec *r ) +{ + int rc = 0; + long input_size = 0; + FILE* ifh1 = 0; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_static_file_handler()"; + #endif + + /* + * Start... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Processing file [%s]\n",cn,r->filename); + mod_gzip_printf( "%s: r->finfo.st_size = %ld\n", + cn, (long) r->finfo.st_size); + #endif + + /* + * If there is a valid file size already associated with + * the request then we can assume the core stat() call succeeded + * and that r->filename actually exists. We shouldn't need + * to waste a call to 'fopen()' just to find out for ourselves + * if the file exists. + * + * If the inbound file size was '0' then we need to do some + * verifications of our own before we give up since the + * absence of size might just be a simple bug in the parent code. + */ + + if ( r->finfo.st_size > 0 ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Source file length already known...\n",cn); + #endif + + input_size = (long) r->finfo.st_size; + } + else /* Do our own checking... */ + { + /* + * See if the requested source file exists... + * Be SURE to open the file in BINARY mode... + */ + + ifh1 = fopen( r->filename, "rb" ); + + if ( !ifh1 ) /* The file cannot be found or opened... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: The requested source file was NOT FOUND.\n",cn); + mod_gzip_printf( "%s: Exit > return( HTTP_NOT_FOUND ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* HTTP ERROR conditions provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:HTTP_NOT_FOUND")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return HTTP_NOT_FOUND; + } + else /* The file was found and opened OK... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: The requested source file is now OPEN...\n",cn); + #endif + } + + /* + * Move the current file pointer to the end of the file... + */ + + if ( fseek( ifh1, 0, SEEK_END ) ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ERROR: fseek() call failed...\n",cn); + #endif + + fclose( ifh1 ); /* FILE is still open so CLOSE it... */ + + /* fseek() failure could be a platform issue so log the event... */ + + ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_ERR, r->server, + "mod_gzip: fseek() failed for r->filename=[%s]",r->filename ); + + /* Return DECLINED and let default logic finish the request... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:FSEEK_FAIL")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + } + + /* + * Get the current SIZE of the requested file... + */ + + input_size = (long) ftell( ifh1 ); + + if ( input_size == -1l ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ERROR: ftell() call failed...\n",cn); + #endif + + fclose( ifh1 ); /* FILE is still open so CLOSE it... */ + + /* ftell() failure could be a platform issue so log the event... */ + + ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_ERR, r->server, + "mod_gzip: ftell() failed for r->filename=[%s]", r->filename ); + + /* Return DECLINED and let default logic finish the request... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:FTELL_FAIL")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + } + + /* + * Once we have the length just close the file... + */ + + if ( fclose( ifh1 ) == EOF ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ERROR: fclose() following ftell() call failed...\n",cn); + #endif + + /* fclose() failure could be a platform issue so log the event... */ + + ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_ERR, r->server, + "mod_gzip: fclose() failed for r->filename=[%s]",r->filename ); + + /* Return DECLINED and let default logic finish the request... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:FCLOSE_FAIL")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + } + + }/* End 'else' */ + + /* + * We have the static filename and the length. + * That's pretty much all we need at this point so + * go ahead and encode/transmit the object... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call mod_gzip_encode_and_transmit()...\n",cn); + #endif + + rc = + mod_gzip_encode_and_transmit( + (request_rec *) r, /* request_rec */ + (char *) r->filename, /* source ( Filename or Memory buffer ) */ + (int ) 1, /* 1=Source is a file 0=Memory buffer */ + (long ) input_size, /* input_size */ + (int ) 0 /* nodecline flag 0=Ok to DECLINE 1=No */ + ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back mod_gzip_encode_and_transmit()...\n",cn); + #endif + + /* + * The encode/transmit path should have already updated + * any relevant 'r->note' values ( if used ) for the transaction + * to reflect the results of the operation. + * + * Just return the result code and finish the transaction. + */ + + #ifdef MOD_GZIP_DEBUG1 + if ( rc == OK ) + { + mod_gzip_printf( "%s: Exit > return( rc = %d OK ) >\n",cn,rc); + } + else if ( rc == DECLINED ) + { + mod_gzip_printf( "%s: Exit > return( rc = %d DECLINED ) >\n",cn,rc); + } + else /* HTTP ERROR */ + { + mod_gzip_printf( "%s: Exit > return( rc = %d HTTP_ERROR ) >\n",cn,rc); + } + #endif /* MOD_GZIP_DEBUG1 */ + + return( rc ); + +}/* End of mod_gzip_static_file_handler() */ + +int mod_gzip_create_unique_filename( +mod_gzip_conf *mgc, +char *target, +int targetmaxlen +) +{ + /* + * Creates a unique work file name. + */ + + long process_id = 0; /* Current Process ID */ + long thread_id = 0; /* Current thread ID */ + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_create_unique_filename()"; + #endif + + /* Start... */ + + #ifdef _WIN32 + process_id = (long) GetCurrentProcessId(); + thread_id = (long) GetCurrentThreadId(); + #else /* !_WIN32 */ + process_id = (long) getpid(); + thread_id = (long) process_id; /* TODO: Add pthreads call */ + #endif /* _WIN32 */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry...\n",cn ); + mod_gzip_printf( "%s: target = %ld\n",cn,(long)target); + mod_gzip_printf( "%s: targetmaxlen = %ld\n",cn,(long)targetmaxlen); + mod_gzip_printf( "%s: process_id = %ld\n",cn,(long)process_id ); + mod_gzip_printf( "%s: thread_id = %ld\n",cn,(long)thread_id ); + mod_gzip_printf( "%s: mod_gzip_iusn = %ld\n",cn,(long)mod_gzip_iusn ); + #endif + + /* + * Sanity checks... + */ + + if ( ( !target ) || ( targetmaxlen == 0 ) ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Invalid target or targetmaxlen value.\n",cn); + mod_gzip_printf( "%s: Exit > return( 1 ) > ERROR >\n",cn ); + #endif + + return 1; + } + + /* + * Use the PROCESS + THREAD ID's and the current IUSN + * ( Instance Unique Sequence Number ) transaction ID to + * create a one-time only unique output workfile name... + */ + + sprintf( + target, + "%s%s_%ld_%ld_%ld.wrk", + mgc->cache.root, /* Either ServerRoot or Config specified dir. */ + mod_gzip_dirsep, /* Forward slash for UNIX, backslash for WIN32 */ + (long) process_id, /* Current process ID */ + (long) thread_id, /* Current thread ID */ + (long) mod_gzip_iusn /* Instance Unique Sequence Number */ + ); + + mod_gzip_iusn++; /* Increment Instance Unique Sequence Number */ + + if ( mod_gzip_iusn > 999999999L ) mod_gzip_iusn = 1; /* Wrap */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: target = [%s]\n",cn,target); + mod_gzip_printf( "%s: Exit > return( 0 ) >\n",cn ); + #endif + + return 0; + +}/* End of mod_gzip_create_unique_filename() */ + + +#ifdef MOD_GZIP_ALLOWS_INTERNAL_COMMANDS + +int mod_gzip_send_html_command_response( +request_rec *r, /* Request record */ +char *tmp, /* Response to send */ +char *ctype /* Content type string */ +) +{ + /* Generic command response transmitter... */ + + int tmplen=0; + char content_length[20]; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_send_html_command_response()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry...\n",cn); + mod_gzip_printf( "%s: ctype=[%s]\n",cn,ctype); + #endif + + /* Add the length of the response to the output header... */ + /* The third parameter to ap_table_set() MUST be a string. */ + + tmplen = strlen( tmp ); + + sprintf( content_length, "%d", tmplen ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: content_length = [%s]\n",cn,content_length); + #endif + + ap_table_set( r->headers_out, "Content-Length", content_length ); + + /* Make sure the content type matches this response... */ + + r->content_type = ctype; /* Actual type passed by caller */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); + #endif + + /* Start a timer... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call ap_soft_timeout()...\n",cn); + #endif + + ap_soft_timeout( "mod_gzip_send_html_command", r ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_soft_timeout()...\n",cn); + #endif + + #ifdef MOD_GZIP_COMMANDS_USE_LAST_MODIFIED + + /* Be sure to update the modifcation 'time' to current */ + /* time before calling 'ap_set_last_modified()'. All that */ + /* call does is set the r->xxxx value into the output */ + /* header. It doesn't actually update the time itself. */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call ap_update_mtime(r,r-finfo.st_mtime)...\n",cn); + #endif + + ap_update_mtime( r, r->finfo.st_mtime ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_update_mtime(r,r-finfo.st_mtime)...\n",cn); + #endif + + /* Update the 'Last modified' stamp in output header... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call ap_set_last_modified()...\n",cn); + #endif + + ap_set_last_modified(r); + + /* TODO: Add 'no-cache' option(s) to mod_gzip command responses */ + /* so user doesn't have hit reload to get fresh data. */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_set_last_modified()...\n",cn); + #endif + + #endif /* MOD_GZIP_COMMANDS_USE_LAST_MODIFIED */ + + /* Send the HTTP response header... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call ap_send_http_header()...\n",cn); + #endif + + ap_send_http_header(r); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_send_http_header()...\n",cn); + #endif + + /* Send the response BODY... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Sending response...\n%s\n",cn,tmp); + #endif + + #ifdef MOD_GZIP_USES_AP_SEND_MMAP + + /* Use ap_send_mmap() call to send the data... */ + + ap_send_mmap( tmp, r, 0, tmplen ); + + #else /* !MOD_GZIP_USES_AP_SEND_MMAP */ + + /* Use ap_rwrite() call to send the data... */ + + ap_rwrite( tmp, tmplen, r ); + + #endif /* MOD_GZIP_USES_AP_SEND_MMAP */ + + /* Clean up and exit... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call ap_kill_timeout()...\n",cn); + #endif + + ap_kill_timeout(r); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_kill_timeout()...\n",cn); + mod_gzip_printf( "%s: Exit > return( OK ) >\n",cn); + #endif + + return OK; + +}/* End of mod_gzip_send_html_command_response() */ + +#endif /* MOD_GZIP_ALLOWS_INTERNAL_COMMANDS */ + +static void * +mod_gzip_create_config( pool *p, server_rec *s ) +{ + int i; + + mod_gzip_conf *ps = 0; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_create_config()"; + #endif + + /* + * Set all the configuration default values... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + #endif + + /* + * Allocate a new config structure... + */ + + ps = ( mod_gzip_conf * ) ap_pcalloc( p, sizeof( mod_gzip_conf ) ); + + /* + * Set all default values... + */ + + ps->req = 1; /* Default is ON */ + ps->req_set = 1; /* Default is ON */ + ps->do_static_files = 1; /* Default is ON */ + ps->do_cgi = 1; /* Default is ON */ + ps->keep_workfiles = 0; /* 1=Keep workfiles 0=No */ + ps->min_http = 0; /* 1001=HTTP/1.1 Default=All HTTP levels */ + + ps->minimum_file_size = (long) mod_gzip_minimum_file_size; + /* Minimum file size in bytes */ + ps->maximum_inmem_size = (long) mod_gzip_maximum_inmem_size; + /* Maximum size for in-memory compression */ + + /* Compressed object cache control variables... */ + + /* Using these default values the compressed object cache + /* can have 2^18 directories (256,000) */ + + ps->cache.root = ap_server_root; /* Default DIR is ServerRoot */ + + ps->cache.space = MOD_GZIP_DEFAULT_CACHE_SPACE; + ps->cache.space_set = 0; + ps->cache.maxexpire = MOD_GZIP_DEFAULT_CACHE_MAXEXPIRE; + ps->cache.maxexpire_set = 0; + ps->cache.defaultexpire = MOD_GZIP_DEFAULT_CACHE_EXPIRE; + ps->cache.defaultexpire_set = 0; + ps->cache.lmfactor = MOD_GZIP_DEFAULT_CACHE_LMFACTOR; + ps->cache.lmfactor_set = 0; + ps->cache.gcinterval = -1; + ps->cache.gcinterval_set = 0; + ps->cache.dirlevels = 3; + ps->cache.dirlevels_set = 0; + ps->cache.dirlength = 1; + ps->cache.dirlength_set = 0; + + /* Initialize the include/exclude item map list... */ + + /* For now all init values are ZERO but don't use */ + /* memset() since this may not always be the case. */ + + ps->imap_total_entries = 0; + + for ( i=0; iimap[i].include = 0; + ps->imap[i].type = 0; + ps->imap[i].action = 0; + ps->imap[i].name[0] = 0; + + }/* End 'i' loop */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ps->imap_total_entries = %d\n", cn, ps->imap_total_entries ); + mod_gzip_printf( "%s: Exit > return( ps ) >\n", cn ); + #endif + + return ps; + +}/* End of mod_gzip_create_config() */ + +static void * +mod_gzip_merge_config( pool *p, void *basev, void *overridesv ) +{ + mod_gzip_conf *ps = ap_pcalloc(p, sizeof(mod_gzip_conf)); + mod_gzip_conf *base = (mod_gzip_conf *) basev; + mod_gzip_conf *overrides = (mod_gzip_conf *) overridesv; + + ps->req = (overrides->req_set == 0) ? base->req : overrides->req; + ps->cache.root = (overrides->cache.root == NULL) ? base->cache.root : overrides->cache.root; + ps->cache.space = (overrides->cache.space_set == 0) ? base->cache.space : overrides->cache.space; + ps->cache.maxexpire = (overrides->cache.maxexpire_set == 0) ? base->cache.maxexpire : overrides->cache.maxexpire; + ps->cache.defaultexpire = (overrides->cache.defaultexpire_set == 0) ? base->cache.defaultexpire : overrides->cache.defaultexpire; + ps->cache.lmfactor = (overrides->cache.lmfactor_set == 0) ? base->cache.lmfactor : overrides->cache.lmfactor; + ps->cache.gcinterval = (overrides->cache.gcinterval_set == 0) ? base->cache.gcinterval : overrides->cache.gcinterval; + ps->cache.dirlevels = (overrides->cache.dirlevels_set == 0) ? base->cache.dirlevels : overrides->cache.dirlevels; + ps->cache.dirlength = (overrides->cache.dirlength_set == 0) ? base->cache.dirlength : overrides->cache.dirlength; + + return ps; + +}/* End of mod_gzip_merge_config() */ + +/* + * Module configuration directive handlers... + */ + +static const char * +mod_gzip_set_on(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_set_on()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) ) + { + /* Set the master 'request control' switches ON... */ + + mgc->req = 1; /* Yes */ + mgc->req_set = 1; /* Yes */ + } + else /* Set the master 'request control' switches OFF... */ + { + mgc->req = 0; /* No */ + mgc->req_set = 0; /* No */ + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: mgc->req = %ld\n", cn, (long) mgc->req ); + mod_gzip_printf( "%s: mgc->req_set = %ld\n", cn, (long) mgc->req_set ); + #endif + + return NULL; +} + +static const char * +mod_gzip_set_keep_workfiles(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_set_keep_workfiles()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) ) + { + mgc->keep_workfiles = 1; /* Yes */ + } + else + { + mgc->keep_workfiles = 0; /* No */ + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: mgc->keep_workfiles = %ld\n", cn, + (long) mgc->keep_workfiles ); + #endif + + return NULL; +} + +static const char * +mod_gzip_set_min_http(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_set_min_http()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + mgc->min_http = (int) atoi( arg ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: mgc->min_http = %ld\n", cn, + (long) mgc->min_http ); + #endif + + return NULL; +} + + +static const char * +mod_gzip_imap_add_item( mod_gzip_conf *mgc, char *arg, int flag1 ) +{ + int x; + char *p1; + int ch1; + int this_type=0; + int this_action=0; + int this_include=flag1; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_imap_add_item()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: 1 arg=[%s]\n", cn, arg ); + + if ( flag1 == 1 ) + { + mod_gzip_printf( "%s: flag1 = %d = INCLUDE\n", cn, flag1 ); + } + else if ( flag1 == 0 ) + { + mod_gzip_printf( "%s: flag1 = %d = EXCLUDE\n", cn, flag1 ); + } + else + { + mod_gzip_printf( "%s: flag1 = %d = ??? Unknown value\n", cn, flag1 ); + } + + mod_gzip_printf( "%s: MOD-GZIP_IMAP_MAXNAMES = %d\n", + cn, MOD_GZIP_IMAP_MAXNAMES ); + + mod_gzip_printf( "%s: mgc->imap_total_entries = %d\n", + cn, mgc->imap_total_entries ); + + #endif /* MOD_GZIP_DEBUG1 */ + + /* + * Parse the config line... + */ + + p1 = arg; + while((*p1!=0)&&(*p1<33)) p1++; + ch1 = *p1; + + this_type = MOD_GZIP_IMAP_ISHANDLER; + this_action = MOD_GZIP_IMAP_DYNAMIC1; + + if ( ch1 == '!' ) + { + arg++; + p1 = arg; + while((*p1!=0)&&(*p1<33)) p1++; + ch1 = *p1; + } + else + { + this_action = MOD_GZIP_IMAP_STATIC1; + } + + if ( ch1 == '.' ) + { + this_type = MOD_GZIP_IMAP_ISEXT; + } + else + { + p1 = arg; + while (*p1!=0) + { + if ( *p1 == '/' ) + { + this_type = MOD_GZIP_IMAP_ISMIME; + } + p1++; + } + } + + /* + * Safety checks... + */ + + if ( ( this_type != MOD_GZIP_IMAP_ISMIME ) && + ( this_type != MOD_GZIP_IMAP_ISEXT ) && + ( this_type != MOD_GZIP_IMAP_ISHANDLER ) ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: this_type = %d = MOD_GZIP_IMAP_IS??? Unknown type\n",cn,this_type); + mod_gzip_printf( "%s: return( mod_gzip: ERROR: Unrecognized item 'type'\n",cn); + #endif + + return( "mod_gzip: ERROR: Unrecognized item 'type'" ); + } + + if ( ( this_action != MOD_GZIP_IMAP_DYNAMIC1 ) && + ( this_action != MOD_GZIP_IMAP_STATIC1 ) ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: this_action = %d = MOD_GZIP_IMAP_??? Unknown action\n",cn,this_action); + mod_gzip_printf( "%s: return( mod_gzip: ERROR: Unrecognized item 'action'\n",cn); + #endif + + return( "mod_gzip: ERROR: Unrecognized item 'action'" ); + } + + /* + * Wildcards... + */ + + if ( this_type != MOD_GZIP_IMAP_ISMIME ) + { + /* + * Wildcards are only allowed in MIME strings such as 'image/*' + */ + + p1 = arg; + while (*p1!=0) + { + if ( *p1 == '*' ) + { + return( "mod_gzip: ERROR: Wildcards are only allowed in MIME strings." ); + } + p1++; + } + } + + /* + * If there is room for a new record then add it... + */ + + if ( mgc->imap_total_entries < MOD_GZIP_IMAP_MAXNAMES ) + { + if ( strlen( arg ) < MOD_GZIP_IMAP_MAXNAMELEN ) + { + x = mgc->imap_total_entries; + + p1 = arg; + while((*p1!=0)&&(*p1<33)) p1++; + + strcpy( mgc->imap[x].name, p1 ); + + mgc->imap[x].include = this_include; + mgc->imap[x].type = this_type; + mgc->imap[x].action = this_action; + + mgc->imap_total_entries++; /* Increase onboard items */ + } + else /* ERROR: Name is too long */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: return( mod_gzip: ERROR: Item name is too long\n",cn); + #endif + + return( "mod_gzip: ERROR: Item name is too long" ); + } + } + else /* ERROR: INDEX is FULL */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: return( mod_gzip: ERROR: Item index is full\n",cn); + #endif + + return( "mod_gzip: ERROR: Item index is full" ); + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( NULL ) >\n",cn); + #endif + + return NULL; + +}/* End of mod_gzip_imap_add_item() */ + +#ifdef MOD_GZIP_DEBUG1 + +int mod_gzip_imap_show_items( mod_gzip_conf *mgc ) +{ + /* + * DEBUG only. Show the complete include/exclude list. + * This is normally called from mod_gzip_init() + * after all the configuration routines have executed. + */ + + int i; + int x; + char cn[]="mod_gzip_imap_show_items()"; + + /* Start... */ + + mod_gzip_printf( "\n"); + mod_gzip_printf( "%s: Entry\n", cn ); + + mod_gzip_printf( "%s: mgc->imap_total_entries= %d\n", cn, + (long) mgc->imap_total_entries ); + + for ( i=0; iimap_total_entries; i++ ) + { + x = i; /* Work variable */ + + mod_gzip_printf( "\n"); + mod_gzip_printf( "%s: mgc->imap[%3.3d].include = %d\n", cn,x,mgc->imap[x].include); + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d\n", cn,x,mgc->imap[x].type); + + if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISMIME ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISMIME\n",cn,x); + } + else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISEXT ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISEXT\n",cn,x); + } + else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISHANDLER ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISHANDLER\n",cn,x); + } + else /* Unrecognized item type... */ + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_IS??? Unknown type\n",cn,x); + } + + mod_gzip_printf( "%s: mgc->imap[%3.3d].action = %d\n", cn,x,mgc->imap[x].action); + + if ( mgc->imap[x].action == MOD_GZIP_IMAP_DYNAMIC1 ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_DYNAMIC1\n",cn,x); + } + else if ( mgc->imap[x].action == MOD_GZIP_IMAP_STATIC1 ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_STATIC1\n",cn,x); + } + else /* Unrecognized action type... */ + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_??? Unknown action\n",cn,x); + } + + mod_gzip_printf( "%s: mgc->imap[%3.3d].name = [%s]\n",cn,x,mgc->imap[x].name); + + }/* End 'i' loop */ + + mod_gzip_printf( "\n"); + + return 0; + +}/* End of mod_gzip_imap_show_items() */ + +#endif /* MOD_GZIP_DEBUG1 */ + +static const char * +mod_gzip_set_item_include(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_set_item_include()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + /* Pass pre-determined pointer to config structure... */ + /* Pass '1' for parm 3 to INCLUDE this item... */ + + return( mod_gzip_imap_add_item( mgc, arg, 1 ) ); +} + +static const char * +mod_gzip_set_item_exclude(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_set_item_exclude()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + /* Pass pre-determined pointer to config structure... */ + /* Pass '0' for parm 3 to EXCLUDE this item... */ + + return( mod_gzip_imap_add_item( mgc, arg, 0 ) ); +} + +static const char * +mod_gzip_set_temp_dir(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + + char cn[]="mod_gzip_set_temp_dir()"; + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + mgc->cache.root = arg; /* For now temp dir is used as cache root */ + + strcpy( mod_gzip_temp_dir, arg ); + mgc->cache.root = mod_gzip_temp_dir; + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: mgc->cache.root=[%s]\n", cn, mgc->cache.root ); + #endif + + return NULL; +} + +static const char * +mod_gzip_set_minimum_file_size(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + long lval; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_set_minimum_file_size()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + lval = (long) atol(arg); + + /* 300 bytes is the minimum at all times */ + if ( lval < 300L ) lval = 300L; + + mgc->minimum_file_size = (long) lval; /* Set config */ + mod_gzip_minimum_file_size = (long) lval; /* Set global */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ....mgc->minimum_file_size = %ld\n", cn, + (long) mgc->minimum_file_size ); + mod_gzip_printf( "%s: mod_gzip_minimum_file_size = %ld\n", cn, + (long) mod_gzip_minimum_file_size ); + #endif + + return NULL; +} + +static const char * +mod_gzip_set_maximum_inmem_size(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + long lval=0; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_set_maximum_inmem_size()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + lval = (long) atol(arg); + + /* 60000 bytes is the current maximum since a malloc() call is used */ + if ( lval > 60000L ) lval = 60000L; + + mgc->maximum_inmem_size = (long) lval; /* Set config */ + mod_gzip_maximum_inmem_size = (long) lval; /* Set global */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ....mgc->maximum_inmem_size = %ld\n", cn, + (long) mgc->maximum_inmem_size ); + mod_gzip_printf( "%s: mod_gzip_maximum_inmem_size = %ld\n", cn, + (long) mod_gzip_maximum_inmem_size ); + #endif + + return NULL; +} + +static const char * +mod_gzip_set_do_static_files(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_set_do_static_files()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) ) + { + mgc->do_static_files = 1; /* Yes */ + } + else + { + mgc->do_static_files = 0; /* No */ + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: mgc->do_static_files = %ld\n", cn, + (long) mgc->do_static_files ); + #endif + + return NULL; +} + +static const char * +mod_gzip_set_do_cgi(cmd_parms *parms, void *dummy, char *arg) +{ + mod_gzip_conf *mgc; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_set_do_cgi()"; + #endif + + /* Start... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry\n", cn ); + mod_gzip_printf( "%s: arg=[%s]\n", cn, arg ); + #endif + + mgc = ( mod_gzip_conf * ) + ap_get_module_config(parms->server->module_config, &gzip_module); + + if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) ) + { + mgc->do_cgi = 1; /* Yes */ + } + else + { + mgc->do_cgi = 0; /* No */ + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: mgc->do_cgi = %ld\n", cn, + (long) mgc->do_cgi ); + #endif + + return NULL; +} + +static const handler_rec mod_gzip_handlers[] = +{ + /* + * This is where we associate an ASCII NAME for our 'handler' + * which is what gets set into the r->handler field for a + * request and allows the function name associated with the + * ASCII name to be called and handle the request... + */ + + /* Add a 'name' and some types to our handler... */ + + {"mod_gzip_handler", mod_gzip_handler}, + {CGI_MAGIC_TYPE, mod_gzip_handler}, + {"cgi-script", mod_gzip_handler}, + {"*", mod_gzip_handler}, + {NULL} +}; + + +static const command_rec mod_gzip_cmds[] = +{ + /* + * Define our httpd.conf configuration diectives and + * the local routines that are responsible for processing + * those directives when the time comes... + */ + + {"mod_gzip_on", mod_gzip_set_on, NULL, RSRC_CONF, TAKE1, + "Yes=mod_gzip will handle requests No=mod_gzip runs in 'passthrough' mode"}, + + {"mod_gzip_do_static_files", mod_gzip_set_do_static_files, NULL, RSRC_CONF, TAKE1, + "'Yes' means mod_gzip will compress static files."}, + + {"mod_gzip_do_cgi", mod_gzip_set_do_cgi, NULL, RSRC_CONF, TAKE1, + "'Yes' means mod_gzip will compress dynamic CGI script output."}, + + {"mod_gzip_keep_workfiles", mod_gzip_set_keep_workfiles, NULL, RSRC_CONF, TAKE1, + "On=Keep work files Off=No"}, + + {"mod_gzip_min_http", mod_gzip_set_min_http, NULL, RSRC_CONF, TAKE1, + "Minimum HTTP support level to receive compression. 1001=HTTP/1.1"}, + + {"mod_gzip_minimum_file_size", mod_gzip_set_minimum_file_size, NULL, RSRC_CONF, TAKE1, + "The minimum size ( in bytes ) before compression will be attempted"}, + + {"mod_gzip_maximum_inmem_size", mod_gzip_set_maximum_inmem_size, NULL, RSRC_CONF, TAKE1, + "The maximum size ( in bytes ) to use for in-memory compression."}, + + {"mod_gzip_temp_dir", mod_gzip_set_temp_dir, NULL, RSRC_CONF, TAKE1, + "The directory to use for work files and compression cache"}, + + {"mod_gzip_item_include", mod_gzip_set_item_include, NULL, RSRC_CONF, TAKE1, + "Add the item the inclusion list"}, + + {"mod_gzip_item_exclude", mod_gzip_set_item_exclude, NULL, RSRC_CONF, TAKE1, + "Add the item the exclusion list"}, + + {NULL} +}; + +/* + * The actual module 'jump' table... + * + * If one of the fixed 'call' points has a valid function + * address then Apache will 'call' into it at the appropriate time. + * + * When the compressed object cache is engaged we will need to + * simply add some handlers for the URI detection and translation + * call point(s). + */ + +module MODULE_VAR_EXPORT gzip_module = +{ + STANDARD_MODULE_STUFF, + mod_gzip_init, /* initializer */ + NULL, /* create per-directory config structure */ + NULL, /* merge per-directory config structures */ + mod_gzip_create_config, /* create per-server config structure */ + mod_gzip_merge_config, /* merge per-server config structures */ + mod_gzip_cmds, /* command table */ + mod_gzip_handlers, /* handlers */ + NULL, /* translate_handler */ + NULL, /* check_user_id */ + NULL, /* check auth */ + NULL, /* check access */ + NULL, /* type_checker */ + NULL, /* pre-run fixups */ + NULL, /* logger */ + NULL, /* header parser */ + NULL, /* child_init */ + NULL, /* child_exit */ + NULL /* post read-request */ +}; + +#ifdef NETWARE +int main(int argc, char *argv[]) +{ + ExitThread(TSR_THREAD, 0); +} +#endif + +FILE *mod_gzip_open_output_file( +request_rec *r, +char *output_filename, +int *rc +) +{ + FILE *ifh; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_open_output_file():::"; + #endif + + /* + * Start... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Entry...\n",cn); + mod_gzip_printf( "%s: output_filename=[%s]\n",cn,output_filename); + #endif + + ifh = fopen( output_filename, "rb" ); /* Open in BINARY mode */ + + if ( !ifh ) /* The file failed to open... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ERROR: Cannot open file [%s]\n", + cn,output_filename); + #endif + + /* + * The workfile was created OK but now will not re-open. + * This is worth a strike in the ERROR log. + */ + + ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_ERR, r->server, + "mod_gzip: Cannot re-open output_filename=[%s]", + output_filename ); + + /* Return DECLINED and let default logic finish the request... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( NULL ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:WORK_OPENFAIL")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + *rc = DECLINED; /* Update caller's result code... */ + + return NULL; + + }/* End 'if ( !ifh )' */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: File is now open...\n",cn); + mod_gzip_printf( "%s: Exit > return( FILE *ifh ) >\n",cn); + #endif + + *rc = OK; /* Update caller's result code */ + + return ifh; /* Return the file handle */ + +}/* End of mod_gzip_open_output_file() */ + +int mod_gzip_encode_and_transmit( +request_rec *r, +char *source, +int source_is_a_file, +long input_size, +int nodecline +) +{ + GZP_CONTROL gzc; + GZP_CONTROL* gzp = &gzc; + + int rc = 0; + FILE *ifh = 0; + int bytesread = 0; + long output_size = 0; + long compression_ratio = 0; + char* gz1_ismem_obuf = 0; + int finalize_stats = 1; + + int gz1_ismem_obuf_was_allocated = 0; + + char content_length[20]; /* For Content-length updates */ + + #define MOD_GZIP_LARGE_BUFFER_SIZE 8192 + + char tmp[ MOD_GZIP_LARGE_BUFFER_SIZE + 2 ]; /* Scratch buffer */ + + char *actual_content_encoding_name = "gzip"; /* Adjustable */ + const char *compression_format; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_encode_and_transmit()"; + #endif + + void *modconf = r->server->module_config; + + #ifdef MOD_GZIP_USES_APACHE_LOGS + char log_info[40]; /* Scratch buffer */ + #endif + + /* + * Start... + * + * Establish a local pointer to module configuration data... + */ + + mod_gzip_conf *conf = + (mod_gzip_conf *) ap_get_module_config( modconf, &gzip_module ); + + #ifdef MOD_GZIP_DEBUG1 + + mod_gzip_printf( "%s: Entry...\n", cn); + mod_gzip_printf( "%s: source_is_a_file = %d\n", cn, source_is_a_file); + mod_gzip_printf( "%s: nodecline = %d\n", cn, nodecline); + + if ( source_is_a_file ) /* Show the filename... */ + { + mod_gzip_printf( "%s: source = [%s]\n", cn, source); + } + else /* Don't try to print the memory buffer... */ + { + mod_gzip_printf( "%s: source = MEMORY BUFFER\n", cn ); + } + + mod_gzip_printf( "%s: input_size = %ld\n", cn,(long)input_size); + + #endif /* MOD_GZIP_DEBUG1 */ + + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* This routine 'assumes' that the final result is 'OK' */ + /* and lets the remainder of the processing set the result */ + /* string to some other value, if necessary. */ + + /* Since we are now using the 'nodecline' flag and might */ + /* have to 'stand and deliver' then this allows the right */ + /* result code to appear in the log files even if we */ + /* cannot DECLINE the processing. */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"OK")); + + /* We can also update the 'input' size right away since it is known */ + + sprintf( log_info,"%d", (int) input_size ); + ap_table_setn( r->notes,"mod_gzip_input_size",ap_pstrdup(r->pool,log_info)); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + /* + * If the source has no length then DECLINE the processing... + */ + + if ( input_size < 1 ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ERROR: Input source has no valid length.\n",cn); + mod_gzip_printf( "%s: This request will not be processed...\n",cn); + #endif + + /* An existing request object with no length is worth a warning... */ + + ap_log_error( APLOG_MARK,APLOG_NOERRNO|APLOG_WARNING, r->server, + "mod_gzip: r->filename=[%s] has no length",r->filename ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:NO_I_LEN")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return DECLINED; + } + + /* + * If we're only supposed to send header information (HEAD request) + * then all we need to do is call ap_send_http_header() at this point + * and then return 'OK'... + */ + + if ( r->header_only ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: HEAD request only... ignore body data...\n",cn); + #endif + + /* + * Set outbound response header fields... + * + * NOTE: If this is just a HEAD request then + * there is no need to make the API call... + * + * ap_update_mtime( r, r->finfo.st_mtime ); + * + * ...and update the actual time. Use the time + * that's currently associated with the object. + */ + + ap_set_last_modified(r); + ap_set_etag(r); + ap_table_setn(r->headers_out, "Accept-Ranges", "bytes"); + + /* Start a timer for this transaction... */ + + ap_soft_timeout( "mod_gzip: HEAD request handler", r ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: r->content_type=[%s]\n",cn,r->content_type); + mod_gzip_printf( "%s: Call ap_send_http_header()...\n",cn); + #endif + + ap_send_http_header(r); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_send_http_header()...\n",cn); + mod_gzip_printf( "%s: Call ap_kill_timeout()...\n",cn); + #endif + + ap_kill_timeout(r); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_kill_timeout()...\n",cn); + mod_gzip_printf( "%s: Exit > return( OK ) >\n",cn); + #endif + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Return OK but distinguish it from a 'GET' request in logs... */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"OK:HEAD_ONLY")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + return OK; + + }/* End 'if( r->header_only )' */ + + /* + * See if the source meets the MINUMUM SIZE requirement... + * + * Default to 300 bytes as a minimum size requirement for it + * to even be worth a compression attempt. This works well as a + * minimum for both GZIP and ZLIB which are both LZ77 based and, + * as such, always have the potential to actually increase the + * size of the file. + * + * The value is a module global that can be adjusted 'on the fly' + * as load conditions change or as required for other reasons. + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: conf->minimum_file_size = %ld\n", + cn, (long) conf->minimum_file_size ); + #endif + + if ( input_size < (long) conf->minimum_file_size ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Source does not meet the minimum size requirement...\n",cn); + mod_gzip_printf( "%s: nodecline = %d\n",cn,nodecline); + #endif + + /* Set the 'mod_gzip_result' note value to something */ + /* that indicates this was too small... */ + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:TOO_SMALL")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + /* Is it OK to DECLINE?... */ + + if ( nodecline ) /* We have been told NOT to DECLINE */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: DECLINE is NOT allowed...\n",cn); + #endif + + /* Skip the compression phase and just set the output */ + /* control skid up to send the real input data... */ + + output_size = input_size; + + if ( source_is_a_file ) /* Source is a workfile... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Force send - source = FILE[%s]\n", + cn,source); + #endif + + strcpy( gzp->output_filename, source ); + gzp->output_ismem = 0; /* Output is a disk file */ + gz1_ismem_obuf = 0; /* Make sure this is NULL */ + gzp->output_ismem_obuf = 0; /* Not used for this method */ + gzp->output_ismem_obuflen = 0; /* Not used for this method */ + + ifh = mod_gzip_open_output_file( r, gzp->output_filename, &rc ); + + if ( !ifh ) /* The file failed to open... */ + { + /* We really MUST decline... */ + /* Logs have already been updated... */ + + return( rc ); + } + } + else /* Source is just a memory buffer... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Force send - source = MEMORY BUFFER\n",cn); + #endif + + gzp->output_ismem = 1; + gz1_ismem_obuf = source; + + gz1_ismem_obuf_was_allocated = 0; /* No 'free' is required */ + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: No compression attempt was made.\n",cn); + mod_gzip_printf( "%s: Advancing directly to transmit phase...\n",cn); + #endif + + goto mod_gzip_encode_and_transmit_send_start; /* Jump */ + } + else /* It's OK to DECLINE the processing... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: DECLINE is allowed...\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + return DECLINED; + } + } + else /* The source is larger than the minimum size requirement... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Source meets the minimum size requirement.\n",cn); + mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); + #endif + } + + /* + * We must now encode the requested object... + * + * Statistically speaking, most 'text/*' pages are + * less than 60k. XML documents are an exception. + * + * If the size of the requested object is less than 60k + * then go ahead and compress the source directly to a + * small memory buffer. If the requested object is greater + * than 60k then go ahead and swap the results to an output + * disk file and then send the contents of the result file. + * + * We can't ever allocate all the memory we want inside of + * a Server task thread so there must always be this kind + * of 'decision' making about when we can compress to + * a memory buffer ( Less than 60k ) and when we must + * compress to DISK. ( Greater than 60k ). + * + * There is a trade-off here between running the risk of + * too many tasks stealing away all the heap space and + * still maintaining performance. Given all the variables + * involved such as the true efficiency of the compression + * algorithm(s) and the speed of the CPU and the amount of + * memory/disk space available there is no 'real' answer to + * this dilemma other than relying on statistical data + * and empirical observations. The 60k limit on in-memory + * compression seems to strike a good balance and performs + * incredibly well under the heaviest of loads. + * + * At all times, the greatest benefit being gained is the + * appreciable reduction of data that must actually be + * sent by the TCP/IP sub-system and the reduced usage + * of those resources to perform the transmission task(s), + * + * The key, then, is to always strive for a balance where + * the time and resource usage it takes to compress a + * deliverable object will always be less than the processor + * burden that would otherwise be realized by handing the + * full, uncompressed object to the TCP/IP sub-system which + * always extend the time that the thread and all its + * locked resources must be maintained as well as the + * overhead for keeping a connection active any longer + * than is absolutely necessary. + * + * As long as the resource usage it takes to accomplish + * a significant reduction in the amount of data that + * must actually be processed by the remainder of the + * HTTP task thread and the TCP/IP sub-system itself + * is always less than the processor burden seen by + * NOT doing so then we are always 'ahead of the game'. + */ + + /* + * See if the object size exceeds the current MAXIMUM size + * to use for in-memory compression... + * + * See notes above about a range of 60k or so being the best + * value for heavy load conditions. + * + * This number is currently a global so it can be changed + * 'on the fly' and can 'breathe' as the load changes. + * It should probably become a thread specific variable + * so each task can have its 'own' max value depending + * on current load conditions. + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: conf->maximum_inmem_size = %ld\n", + cn, (long) conf->maximum_inmem_size ); + #endif + + /* + * Set up the INPUT target... + */ + + /* The size and type of the input source is always known */ + /* and was passed by the caller... */ + + if ( source_is_a_file ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Input source is file[%s]\n",cn,source); + #endif + + strcpy( gzp->input_filename, source ); + + gzp->input_ismem = 0; /* Input is a disk file */ + gzp->input_ismem_ibuf = 0; /* Source buffer */ + gzp->input_ismem_ibuflen = 0; /* Length of data */ + } + else + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Input source is a MEMORY BUFFER\n",cn); + #endif + + *gzp->input_filename = 0; /* Not used */ + + gzp->input_ismem = 1; /* Input is a memory buffer */ + gzp->input_ismem_ibuf = source; /* Source buffer */ + gzp->input_ismem_ibuflen = input_size; /* Length of data */ + } + + /* + * Set up the OUTPUT target... + */ + + gzp->decompress = 0; /* Perform encoding */ + + /* Recover the compression format we're supposed to use. */ + compression_format = ap_table_get(r->notes, "mod_gzip_compression_format"); + if (compression_format && strcmp(compression_format, "deflate") == 0) + { + actual_content_encoding_name = "deflate"; + gzp->compression_format = DEFLATE_FORMAT; + } + else + { + gzp->compression_format = GZIP_FORMAT; + } + + if ( input_size <= (long) conf->maximum_inmem_size ) + { + /* The input source is small enough to compress directly */ + /* to an in-memory output buffer... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Input source is small enough for in-memory compression.\n",cn); + #endif + + *gzp->output_filename = 0; /* Not used */ + gzp->output_ismem = 1; /* Output is a memory buffer */ + + /* + * Allocate a memory buffer to hold compressed output. + * + * For now this is borrowed from the heap for only + * the lifetime of this function call. If the stack + * can handle the current in-memory MAXSIZE then + * that will work just as well. + * + * Add at least 1000 bytes in case the compression + * algorithm(s) actually expands the source ( which is + * not likely but is always a possibility when using + * any LZ77 based compression such as GZIP or ZLIB ) + */ + + gz1_ismem_obuf = (char *) malloc( input_size + 1000 ); + + if ( !gz1_ismem_obuf ) + { + /* + * There wasn't enough memory left for another + * in-memory compression buffer so default to using + * an output disk file instead... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ERROR: Cannot allocate GZP memory...\n",cn); + mod_gzip_printf( "%s: Defaulting to output file method... \n",cn); + #endif + + gzp->output_ismem = 0; /* Switch to using a disk file */ + } + + else /* We got the memory we need for in-memory compression... */ + { + /* Set the local flag which tells the exit logic */ + /* that 'gz1_ismem_obuf' was actually allocated */ + /* and not simply set to 'source' so that the */ + /* allocation can be 'freed' on exit... */ + + gz1_ismem_obuf_was_allocated = 1; /* 'free' is required */ + + /* Compression codecs require a 'clean' buffer so */ + /* we need to spend the cycles for a memset() call. */ + + memset( gz1_ismem_obuf, 0, ( input_size + 1000 ) ); + + /* Set OUTPUT buffer control variables... */ + + gzp->output_ismem_obuf = gz1_ismem_obuf; + gzp->output_ismem_obuflen = input_size + 1000; + } + + }/* End 'if ( input_size <= conf->maximum_inmem_size )' */ + + /* + * If we are unable ( or it is unadvisable ) to use + * an in-memory output buffer at this time then the + * 'gzp->output_ismem' flag will still be ZERO at this point. + */ + + if ( gzp->output_ismem != 1 ) + { + /* + * The input source is NOT small enough to compress to an + * in-memory output buffer or it is unadvisable to do + * so at this time so just use an output file... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Input source too big for in-memory compression.\n",cn); + #endif + + /* + * Create the GZP output target name... + */ + + mod_gzip_create_unique_filename( + (mod_gzip_conf *) conf, + (char *) gzp->output_filename, + MOD_GZIP_MAX_PATH_LEN + ); + + /* + * COMPRESSION OBJECT CACHE + * + * TODO: Obviously one place to add the compression cache + * logic is right here. If there is already a pre-compressed + * version of the requested entity sitting in the special + * compression cache and it is 'fresh' then go ahead and + * send it as the actual response. Add a CRC/MD5 checksum + * to the stored compression object(s) so we can quickly + * determine if the compressed object is 'fresh'. Relying + * on Content-length and/or modification time/date won't handle + * all possible expiration scenarios for compressed objects. + */ + + gzp->output_ismem = 0; /* Output is a disk file */ + + gz1_ismem_obuf = 0; /* Make sure this is NULL */ + + /* Set OUTPUT buffer control variables... */ + + gzp->output_ismem_obuf = 0; /* Not used for this method */ + gzp->output_ismem_obuflen = 0; /* Not used for this method */ + + }/* End 'else' */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: gzp->decompress = %d\n" ,cn,gzp->decompress); + mod_gzip_printf( "%s: gzp->compression_format = %d\n",cn,gzp->compression_format); + mod_gzip_printf( "%s: gzp->input_ismem = %d\n", cn,gzp->input_ismem); + mod_gzip_printf( "%s: gzp->output_ismem = %d\n", cn,gzp->output_ismem); + mod_gzip_printf( "%s: gzp->input_filename = [%s]\n",cn,gzp->input_filename); + mod_gzip_printf( "%s: gzp->output_filename = [%s]\n",cn,gzp->output_filename); + mod_gzip_printf( "%s: Call gzp_main()...\n",cn); + #endif + + rc = gzp_main( gzp ); /* Perform the compression... */ + + output_size = (long) gzp->bytes_out; + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back gzp_main()...\n",cn); + mod_gzip_printf( "%s: input_size = %ld\n",cn,(long)input_size); + mod_gzip_printf( "%s: output_size = %ld\n",cn,(long)output_size); + mod_gzip_printf( "%s: gzp->bytes_out = %ld\n",cn,(long)gzp->bytes_out); + mod_gzip_printf( "%s: Bytes saved = %ld\n",cn, + (long)input_size-gzp->bytes_out ); + #endif + + /* Compute the compresion ratio for access.log and */ + /* internal statistics update... */ + + compression_ratio = 0; /* Reset */ + + /* Prevent 'Divide by zero' error... */ + + if ( ( input_size > 0 ) && + ( output_size > 0 ) ) + { + compression_ratio = 100 - (int) + ( output_size * 100L / input_size ); + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Compression ratio = %ld percent\n",cn, + (long) compression_ratio ); + #endif + + /* + * Update the logs with output size information + * as soon as it is known in case there was an + * error or we must DECLINE. At least the logs + * will then show the sizes and the results. + */ + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + sprintf( log_info,"%d", (int) output_size ); + ap_table_setn( r->notes,"mod_gzip_output_size",ap_pstrdup(r->pool,log_info)); + + sprintf( log_info,"%d", (int) compression_ratio ); + ap_table_setn( r->notes,"mod_gzip_compression_ratio",ap_pstrdup(r->pool,log_info)); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + /* + * Evaluate the compression result(s)... + * + * If the compression pass failed then the output length + * will be ZERO bytes... + */ + + if ( output_size < 1 ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Compressed version has no length.\n",cn); + mod_gzip_printf( "%s: Sending the original version uncompressed...\n",cn); + #endif + + finalize_stats = 0; /* Don't update stats again */ + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: gzp_main(ERR): r->uri=[%s] input_size=%ld output_size=%ld gzp->output_filename=[%s]", + r->uri,(long)input_size,(long)output_size,gzp->output_filename); + } + + /* + * NOTE: It's perfectly possible that we have made it all + * the way to here and the straight execution of the + * compressor is the first time there has been a check for + * the actual existence of the requested object. This will + * be especially true for STATIC requests. + * + * The compressor itself will fail if/when it can't find + * the input target so 'DECLINED:NO_O_LEN' could simply + * means the file was not found. In these cases the Apache + * logs should also contain the correct '404 Not Found' code. + */ + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:NO_O_LEN")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + /* Is it OK to DECLINE?... */ + + if ( nodecline ) /* We have been told NOT to DECLINE... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: DECLINE is NOT allowed...\n",cn); + #endif + + /* Just set the output control skid */ + /* to send the real input data... */ + + output_size = input_size; + + if ( source_is_a_file ) /* Source is a workfile... */ + { + strcpy( gzp->output_filename, source ); + + gzp->output_ismem = 0; /* Output is a disk file */ + gz1_ismem_obuf = 0; /* Make sure this is NULL */ + gzp->output_ismem_obuf = 0; /* Not used for this method */ + gzp->output_ismem_obuflen = 0; /* Not used for this method */ + + ifh = mod_gzip_open_output_file( r, gzp->output_filename, &rc ); + + if ( !ifh ) /* We really must DECLINE... */ + { + return( rc ); + } + } + else /* Source is just a memory buffer... */ + { + gzp->output_ismem = 1; + gz1_ismem_obuf = source; + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Advancing directly to transmit phase...\n",cn); + #endif + + goto mod_gzip_encode_and_transmit_send_start; /* Jump */ + } + else /* It's OK to DECLINE the processing... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: DECLINE is allowed...\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + /* Free the local memory buffer allocation ( if necessary )... */ + + if ( gz1_ismem_obuf ) + { + /* The pointer may have been 'borrowed' and was */ + /* not actually 'allocated' so check the flag... */ + + if ( gz1_ismem_obuf_was_allocated ) + { + free( gz1_ismem_obuf ); + + gz1_ismem_obuf = 0; + gz1_ismem_obuf_was_allocated = 0; + + }/* End 'if( gz1_ismem_obuf_was_allocated )' */ + + }/* End 'if( gz1_ismem_obuf )' */ + + /* Return... */ + + return DECLINED; + } + + }/* End 'if( output_size < 1 )' */ + + /* + * If we reach this point then the compressed version has + * a valid length. Time to see if it it's worth sending. + * + * If the original source is SMALLER than the COMPRESSED + * version ( not likely but possible with LZ77 ) then + * just punt and send the original source... + */ + + if ( output_size > input_size ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Compressed version is larger than original.\n",cn); + mod_gzip_printf( "%s: Sending the original version uncompressed...\n",cn); + #endif + + finalize_stats = 0; /* Don't update stats again */ + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + /* Each 'DECLINE' condition provides a short ':WHYTAG' for logs */ + + ap_table_setn( + r->notes,"mod_gzip_result",ap_pstrdup(r->pool,"DECLINED:ORIGINAL_SMALLER")); + + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + /* Is it OK to DECLINE?... */ + + if ( nodecline ) /* We have been told NOT to DECLINE... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: DECLINE is NOT allowed...\n",cn); + #endif + + /* Just set the output control skid */ + /* to send the real input data... */ + + output_size = input_size; + + if ( source_is_a_file ) /* Source is a workfile... */ + { + strcpy( gzp->output_filename, source ); + + gzp->output_ismem = 0; /* Output is a disk file */ + gz1_ismem_obuf = 0; /* Make sure this is NULL */ + gzp->output_ismem_obuf = 0; /* Not used for this method */ + gzp->output_ismem_obuflen = 0; /* Not used for this method */ + + ifh = mod_gzip_open_output_file( r, gzp->output_filename, &rc ); + + if ( !ifh ) /* We really must DECLINE... */ + { + return( rc ); + } + } + else /* Source is just a memory buffer... */ + { + gzp->output_ismem = 1; + gz1_ismem_obuf = source; + + gz1_ismem_obuf_was_allocated = 0; /* No 'free' is required */ + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Advancing directly to transmit phase...\n",cn); + #endif + + goto mod_gzip_encode_and_transmit_send_start; /* Jump */ + } + else /* It's OK to DECLINE the processing... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: DECLINE is allowed...\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + /* Free the local memory buffer allocation ( if necessary )... */ + + if ( gz1_ismem_obuf ) + { + /* The pointer may have been 'borrowed' and was */ + /* not actually 'allocated' so check the flag... */ + + if ( gz1_ismem_obuf_was_allocated ) + { + free( gz1_ismem_obuf ); + + gz1_ismem_obuf = 0; + gz1_ismem_obuf_was_allocated = 0; + + }/* End 'if( gz1_ismem_obuf_was_allocated )' */ + + }/* End 'if( gz1_ismem_obuf )' */ + + /* Return... */ + + return DECLINED; + } + } + else /* Compressed version is smaller than original... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Compressed version is smaller than original.\n",cn); + mod_gzip_printf( "%s: Sending the compressed version...\n",cn); + #endif + } + + /* + * If an output workfile was used then make SURE it is going + * to reopen before beginning the transmit phase. + * + * If we begin the transmit phase before discovering a problem + * re-opening the workfile then we have lost the chance to + * DECLINE the processing and allow the default logic to + * deliver the requested object. + * + * This only matters for 'static' files or times when the + * 'nodecline' flag is FALSE and it is actually OK to DECLINE. + */ + + if ( !gzp->output_ismem ) /* Workfile was used... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Opening compressed output file [%s]...\n", + cn, gzp->output_filename ); + #endif + + ifh = mod_gzip_open_output_file( r, gzp->output_filename, &rc ); + + if ( !ifh ) /* The file failed to open... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: ERROR: Cannot re-open file [%s]\n", + cn,gzp->output_filename); + #endif + + /* We really must DECLINE... */ + /* Logs have already been updated... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif + + return DECLINED; + + }/* End 'if ( !ifh )' */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Workile re-opened OK...\n",cn); + #endif + + }/* End 'if ( !gzp->output_ismem )' */ + + /* + * IMPORTANT + * + * If we have made it to here then all is well and only + * now can we set the encoding for this response... + * + * We must do this 'above' any jump points that might + * be sending the 'untouched' data or the browser will + * get confused regarding the actual content. + */ + + r->content_encoding = actual_content_encoding_name; + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: r->content_encoding is now [%s]\n", + cn, r->content_encoding ); + #endif + + /* + * Begin the transmission phase... + * + * Even if the 'nodecline' flag is TRUE if we encounter + * any fatal errors at this point we must 'DECLINE'. + */ + + mod_gzip_encode_and_transmit_send_start: ; /* <<-- Jump point */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Starting transmit phase...\n",cn); + #endif + + /* + * We are ready to send content so update the "Content-length:" + * response field and send the HTTP header. We don't need to + * worry about setting the "Content-type:" field since we are + * simply accepting the value that was passed to us as indicated + * by the inbound r->content_type string. The "Content-type:" + * field never changes even when multiple encodings have been + * applied to the content itself. + * + * This version does not make any attempt to use 'Chunked' + * transfer encoding since there are so many user agents that + * do not support it and when Content-length is known prior + * to header transmission ( as is always the case with this + * code ) then there is simply no reason to even think about + * using the slower and more problematic 'Chunked' encoding + * transfer method. + */ + + /* + * Set relevant outbound response header fields... + * + * Be sure to call ap_update_mtime() before calling + * ap_set_last_modified() to be sure the 'current' + * time is actually updated in outbound response header. + */ + + ap_update_mtime( r, r->finfo.st_mtime ); + ap_set_last_modified(r); + ap_set_etag(r); + ap_table_setn(r->headers_out, "Accept-Ranges", "bytes"); + + /* + * Start a timer for this transaction... + */ + + ap_soft_timeout( "mod_gzip: Encoded data transmit", r ); + + /* + * Return the length of the compressed output in + * the response header. + * + * See notes above about there never being a requirement + * to use 'Chunked' transfer encoding since the content + * length is always 'known' prior to transmission. + */ + + sprintf( content_length, "%ld", output_size ); + ap_table_set (r->headers_out, "Content-Length", content_length ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: output_size = %ld\n",cn,(long)output_size); + mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); + mod_gzip_printf( "%s: Call ap_send_http_header()...\n",cn); + #endif + + ap_send_http_header(r); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_send_http_header()...\n",cn); + #endif + + /* + * Send the response... + * + * If the requested object was small enough to fit into + * our special in-memory output space then send the result + * directly from memory. If the requested object exceeded + * the minimum size for in-memory compression then an output + * file was used so re-open and send the results file... + */ + + if ( gzp->output_ismem ) + { + /* Send the in-memory output buffer... */ + + #ifdef MOD_GZIP_DEBUG1 + + mod_gzip_printf( "%s: Sending the in-memory output buffer...\n",cn); + mod_gzip_printf( "%s: output_size = %ld\n",cn,(long)output_size); + + /* Turn this 'on' for VERY verbose diagnostics... + #define MOD_GZIP_DUMP_JUST_BEFORE_SENDING + */ + #ifdef MOD_GZIP_DUMP_JUST_BEFORE_SENDING + mod_gzip_hexdump( gz1_ismem_obuf, output_size ); + #endif + + #endif /* MOD_GZIP_DEBUG1 */ + + /* This module can use either ap_send_mmap() or ap_rwrite()... */ + + #ifdef MOD_GZIP_USES_AP_SEND_MMAP + + /* Use ap_send_mmap() call to send the data... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call ap_send_mmap( gz1_ismem_obuf, bytes=%ld )...\n", + cn, (long)output_size ); + #endif + + ap_send_mmap( gz1_ismem_obuf, r, 0, output_size ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_send_mmap( gz1_ismem_obuf, bytes=%ld )...\n", + cn, (long)output_size ); + #endif + + #else /* !MOD_GZIP_USES_AP_SEND_MMAP */ + + /* Use ap_rwrite() call to send the data... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call ap_rwrite( gz1_ismem_obuf, bytes=%ld )...\n", + cn, (long)output_size ); + #endif + + ap_rwrite( gz1_ismem_obuf, output_size, r ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_rwrite( gz1_ismem_obuf, bytes=%ld )...\n", + cn, (long)output_size ); + #endif + + #endif /* MOD_GZIP_USES_AP_SEND_MMAP */ + + /* Stop the timer... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call ap_kill_timeout()...\n",cn); + #endif + + ap_kill_timeout(r); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_kill_timeout()...\n",cn); + #endif + + /* Free the local memory buffer allocation ( if necessary )... */ + + if ( gz1_ismem_obuf ) + { + /* The pointer may have been 'borrowed' and was */ + /* not actually 'allocated' so check the flag... */ + + if ( gz1_ismem_obuf_was_allocated ) + { + free( gz1_ismem_obuf ); + + gz1_ismem_obuf = 0; + gz1_ismem_obuf_was_allocated = 0; + + }/* End 'if( gz1_ismem_obuf_was_allocated )' */ + + }/* End 'if( gz1_ismem_obuf )' */ + } + else /* Output workfile was used so send the contents... */ + { + /* + * NOTE: The workfile was already 're-opened' up above + * before the transmit phase began so that we still had + * the chance to return DECLINED if, for some reason, the + * workfile could not be re-opened. + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: sizeof( tmp ) = %d\n",cn,sizeof(tmp)); + mod_gzip_printf( "%s: Transmit buffer size = %d\n",cn,sizeof(tmp)); + mod_gzip_printf( "%s: Sending compressed output file...\n",cn); + #endif + + for (;;) + { + bytesread = fread( tmp, 1, sizeof( tmp ), ifh ); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back fread(): bytesread=%d\n",cn,bytesread); + #endif + + if ( bytesread < 1 ) break; /* File is exhausted... We are done...*/ + + /* This module can use either ap_send_mmap() or ap_rwrite()... */ + + #ifdef MOD_GZIP_USES_AP_SEND_MMAP + + /* Use ap_send_mmap() call to send the data... */ + + ap_send_mmap( tmp, r, 0, bytesread ); + + #else /* !MOD_GZIP_USES_AP_SEND_MMAP */ + + /* Use ap_rwrite() call to send the data... */ + + ap_rwrite( tmp, bytesread, r ); + + #endif /* MOD_GZIP_USES_AP_SEND_MMAP */ + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Done Sending compressed output file...\n",cn); + mod_gzip_printf( "%s: Closing workfile [%s]...\n", + cn, gzp->output_filename ); + #endif + + fclose( ifh ); /* Close the input file */ + + /* Stop the timer before attempting to delete the workfile... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Call ap_kill_timeout()...\n",cn); + #endif + + ap_kill_timeout(r); + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Back ap_kill_timeout()...\n",cn); + #endif + + /* Delete the workfile if 'keep' flag is OFF... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: conf->keep_workfiles = %d\n", + cn, conf->keep_workfiles ); + #endif + + if ( !conf->keep_workfiles ) /* Default is OFF */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Deleting workfile [%s]...\n", + cn, gzp->output_filename ); + #endif + + #ifdef _WIN32 + DeleteFile( gzp->output_filename ); + #else /* !_WIN32 */ + unlink( gzp->output_filename ); + #endif /* _WIN32 */ + } + else /* Keep all work files... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Keeping workfile [%s]...\n", + cn, gzp->output_filename ); + #endif + } + + }/* End 'else' that sends compressed workfile */ + + /* + * The compressed object has been sent... + */ + + #ifdef MOD_GZIP_USES_APACHE_LOGS + + if ( finalize_stats ) + { + sprintf( log_info,"%d", (int) output_size ); + ap_table_setn( r->notes,"mod_gzip_output_size",ap_pstrdup(r->pool,log_info)); + + sprintf( log_info,"%d", (int) compression_ratio ); + ap_table_setn( r->notes,"mod_gzip_compression_ratio",ap_pstrdup(r->pool,log_info)); + + } + #endif /* MOD_GZIP_USES_APACHE_LOGS */ + + if ( r->server->loglevel == APLOG_DEBUG ) + { + /* + * If LogLevel is 'debug' then show the compression results + * in the log(s)... + */ + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: r->uri=[%s] OK: Bytes In:%ld Out:%ld Compression: %ld pct.", + r->uri, + (long) input_size, + (long) output_size, + (long) compression_ratio + ); + + }/* End 'if( r->server->loglevel == APLOG_DEBUG )' */ + + /* + * Return OK to the Server to indicate SUCCESS... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( OK ) >\n",cn); + #endif + + return OK; + +}/* End of mod_gzip_encode_and_transmit() */ + +int mod_gzip_ismatch( char *s1, char *s2, int len1, int haswilds ) +{ + /* Behaves just like strncmp() but IGNORES differences */ + /* between FORWARD or BACKWARD slashes in a STRING, allows */ + /* wildcard matches, and can ignore length value. */ + /* It uses pointers and is faster than using lib calls. */ + + /* Unlike strncmp() this routine returns TRUE (1) if the */ + /* strings match and FALSE (0) if they do not... */ + + int i; + int l1; + int l2; + int distance; + char ch1; + char ch2; + + /* WARNING! We MUST have a check for 'NULL' on the pointer(s) */ + /* themselves or we might GP */ + + if ( ( s1 == 0 ) || ( s2 == 0 ) ) + { + /* SAFETY! If pointer itself if NULL */ + /* don't enter LOOP... */ + + return( 0 ); /* Return FALSE for NOMATCH... */ + } + + distance = len1; /* Default to value passed... */ + + /* If no length was given then the 2 strings must already */ + /* have the same length or this is a 'no match'... */ + /* Exception to this is if wildcards are present. */ + + if ( len1 == 0 ) + { + l1 = strlen( s1 ); + l2 = strlen( s2 ); + + /* If either string had a valid pointer but is EMPTY */ + /* then this is an automatic 'no match'... */ + + if ((l1==0)||(l2==0)) + { + return( 0 ); /* Return FALSE for NOMATCH... */ + } + + if ( l1 != l2 ) + { + if ( haswilds == 0 ) + { + return( 0 ); /* Return FALSE for NOMATCH... */ + } + } + + /* If the lengths ARE equal then this is a possible */ + /* match. Use the smaller of the 2 values for scan...*/ + + if ( l1 < l2 ) distance = l1; + else distance = l2; + } + + /* Final check... if distance is still 0 then this */ + /* is an automatic 'no match'... */ + + if ( distance == 0 ) + { + return( 0 ); /* Return FALSE for NOMATCH... */ + } + + /* Do the deed... */ + + for ( i=0; icontent_type ) clen = strlen( r->content_type ); + if ( r->handler ) hlen = strlen( r->handler ); + + if ( r->filename ) + { + flen = strlen( r->filename ); + p1 = r->filename; + while(*p1!=0){if (*p1=='.') file_extension=p1; p1++;} + if ( file_extension ) file_extension_len = strlen( file_extension ); + } + + #ifdef MOD_GZIP_DEBUG1 + + mod_gzip_printf( "%s: Entry...\n",cn); + mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); + mod_gzip_printf( "%s: clen = %d\n", cn,clen); + mod_gzip_printf( "%s: r->handler = [%s]\n",cn,r->handler); + mod_gzip_printf( "%s: hlen = %d\n", cn,hlen); + mod_gzip_printf( "%s: r->filename = [%s]\n",cn,r->filename); + mod_gzip_printf( "%s: flen = %d\n", cn,flen); + mod_gzip_printf( "%s: file_extension = [%s]\n",cn,file_extension); + mod_gzip_printf( "%s: file_extension_len = %d\n", cn,file_extension_len); + + #endif /* MOD_GZIP_DEBUG1 */ + + /* + * Sanity checks... + */ + + if ( ( hlen == 0 ) && ( clen == 0 ) ) + { + /* + * If the header analysis and/or negotiation phase has + * determined this to be a CGI script then the r->content_type + * field will be (null) but r->handler will contain "cgi-script". + * or "php-script" or the like. + * + * If the analysis has determined this is a static file + * then r->handler will be (null) but the r->content_type + * field will be "text/html" or "text/plain" or whatever. + * + * Both the r->content_type field and the r->handler + * field are empty. Ignore this one... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Both hlen and clen are ZERO...\n",cn); + mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_DECLINED1 ) >\n",cn); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: There is no valid r->handler or r->content_length "); + } + + return( MOD_GZIP_IMAP_DECLINED1 ); + } + + /* + * Perform 2 passes at the Include/Exclude list... + * + * The first pass is the higher-priority EXCLUSION check. + * The second pass is the lower-priority INCLUSION check. + */ + + for ( pass=0; pass<2; pass++ ) + { + + pass_result = 0; /* Reset result */ + + if ( pass == 0 ) /* EXCLUSION CHECK */ + { + filter_value = 0; + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: EXCLUSION CHECK...\n",cn); + #endif + } + else if ( pass == 1 ) /* INCLUSION CHECK */ + { + filter_value = 1; + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: INCLUSION CHECK...\n",cn); + #endif + } + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: pass = %d\n", cn, pass ); + mod_gzip_printf( "%s: filter_value = %d\n", cn, filter_value ); + mod_gzip_printf( "%s: mgc->imap_total_entries = %d\n", cn, + (int) mgc->imap_total_entries ); + #endif + + for ( x=0; ximap_total_entries; x++ ) + { + if ( r->server->loglevel == APLOG_DEBUG ) + { + /* Show the lookups in the Apache ERROR log if DEBUG is on */ + + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: mgc->imap[%3.3d] = i%2.2d t%4.4d a%4.4d n[%s]", + x, + mgc->imap[x].include, + mgc->imap[x].type, + mgc->imap[x].action, + mgc->imap[x].name + ); + } + + #ifdef MOD_GZIP_DEBUG1 + + mod_gzip_printf( "%s: --------------------------------------------\n",cn); + mod_gzip_printf( "%s: r->handler = [%s]\n",cn,r->handler); + mod_gzip_printf( "%s: r->content_type = [%s]\n",cn,r->content_type); + mod_gzip_printf( "%s: r->filename = [%s]\n",cn,r->filename); + mod_gzip_printf( "%s: file_extension = [%s]\n",cn,file_extension); + mod_gzip_printf( "%s: mgc->imap[%3.3d].include = %d\n",cn,x,mgc->imap[x].include); + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d\n",cn,x,mgc->imap[x].type); + + if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISMIME ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISMIME\n",cn,x); + } + else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISEXT ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISEXT\n",cn,x); + } + else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISHANDLER ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_ISHANDLER\n",cn,x); + } + else /* Unrecognized item type... */ + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].type = MOD_GZIP_IMAP_IS??? Unknown type\n",cn,x); + } + + mod_gzip_printf( "%s: mgc->imap[%3.3d].action = %d\n", cn,x,mgc->imap[x].action); + + if ( mgc->imap[x].action == MOD_GZIP_IMAP_DYNAMIC1 ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_DYNAMIC1\n",cn,x); + } + else if ( mgc->imap[x].action == MOD_GZIP_IMAP_STATIC1 ) + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_STATIC1\n",cn,x); + } + else /* Unrecognized action type... */ + { + mod_gzip_printf( "%s: mgc->imap[%3.3d].action = MOD_GZIP_IMAP_??? Unknown action\n",cn,x); + } + + mod_gzip_printf( "%s: mgc->imap[%3.3d].name = [%s]\n",cn,x,mgc->imap[x].name); + + #endif /* MOD_GZIP_DEBUG1 */ + + /* 'filter_value' mirrors 'pass' value for now but this might */ + /* not always be true. First pass is EXCLUDE and second is INCLUDE */ + + if ( mgc->imap[x].include == filter_value ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: This record matches filter_value %d\n", + cn, filter_value ); + mod_gzip_printf( "%s: The record will be checked...\n",cn); + #endif + + /* + * Set work values for this record... + */ + + this_type = mgc->imap[x].type; + this_action = mgc->imap[x].action; + this_name = mgc->imap[x].name; + + /* + * If the header analysis and/or negotiation phase has + * determined this to be a CGI script then the r->content_type + * field will be (null) but r->handler will contain "cgi-script". + * + * If the analysis has determined this is a static file + * then r->handler will be (null) but the r->content_type + * field will be "text/html" or "text/plain" or whatever. + */ + + if ( hlen > 0 ) /* r->handler field has a value... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: hlen has value...\n",cn); + #endif + + if ( this_type == MOD_GZIP_IMAP_ISHANDLER ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: this_type = ISHANDLER\n",cn); + mod_gzip_printf( "%s: Call mod_gzip_ismatch(%s,%s,0,0)...\n", + cn, this_name, r->handler ); + #endif + + /* mod_gzip_ismatch()... */ + + /* The 2 strings must match exactly so */ + /* pass '0' for parm 3... */ + + /* Wildcard matches are not allowed for */ + /* handler strings like 'cgi-script' so */ + /* Fourth parm should be 0.. */ + + if ( mod_gzip_ismatch( + this_name, (char *)r->handler,0,0) ) + { + pass_result = 1; /* We found a match */ + action_flag = this_action; /* What to do */ + break; /* Stop now */ + } + + }/* End 'if ( this_type == MOD_GZIP_IMAP_ISHANDLER )' */ + + }/* End 'if( hlen > 0 )' */ + + if ( clen > 0 ) /* r->content_type field has a value... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: clen has value...\n",cn); + #endif + + if ( this_type == MOD_GZIP_IMAP_ISMIME ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: this_type = ISMIME\n",cn); + mod_gzip_printf( "%s: Wildcards matches are OK for MIME types.\n",cn); + mod_gzip_printf( "%s: Call mod_gzip_ismatch(%s,%s,0,1)...\n", + cn, this_name, r->content_type ); + #endif + + /* mod_gzip_ismatch()... */ + + /* Wildcard matches are ALLOWED for */ + /* MIME type strings like 'cgi-script' */ + /* so fourth parm should be 1... */ + + if ( mod_gzip_ismatch( + this_name, (char *)r->content_type, 0, 1 ) ) + { + pass_result = 1; /* We found a match */ + action_flag = this_action; /* What to do */ + break; /* Stop now */ + } + + }/* End 'if ( this_type == MOD_GZIP_IMAP_ISMIME )' */ + + }/* End 'if( clen > 0 )' */ + + if ( flen > 0 ) /* r->filename field has a value... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: flen has value...\n",cn); + #endif + + if ( this_type == MOD_GZIP_IMAP_ISEXT ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: this_type = ISEXT\n",cn); + #endif + + if ( file_extension_len > 0 ) /* There is a file extension */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: file_extension_len has value...\n",cn); + mod_gzip_printf( "%s: Call mod_gzip_ismatch(%s,%s,0,0)...\n", + cn, this_name, file_extension ); + #endif + + /* mod_gzip_ismatch()... */ + + /* The 2 strings must match exactly so */ + /* pass '0' for parm 3... */ + + /* Wildcard matches are not allowed for */ + /* file extensions like '.html' so */ + /* Fourth parm should be 0.. */ + + if ( mod_gzip_ismatch( + this_name, file_extension, 0, 0 ) ) + { + pass_result = 1; /* We found a match */ + action_flag = this_action; /* What to do */ + break; /* Stop now */ + } + + }/* End 'if( file_extension_len > 0 )' */ + + }/* End 'if( this_type == MOD_GZIP)IMAP_ISEXT )' */ + + }/* End 'if( flen > 0 )' */ + + }/* End 'if ( mgc->imap[x].include == filter )' */ + + else /* The record did not match the current 'filter' value... */ + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: This record does NOT match filter_value %d\n", + cn, filter_value ); + mod_gzip_printf( "%s: The record has been SKIPPED...\n",cn); + #endif + } + + }/* End 'x' loop that looks at 'filtered' records... */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: --------------------------------------------\n",cn); + mod_gzip_printf( "%s: pass_result = %d\n",cn,pass_result); + #endif + + if ( pass_result ) /* We are done... */ + { + if ( pass == 0 ) item_is_excluded = 1; + else item_is_included = 1; + + break; /* Break out of 'pass' loop now... */ + } + + }/* End 'pass' loop */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: item_is_excluded = %d\n",cn,item_is_excluded); + mod_gzip_printf( "%s: item_is_included = %d\n",cn,item_is_included); + mod_gzip_printf( "%s: action_flag = %d\n",cn,action_flag); + #endif + + if ( item_is_excluded ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: The item is excluded...\n",cn); + mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_DECLINED1 ) >\n",cn); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: This item is EXCLUDED as per httpd.conf"); + } + + return( MOD_GZIP_IMAP_DECLINED1 ); + } + + else if ( item_is_included ) + { + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: The item is included...\n",cn); + mod_gzip_printf( "%s: Exit > return( action_flag = %d ) >\n",cn,action_flag); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: This item is INCLUDED as per httpd.conf"); + } + + return( action_flag ); /* STATIC1 or DYNAMIC1 */ + } + + /* + * Default action is to DECLINE processing... + */ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_DECLINED1 ) >\n",cn); + #endif + + if ( r->server->loglevel == APLOG_DEBUG ) + { + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: This item was NOT FOUND in any mod_gzip httpd item record."); + ap_log_error( "",0,APLOG_NOERRNO|APLOG_DEBUG, r->server, + "mod_gzip: This item will NOT be processed."); + } + + return( MOD_GZIP_IMAP_DECLINED1 ); + +}/* End of mod_gzip_get_action_flag() */ + +/*--------------------------------------------------------------------------*/ +/* ALL SOURCE CODE BELOW THIS POINT IS COMPRESSION SPECIFIC... */ +/*--------------------------------------------------------------------------*/ + +#define USE_GATHER +extern MODULE_VAR_EXPORT int ap_suexec_enabled; +extern API_EXPORT(void) +ap_internal_redirect_handler(const char *new_uri, request_rec *); +long mod_gzip_ap_send_fb( +BUFF *fb, +request_rec *r, +int *final_return_code +); +long mod_gzip_ap_send_fb_length( +BUFF *fb, +request_rec *r, +long length, +int *final_return_code +); +#define DEFAULT_LOGBYTES 10385760 +#define DEFAULT_BUFBYTES 1024 +static int mod_gzip_cgi_child(void *child_stuff, child_info *pinfo); +typedef struct { + char *logname; + long logbytes; + int bufbytes; +} cgi_server_conf; +struct mod_gzip_cgi_child_stuff { +#ifdef TPF + TPF_FORK_CHILD t; +#endif + request_rec *r; + int nph; + int debug; + char *argv0; +}; +static int is_scriptaliased( request_rec *r ) +{ + const char *t = ap_table_get(r->notes, "alias-forced-type"); + return t && (!strcasecmp(t, "cgi-script")); +} +static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret, + int show_errno, char *error) +{ + FILE *f; + struct stat finfo; + ap_log_rerror(APLOG_MARK, show_errno|APLOG_ERR, r, + "%s: %s", error, r->filename); + if (!conf->logname || + ((stat(ap_server_root_relative(r->pool, conf->logname), &finfo) == 0) + && (finfo.st_size > conf->logbytes)) || + ((f = ap_pfopen(r->pool, ap_server_root_relative(r->pool, conf->logname), + "a")) == NULL)) { + return ret; + } + fprintf(f, "%%%% [%s] %s %s%s%s %s\n", ap_get_time(), r->method, r->uri, + r->args ? "?" : "", r->args ? r->args : "", r->protocol); + fprintf(f, "%%%% %d %s\n", ret, r->filename); + fprintf(f, "%%error\n%s\n", error); + ap_pfclose(r->pool, f); + return ret; +} +static int log_script(request_rec *r, cgi_server_conf * conf, int ret, + char *dbuf, const char *sbuf, BUFF *script_in, BUFF *script_err) +{ + array_header *hdrs_arr = ap_table_elts(r->headers_in); + table_entry *hdrs = (table_entry *) hdrs_arr->elts; + char argsbuffer[HUGE_STRING_LEN]; + FILE *f; + int i; + struct stat finfo; + if (!conf->logname || + ((stat(ap_server_root_relative(r->pool, conf->logname), &finfo) == 0) + && (finfo.st_size > conf->logbytes)) || + ((f = ap_pfopen(r->pool, ap_server_root_relative(r->pool, conf->logname), + "a")) == NULL)) { + while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_in) > 0) + continue; +#if defined(_WIN32) || defined(NETWARE) + while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, r, + "%s", argsbuffer); + } +#else + while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) + continue; +#endif + return ret; + } + fprintf(f, "%%%% [%s] %s %s%s%s %s\n", ap_get_time(), r->method, r->uri, + r->args ? "?" : "", r->args ? r->args : "", r->protocol); + fprintf(f, "%%%% %d %s\n", ret, r->filename); + fputs("%request\n", f); + for (i = 0; i < hdrs_arr->nelts; ++i) { + if (!hdrs[i].key) + continue; + fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); + } + if ((r->method_number == M_POST || r->method_number == M_PUT) + && *dbuf) { + fprintf(f, "\n%s\n", dbuf); + } + fputs("%response\n", f); + hdrs_arr = ap_table_elts(r->err_headers_out); + hdrs = (table_entry *) hdrs_arr->elts; + for (i = 0; i < hdrs_arr->nelts; ++i) { + if (!hdrs[i].key) + continue; + fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val); + } + if (sbuf && *sbuf) + fprintf(f, "%s\n", sbuf); + if (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_in) > 0) { + fputs("%stdout\n", f); + fputs(argsbuffer, f); + while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_in) > 0) + fputs(argsbuffer, f); + fputs("\n", f); + } + if (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) { + fputs("%stderr\n", f); + fputs(argsbuffer, f); + while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) + fputs(argsbuffer, f); + fputs("\n", f); + } + ap_bclose( script_in ); + ap_bclose( script_err ); + ap_pfclose(r->pool, f); + return ret; +} +int mod_gzip_cgi_handler( request_rec *r ) +{ + int bytesread; + int retval, nph, dbpos = 0; + char *argv0, *dbuf = NULL; + BUFF *script_out, *script_in, *script_err; + char argsbuffer[HUGE_STRING_LEN]; + int is_included = !strcmp(r->protocol, "INCLUDED"); + void *sconf = r->server->module_config; + int final_result = DECLINED; + #define MOD_GZIP_ENGAGED + #ifdef MOD_GZIP_ENGAGED + cgi_server_conf conf_local; + cgi_server_conf *conf = &conf_local; + char cgi_logname[]=""; + #else + cgi_server_conf *conf = + (cgi_server_conf *) ap_get_module_config(sconf, &cgi_module); + #endif + const char *location; + struct mod_gzip_cgi_child_stuff cld; + #ifdef MOD_GZIP_ENGAGED + conf->logname = cgi_logname; + conf->logbytes = (long) 60000L; + conf->bufbytes = (int) 20000; + #endif + if ( r->method_number == M_OPTIONS ) + { + r->allowed |= (1 << M_GET); + r->allowed |= (1 << M_POST); + return DECLINED; + } + if ((argv0 = strrchr(r->filename, '/')) != NULL) + { + argv0++; + } + else + { + argv0 = r->filename; + } + nph = !(strncmp(argv0, "nph-", 4)); + if ( !(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r) ) + { + return log_scripterror(r, conf, FORBIDDEN, APLOG_NOERRNO, + "Options ExecCGI is off in this directory"); + } + if ( nph && is_included ) + { + return log_scripterror(r, conf, FORBIDDEN, APLOG_NOERRNO, + "attempt to include NPH CGI script"); + } + #if defined(OS2) || defined(_WIN32) + if ( r->finfo.st_mode == 0 ) + { + struct stat statbuf; + char *newfile; + newfile = ap_pstrcat(r->pool, r->filename, ".EXE", NULL); + if ((stat(newfile, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode))) + { + return log_scripterror(r, conf, NOT_FOUND, 0, + "script not found or unable to stat"); + } + else + { + r->filename = newfile; + } + } + #else + if ( r->finfo.st_mode == 0 ) + { + return log_scripterror(r, conf, NOT_FOUND, APLOG_NOERRNO, + "script not found or unable to stat"); + } + #endif + if ( S_ISDIR( r->finfo.st_mode ) ) + { + return log_scripterror(r, conf, FORBIDDEN, APLOG_NOERRNO, + "attempt to invoke directory as script"); + } + if ( !ap_suexec_enabled ) + { + if ( !ap_can_exec( &r->finfo ) ) + { + return log_scripterror(r, conf, FORBIDDEN, APLOG_NOERRNO, + "file permissions deny server execution"); + } + } + if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) + { + return retval; + } + ap_add_common_vars(r); + cld.argv0 = argv0; + cld.r = r; + cld.nph = nph; + cld.debug = conf->logname ? 1 : 0; + #ifdef TPF + cld.t.filename = r->filename; + cld.t.subprocess_env = r->subprocess_env; + cld.t.prog_type = FORK_FILE; + #endif + #ifdef CHARSET_EBCDIC + ap_bsetflag( r->connection->client, B_EBCDIC2ASCII, 1 ); + #endif + if ( !ap_bspawn_child( + r->main ? r->main->pool : r->pool, + mod_gzip_cgi_child, + (void *) &cld, + kill_after_timeout, + &script_out, + &script_in, + &script_err + ) + ) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "couldn't spawn child process: %s", r->filename); + return HTTP_INTERNAL_SERVER_ERROR; + } + else + { + } + if ( ap_should_client_block(r) ) + { + int dbsize, len_read; + if ( conf->logname ) + { + dbuf = ap_pcalloc( r->pool, conf->bufbytes + 1 ); + dbpos = 0; + } + ap_hard_timeout("copy script args", r); + for (;;) + { + len_read = + ap_get_client_block( r, argsbuffer, HUGE_STRING_LEN ); + if ( len_read < 1 ) + { + break; + } + if (conf->logname) + { + if ((dbpos + len_read) > conf->bufbytes) + { + dbsize = conf->bufbytes - dbpos; + } + else + { + dbsize = len_read; + } + memcpy(dbuf + dbpos, argsbuffer, dbsize); + dbpos += dbsize; + } + ap_reset_timeout(r); + if ( ap_bwrite(script_out, argsbuffer, len_read) < len_read ) + { + while ( len_read= + ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0) + { + } + break; + } + else + { + } + } + ap_bflush( script_out ); + ap_kill_timeout(r); + } + else + { + } + ap_bclose( script_out ); + if ( script_in && !nph ) + { + char sbuf[MAX_STRING_LEN]; + int ret; + if ((ret = ap_scan_script_header_err_buff(r, script_in, sbuf))) + { + return log_script(r, conf, ret, dbuf, sbuf, script_in, script_err); + } + #ifdef CHARSET_EBCDIC + ap_checkconv(r); + #endif + location = ap_table_get( r->headers_out, "Location" ); + if ( location && location[0] == '/' && r->status == 200 ) + { + ap_hard_timeout("read from script", r); + while ( ap_bgets(argsbuffer, HUGE_STRING_LEN, script_in) > 0 ) + { + continue; + } + while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) + { + continue; + } + ap_kill_timeout(r); + r->method = ap_pstrdup(r->pool, "GET"); + r->method_number = M_GET; + ap_table_unset( r->headers_in, "Content-Length" ); + ap_internal_redirect_handler( location, r ); + return OK; + } + else if ( location && r->status == 200 ) + { + return REDIRECT; + } + #ifdef USE_GATHER + if ( r->header_only ) + { + ap_send_http_header(r); + } + else + { + } + #else /* !USE_GATHER */ + ap_send_http_header(r); + #endif /* USE_GATHER */ + if (!r->header_only) + { + mod_gzip_ap_send_fb( script_in, r, &final_result ); + } + ap_bclose( script_in ); + ap_soft_timeout("soaking script stderr", r); + for (;;) + { + bytesread = ap_bgets( argsbuffer, HUGE_STRING_LEN, script_err ); + if ( bytesread < 1 ) + { + break; + } + } + ap_kill_timeout(r); + ap_bclose( script_err ); + } + else + { + } + if ( script_in && nph ) + { + #ifdef RUSSIAN_APACHE + if (ra_charset_active(r)) + { + r->ra_codep=NULL; + } + #endif + mod_gzip_ap_send_fb( script_in, r, &final_result ); + } + else + { + } + #ifdef ORIGINAL + return OK; + #endif + return final_result; +} +static int mod_gzip_cgi_child(void *child_stuff, child_info *pinfo) +{ + struct mod_gzip_cgi_child_stuff *cld = (struct mod_gzip_cgi_child_stuff *) child_stuff; + request_rec *r = cld->r; + char *argv0 = cld->argv0; + int child_pid; + +/* WARNING! If the following DEBUG_CGI switch is ON you may need to */ +/* run Apache with the -X switch or the dynamic compression */ +/* of some CGI output ( most notable Zope ) will start to fail. */ +/* This DEBUG_CGI switch should NEVER be on for production runs. */ +/* +#define DEBUG_CGI +*/ + +#ifdef DEBUG_CGI +#ifdef OS2 + FILE *dbg = fopen("con", "w"); +#else + #ifdef _WIN32 + FILE *dbg = fopen("c:\\script.dbg", "a" ); + #else + FILE *dbg = fopen("/dev/tty", "w"); + #endif +#endif + int i; +#endif + char **env; + RAISE_SIGSTOP(CGI_CHILD); +#ifdef DEBUG_CGI + fprintf(dbg, "Attempting to exec %s as %sCGI child (argv0 = %s)\n", + r->filename, cld->nph ? "NPH " : "", argv0); +#endif + ap_add_cgi_vars(r); + env = ap_create_environment(r->pool, r->subprocess_env); +#ifdef DEBUG_CGI + fprintf(dbg, "Environment: \n"); + for (i = 0; env[i]; ++i) + fprintf(dbg, "'%s'\n", env[i]); +#endif +#ifndef _WIN32 + #ifdef DEBUG_CGI + fprintf(dbg, "Call ap_chdir_file(r->filename=[%s]\n",r->filename); + #endif + ap_chdir_file(r->filename); + #ifdef DEBUG_CGI + fprintf(dbg, "Back ap_chdir_file(r->filename=[%s]\n",r->filename); + #endif +#endif + if (!cld->debug) + ap_error_log2stderr(r->server); +#ifdef TPF + #ifdef DEBUG_CGI + #ifdef _WIN32 + fprintf(dbg, "TPF defined... return( 0 ) now...\n"); + if ( dbg ) { fclose(dbg); dbg=0; } + #endif + #endif + return (0); +#else + #ifdef DEBUG_CGI + fprintf(dbg, "Call ap_cleanup_for_exec()...\n"); + #endif + ap_cleanup_for_exec(); + #ifdef DEBUG_CGI + fprintf(dbg, "Back ap_cleanup_for_exec()...\n"); + fprintf(dbg, "Call ap_call_exec()...\n"); + #endif + child_pid = ap_call_exec(r, pinfo, argv0, env, 0); + #ifdef DEBUG_CGI + fprintf(dbg, "Back ap_call_exec()...\n"); + #endif +#if defined(_WIN32) || defined(OS2) + #ifdef DEBUG_CGI + #ifdef _WIN32 + fprintf(dbg, "_WIN32 or OS2 defined... return( child_pid ) now...\n"); + if ( dbg ) { fclose(dbg); dbg=0; } + #endif + #endif + return (child_pid); +#else + ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "exec of %s failed", r->filename); + exit(0); + #ifdef DEBUG_CGI + #ifdef _WIN32 + if ( dbg ) { fclose(dbg); dbg=0; } + #endif + #endif + return (0); +#endif +#endif +} +#define MOD_GZIP_SET_BYTES_SENT(r) \ + do { if (r->sent_bodyct) \ + ap_bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \ + } while (0) +long mod_gzip_ap_send_fb( BUFF *fb, request_rec *r, int *final_return_code ) +{ + long lrc; + int return_code=DECLINED; + lrc = (long ) mod_gzip_ap_send_fb_length( fb, r, -1, &return_code ); + *final_return_code = return_code; + return lrc; +} +#ifdef USE_TPF_SELECT +#define mod_gzip_ap_select(_a, _b, _c, _d, _e) \ + tpf_select(_a, _b, _c, _d, _e) +#elif defined(SELECT_NEEDS_CAST) +#define mod_gzip_ap_select(_a, _b, _c, _d, _e) \ + select((_a), (int *)(_b), (int *)(_c), (int *)(_d), (_e)) +#else +#define mod_gzip_ap_select(_a, _b, _c, _d, _e) \ + select(_a, _b, _c, _d, _e) +#endif +long mod_gzip_ap_send_fb_length( +BUFF *fb, +request_rec *r, +long length, +int *final_return_code +) +{ + char cn[]="mod_gzip_ab_send_fb_length()"; + char buf[IOBUFSIZE]; + long total_bytes_sent = 0; + register int n; + register int len; + register int fd; + fd_set fds; + int rc; + #ifndef USE_GATHER + register int w; + register int o; + #endif + #ifdef USE_GATHER + int gather_on = 0; + int gather_todisk = 0; + int gather_origin = 0; + char *gather_bufstart = 0; + char *gather_source = 0; + char *gather_buf = 0; + int gather_bufmaxlen = 60000; + int gather_byteswritten = 0; + int gather_length = 0; + int gather_maxlen = 0; + long gather_totlen = 0; + FILE *gather_fh1 = 0; + char gather_filename[ MOD_GZIP_MAX_PATH_LEN + 2 ]; + #endif + void *modconf = r->server->module_config; + mod_gzip_conf *conf; + *final_return_code = DECLINED; + conf = (mod_gzip_conf *) ap_get_module_config( modconf, &gzip_module ); + if ( length == 0 ) + { + return 0; + } + ap_bsetflag( fb, B_RD, 0 ); + #ifndef TPF + ap_bnonblock( fb, B_RD ); + #endif + fd = ap_bfileno( fb, B_RD ); + #ifdef CHECK_FD_SETSIZE + if ( fd >= FD_SETSIZE ) + { + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, + "send body: filedescriptor (%u) larger than FD_SETSIZE (%u) " + "found, you probably need to rebuild Apache with a " + "larger FD_SETSIZE", fd, FD_SETSIZE); + return 0; + } + else + { + } + #else + #endif + ap_soft_timeout("send body", r); + FD_ZERO( &fds ); + #ifdef USE_GATHER + gather_on = 0; + if ( (long) conf->maximum_inmem_size < (long) gather_bufmaxlen ) + { + gather_maxlen = (int) conf->maximum_inmem_size; + } + else + { + gather_maxlen = (int) gather_bufmaxlen; + } + gather_bufstart = malloc( (int)(gather_maxlen + 2) ); + if ( gather_bufstart ) + { + gather_on = 1; + gather_buf = gather_bufstart; + gather_source = gather_bufstart; + gather_origin = 0; + } + else + { + } + #endif + while( !r->connection->aborted ) + { + #ifdef NDELAY_PIPE_RETURNS_ZERO + int afterselect = 0; + #endif + if ( (length > 0) && (total_bytes_sent + IOBUFSIZE) > length ) + { + len = length - total_bytes_sent; + } + else + { + len = IOBUFSIZE; + } + do { + n = ap_bread( fb, buf, len ); + #ifdef NDELAY_PIPE_RETURNS_ZERO + if ((n > 0) || (n == 0 && afterselect)) + { + break; + } + #else + if (n >= 0) + { + break; + } + #endif + if ( r->connection->aborted ) + { + break; + } + if ( n < 0 && errno != EAGAIN ) + { + break; + } + if ( ap_bflush( r->connection->client ) < 0 ) + { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before send body completed"); + ap_bsetflag( r->connection->client, B_EOUT, 1 ); + r->connection->aborted = 1; + break; + } + #ifdef _WIN32 + FD_SET( (unsigned) fd, &fds ); + #else + FD_SET( fd, &fds ); + #endif + #ifdef FUTURE_USE + mod_gzip_ap_select(fd + 1, &fds, NULL, NULL, NULL); + #endif + #ifdef NDELAY_PIPE_RETURNS_ZERO + afterselect = 1; + #endif + } while ( !r->connection->aborted ); + if ( n < 1 || r->connection->aborted ) + { + break; + } + #ifdef USE_GATHER + if ( gather_on ) + { + if ( ( gather_length + n ) >= gather_maxlen ) + { + if ( !gather_fh1 ) + { + mod_gzip_create_unique_filename( + (mod_gzip_conf *) conf, + (char *) gather_filename, + sizeof( gather_filename ) + ); + gather_fh1 = fopen( gather_filename, "wb" ); + if ( gather_fh1 ) + { + gather_source = gather_filename; + gather_origin = 1; + } + else + { + gather_on = 0; + } + } + if ( ( gather_fh1 ) && ( gather_length > 0 ) ) + { + gather_byteswritten = + fwrite( gather_bufstart, 1, gather_length, gather_fh1 ); + if ( gather_byteswritten != gather_length ) + { + gather_on = 0; + } + } + if ( ( gather_fh1 ) && ( n > 0 ) ) + { + gather_byteswritten = + fwrite( buf, 1, n, gather_fh1 ); + if ( gather_byteswritten != n ) + { + gather_on = 0; + } + } + gather_buf = gather_bufstart; + gather_length = 0; + } + else + { + if ( gather_on ) + { + memcpy( gather_buf, buf, n ); + gather_buf += n; + gather_length += n; + } + } + gather_totlen += n; + } + #endif + #ifdef FUTURE_USE + o = 0; + while ( n && !r->connection->aborted ) + { + #ifdef RUSSIAN_APACHE + unsigned char *newbuf,*p; + int newlen=0; + if ( ra_charset_active(r) ) + { + if ( ra_flag( r, RA_WIDE_CHARS_SC ) ) + { + ra_data_server2client(r,&buf[o],n,&newbuf,&newlen); + p=newbuf; + while( newlen > 0 ) + { + w = ap_bwrite( r->connection->client, p, newlen ); + if(w<=0) goto RECODE_DONE; + newlen-=w; + p+=w; + } + w=n; + } + else + { + unsigned char *t = r->ra_codep->cp_otabl_p; + unsigned char *b = (unsigned char *)&buf[o]; + unsigned char *end = b+n; + while( b < end ) + { + *b = t[*b]; + b++; + } + w = ap_bwrite( r->connection->client, &buf[o], n ); + } + } + else + { + w = ap_bwrite( r->connection->client, &buf[o], n ); + } + RECODE_DONE:; + #else + w = ap_bwrite( r->connection->client, &buf[o], n ); + #endif + if ( w > 0 ) + { + ap_reset_timeout(r); + total_bytes_sent += w; + n -= w; + o += w; + } + else if ( w < 0 ) + { + if ( !r->connection->aborted ) + { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before send body completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + break; + } + } + #endif + } + ap_kill_timeout(r); + MOD_GZIP_SET_BYTES_SENT(r); + #ifdef USE_GATHER + if ( gather_fh1 ) + { + if ( gather_length > 0 ) + { + gather_byteswritten = + fwrite( gather_bufstart, 1, gather_length, gather_fh1 ); + if ( gather_byteswritten != gather_length ) + { + gather_on = 0; + } + } + fclose( gather_fh1 ); + gather_fh1 = 0; + } + if ( gather_totlen > 0 ) + { + rc = + mod_gzip_encode_and_transmit( + (request_rec *) r, + (char *) gather_source, + (int ) gather_origin, + (long ) gather_totlen, + (int ) 1 + ); + *final_return_code = rc; + } + if ( gather_bufstart ) + { + free( gather_bufstart ); + gather_bufstart = 0; + } + gather_on = 0; + #endif + return total_bytes_sent; +} + +/*--------------------------------------------------------------------------*/ +/* COMPRESSION SUPPORT ROUTINES */ +/*--------------------------------------------------------------------------*/ + +#define BIG_MEM + +typedef unsigned uns; +typedef unsigned int uni; +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; +typedef int gz1_file_t; + +#ifdef __STDC__ + typedef void *voidp; +#else + typedef char *voidp; +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +#if defined(__OS2__) && !defined(OS2) +# define OS2 +#endif + +#if defined(OS2) && defined(MSDOS) +# undef MSDOS +#endif + +#ifdef MSDOS +# ifdef __GNUC__ +# define near +# else +# define MAXSEG_64K +# ifdef __TURBOC__ +# define NO_OFF_T +# ifdef __BORLANDC__ +# define DIRENT +# else +# define NO_UTIME +# endif +# else +# define HAVE_SYS_UTIME_H +# define NO_UTIME_H +# endif +# endif +# define PATH_SEP2 '\\' +# define PATH_SEP3 ':' +# define MAX_PATH_LEN 128 +# define NO_MULTIPLE_DOTS +# define MAX_EXT_CHARS 3 +# define Z_SUFFIX "z" +# define NO_CHOWN +# define PROTO +# define STDC_HEADERS +# define NO_SIZE_CHECK +# define casemap(c) tolow(c) +# include +# undef OS_CODE +# define OS_CODE 0x00 +# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY) +# if !defined(NO_ASM) && !defined(ASMV) +# define ASMV +# endif +#else +# define near +#endif + +#ifdef OS2 +# define PATH_SEP2 '\\' +# define PATH_SEP3 ':' +# define MAX_PATH_LEN 260 +# ifdef OS2FAT +# define NO_MULTIPLE_DOTS +# define MAX_EXT_CHARS 3 +# define Z_SUFFIX "z" +# define casemap(c) tolow(c) +# endif +# define NO_CHOWN +# define PROTO +# define STDC_HEADERS +# include +# undef OS_CODE +# define OS_CODE 0x06 +# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY) +# ifdef _MSC_VER +# define HAVE_SYS_UTIME_H +# define NO_UTIME_H +# define MAXSEG_64K +# undef near +# define near _near +# endif +# ifdef __EMX__ +# define HAVE_SYS_UTIME_H +# define NO_UTIME_H +# define DIRENT +# define EXPAND(argc,argv) \ + {_response(&argc, &argv); _wildcard(&argc, &argv);} +# endif +# ifdef __BORLANDC__ +# define DIRENT +# endif +# ifdef __ZTC__ +# define NO_DIR +# define NO_UTIME_H +# include +# define EXPAND(argc,argv) \ + {response_expand(&argc, &argv);} +# endif +#endif + +#ifdef _WIN32 +# define HAVE_SYS_UTIME_H +# define NO_UTIME_H +# define PATH_SEP2 '\\' +# define PATH_SEP3 ':' +# undef MAX_PATH_LEN +# define MAX_PATH_LEN 260 +# define NO_CHOWN +# define PROTO +# define STDC_HEADERS +# define SET_BINARY_MODE(fd) setmode(fd, O_BINARY) +# include +# ifdef NTFAT +# define NO_MULTIPLE_DOTS +# define MAX_EXT_CHARS 3 +# define Z_SUFFIX "z" +# define casemap(c) tolow(c) +# endif +# undef OS_CODE + +# define OS_CODE 0x00 + +#endif + +#ifdef MSDOS +# ifdef __TURBOC__ +# include +# define DYN_ALLOC + void * fcalloc (unsigned items, unsigned size); + void fcfree (void *ptr); +# else +# define fcalloc(nitems,itemsize) halloc((long)(nitems),(itemsize)) +# define fcfree(ptr) hfree(ptr) +# endif +#else +# ifdef MAXSEG_64K +# define fcalloc(items,size) calloc((items),(size)) +# else +# define fcalloc(items,size) malloc((size_t)(items)*(size_t)(size)) +# endif +# define fcfree(ptr) free(ptr) +#endif + +#if defined(VAXC) || defined(VMS) +# define PATH_SEP ']' +# define PATH_SEP2 ':' +# define SUFFIX_SEP ';' +# define NO_MULTIPLE_DOTS +# define Z_SUFFIX "-gz" +# define RECORD_IO 1 +# define casemap(c) tolow(c) +# undef OS_CODE +# define OS_CODE 0x02 +# define OPTIONS_VAR "GZIP_OPT" +# define STDC_HEADERS +# define NO_UTIME +# define EXPAND(argc,argv) vms_expand_args(&argc,&argv); +# include +# define unlink delete +# ifdef VAXC +# define NO_FCNTL_H +# include +# endif +#endif + +#ifdef AMIGA +# define PATH_SEP2 ':' +# define STDC_HEADERS +# undef OS_CODE +# define OS_CODE 0x01 +# define ASMV +# ifdef __GNUC__ +# define DIRENT +# define HAVE_UNISTD_H +# else +# define NO_STDIN_FSTAT +# define SYSDIR +# define NO_SYMLINK +# define NO_CHOWN +# define NO_FCNTL_H +# include +# define direct dirent + extern void _expand_args(int *argc, char ***argv); +# define EXPAND(argc,argv) _expand_args(&argc,&argv); +# undef O_BINARY +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# ifndef STDC_HEADERS +# define STDC_HEADERS +# define HAVE_UNISTD_H +# define DIRENT +# endif +# define ASMV +# undef OS_CODE +# define OS_CODE 0x05 +# ifdef TOSFS +# define PATH_SEP2 '\\' +# define PATH_SEP3 ':' +# define MAX_PATH_LEN 128 +# define NO_MULTIPLE_DOTS +# define MAX_EXT_CHARS 3 +# define Z_SUFFIX "z" +# define NO_CHOWN +# define casemap(c) tolow(c) +# define NO_SYMLINK +# endif +#endif + +#ifdef MACOS +# define PATH_SEP ':' +# define DYN_ALLOC +# define PROTO +# define NO_STDIN_FSTAT +# define NO_CHOWN +# define NO_UTIME +# define chmod(file, mode) (0) +# define OPEN(name, flags, mode) open(name, flags) +# undef OS_CODE +# define OS_CODE 0x07 +# ifdef MPW +# define isatty(fd) ((fd) <= 2) +# endif +#endif + +#ifdef __50SERIES +# define PATH_SEP '>' +# define STDC_HEADERS +# define NO_MEMORY_H +# define NO_UTIME_H +# define NO_UTIME +# define NO_CHOWN +# define NO_STDIN_FSTAT +# define NO_SIZE_CHECK +# define NO_SYMLINK +# define RECORD_IO 1 +# define casemap(c) tolow(c) +# define put_char(c) put_byte((c) & 0x7F) +# define get_char(c) ascii2pascii(get_byte()) +# undef OS_CODE +# define OS_CODE 0x0F +# ifdef SIGTERM +# undef SIGTERM +# endif +#endif + +#if defined(pyr) && !defined(NOMEMCPY) +# define NOMEMCPY +#endif + +#ifdef TOPS20 +# undef OS_CODE +# define OS_CODE 0x0a +#endif + +#ifndef unix +# define NO_ST_INO +#endif + +#ifndef OS_CODE +# undef OS_CODE +# define OS_CODE 0x03 +#endif + +#ifndef PATH_SEP +# define PATH_SEP '/' +#endif + +#ifndef casemap +# define casemap(c) (c) +#endif + +#ifndef OPTIONS_VAR +# define OPTIONS_VAR "GZIP" +#endif + +#ifndef Z_SUFFIX +# define Z_SUFFIX ".gz" +#endif + +#ifdef MAX_EXT_CHARS +# define MAX_SUFFIX MAX_EXT_CHARS +#else +# define MAX_SUFFIX 30 +#endif + +#ifndef MIN_PART +# define MIN_PART 3 +#endif + +#ifndef EXPAND +# define EXPAND(argc,argv) +#endif + +#ifndef RECORD_IO +# define RECORD_IO 0 +#endif + +#ifndef SET_BINARY_MODE +# define SET_BINARY_MODE(fd) +#endif + +#ifndef OPEN +# define OPEN(name, flags, mode) open(name, flags, mode) +#endif + +#ifndef get_char +# define get_char() get_byte() +#endif + +#ifndef put_char +# define put_char(c) put_byte(c) +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define OK 0 +#define LZ1_ERROR 1 +#define WARNING 2 +#define STORED 0 +#define COMPRESSED 1 +#define PACKED 2 +#define LZHED 3 +#define DEFLATED 8 +#define MAX_METHODS 9 + +#ifndef O_CREAT +#include +#ifndef O_CREAT +#define O_CREAT FCREAT +#endif +#ifndef O_EXCL +#define O_EXCL FEXCL +#endif +#endif + +#ifndef S_IRUSR +#define S_IRUSR 0400 +#endif +#ifndef S_IWUSR +#define S_IWUSR 0200 +#endif +#define RW_USER (S_IRUSR | S_IWUSR) + +#ifndef MAX_PATH_LEN +#define MAX_PATH_LEN 256 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#define PACK_MAGIC "\037\036" +#define GZIP_MAGIC "\037\213" +#define OLD_GZIP_MAGIC "\037\236" +#define LZH_MAGIC "\037\240" +#define PKZIP_MAGIC "\120\113\003\004" +#define ASCII_FLAG 0x01 +#define CONTINUATION 0x02 +#define EXTRA_FIELD 0x04 +#define ORIG_NAME 0x08 +#define COMMENT 0x10 +#define ENCRYPTED 0x20 +#define RESERVED 0xC0 +#define UNKNOWN 0xffff +#define BINARY 0 +#define ASCII 1 + +#ifndef WSIZE +#define WSIZE 0x8000 +#endif + +#ifndef INBUFSIZ +#ifdef SMALL_MEM +#define INBUFSIZ 0x2000 +#else +#define INBUFSIZ 0x8000 +#endif +#endif +#define INBUF_EXTRA 64 + +#ifndef OUTBUFSIZ +#ifdef SMALL_MEM +#define OUTBUFSIZ 8192 +#else +#define OUTBUFSIZ 0x4000 +#endif +#endif +#define OUTBUF_EXTRA 2048 + +#ifndef DIST_BUFSIZE +#ifdef SMALL_MEM +#define DIST_BUFSIZE 0x2000 +#else +#define DIST_BUFSIZE 0x8000 +#endif +#endif + +#ifndef BITS +#define BITS 16 +#endif + +#define LZW_MAGIC "\037\235" + +#define MIN_MATCH 3 +#define MAX_MATCH 258 + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +#define MAX_DIST (WSIZE-MIN_LOOKAHEAD) + +#ifdef SMALL_MEM +#define HASH_BITS 13 +#endif +#ifdef MEDIUM_MEM +#define HASH_BITS 14 +#endif +#ifndef HASH_BITS +#define HASH_BITS 15 +#endif + +#define HASH_SIZE (unsigned)(1<block_start >= 0L ? (char*)&gz1->window[(unsigned)gz1->block_start] : \ + (char*)NULL, (long)gz1->strstart - gz1->block_start, (eof)) + +#ifdef DYN_ALLOC +# define ALLOC(type, array, size) { \ + array = (type*)fcalloc((size_t)(((size)+1L)/2), 2*sizeof(type)); \ + if (array == NULL) error("insufficient memory"); \ + } +# define FREE(array) {if (array != NULL) fcfree(array), array=NULL;} +#else +# define ALLOC(type, array, size) +# define FREE(array) +#endif + +#define GZ1_MAX(a,b) (a >= b ? a : b) + +#define tolow(c) (isupper(c) ? (c)-'A'+'a' : (c)) + +#define smaller(tree, n, m) \ + (tree[n].fc.freq < tree[m].fc.freq || \ + (tree[n].fc.freq == tree[m].fc.freq && gz1->depth[n] <= gz1->depth[m])) + +#define send_code(c, tree) send_bits(gz1,tree[c].fc.code, tree[c].dl.len) + +#define put_byte(c) {gz1->outbuf[gz1->outcnt++]=(uch)(c); if (gz1->outcnt==OUTBUFSIZ)\ + flush_outbuf(gz1);} + +#define put_short(w) \ +{ if (gz1->outcnt < OUTBUFSIZ-2) { \ + gz1->outbuf[gz1->outcnt++] = (uch) ((w) & 0xff); \ + gz1->outbuf[gz1->outcnt++] = (uch) ((ush)(w) >> 8); \ + } else { \ + put_byte((uch)((w) & 0xff)); \ + put_byte((uch)((ush)(w) >> 8)); \ + } \ +} + +#define put_long(n) { \ + put_short((n) & 0xffff); \ + put_short(((ulg)(n)) >> 16); \ +} + +#ifdef CRYPT + +# define NEXTBYTE() \ + (decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte()) +#else +# define NEXTBYTE() (uch)get_byte() +#endif + +#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<>=(n);k-=(n);} + +#define SH(p) ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)) +#define LG(p) ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)) + +#define put_ubyte(c) {gz1->window[gz1->outcnt++]=(uch)(c); if (gz1->outcnt==WSIZE)\ + flush_window(gz1);} + +#define WARN(msg) { if (gz1->exit_code == OK) gz1->exit_code = WARNING; } + +#define get_byte() (gz1->inptr < gz1->insize ? gz1->inbuf[gz1->inptr++] : fill_inbuf(gz1,0)) +#define try_byte() (gz1->inptr < gz1->insize ? gz1->inbuf[gz1->inptr++] : fill_inbuf(gz1,1)) + +#define d_code(dist) \ + ((dist) < 256 ? gz1->dist_code[dist] : gz1->dist_code[256+((dist)>>7)]) + +typedef struct config { + ush good_length; + ush max_lazy; + ush nice_length; + ush max_chain; +} config; + +config configuration_table[10] = { + + {0, 0, 0, 0}, + {4, 4, 8, 4}, + {4, 5, 16, 8}, + {4, 6, 32, 32}, + {4, 4, 16, 16}, + {8, 16, 32, 32}, + {8, 16, 128, 128}, + {8, 32, 128, 256}, + {32, 128, 258, 1024}, + {32, 258, 258, 4096}}; + +typedef struct ct_data { + + union { + ush freq; + ush code; + } fc; + union { + ush dad; + ush len; + } dl; + +} ct_data; + +typedef struct tree_desc { + ct_data *dyn_tree; + ct_data *static_tree; + int *extra_bits; + int extra_base; + int elems; + int max_length; + int max_code; +} tree_desc; + +struct huft { + uch e; + uch b; + union { + ush n; + struct huft *t; + } v; +}; + +uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + +int extra_lbits[LENGTH_CODES] + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +int extra_dbits[D_CODES] + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +int extra_blbits[BL_CODES] + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +ulg crc_32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +typedef struct _GZ1 { + long compression_format; + + long versionid1; + int state; + int done; + int deflate1_initialized; + unsigned deflate1_hash_head; + unsigned deflate1_prev_match; + int deflate1_flush; + int deflate1_match_available; + unsigned deflate1_match_length; + + char ifname[MAX_PATH_LEN]; + char ofname[MAX_PATH_LEN]; + + struct stat istat; + gz1_file_t zfile; + + int input_ismem; + char *input_ptr; + long input_bytesleft; + + int output_ismem; + char *output_ptr; + uns output_maxlen; + + int compr_level; + long time_stamp; + long ifile_size; + int ifd; + int ofd; + int part_nb; + int last_member; + int save_orig_name; + long header_bytes; + long bytes_in; + long bytes_out; + uns insize; + uns inptr; + uns outcnt; + uns ins_h; + long block_start; + uns good_match; + uni max_lazy_match; + uni prev_length; + uns max_chain_length; + uns strstart; + uns match_start; + int eofile; + uns lookahead; + ush *file_type; + int *file_method; + ulg opt_len; + ulg static_len; + ulg compressed_len; + ulg input_len; + uns last_flags; + uch flags; + uns last_lit; + uns last_dist; + uch flag_bit; + int heap_len; + int heap_max; + ulg bb; + uns bk; + ush bi_buf; + int bi_valid; + uns hufts; + int decrypt; + int ascii; + int msg_done; + int abortflag; + int decompress; + int do_lzw; + int to_stdout; + int force; + int verbose; + int quiet; + int list; + int test; + int ext_header; + int pkzip; + int method; + int level; + int no_time; + int no_name; + int exit_code; + int lbits; + int dbits; + ulg window_size; + ulg crc; + ulg adler; + + uch dist_code[512]; + uch length_code[MAX_MATCH-MIN_MATCH+1]; + int heap[2*L_CODES+1]; + uch depth[2*L_CODES+1]; + int base_length[LENGTH_CODES]; + int base_dist[D_CODES]; + ush bl_count[MAX_BITS+1]; + uch flag_buf[(LIT_BUFSIZE/8)]; + + #ifdef DYN_ALLOC + uch *inbuf; + uch *outbuf; + ush *d_buf; + uch *window; + #else + uch inbuf [INBUFSIZ +INBUF_EXTRA]; + uch outbuf[OUTBUFSIZ+OUTBUF_EXTRA]; + ush d_buf [DIST_BUFSIZE]; + uch window[2L*WSIZE]; + #endif + + #ifdef FULL_SEARCH + #define nice_match MAX_MATCH + #else + int nice_match; + #endif + + #ifdef CRYPT + uch cc; + #endif + + ct_data static_ltree[L_CODES+2]; + ct_data static_dtree[D_CODES]; + ct_data dyn_dtree[(2*D_CODES+1)]; + ct_data dyn_ltree[HEAP_SIZE]; + ct_data bl_tree[2*BL_CODES+1]; + + tree_desc l_desc; + tree_desc d_desc; + tree_desc bl_desc; + + #ifndef MAXSEG_64K + + ush prev2[1L<prev2 + #define head (gz1->prev2+WSIZE) + + #else + + ush * prev2; + ush * tab_prefix1; + + #define prev gz1->prev2 + #define head gz1->tab_prefix1 + + #endif + +} GZ1; +typedef GZ1 *PGZ1; +int gz1_size = sizeof( GZ1 ); + +/* Declare some local function protypes... */ + +/* Any routine name that can/might conflict with */ +/* other modules or object code should simply have */ +/* the standard prefix 'gz1_' added to the front. */ +/* This will only usually be any kind of problem at all */ +/* if the code is being compiled directly into the parent */ +/* instead of being built as a standalone DLL or DSO library. */ + +PGZ1 gz1_init ( void ); +int gz1_cleanup ( PGZ1 gz1 ); +ulg gz1_deflate ( PGZ1 gz1 ); +ulg gz1_deflate_fast( PGZ1 gz1 ); + +/* The rest of the routines should not need the 'gz1_' prefix. */ +/* No conflicts reported at this time. */ + +int inflate ( PGZ1 gz1 ); +int inflate_dynamic( PGZ1 gz1 ); +int inflate_stored ( PGZ1 gz1 ); +int inflate_fixed ( PGZ1 gz1 ); +void fill_window ( PGZ1 gz1 ); +void flush_outbuf ( PGZ1 gz1 ); +void flush_window ( PGZ1 gz1 ); +void bi_windup ( PGZ1 gz1 ); +void set_file_type ( PGZ1 gz1 ); +void init_block ( PGZ1 gz1 ); +int build_bl_tree ( PGZ1 gz1 ); +void read_error ( PGZ1 gz1 ); +void write_error ( PGZ1 gz1 ); +int get_header ( PGZ1 gz1, int in ); +int inflate_block ( PGZ1 gz1, int *e ); +int fill_inbuf ( PGZ1 gz1, int eof_ok ); +char *gz1_basename ( PGZ1 gz1, char *fname ); +int longest_match ( PGZ1 gz1, unsigned cur_match ); +void bi_init ( PGZ1 gz1, gz1_file_t zipfile ); +int file_read ( PGZ1 gz1, char *buf, unsigned size ); +void write_buf ( PGZ1 gz1, int fd, voidp buf, unsigned cnt ); + +void error( char *msg ); + +/* XXX - Precomputed zlib header. If you change the window size or + * compression level from the defaults, this will break badly. The + * algorithm to build this is fairly complex; you can find it in + * the file deflate.c from the zlib distribution. + */ +#define ZLIB_HEADER "\170œ" + +ulg adler32(ulg adler, uch *buf, unsigned len); + +int zip( +PGZ1 gz1, +int in, +int out +); + +ulg flush_block( +PGZ1 gz1, +char *buf, +ulg stored_len, +int eof +); + +void copy_block( +PGZ1 gz1, +char *buf, +unsigned len, +int header +); + +int ct_tally( +PGZ1 gz1, +int dist, +int lc +); + +void send_bits( +PGZ1 gz1, +int value, +int length +); + +void send_tree( +PGZ1 gz1, +ct_data *tree, +int max_code +); + +void send_all_trees( +PGZ1 gz1, +int lcodes, +int dcodes, +int blcodes +); + +void ct_init( +PGZ1 gz1, +ush *attr, +int *methodp +); + +void lm_init( +PGZ1 gz1, +int pack_level, +ush *flags +); + +void build_tree( +PGZ1 gz1, +tree_desc *desc +); + +void compress_block( +PGZ1 gz1, +ct_data *ltree, +ct_data *dtree +); + +void gen_bitlen( +PGZ1 gz1, +tree_desc *desc +); + +void pqdownheap( +PGZ1 gz1, +ct_data *tree, +int k +); + +int huft_build( +PGZ1 gz1, +unsigned *b, +unsigned n, +unsigned s, +ush *d, +ush *e, +struct huft **t, +int *m +); + +ulg updcrc( +PGZ1 gz1, +uch *s, +unsigned n +); + +int inflate_codes( +PGZ1 gz1, +struct huft *tl, +struct huft *td, +int bl, +int bd +); + +void gen_codes( +PGZ1 gz1, +ct_data *tree, +int max_code +); + +void scan_tree( +PGZ1 gz1, +ct_data *tree, +int max_code +); + +unsigned bi_reverse( +PGZ1 gz1, +unsigned code, +int len +); + +int huft_free( +PGZ1 gz1, +struct huft *t +); + +PGZ1 gz1_init() +{ + PGZ1 gz1=0; + + gz1 = (PGZ1) malloc( gz1_size ); + + if ( !gz1 ) + { + return 0; + } + + memset( gz1, 0, gz1_size ); + + ALLOC(uch, gz1->inbuf, INBUFSIZ +INBUF_EXTRA); + + if ( !gz1->inbuf ) + { + free( gz1 ); + return 0; + } + + ALLOC(uch, gz1->outbuf, OUTBUFSIZ+OUTBUF_EXTRA); + + if ( !gz1->outbuf ) + { + FREE( gz1->inbuf ); + free( gz1 ); + return 0; + } + + ALLOC(ush, gz1->d_buf, DIST_BUFSIZE); + + if ( !gz1->d_buf ) + { + FREE( gz1->outbuf ); + FREE( gz1->inbuf ); + free( gz1 ); + return 0; + } + + ALLOC(uch, gz1->window, 2L*WSIZE); + + if ( !gz1->window ) + { + FREE( gz1->d_buf ); + FREE( gz1->outbuf ); + FREE( gz1->inbuf ); + free( gz1 ); + return 0; + } + + #ifndef MAXSEG_64K + + #else + + ALLOC(ush, gz1->prev2, 1L<<(BITS-1) ); + + if ( !gz1->prev2 ) + { + FREE( gz1->window ); + FREE( gz1->d_buf ); + FREE( gz1->outbuf ); + FREE( gz1->inbuf ); + free( gz1 ); + return 0; + } + + ALLOC(ush, gz1->tab_prefix1, 1L<<(BITS-1) ); + + if ( !gz1->tab_prefix1 ) + { + FREE( gz1->prev2 ); + FREE( gz1->window ); + FREE( gz1->d_buf ); + FREE( gz1->outbuf ); + FREE( gz1->inbuf ); + free( gz1 ); + return 0; + } + + #endif + + gz1->method = DEFLATED; + gz1->level = 6; + gz1->no_time = -1; + gz1->no_name = -1; + gz1->exit_code = OK; + gz1->lbits = 9; + gz1->dbits = 6; + + gz1->window_size = (ulg)2*WSIZE; + gz1->crc = (ulg)0xffffffffL; + + gz1->d_desc.dyn_tree = (ct_data *) gz1->dyn_dtree; + gz1->d_desc.static_tree = (ct_data *) gz1->static_dtree; + gz1->d_desc.extra_bits = (int *) extra_dbits; + gz1->d_desc.extra_base = (int ) 0; + gz1->d_desc.elems = (int ) D_CODES; + gz1->d_desc.max_length = (int ) MAX_BITS; + gz1->d_desc.max_code = (int ) 0; + + gz1->l_desc.dyn_tree = (ct_data *) gz1->dyn_ltree; + gz1->l_desc.static_tree = (ct_data *) gz1->static_ltree; + gz1->l_desc.extra_bits = (int *) extra_lbits; + gz1->l_desc.extra_base = (int ) LITERALS+1; + gz1->l_desc.elems = (int ) L_CODES; + gz1->l_desc.max_length = (int ) MAX_BITS; + gz1->l_desc.max_code = (int ) 0; + + gz1->bl_desc.dyn_tree = (ct_data *) gz1->bl_tree; + gz1->bl_desc.static_tree = (ct_data *) 0; + gz1->bl_desc.extra_bits = (int *) extra_blbits; + gz1->bl_desc.extra_base = (int ) 0; + gz1->bl_desc.elems = (int ) BL_CODES; + gz1->bl_desc.max_length = (int ) MAX_BL_BITS; + gz1->bl_desc.max_code = (int ) 0; + + return (PGZ1) gz1; + +} + +int gz1_cleanup( PGZ1 gz1 ) +{ + + #ifndef MAXSEG_64K + + #else + + FREE( gz1->tab_prefix1 ); + FREE( gz1->prev2 ); + #endif + + FREE( gz1->window ); + FREE( gz1->d_buf ); + FREE( gz1->outbuf ); + FREE( gz1->inbuf ); + + free( gz1 ); + gz1 = 0; + + return 0; +} + +int (*read_buf)(PGZ1 gz1, char *buf, unsigned size); + +void error( char *msg ) +{ + msg = msg; +} + +int (*work)( PGZ1 gz1, int infile, int outfile ) = 0; + +#ifdef __BORLANDC__ +#pragma argsused +#endif + +int get_header( PGZ1 gz1, int in ) +{ + uch flags; + char magic[2]; + ulg stamp; + unsigned len; + unsigned part; + + if ( gz1->force && gz1->to_stdout ) + { + magic[0] = (char)try_byte(); + magic[1] = (char)try_byte(); + } + else + { + magic[0] = (char)get_byte(); + magic[1] = (char)get_byte(); + } + + gz1->method = -1; + gz1->header_bytes = 0; + gz1->last_member = RECORD_IO; + gz1->part_nb++; + + if ( memcmp(magic, GZIP_MAGIC, 2 ) == 0 || + memcmp(magic, OLD_GZIP_MAGIC, 2 ) == 0 ) + { + gz1->method = (int)get_byte(); + + if ( gz1->method != DEFLATED ) + { + gz1->exit_code = LZ1_ERROR; + + return -1; + } + + return -1; + + if ((flags & ENCRYPTED) != 0) + { + gz1->exit_code = LZ1_ERROR; + return -1; + } + + if ((flags & CONTINUATION) != 0) + { + gz1->exit_code = LZ1_ERROR; + if ( gz1->force <= 1) return -1; + } + + if ((flags & RESERVED) != 0) + { + gz1->exit_code = LZ1_ERROR; + if ( gz1->force <= 1) + return -1; + } + + stamp = (ulg)get_byte(); + stamp |= ((ulg)get_byte()) << 8; + stamp |= ((ulg)get_byte()) << 16; + stamp |= ((ulg)get_byte()) << 24; + + if ( stamp != 0 && !gz1->no_time ) + { + gz1->time_stamp = stamp; + } + + (void)get_byte(); + (void)get_byte(); + + if ((flags & CONTINUATION) != 0) + { + part = (unsigned) get_byte(); + part |= ((unsigned) get_byte())<<8; + } + + if ((flags & EXTRA_FIELD) != 0) + { + len = (unsigned) get_byte(); + len |= ((unsigned) get_byte())<<8; + + while (len--) (void)get_byte(); + } + + if ((flags & COMMENT) != 0) + { + while (get_char() != 0) ; + } + + if ( gz1->part_nb == 1 ) + { + gz1->header_bytes = gz1->inptr + 2*sizeof(long); + } + } + + return gz1->method; +} + +int fill_inbuf( PGZ1 gz1, int eof_ok ) +{ + int len; + int bytes_to_copy; + + gz1->insize = 0; + errno = 0; + + do { + if ( gz1->input_ismem ) + { + if ( gz1->input_bytesleft > 0 ) + { + bytes_to_copy = INBUFSIZ - gz1->insize; + + if ( bytes_to_copy > gz1->input_bytesleft ) + { + bytes_to_copy = gz1->input_bytesleft; + } + + memcpy( + (char*)gz1->inbuf+gz1->insize, + gz1->input_ptr, + bytes_to_copy + ); + + gz1->input_ptr += bytes_to_copy; + gz1->input_bytesleft -= bytes_to_copy; + + len = bytes_to_copy; + } + else + { + len = 0; + } + } + else + { + len = + read( + gz1->ifd, + (char*)gz1->inbuf+gz1->insize, + INBUFSIZ-gz1->insize + ); + } + + if (len == 0 || len == EOF) break; + + gz1->insize += len; + + } while( gz1->insize < INBUFSIZ ); + + if ( gz1->insize == 0 ) + { + if( eof_ok ) return EOF; + read_error( gz1 ); + } + + gz1->bytes_in += (ulg) gz1->insize; + gz1->inptr = 1; + + return gz1->inbuf[0]; +} + +ulg updcrc( +PGZ1 gz1, +uch *s, +unsigned n +) +{ + register ulg c; + + if ( s == NULL ) + { + c = 0xffffffffL; + } + else + { + c = gz1->crc; + + if ( n ) + { + do{ + c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); + + } while( --n ); + } + } + + gz1->crc = c; + + return( c ^ 0xffffffffL ); +} + +void read_error( PGZ1 gz1 ) +{ + gz1->abortflag = 1; +} + +void mod_gzip_strlwr( char *s ) +{ + char *p1=s; + + if ( s == 0 ) return; + + while ( *p1 != 0 ) + { + if ( *p1 > 96 ) *p1 = *p1 - 32; + p1++; + } +} + +#ifdef __BORLANDC__ +#pragma argsused +#endif + +char *gz1_basename( PGZ1 gz1, char *fname ) +{ + char *p; + + if ((p = strrchr(fname, PATH_SEP)) != NULL) fname = p+1; + + #ifdef PATH_SEP2 + if ((p = strrchr(fname, PATH_SEP2)) != NULL) fname = p+1; + #endif + + #ifdef PATH_SEP3 + if ((p = strrchr(fname, PATH_SEP3)) != NULL) fname = p+1; + #endif + + #ifdef SUFFIX_SEP + if ((p = strrchr(fname, SUFFIX_SEP)) != NULL) *p = '\0'; + #endif + + if (casemap('A') == 'a') mod_gzip_strlwr(fname); + + return fname; +} + +void write_buf( PGZ1 gz1, int fd, voidp buf, unsigned cnt ) +{ + unsigned n; + + if ( gz1->output_ismem ) + { + if ( ( gz1->bytes_out + cnt ) < gz1->output_maxlen ) + { + memcpy( gz1->output_ptr, buf, cnt ); + gz1->output_ptr += cnt; + } + else + { + write_error( gz1 ); + } + } + else + { + while ((n = write(fd, buf, cnt)) != cnt) + { + if (n == (unsigned)(-1)) + { + write_error( gz1 ); + } + cnt -= n; + buf = (voidp)((char*)buf+n); + } + } +} + +void write_error( PGZ1 gz1 ) +{ + gz1->abortflag = 1; +} + +#ifdef __TURBOC__ +#ifndef BC55 + +static ush ptr_offset = 0; + +void * fcalloc( +unsigned items, +unsigned size +) +{ + void * buf = farmalloc((ulg)items*size + 16L); + + if (buf == NULL) return NULL; + + if (ptr_offset == 0) + { + ptr_offset = (ush)((uch*)buf-0); + } + else if (ptr_offset != (ush)((uch*)buf-0)) + { + error("inconsistent ptr_offset"); + } + + *((ush*)&buf+1) += (ptr_offset + 15) >> 4; + *(ush*)&buf = 0; + + return buf; +} + +void fcfree( void *ptr ) +{ + *((ush*)&ptr+1) -= (ptr_offset + 15) >> 4; + *(ush*)&ptr = ptr_offset; + + farfree(ptr); +} + +#endif +#endif + +int zip( +PGZ1 gz1, +int in, +int out +) +{ + uch flags = 0; + ush attr = 0; + ush deflate_flags = 0; + + gz1->ifd = in; + gz1->ofd = out; + gz1->outcnt = 0; + + gz1->method = DEFLATED; + + put_byte(GZIP_MAGIC[0]); + put_byte(GZIP_MAGIC[1]); + put_byte(DEFLATED); + + if ( gz1->save_orig_name ) + { + flags |= ORIG_NAME; + } + + put_byte(flags); + put_long(gz1->time_stamp); + + gz1->crc = -1; + + updcrc( gz1, NULL, 0 ); + + bi_init( gz1, out ); + ct_init( gz1, &attr, &gz1->method ); + lm_init( gz1, gz1->level, &deflate_flags ); + + put_byte((uch)deflate_flags); + + put_byte(OS_CODE); + + if ( gz1->save_orig_name ) + { + char *p = gz1_basename( gz1, gz1->ifname ); + + do { + put_char(*p); + + } while (*p++); + } + + gz1->header_bytes = (long)gz1->outcnt; + + (void) gz1_deflate( gz1 ); + + put_long( gz1->crc ); + put_long( gz1->bytes_in ); + + gz1->header_bytes += 2*sizeof(long); + + flush_outbuf( gz1 ); + + return OK; +} + +ulg gz1_deflate( PGZ1 gz1 ) +{ + unsigned hash_head; + unsigned prev_match; + int flush; + int match_available = 0; + register unsigned match_length = MIN_MATCH-1; +#ifdef DEBUG + long isize; +#endif + + if (gz1->compr_level <= 3) + { + return gz1_deflate_fast(gz1); + } + + while (gz1->lookahead != 0) + { + gz1->ins_h = + (((gz1->ins_h)<window[gz1->strstart+MIN_MATCH-1])) & HASH_MASK; + + prev[ gz1->strstart & WMASK ] = hash_head = head[ gz1->ins_h ]; + + head[ gz1->ins_h ] = gz1->strstart; + + gz1->prev_length = match_length, prev_match = gz1->match_start; + match_length = MIN_MATCH-1; + + if (hash_head != NIL && gz1->prev_length < gz1->max_lazy_match && + gz1->strstart - hash_head <= MAX_DIST) { + + match_length = longest_match( gz1, hash_head ); + + if (match_length > gz1->lookahead) match_length = gz1->lookahead; + + if (match_length == MIN_MATCH && gz1->strstart-gz1->match_start > TOO_FAR){ + + match_length--; + } + } + + if (gz1->prev_length >= MIN_MATCH && match_length <= gz1->prev_length) { + + flush = ct_tally(gz1,gz1->strstart-1-prev_match, gz1->prev_length - MIN_MATCH); + + gz1->lookahead -= ( gz1->prev_length - 1 ); + gz1->prev_length -= 2; + + do { + gz1->strstart++; + + gz1->ins_h = + (((gz1->ins_h)<window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK; + + prev[ gz1->strstart & WMASK ] = hash_head = head[gz1->ins_h]; + + head[ gz1->ins_h ] = gz1->strstart; + + } while (--gz1->prev_length != 0); + match_available = 0; + match_length = MIN_MATCH-1; + gz1->strstart++; + if (flush) FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; + + } else if (match_available) { + + if (ct_tally( gz1, 0, gz1->window[gz1->strstart-1] )) { + FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; + } + gz1->strstart++; + gz1->lookahead--; + } else { + + match_available = 1; + gz1->strstart++; + gz1->lookahead--; + } + + while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile) fill_window(gz1); + } + if (match_available) ct_tally( gz1, 0, gz1->window[gz1->strstart-1] ); + + return FLUSH_BLOCK(1); + + return 0; +} + +void flush_outbuf( PGZ1 gz1 ) +{ + if ( gz1->outcnt == 0 ) + { + return; + } + + write_buf( gz1, gz1->ofd, (char *)gz1->outbuf, gz1->outcnt ); + + gz1->bytes_out += (ulg)gz1->outcnt; + gz1->outcnt = 0; +} + +void lm_init( +PGZ1 gz1, +int pack_level, +ush *flags +) +{ + register unsigned j; + + if ( pack_level < 1 || pack_level > 9 ) + { + error("bad pack level"); + } + + gz1->compr_level = pack_level; + + #if defined(MAXSEG_64K) && HASH_BITS == 15 + for (j = 0; j < HASH_SIZE; j++) head[j] = NIL; + #else + memset( (char*)head, 0, (HASH_SIZE*sizeof(*head)) ); + #endif + + gz1->max_lazy_match = configuration_table[pack_level].max_lazy; + gz1->good_match = configuration_table[pack_level].good_length; + #ifndef FULL_SEARCH + gz1->nice_match = configuration_table[pack_level].nice_length; + #endif + gz1->max_chain_length = configuration_table[pack_level].max_chain; + + if ( pack_level == 1 ) + { + *flags |= FAST; + } + else if ( pack_level == 9 ) + { + *flags |= SLOW; + } + + gz1->strstart = 0; + gz1->block_start = 0L; + #ifdef ASMV + match_init(); + #endif + + gz1->lookahead = read_buf(gz1,(char*)gz1->window, + sizeof(int) <= 2 ? (unsigned)WSIZE : 2*WSIZE); + + if (gz1->lookahead == 0 || gz1->lookahead == (unsigned)EOF) + { + gz1->eofile = 1, gz1->lookahead = 0; + return; + } + + gz1->eofile = 0; + + while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile) + { + fill_window(gz1); + } + + gz1->ins_h = 0; + + for ( j=0; jins_h = + (((gz1->ins_h)<window[j])) & HASH_MASK; + } +} + +void fill_window( PGZ1 gz1 ) +{ + register unsigned n, m; + + unsigned more = + (unsigned)( gz1->window_size - (ulg)gz1->lookahead - (ulg)gz1->strstart ); + + if ( more == (unsigned)EOF) + { + more--; + } + else if ( gz1->strstart >= WSIZE+MAX_DIST ) + { + memcpy((char*)gz1->window, (char*)gz1->window+WSIZE, (unsigned)WSIZE); + + gz1->match_start -= WSIZE; + gz1->strstart -= WSIZE; + + gz1->block_start -= (long) WSIZE; + + for ( n = 0; n < HASH_SIZE; n++ ) + { + m = head[n]; + head[n] = (ush)(m >= WSIZE ? m-WSIZE : NIL); + } + + for ( n = 0; n < WSIZE; n++ ) + { + m = prev[n]; + + prev[n] = (ush)(m >= WSIZE ? m-WSIZE : NIL); + } + + more += WSIZE; + } + + if ( !gz1->eofile ) + { + n = read_buf(gz1,(char*)gz1->window+gz1->strstart+gz1->lookahead, more); + + if ( n == 0 || n == (unsigned)EOF ) + { + gz1->eofile = 1; + } + else + { + gz1->lookahead += n; + } + } +} + +ulg gz1_deflate_fast( PGZ1 gz1 ) +{ + unsigned hash_head; + int flush; + unsigned match_length = 0; + + gz1->prev_length = MIN_MATCH-1; + + while (gz1->lookahead != 0) + { + gz1->ins_h = + (((gz1->ins_h)<window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK; + + prev[ gz1->strstart & WMASK ] = hash_head = head[ gz1->ins_h ]; + + head[ gz1->ins_h ] = gz1->strstart; + + if (hash_head != NIL && gz1->strstart - hash_head <= MAX_DIST) { + + match_length = longest_match( gz1, hash_head ); + + if (match_length > gz1->lookahead) match_length = gz1->lookahead; + } + if (match_length >= MIN_MATCH) { + + flush = ct_tally(gz1,gz1->strstart-gz1->match_start, match_length - MIN_MATCH); + + gz1->lookahead -= match_length; + + if (match_length <= gz1->max_lazy_match ) + { + match_length--; + + do { + gz1->strstart++; + + gz1->ins_h = + (((gz1->ins_h)<window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK; + + prev[ gz1->strstart & WMASK ] = hash_head = head[ gz1->ins_h ]; + + head[ gz1->ins_h ] = gz1->strstart; + + } while (--match_length != 0); + gz1->strstart++; + } else { + gz1->strstart += match_length; + match_length = 0; + gz1->ins_h = gz1->window[gz1->strstart]; + + gz1->ins_h = + (((gz1->ins_h)<window[gz1->strstart+1])) & HASH_MASK; + +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + } else { + + flush = ct_tally(gz1, 0, gz1->window[gz1->strstart]); + gz1->lookahead--; + gz1->strstart++; + } + if (flush) FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; + + while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile) fill_window(gz1); + } + + return FLUSH_BLOCK(1); +} + +void ct_init( +PGZ1 gz1, +ush *attr, +int *methodp +) +{ + #ifdef DD1 + int i,ii; + #endif + + int n; + int bits; + int length; + int code; + int dist; + + gz1->file_type = attr; + gz1->file_method = methodp; + gz1->compressed_len = gz1->input_len = 0L; + + if ( gz1->static_dtree[0].dl.len != 0 ) + { + return; + } + + length = 0; + + for ( code = 0; code < LENGTH_CODES-1; code++ ) + { + gz1->base_length[code] = length; + + for ( n = 0; n < (1<length_code[length++] = (uch)code; + } + } + + gz1->length_code[length-1] = (uch)code; + + dist = 0; + + for ( code = 0 ; code < 16; code++ ) + { + gz1->base_dist[code] = dist; + + for ( n = 0; n < (1<dist_code[dist++] = (uch)code; + } + } + + dist >>= 7; + + for ( ; code < D_CODES; code++ ) + { + gz1->base_dist[code] = dist << 7; + + for ( n = 0; n < (1<<(extra_dbits[code]-7)); n++ ) + { + gz1->dist_code[256 + dist++] = (uch)code; + } + } + + for ( bits = 0; bits <= MAX_BITS; bits++ ) + { + gz1->bl_count[bits] = 0; + } + + n = 0; + + while (n <= 143) gz1->static_ltree[n++].dl.len = 8, gz1->bl_count[8]++; + while (n <= 255) gz1->static_ltree[n++].dl.len = 9, gz1->bl_count[9]++; + while (n <= 279) gz1->static_ltree[n++].dl.len = 7, gz1->bl_count[7]++; + while (n <= 287) gz1->static_ltree[n++].dl.len = 8, gz1->bl_count[8]++; + + gen_codes(gz1,(ct_data *)gz1->static_ltree, L_CODES+1); + + for ( n = 0; n < D_CODES; n++ ) + { + gz1->static_dtree[n].dl.len = 5; + gz1->static_dtree[n].fc.code = bi_reverse( gz1, n, 5 ); + } + + init_block( gz1 ); +} + +ulg flush_block( +PGZ1 gz1, +char *buf, +ulg stored_len, +int eof +) +{ + ulg opt_lenb; + ulg static_lenb; + int max_blindex; + + gz1->flag_buf[gz1->last_flags] = gz1->flags; + + if (*gz1->file_type == (ush)UNKNOWN) set_file_type(gz1); + + build_tree( gz1, (tree_desc *)(&gz1->l_desc) ); + build_tree( gz1, (tree_desc *)(&gz1->d_desc) ); + + max_blindex = build_bl_tree( gz1 ); + + opt_lenb = (gz1->opt_len+3+7)>>3; + static_lenb = (gz1->static_len+3+7)>>3; + gz1->input_len += stored_len; + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + +#ifdef FORCE_METHOD + + if ( level == 1 && eof && gz1->compressed_len == 0L ) +#else + if (stored_len <= opt_lenb && eof && gz1->compressed_len == 0L && 0 ) +#endif + { + if (buf == (char*)0) error ("block vanished"); + + copy_block( gz1, buf, (unsigned)stored_len, 0 ); + + gz1->compressed_len = stored_len << 3; + *gz1->file_method = STORED; + +#ifdef FORCE_METHOD + } else if (level == 2 && buf != (char*)0) { +#else + } else if (stored_len+4 <= opt_lenb && buf != (char*)0) { + +#endif + + send_bits(gz1,(STORED_BLOCK<<1)+eof, 3); + gz1->compressed_len = (gz1->compressed_len + 3 + 7) & ~7L; + gz1->compressed_len += (stored_len + 4) << 3; + + copy_block(gz1, buf, (unsigned)stored_len, 1); + +#ifdef FORCE_METHOD + } else if (level == 3) { +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(gz1,(STATIC_TREES<<1)+eof, 3); + + compress_block( + gz1, + (ct_data *)gz1->static_ltree, + (ct_data *)gz1->static_dtree + ); + + gz1->compressed_len += 3 + gz1->static_len; + } + else + { + send_bits(gz1,(DYN_TREES<<1)+eof, 3); + + send_all_trees( + gz1, + gz1->l_desc.max_code+1, + gz1->d_desc.max_code+1, + max_blindex+1 + ); + + compress_block( + gz1, + (ct_data *)gz1->dyn_ltree, + (ct_data *)gz1->dyn_dtree + ); + + gz1->compressed_len += 3 + gz1->opt_len; + } + + init_block( gz1 ); + + if ( eof ) + { + bi_windup( gz1 ); + + gz1->compressed_len += 7; + } + + return gz1->compressed_len >> 3; +} + +#ifdef __BORLANDC__ +#pragma argsused +#endif + +unsigned bi_reverse( +PGZ1 gz1, +unsigned code, +int len +) +{ + register unsigned res = 0; + + do { + res |= code & 1; + code >>= 1, res <<= 1; + + } while (--len > 0); + + return res >> 1; +} + +void set_file_type( PGZ1 gz1 ) +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + + while (n < 7) bin_freq += gz1->dyn_ltree[n++].fc.freq; + while (n < 128) ascii_freq += gz1->dyn_ltree[n++].fc.freq; + while (n < LITERALS) bin_freq += gz1->dyn_ltree[n++].fc.freq; + + *gz1->file_type = bin_freq > (ascii_freq >> 2) ? BINARY : ASCII; +} + +void init_block( PGZ1 gz1 ) +{ + int n; + + for (n = 0; n < L_CODES; n++) gz1->dyn_ltree[n].fc.freq = 0; + for (n = 0; n < D_CODES; n++) gz1->dyn_dtree[n].fc.freq = 0; + for (n = 0; n < BL_CODES; n++) gz1->bl_tree[n].fc.freq = 0; + + gz1->dyn_ltree[END_BLOCK].fc.freq = 1; + + gz1->opt_len = 0L; + gz1->static_len = 0L; + gz1->last_lit = 0; + gz1->last_dist = 0; + gz1->last_flags = 0; + gz1->flags = 0; + gz1->flag_bit = 1; +} + +void bi_init( PGZ1 gz1, gz1_file_t zipfile ) +{ + gz1->zfile = zipfile; + gz1->bi_buf = 0; + gz1->bi_valid = 0; + + if ( gz1->zfile != NO_FILE ) + { + read_buf = file_read; + } +} + +int ct_tally( +PGZ1 gz1, +int dist, +int lc +) +{ + int dcode; + + gz1->inbuf[gz1->last_lit++] = (uch)lc; + + if ( dist == 0 ) + { + gz1->dyn_ltree[lc].fc.freq++; + } + else + { + dist--; + + gz1->dyn_ltree[gz1->length_code[lc]+LITERALS+1].fc.freq++; + gz1->dyn_dtree[d_code(dist)].fc.freq++; + gz1->d_buf[gz1->last_dist++] = (ush)dist; + gz1->flags |= gz1->flag_bit; + } + + gz1->flag_bit <<= 1; + + if ( (gz1->last_lit & 7) == 0 ) + { + gz1->flag_buf[gz1->last_flags++] = gz1->flags; + gz1->flags = 0, gz1->flag_bit = 1; + } + + if ( gz1->level > 2 && (gz1->last_lit & 0xfff) == 0) + { + ulg out_length = (ulg) ( gz1->last_lit * 8L ); + ulg in_length = (ulg) ( gz1->strstart - gz1->block_start ); + + for ( dcode = 0; dcode < D_CODES; dcode++ ) + { + out_length += (ulg) ((gz1->dyn_dtree[dcode].fc.freq)*(5L+extra_dbits[dcode])); + } + + out_length >>= 3; + + if ( gz1->last_dist < gz1->last_lit/2 && out_length < in_length/2 ) + { + return 1; + } + } + + return( gz1->last_lit == LIT_BUFSIZE-1 || gz1->last_dist == DIST_BUFSIZE ); +} + +void compress_block( +PGZ1 gz1, +ct_data *ltree, +ct_data *dtree +) +{ + unsigned dist; + int lc; + unsigned lx = 0; + unsigned dx = 0; + unsigned fx = 0; + uch flag = 0; + unsigned code; + int extra; + + if (gz1->last_lit != 0) do { + if ((lx & 7) == 0) flag = gz1->flag_buf[fx++]; + lc = gz1->inbuf[lx++]; + if ((flag & 1) == 0) { + send_code(lc, ltree); + } else { + + code = gz1->length_code[lc]; + send_code(code+LITERALS+1, ltree); + extra = extra_lbits[code]; + if (extra != 0) { + lc -= gz1->base_length[code]; + send_bits(gz1,lc, extra); + } + dist = gz1->d_buf[dx++]; + + code = d_code(dist); + + send_code(code, dtree); + extra = extra_dbits[code]; + if (extra != 0) { + dist -= gz1->base_dist[code]; + send_bits(gz1,dist, extra); + } + } + flag >>= 1; + } while (lx < gz1->last_lit); + + send_code(END_BLOCK, ltree); +} + +#ifndef ASMV + +int longest_match( PGZ1 gz1, unsigned cur_match ) +{ + unsigned chain_length = gz1->max_chain_length; + register uch *scan = gz1->window + gz1->strstart; + register uch *match; + register int len; + int best_len = gz1->prev_length; + unsigned limit = gz1->strstart > (unsigned)MAX_DIST ? gz1->strstart - (unsigned)MAX_DIST : NIL; + +#if HASH_BITS < 8 || MAX_MATCH != 258 + error: Code too clever +#endif + +#ifdef UNALIGNED_OK + + register uch *strend = gz1->window + gz1->strstart + MAX_MATCH - 1; + register ush scan_start = *(ush*)scan; + register ush scan_end = *(ush*)(scan+best_len-1); +#else + register uch *strend = gz1->window + gz1->strstart + MAX_MATCH; + register uch scan_end1 = scan[best_len-1]; + register uch scan_end = scan[best_len]; +#endif + + if (gz1->prev_length >= gz1->good_match) { + chain_length >>= 2; + } + + do { + match = gz1->window + cur_match; + +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + + if (*(ush*)(match+best_len-1) != scan_end || + *(ush*)match != scan_start) continue; + + scan++, match++; + do { + } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && + *(ush*)(scan+=2) == *(ush*)(match+=2) && + *(ush*)(scan+=2) == *(ush*)(match+=2) && + *(ush*)(scan+=2) == *(ush*)(match+=2) && + scan < strend); + + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); +#else + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + scan += 2, match++; + + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; +#endif + if (len > best_len) { + gz1->match_start = cur_match; + best_len = len; + if (len >= gz1->nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ush*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & WMASK]) > limit + && --chain_length != 0); + + return best_len; +} +#endif + +void send_bits( +PGZ1 gz1, +int value, +int length +) +{ + if ( gz1->bi_valid > (int) BUFSIZE - length ) + { + gz1->bi_buf |= (value << gz1->bi_valid); + + put_short(gz1->bi_buf); + + gz1->bi_buf = (ush)value >> (BUFSIZE - gz1->bi_valid); + gz1->bi_valid += length - BUFSIZE; + } + else + { + gz1->bi_buf |= value << gz1->bi_valid; + gz1->bi_valid += length; + } +} + +void build_tree( +PGZ1 gz1, +tree_desc *desc +) +{ + int elems = desc->elems; + ct_data *tree = desc->dyn_tree; + ct_data *stree = desc->static_tree; + + int n; + int m; + int max_code = -1; + int node = elems; + int new1; + + gz1->heap_len = 0, gz1->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].fc.freq != 0) { + gz1->heap[++gz1->heap_len] = max_code = n; + gz1->depth[n] = 0; + } else { + tree[n].dl.len = 0; + } + } + + while (gz1->heap_len < 2) { + new1 = gz1->heap[++gz1->heap_len] = (max_code < 2 ? ++max_code : 0); + tree[new1].fc.freq = 1; + gz1->depth[new1] = 0; + gz1->opt_len--; if (stree) gz1->static_len -= stree[new1].dl.len; + } + desc->max_code = max_code; + + for (n = gz1->heap_len/2; n >= 1; n--) pqdownheap(gz1, tree, n); + + do { + n = gz1->heap[SMALLEST]; + gz1->heap[SMALLEST] = gz1->heap[gz1->heap_len--]; + pqdownheap(gz1, tree, SMALLEST); + m = gz1->heap[SMALLEST]; + gz1->heap[--gz1->heap_max] = n; + gz1->heap[--gz1->heap_max] = m; + tree[node].fc.freq = tree[n].fc.freq + tree[m].fc.freq; + gz1->depth[node] = (uch) (GZ1_MAX(gz1->depth[n], gz1->depth[m]) + 1); + tree[n].dl.dad = tree[m].dl.dad = (ush)node; + gz1->heap[SMALLEST] = node++; + pqdownheap(gz1, tree, SMALLEST); + + } while (gz1->heap_len >= 2); + + gz1->heap[--gz1->heap_max] = gz1->heap[SMALLEST]; + + gen_bitlen(gz1,(tree_desc *)desc); + + gen_codes(gz1,(ct_data *)tree, max_code); +} + +int build_bl_tree( PGZ1 gz1 ) +{ + int max_blindex; + + scan_tree( gz1, (ct_data *)gz1->dyn_ltree, gz1->l_desc.max_code ); + scan_tree( gz1, (ct_data *)gz1->dyn_dtree, gz1->d_desc.max_code ); + + build_tree( gz1, (tree_desc *)(&gz1->bl_desc) ); + + for ( max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex-- ) + { + if (gz1->bl_tree[bl_order[max_blindex]].dl.len != 0) break; + } + + gz1->opt_len += 3*(max_blindex+1) + 5+5+4; + + return max_blindex; +} + +void gen_codes( +PGZ1 gz1, +ct_data *tree, +int max_code +) +{ + ush next_code[MAX_BITS+1]; + ush code = 0; + int bits; + int n; + + for ( bits = 1; bits <= MAX_BITS; bits++ ) + { + next_code[bits] = code = (code + gz1->bl_count[bits-1]) << 1; + } + + for ( n = 0; n <= max_code; n++ ) + { + int len = tree[n].dl.len; + if (len == 0) continue; + + tree[n].fc.code = bi_reverse( gz1, next_code[len]++, len ); + } + + return; +} + +void gen_bitlen( +PGZ1 gz1, +tree_desc *desc +) +{ + ct_data *tree = desc->dyn_tree; + int *extra = desc->extra_bits; + int base = desc->extra_base; + int max_code = desc->max_code; + int max_length = desc->max_length; + ct_data *stree = desc->static_tree; + int h; + int n, m; + int bits; + int xbits; + ush f; + int overflow = 0; + + for (bits = 0; bits <= MAX_BITS; bits++) gz1->bl_count[bits] = 0; + + tree[gz1->heap[gz1->heap_max]].dl.len = 0; + + for (h = gz1->heap_max+1; h < HEAP_SIZE; h++) { + n = gz1->heap[h]; + bits = tree[tree[n].dl.dad].dl.len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].dl.len = (ush)bits; + + if (n > max_code) continue; + + gz1->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].fc.freq; + gz1->opt_len += (ulg)f * (bits + xbits); + if (stree) gz1->static_len += (ulg)f * (stree[n].dl.len + xbits); + } + if (overflow == 0) return; + + do { + bits = max_length-1; + while (gz1->bl_count[bits] == 0) bits--; + gz1->bl_count[bits]--; + gz1->bl_count[bits+1] += 2; + gz1->bl_count[max_length]--; + + overflow -= 2; + } while (overflow > 0); + + for (bits = max_length; bits != 0; bits--) { + n = gz1->bl_count[bits]; + while (n != 0) { + m = gz1->heap[--h]; + if (m > max_code) continue; + if (tree[m].dl.len != (unsigned) bits) { + gz1->opt_len += ((long)bits-(long)tree[m].dl.len)*(long)tree[m].fc.freq; + tree[m].dl.len = (ush)bits; + } + n--; + } + } +} + +void copy_block( +PGZ1 gz1, +char *buf, +unsigned len, +int header +) +{ + #ifdef CRYPT + int t; + #endif + + bi_windup( gz1 ); + + if ( header ) + { + put_short((ush)len); + put_short((ush)~len); + } + + while( len-- ) + { + #ifdef CRYPT + if (key) zencode(*buf, t); + #endif + + put_byte(*buf++); + } +} + +int file_read( PGZ1 gz1, char *buf, unsigned size ) +{ + unsigned len = 0; + unsigned bytes_to_copy = 0; + + if ( gz1->input_ismem ) + { + if ( gz1->input_bytesleft > 0 ) + { + bytes_to_copy = size; + + if ( bytes_to_copy > (unsigned) gz1->input_bytesleft ) + { + bytes_to_copy = (unsigned) gz1->input_bytesleft; + } + + memcpy( buf, gz1->input_ptr, bytes_to_copy ); + + gz1->input_ptr += bytes_to_copy; + gz1->input_bytesleft -= bytes_to_copy; + + len = bytes_to_copy; + } + else + { + len = 0; + } + } + else + { + len = read( gz1->ifd, buf, size ); + } + + if ( len == (unsigned)(-1) || len == 0 ) + { + gz1->crc = gz1->crc ^ 0xffffffffL; + /* XXX - Do we need to do something with Adler CRC's here? + * I don't think so--they don't seem to need postprocessing. */ + return (int)len; + } + + if (gz1->compression_format != DEFLATE_FORMAT) + { + updcrc( gz1, (uch*)buf, len ); + } + else + { + gz1->adler = adler32(gz1->adler, (uch*)buf, len); + } + + gz1->bytes_in += (ulg)len; + + return (int)len; +} + +void bi_windup( PGZ1 gz1 ) +{ + if ( gz1->bi_valid > 8 ) + { + put_short(gz1->bi_buf); + } + else if ( gz1->bi_valid > 0 ) + { + put_byte(gz1->bi_buf); + } + + gz1->bi_buf = 0; + gz1->bi_valid = 0; +} + +void send_all_trees( +PGZ1 gz1, +int lcodes, +int dcodes, +int blcodes +) +{ + int rank; + + send_bits(gz1,lcodes-257, 5); + send_bits(gz1,dcodes-1, 5); + send_bits(gz1,blcodes-4, 4); + + for ( rank = 0; rank < blcodes; rank++ ) + { + send_bits(gz1,gz1->bl_tree[bl_order[rank]].dl.len, 3 ); + } + + send_tree(gz1,(ct_data *)gz1->dyn_ltree, lcodes-1); + send_tree(gz1,(ct_data *)gz1->dyn_dtree, dcodes-1); +} + +void send_tree( +PGZ1 gz1, +ct_data *tree, +int max_code +) +{ + int n; + int prevlen = -1; + int curlen; + int nextlen = tree[0].dl.len; + int count = 0; + int max_count = 7; + int min_count = 4; + + if (nextlen == 0) max_count = 138, min_count = 3; + + for ( n = 0; n <= max_code; n++ ) + { + curlen = nextlen; + nextlen = tree[n+1].dl.len; + + if (++count < max_count && curlen == nextlen) + { + continue; + } + else if (count < min_count) + { + do { send_code(curlen, gz1->bl_tree); } while (--count != 0); + } + else if (curlen != 0) + { + if ( curlen != prevlen ) + { + send_code(curlen, gz1->bl_tree); count--; + } + + send_code( REP_3_6, gz1->bl_tree ); send_bits(gz1,count-3, 2); + } + else if (count <= 10) + { + send_code(REPZ_3_10, gz1->bl_tree); send_bits(gz1,count-3, 3); + } + else + { + send_code(REPZ_11_138, gz1->bl_tree); send_bits(gz1,count-11, 7); + } + + count = 0; + prevlen = curlen; + + if (nextlen == 0) + { + max_count = 138, min_count = 3; + } + else if (curlen == nextlen) + { + max_count = 6, min_count = 3; + } + else + { + max_count = 7, min_count = 4; + } + } +} + +void scan_tree( +PGZ1 gz1, +ct_data *tree, +int max_code +) +{ + int n; + int prevlen = -1; + int curlen; + int nextlen = tree[0].dl.len; + int count = 0; + int max_count = 7; + int min_count = 4; + + if (nextlen == 0) max_count = 138, min_count = 3; + + tree[max_code+1].dl.len = (ush)0xffff; + + for ( n = 0; n <= max_code; n++ ) + { + curlen = nextlen; + nextlen = tree[n+1].dl.len; + + if ( ++count < max_count && curlen == nextlen ) + { + continue; + } + else if ( count < min_count ) + { + gz1->bl_tree[curlen].fc.freq += count; + } + else if ( curlen != 0 ) + { + if ( curlen != prevlen ) gz1->bl_tree[curlen].fc.freq++; + gz1->bl_tree[REP_3_6].fc.freq++; + } + else if ( count <= 10 ) + { + gz1->bl_tree[REPZ_3_10].fc.freq++; + } + else + { + gz1->bl_tree[REPZ_11_138].fc.freq++; + } + + count = 0; + prevlen = curlen; + + if ( nextlen == 0 ) + { + max_count = 138; + min_count = 3; + } + else if (curlen == nextlen) + { + max_count = 6; + min_count = 3; + } + else + { + max_count = 7; + min_count = 4; + } + } +} + +void pqdownheap( +PGZ1 gz1, +ct_data *tree, +int k +) +{ + int v = gz1->heap[k]; + int j = k << 1; + + while( j <= gz1->heap_len ) + { + if (j < gz1->heap_len && smaller(tree, gz1->heap[j+1], gz1->heap[j])) j++; + + if (smaller(tree, v, gz1->heap[j])) break; + + gz1->heap[k] = gz1->heap[j]; k = j; + + j <<= 1; + } + + gz1->heap[k] = v; +} + + +#define GZS_ZIP1 1 +#define GZS_ZIP2 2 +#define GZS_DEFLATE1 3 +#define GZS_DEFLATE2 4 + +int gzs_fsp ( PGZ1 gz1 ); +int gzs_zip1 ( PGZ1 gz1 ); +int gzs_zip2 ( PGZ1 gz1 ); +int gzs_deflate1( PGZ1 gz1 ); +int gzs_deflate2( PGZ1 gz1 ); + +int gzp_main( GZP_CONTROL *gzp ) +{ + PGZ1 gz1 = 0; + int rc = 0; + int final_exit_code = 0; + int ofile_flags = O_RDWR | O_CREAT | O_TRUNC | O_BINARY; + + gzp->result_code = 0; + gzp->bytes_out = 0; + + gz1 = (PGZ1) gz1_init(); + + if ( gz1 == 0 ) + { + return 0; + } + + gz1->decompress = gzp->decompress; + gz1->compression_format = gzp->compression_format; + + strcpy( gz1->ifname, gzp->input_filename ); + strcpy( gz1->ofname, gzp->output_filename ); + + gz1->input_ismem = gzp->input_ismem; + gz1->input_ptr = gzp->input_ismem_ibuf; + gz1->input_bytesleft = gzp->input_ismem_ibuflen; + + gz1->output_ismem = gzp->output_ismem; + gz1->output_ptr = gzp->output_ismem_obuf; + gz1->output_maxlen = gzp->output_ismem_obuflen; + + if ( gz1->no_time < 0 ) gz1->no_time = gz1->decompress; + if ( gz1->no_name < 0 ) gz1->no_name = gz1->decompress; + + work = zip; + + if ( !gz1->input_ismem ) + { + errno = 0; + + rc = stat( gz1->ifname, &gz1->istat ); + + if ( rc != 0 ) + { + gz1_cleanup( gz1 ); + + return 0; + } + + gz1->ifile_size = gz1->istat.st_size; + + gz1->ifd = + OPEN( + gz1->ifname, + gz1->ascii && !gz1->decompress ? O_RDONLY : O_RDONLY | O_BINARY, + RW_USER + ); + + if ( gz1->ifd == -1 ) + { + gz1_cleanup( gz1 ); + + return 0; + } + } + + if ( !gz1->output_ismem ) + { + if ( gz1->ascii && gz1->decompress ) + { + ofile_flags &= ~O_BINARY; + } + + gz1->ofd = OPEN( gz1->ofname, ofile_flags, RW_USER ); + + if ( gz1->ofd == -1 ) + { + if ( gz1->ifd ) + { + close( gz1->ifd ); + gz1->ifd = 0; + } + + gz1_cleanup( gz1 ); + + return 0; + } + } + + gz1->outcnt = 0; + gz1->insize = 0; + gz1->inptr = 0; + gz1->bytes_in = 0L; + gz1->bytes_out = 0L; + gz1->part_nb = 0; + + if ( gz1->decompress ) + { + gz1->method = get_header( gz1, gz1->ifd ); + + if ( gz1->method < 0 ) + { + if ( gz1->ifd ) + { + close( gz1->ifd ); + gz1->ifd = 0; + } + + if ( gz1->ofd ) + { + close( gz1->ofd ); + gz1->ofd = 0; + } + + return 0; + } + } + + gz1->save_orig_name = 0; + + gz1->state = GZS_ZIP1; + + for (;;) + { + gzs_fsp( gz1 ); + + if ( gz1->done == 1 ) break; + } + + if ( gz1->ifd ) + { + close( gz1->ifd ); + gz1->ifd = 0; + } + + if ( gz1->ofd ) + { + close( gz1->ofd ); + gz1->ofd = 0; + } + + gzp->result_code = gz1->exit_code; + gzp->bytes_out = gz1->bytes_out; + + final_exit_code = (int) gz1->exit_code; + + gz1_cleanup( gz1 ); + + return final_exit_code; +} + +int gzs_fsp( PGZ1 gz1 ) +{ + int rc=0; + + switch( gz1->state ) + { + case GZS_ZIP1: + + rc = gzs_zip1( gz1 ); + + break; + + case GZS_ZIP2: + + rc = gzs_zip2( gz1 ); + + break; + + case GZS_DEFLATE1: + + rc = gzs_deflate1( gz1 ); + + break; + + case GZS_DEFLATE2: + + rc = gzs_deflate2( gz1 ); + + break; + + default: + + gz1->done = 1; + + break; + } + + return( rc ); +} + + +int gzs_zip1( PGZ1 gz1 ) +{ + uch flags = 0; + ush attr = 0; + ush deflate_flags = 0; + + gz1->outcnt = 0; + + gz1->method = DEFLATED; + + if (gz1->compression_format != DEFLATE_FORMAT) + { + put_byte(GZIP_MAGIC[0]); + put_byte(GZIP_MAGIC[1]); + put_byte(DEFLATED); + } + else + { + /* Yes, I know RFC 1951 doesn't mention any header at the start of + * a deflated document, but zlib absolutely requires one. And since nearly + * all "deflate" implementations use zlib, we need to play along with this + * brain damage. */ + put_byte(ZLIB_HEADER[0]); + put_byte(ZLIB_HEADER[1]); + } + + if ( gz1->save_orig_name ) + { + flags |= ORIG_NAME; + } + + if (gz1->compression_format != DEFLATE_FORMAT) + { + put_byte(flags); + put_long(gz1->time_stamp); + + gz1->crc = -1; + updcrc( gz1, NULL, 0 ); + } + else + { + /* Deflate compression uses an Adler32 CRC, not a CRC32. */ + gz1->adler = 1L; + } + + gz1->state = GZS_ZIP2; + + return 0; +} + +int gzs_zip2( PGZ1 gz1 ) +{ + uch flags = 0; + ush attr = 0; + ush deflate_flags = 0; + + bi_init( gz1, gz1->ofd ); + ct_init( gz1, &attr, &gz1->method ); + lm_init( gz1, gz1->level, &deflate_flags ); + + if (gz1->compression_format != DEFLATE_FORMAT) + { + put_byte((uch)deflate_flags); + put_byte(OS_CODE); + if ( gz1->save_orig_name ) + { + char *p = gz1_basename( gz1, gz1->ifname ); + + do { + put_char(*p); + + } while (*p++); + } + } + + gz1->header_bytes = (long)gz1->outcnt; + + gz1->state = GZS_DEFLATE1; + + return 0; +} + +int gzs_deflate1( PGZ1 gz1 ) +{ + if ( !gz1->deflate1_initialized ) + { + gz1->deflate1_match_available = 0; + gz1->deflate1_match_length = MIN_MATCH-1; + gz1->deflate1_initialized = 1; + } + + if ( gz1->compr_level <= 3 ) + { + gz1->done = 1; + + return 0; + } + + if ( gz1->lookahead == 0 ) + { + if ( gz1->deflate1_match_available ) + { + ct_tally( gz1, 0, gz1->window[gz1->strstart-1] ); + } + + gz1->state = GZS_DEFLATE2; + + return (int) FLUSH_BLOCK(1); + } + + #ifdef STAY_HERE_FOR_A_CERTAIN_AMOUNT_OF_ITERATIONS + + while( iterations < max_iterations_per_yield ) + { + #endif + + gz1->ins_h = + (((gz1->ins_h)<window[gz1->strstart+MIN_MATCH-1])) & HASH_MASK; + + prev[ gz1->strstart & WMASK ] = gz1->deflate1_hash_head = head[ gz1->ins_h ]; + + head[ gz1->ins_h ] = gz1->strstart; + + gz1->prev_length = gz1->deflate1_match_length, gz1->deflate1_prev_match = gz1->match_start; + gz1->deflate1_match_length = MIN_MATCH-1; + + if ( gz1->deflate1_hash_head != NIL && gz1->prev_length < gz1->max_lazy_match && + gz1->strstart - gz1->deflate1_hash_head <= MAX_DIST) + { + gz1->deflate1_match_length = longest_match( gz1, gz1->deflate1_hash_head ); + + if ( gz1->deflate1_match_length > gz1->lookahead ) + { + gz1->deflate1_match_length = gz1->lookahead; + } + + if (gz1->deflate1_match_length == MIN_MATCH && gz1->strstart-gz1->match_start > TOO_FAR) + { + gz1->deflate1_match_length--; + } + } + + if ( gz1->prev_length >= MIN_MATCH && gz1->deflate1_match_length <= gz1->prev_length ) + { + gz1->deflate1_flush = + ct_tally(gz1,gz1->strstart-1-gz1->deflate1_prev_match, gz1->prev_length - MIN_MATCH); + + gz1->lookahead -= ( gz1->prev_length - 1 ); + gz1->prev_length -= 2; + + do { + gz1->strstart++; + + gz1->ins_h = + (((gz1->ins_h)<window[ gz1->strstart + MIN_MATCH-1])) & HASH_MASK; + + prev[ gz1->strstart & WMASK ] = gz1->deflate1_hash_head = head[gz1->ins_h]; + + head[ gz1->ins_h ] = gz1->strstart; + + } while (--gz1->prev_length != 0); + + gz1->deflate1_match_available = 0; + gz1->deflate1_match_length = MIN_MATCH-1; + + gz1->strstart++; + + if (gz1->deflate1_flush) FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; + } + + else + { + if ( gz1->deflate1_match_available ) + { + if ( ct_tally( gz1, 0, gz1->window[gz1->strstart-1] ) ) + { + FLUSH_BLOCK(0), gz1->block_start = gz1->strstart; + } + + gz1->strstart++; + gz1->lookahead--; + } + else + { + gz1->deflate1_match_available = 1; + gz1->strstart++; + gz1->lookahead--; + } + + while (gz1->lookahead < MIN_LOOKAHEAD && !gz1->eofile ) + { + fill_window(gz1); + } + } + + return 0; +} + +int gzs_deflate2( PGZ1 gz1 ) +{ + #if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO) + if (gz1->ifile_size != -1L && gz1->isize != (ulg)gz1->ifile_size) + { + } + #endif + + if (gz1->compression_format != DEFLATE_FORMAT) + { + put_long( gz1->crc ); + put_long( gz1->bytes_in ); + gz1->header_bytes += 2*sizeof(long); + } + else + { + /* Append an Adler32 CRC to our deflated data. + * Yes, I know RFC 1951 doesn't mention any CRC at the end of a + * deflated document, but zlib absolutely requires one. And since nearly + * all "deflate" implementations use zlib, we need to play along with this + * brain damage. */ + put_byte( (gz1->adler >> 24) ); + put_byte( (gz1->adler >> 16) & 0xFF ); + put_byte( (gz1->adler >> 8) & 0xFF ); + put_byte( (gz1->adler ) & 0xFF ); + gz1->header_bytes += 4*sizeof(uch); + } + + flush_outbuf( gz1 ); + + gz1->done = 1; + + return OK; +} + + +/* ========================================================================= + adler32 -- compute the Adler-32 checksum of a data stream + Copyright (C) 1995-1998 Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Modified by Eric Kidd to play nicely with mod_gzip. + */ + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +ulg adler32(ulg adler, uch *buf, unsigned len) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} + + +/* END OF FILE */ + + diff --git a/trunk/tools/turbocharger/mod_gzip.c.diff b/trunk/tools/turbocharger/mod_gzip.c.diff new file mode 100644 index 000000000..a2c500063 --- /dev/null +++ b/trunk/tools/turbocharger/mod_gzip.c.diff @@ -0,0 +1,365 @@ +--- mod_gzip.c-old Fri Jan 26 10:50:05 2001 ++++ mod_gzip.c Fri Jan 26 15:08:26 2001 +@@ -575,10 +575,15 @@ + * The GZP request control structure... + */ + ++#define GZIP_FORMAT (0) ++#define DEFLATE_FORMAT (1) ++ + typedef struct _GZP_CONTROL { + + int decompress; /* 0=Compress 1=Decompress */ + ++ int compression_format; /* GZIP_FORMAT or DEFLATE_FORMAT */ ++ + /* Input control... */ + + int input_ismem; /* Input source is memory buffer, not file */ +@@ -2209,10 +2214,11 @@ + mod_gzip_printf( "%s: Checking for 'gzip' designator...\n",cn); + #endif + +- if ( strstr( has_encoding, "gzip" ) ) ++ if ( strstr( has_encoding, "gzip" ) || ++ strstr( has_encoding, "deflate" ) ) + { + #ifdef MOD_GZIP_DEBUG1 +- mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' designator...\n",cn); ++ mod_gzip_printf( "%s: 'Content-encoding:' field contains 'gzip' or 'deflate' designator...\n",cn); + mod_gzip_printf( "%s: Pre-compression is assumed.\n",cn); + mod_gzip_printf( "%s: Exit > return( DECLINED ) >\n",cn); + #endif +@@ -2237,7 +2243,7 @@ + else /* 'gzip' designator not found... */ + { + #ifdef MOD_GZIP_DEBUG1 +- mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' designator...\n",cn); ++ mod_gzip_printf( "%s: 'Content-encoding:' field does NOT contain 'gzip' or 'deflate' designator...\n",cn); + mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); + #endif + } +@@ -2347,10 +2353,21 @@ + if ( accept_encoding ) + { + /* ...and if it has the right 'gzip' indicator... */ +- ++ /* We record the compression format in a request note, so we ++ * can get it again later, and so it can potentially be logged. ++ */ + if ( strstr( accept_encoding, "gzip" ) ) + { + process = 1; /* ...set the 'process' flag TRUE */ ++ ap_table_setn( r->notes,"mod_gzip_compression_format", ++ ap_pstrdup(r->pool,"gzip")); ++ ++ } ++ else if ( strstr( accept_encoding, "deflate" ) ) ++ { ++ process = 1; /* ...set the 'process' flag TRUE */ ++ ap_table_setn( r->notes,"mod_gzip_compression_format", ++ ap_pstrdup(r->pool,"deflate")); + } + + }/* End 'if( accept_encoding )' */ +@@ -2388,7 +2405,7 @@ + else /* 'gzip' designator was seen in 'Accept-Encoding:' field */ + { + #ifdef MOD_GZIP_DEBUG1 +- mod_gzip_printf( "%s: 'gzip' capability specified by user-agent.\n",cn); ++ mod_gzip_printf( "%s: 'gzip' or 'deflate' capability specified by user-agent.\n",cn); + mod_gzip_printf( "%s: Assuming OK to proceed...\n",cn); + #endif + } +@@ -4093,7 +4110,8 @@ + + char tmp[ MOD_GZIP_LARGE_BUFFER_SIZE + 2 ]; /* Scratch buffer */ + +- char actual_content_encoding_name[] = "gzip"; /* Adjustable */ ++ char *actual_content_encoding_name = "gzip"; /* Adjustable */ ++ const char *compression_format; + + #ifdef MOD_GZIP_DEBUG1 + char cn[]="mod_gzip_encode_and_transmit()"; +@@ -4470,6 +4488,18 @@ + + gzp->decompress = 0; /* Perform encoding */ + ++ /* Recover the compression format we're supposed to use. */ ++ compression_format = ap_table_get(r->notes, "mod_gzip_compression_format"); ++ if (compression_format && strcmp(compression_format, "deflate") == 0) ++ { ++ actual_content_encoding_name = "deflate"; ++ gzp->compression_format = DEFLATE_FORMAT; ++ } ++ else ++ { ++ gzp->compression_format = GZIP_FORMAT; ++ } ++ + if ( input_size <= (long) conf->maximum_inmem_size ) + { + /* The input source is small enough to compress directly */ +@@ -4591,6 +4621,7 @@ + + #ifdef MOD_GZIP_DEBUG1 + mod_gzip_printf( "%s: gzp->decompress = %d\n" ,cn,gzp->decompress); ++ mod_gzip_printf( "%s: gzp->compression_format = %d\n",cn,gzp->compression_format); + mod_gzip_printf( "%s: gzp->input_ismem = %d\n", cn,gzp->input_ismem); + mod_gzip_printf( "%s: gzp->output_ismem = %d\n", cn,gzp->output_ismem); + mod_gzip_printf( "%s: gzp->input_filename = [%s]\n",cn,gzp->input_filename); +@@ -7256,6 +7287,8 @@ + }; + + typedef struct _GZ1 { ++ long compression_format; ++ + long versionid1; + int state; + int done; +@@ -7345,6 +7378,7 @@ + int dbits; + ulg window_size; + ulg crc; ++ ulg adler; + + uch dist_code[512]; + uch length_code[MAX_MATCH-MIN_MATCH+1]; +@@ -7449,6 +7483,15 @@ + + void error( char *msg ); + ++/* XXX - Precomputed zlib header. If you change the window size or ++ * compression level from the defaults, this will break badly. The ++ * algorithm to build this is fairly complex; you can find it in ++ * the file deflate.c from the zlib distribution. ++ */ ++#define ZLIB_HEADER "\170œ" ++ ++ulg adler32(ulg adler, uch *buf, unsigned len); ++ + int zip( + PGZ1 gz1, + int in, +@@ -9088,10 +9131,20 @@ + if ( len == (unsigned)(-1) || len == 0 ) + { + gz1->crc = gz1->crc ^ 0xffffffffL; ++ /* XXX - Do we need to do something with Adler CRC's here? ++ * I don't think so--they don't seem to need postprocessing. */ + return (int)len; + } + +- updcrc( gz1, (uch*)buf, len ); ++ if (gz1->compression_format != DEFLATE_FORMAT) ++ { ++ updcrc( gz1, (uch*)buf, len ); ++ } ++ else ++ { ++ gz1->adler = adler32(gz1->adler, (uch*)buf, len); ++ } ++ + gz1->bytes_in += (ulg)len; + + return (int)len; +@@ -9288,6 +9341,7 @@ + gz1->heap[k] = v; + } + ++ + #define GZS_ZIP1 1 + #define GZS_ZIP2 2 + #define GZS_DEFLATE1 3 +@@ -9317,6 +9371,7 @@ + } + + gz1->decompress = gzp->decompress; ++ gz1->compression_format = gzp->compression_format; + + strcpy( gz1->ifname, gzp->input_filename ); + strcpy( gz1->ofname, gzp->output_filename ); +@@ -9489,6 +9544,7 @@ + return( rc ); + } + ++ + int gzs_zip1( PGZ1 gz1 ) + { + uch flags = 0; +@@ -9499,21 +9555,40 @@ + + gz1->method = DEFLATED; + +- put_byte(GZIP_MAGIC[0]); +- put_byte(GZIP_MAGIC[1]); +- put_byte(DEFLATED); ++ if (gz1->compression_format != DEFLATE_FORMAT) ++ { ++ put_byte(GZIP_MAGIC[0]); ++ put_byte(GZIP_MAGIC[1]); ++ put_byte(DEFLATED); ++ } ++ else ++ { ++ /* Yes, I know RFC 1951 doesn't mention any header at the start of ++ * a deflated document, but zlib absolutely requires one. And since nearly ++ * all "deflate" implementations use zlib, we need to play along with this ++ * brain damage. */ ++ put_byte(ZLIB_HEADER[0]); ++ put_byte(ZLIB_HEADER[1]); ++ } + + if ( gz1->save_orig_name ) + { + flags |= ORIG_NAME; + } + +- put_byte(flags); +- put_long(gz1->time_stamp); +- +- gz1->crc = -1; ++ if (gz1->compression_format != DEFLATE_FORMAT) ++ { ++ put_byte(flags); ++ put_long(gz1->time_stamp); + +- updcrc( gz1, NULL, 0 ); ++ gz1->crc = -1; ++ updcrc( gz1, NULL, 0 ); ++ } ++ else ++ { ++ /* Deflate compression uses an Adler32 CRC, not a CRC32. */ ++ gz1->adler = 1L; ++ } + + gz1->state = GZS_ZIP2; + +@@ -9529,18 +9604,20 @@ + bi_init( gz1, gz1->ofd ); + ct_init( gz1, &attr, &gz1->method ); + lm_init( gz1, gz1->level, &deflate_flags ); +- put_byte((uch)deflate_flags); +- +- put_byte(OS_CODE); + +- if ( gz1->save_orig_name ) ++ if (gz1->compression_format != DEFLATE_FORMAT) + { +- char *p = gz1_basename( gz1, gz1->ifname ); ++ put_byte((uch)deflate_flags); ++ put_byte(OS_CODE); ++ if ( gz1->save_orig_name ) ++ { ++ char *p = gz1_basename( gz1, gz1->ifname ); + +- do { +- put_char(*p); ++ do { ++ put_char(*p); + +- } while (*p++); ++ } while (*p++); ++ } + } + + gz1->header_bytes = (long)gz1->outcnt; +@@ -9674,10 +9751,25 @@ + } + #endif + +- put_long( gz1->crc ); +- put_long( gz1->bytes_in ); +- +- gz1->header_bytes += 2*sizeof(long); ++ if (gz1->compression_format != DEFLATE_FORMAT) ++ { ++ put_long( gz1->crc ); ++ put_long( gz1->bytes_in ); ++ gz1->header_bytes += 2*sizeof(long); ++ } ++ else ++ { ++ /* Append an Adler32 CRC to our deflated data. ++ * Yes, I know RFC 1951 doesn't mention any CRC at the end of a ++ * deflated document, but zlib absolutely requires one. And since nearly ++ * all "deflate" implementations use zlib, we need to play along with this ++ * brain damage. */ ++ put_byte( (gz1->adler >> 24) ); ++ put_byte( (gz1->adler >> 16) & 0xFF ); ++ put_byte( (gz1->adler >> 8) & 0xFF ); ++ put_byte( (gz1->adler ) & 0xFF ); ++ gz1->header_bytes += 4*sizeof(uch); ++ } + + flush_outbuf( gz1 ); + +@@ -9685,6 +9777,67 @@ + + return OK; + } ++ ++ ++/* ========================================================================= ++ adler32 -- compute the Adler-32 checksum of a data stream ++ Copyright (C) 1995-1998 Mark Adler ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++ Modified by Eric Kidd to play nicely with mod_gzip. ++ */ ++ ++#define BASE 65521L /* largest prime smaller than 65536 */ ++#define NMAX 5552 ++/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ ++ ++#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} ++#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); ++#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); ++#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); ++#define DO16(buf) DO8(buf,0); DO8(buf,8); ++ ++ulg adler32(ulg adler, uch *buf, unsigned len) ++{ ++ unsigned long s1 = adler & 0xffff; ++ unsigned long s2 = (adler >> 16) & 0xffff; ++ int k; ++ ++ if (buf == NULL) return 1L; ++ ++ while (len > 0) { ++ k = len < NMAX ? len : NMAX; ++ len -= k; ++ while (k >= 16) { ++ DO16(buf); ++ buf += 16; ++ k -= 16; ++ } ++ if (k != 0) do { ++ s1 += *buf++; ++ s2 += s1; ++ } while (--k); ++ s1 %= BASE; ++ s2 %= BASE; ++ } ++ return (s2 << 16) | s1; ++} ++ + + /* END OF FILE */ + diff --git a/trunk/tools/xml-rpc-api2cpp/DataType.cpp b/trunk/tools/xml-rpc-api2cpp/DataType.cpp new file mode 100644 index 000000000..8571f8036 --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/DataType.cpp @@ -0,0 +1,268 @@ +#include +#include +#include +#include +#include + +#include "xmlrpc-c/oldcppwrapper.hpp" +#include "DataType.hpp" + +using namespace std; + + + +//========================================================================= +// abstract class DataType +//========================================================================= +// Instances of DataType know how generate code fragments for manipulating +// a specific XML-RPC data type. + +string +DataType::defaultParameterBaseName(unsigned int const position) const { + + ostringstream nameStream; + + nameStream << typeName() << position; + + return nameStream.str(); +} + + + +class RawDataType : public DataType { +public: + RawDataType(string const& typeName) : DataType(typeName) {} + + virtual string + parameterFragment(string const& baseName) const; + + virtual string + inputConversionFragment(string const& baseName) const; + + virtual string + returnTypeFragment() const; + + virtual string + outputConversionFragment(string const& varName) const; +}; + + + +string +RawDataType::parameterFragment(string const& baseName) const { + return "XmlRpcValue /*" + typeName() + "*/ " + baseName; +} + + + +string +RawDataType::inputConversionFragment(string const& baseName) const { + + return baseName; +} + + + +string +RawDataType::returnTypeFragment() const { + return "XmlRpcValue /*" + typeName() + "*/"; +} + + + +string +RawDataType::outputConversionFragment(string const& varName) const { + + return varName; +} + + + +class SimpleDataType : public DataType { + string mNativeType; + string mMakerFunc; + string mGetterFunc; + +public: + SimpleDataType(string const& typeName, + string const& nativeType, + string const& makerFunc, + string const& getterFunc); + + virtual string + parameterFragment(string const& baseName) const; + + virtual string + inputConversionFragment(string const& baseName) const; + + virtual string + returnTypeFragment() const; + + virtual string + outputConversionFragment(string const& varName) const; +}; + + + +SimpleDataType::SimpleDataType(string const& typeName, + string const& nativeType, + string const& makerFunc, + string const& getterFunc) + : DataType(typeName), + mNativeType(nativeType), + mMakerFunc(makerFunc), + mGetterFunc(getterFunc) { +} + + + +string +SimpleDataType::parameterFragment(string const& baseName) const { + + return mNativeType + " const " + baseName; +} + + + +string +SimpleDataType::inputConversionFragment(string const& baseName) const { + + return mMakerFunc + "(" + baseName + ")"; +} + + + +string +SimpleDataType::returnTypeFragment() const { + + return mNativeType; +} + + + +string +SimpleDataType::outputConversionFragment(string const& varName) const { + return varName + "." + mGetterFunc + "()"; +} + + + +class VoidDataType : public DataType { +public: + VoidDataType() : DataType("void") {} + + virtual string + parameterFragment(string const& baseName) const; + + virtual string + inputConversionFragment(string const& baseName) const; + + virtual string + returnTypeFragment() const; + + virtual string + outputConversionFragment(string const& varName) const; +}; + + + +string +VoidDataType::parameterFragment(string const&) const { + + throw domain_error("Can't handle functions with 'void' arguments'"); +} + + + +string +VoidDataType::inputConversionFragment(string const&) const { + + throw domain_error("Can't handle functions with 'void' arguments'"); +} + + + +string +VoidDataType::returnTypeFragment () const { + + return "void"; +} + + + +string +VoidDataType::outputConversionFragment(string const&) const { + return "/* Return value ignored. */"; +} + + + +static SimpleDataType const intType ("int", "XmlRpcValue::int32", + "XmlRpcValue::makeInt", + "getInt"); +static SimpleDataType const boolType ("bool", "bool", + "XmlRpcValue::makeBool", + "getBool"); +static SimpleDataType const doubleType ("double", "double", + "XmlRpcValue::makeDouble", + "getDouble"); +static SimpleDataType const stringType ("string", "std::string", + "XmlRpcValue::makeString", + "getString"); + +static RawDataType const dateTimeType ("dateTime"); +static RawDataType const base64Type ("base64"); +static RawDataType const structType ("struct"); +static RawDataType const arrayType ("array"); + +static VoidDataType const voidType; + + + +const DataType& +findDataType(string const& name) { +/*---------------------------------------------------------------------------- + Given the name of an XML-RPC data type, try to find a corresponding + DataType object. +-----------------------------------------------------------------------------*/ + if (name == "int" || name == "i4") + return intType; + else if (name == "boolean") + return boolType; + else if (name == "double") + return doubleType; + else if (name == "string") + return stringType; + else if (name == "dateTime.iso8601") + return dateTimeType; + else if (name == "base64") + return base64Type; + else if (name == "struct") + return structType; + else if (name == "array") + return arrayType; + else if (name == "void") + return voidType; + else if (name == "INT") + return intType; + else if (name == "BOOLEAN") + return boolType; + else if (name == "DOUBLE") + return doubleType; + else if (name == "STRING") + return stringType; + else if (name == "DATETIME.ISO8601") + return dateTimeType; + else if (name == "BASE64") + return base64Type; + else if (name == "STRUCT") + return structType; + else if (name == "ARRAY") + return arrayType; + else if (name == "VOID") + return voidType; + else if (name == "NIL") + return voidType; + else + throw domain_error("Unknown XML-RPC type name '" + name + "'"); +} diff --git a/trunk/tools/xml-rpc-api2cpp/DataType.hpp b/trunk/tools/xml-rpc-api2cpp/DataType.hpp new file mode 100644 index 000000000..0945961ba --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/DataType.hpp @@ -0,0 +1,43 @@ +#include +#include + +class DataType { + std::string mTypeName; + + DataType(DataType const&) { assert(false); } + + DataType& operator= (DataType const&) { + assert(false); + return *this; + } + +public: + DataType(const std::string& type_name) : mTypeName(type_name) {} + + virtual ~DataType () {} + + // Return the name for this XML-RPC type. + virtual std::string + typeName() const { return mTypeName; } + + // Given a parameter position, calculate a unique base name for all + // parameter-related variables. + virtual std::string + defaultParameterBaseName(unsigned int const position) const; + + // Virtual functions for processing parameters. + virtual std::string + parameterFragment(std::string const& base_name) const = 0; + + virtual std::string + inputConversionFragment(std::string const& base_name) const = 0; + + // Virtual functions for processing return values. + virtual std::string + returnTypeFragment () const = 0; + + virtual std::string + outputConversionFragment(std::string const& var_name) const = 0; +}; + +const DataType& findDataType(const std::string& name); diff --git a/trunk/tools/xml-rpc-api2cpp/Makefile b/trunk/tools/xml-rpc-api2cpp/Makefile new file mode 100644 index 000000000..4e3b7a363 --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/Makefile @@ -0,0 +1,73 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/xml-rpc-api2cpp + +default: all + +include $(BLDDIR)/config.mk + +PROGS := xml-rpc-api2cpp +PROGRAMS_TO_INSTALL := $(PROGS) +MAN_FILES_TO_INSTALL := xml-rpc-api2cpp.1 + +all: $(PROGS) + +include $(SRCDIR)/tools/common.mk + +# in Glibc 2.2 has a bug that results in inlining failure, +# so we disable warnings for that: +CFLAGS_LOCAL = $(CFLAGS_NO_INLINE_WARNING) + +INCLUDES = -I$(BLDDIR) -I$(BLDDIR)/include -Isrcdir/include + +CLIENT_LDLIBS += $(SOCKETLIBOPT) + +LDLIBS = -L$(BLDDIR)/src/cpp -lxmlrpc_cpp -L$(BLDDIR)/src -lxmlrpc_server \ + $(CLIENT_LDLIBS) + +OBJECTS = \ + xml-rpc-api2cpp.o \ + DataType.o \ + XmlRpcFunction.o \ + XmlRpcClass.o \ + SystemProxy.o \ + +xml-rpc-api2cpp: \ + $(OBJECTS) \ + $(LIBXMLRPC_CPP) \ + $(CLIENT_LIBS_DEP) \ + $(LIBXMLRPC_SERVER) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_XML) \ + $(LIBXMLRPC_UTIL) + $(CXXLD) -o $@ $(LDFLAGS_ALL) $(OBJECTS) $(LDLIBS) + +%.o:%.cpp + $(CXX) -c $(CXXFLAGS_ALL) $< + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean +clean: clean-common + rm -f $(PROGS) + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: dep +dep: dep-common diff --git a/trunk/tools/xml-rpc-api2cpp/SystemProxy.cpp b/trunk/tools/xml-rpc-api2cpp/SystemProxy.cpp new file mode 100644 index 000000000..f24fadc64 --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/SystemProxy.cpp @@ -0,0 +1,39 @@ +// SystemProxy.cc - xmlrpc-c C++ proxy class +// Auto-generated by xml-rpc-api2cpp. +// But for now, this file is maintained manually. When someone figures +// out how stuff in this directory works, maybe we'll make it an automatically +// generated file. -Bryan 2005.06.05. + +#include + +#include "xmlrpc-c/oldcppwrapper.hpp" +#include "SystemProxy.hpp" + +using namespace std; + +XmlRpcValue /*array*/ SystemProxy::listMethods () { + XmlRpcValue params = XmlRpcValue::makeArray(); + XmlRpcValue result = this->mClient.call("system.listMethods", params); + return result; +} + +XmlRpcValue /*array*/ SystemProxy::methodSignature (string string1) { + XmlRpcValue params = XmlRpcValue::makeArray(); + params.arrayAppendItem(XmlRpcValue::makeString(string1)); + XmlRpcValue result = this->mClient.call("system.methodSignature", params); + return result; +} + +string SystemProxy::methodHelp (string string1) { + XmlRpcValue params = XmlRpcValue::makeArray(); + params.arrayAppendItem(XmlRpcValue::makeString(string1)); + XmlRpcValue result = this->mClient.call("system.methodHelp", params); + return result.getString(); +} + +XmlRpcValue /*array*/ SystemProxy::multicall (XmlRpcValue /*array*/ array1) { + XmlRpcValue params = XmlRpcValue::makeArray(); + params.arrayAppendItem(array1); + XmlRpcValue result = this->mClient.call("system.multicall", params); + return result; +} diff --git a/trunk/tools/xml-rpc-api2cpp/SystemProxy.hpp b/trunk/tools/xml-rpc-api2cpp/SystemProxy.hpp new file mode 100644 index 000000000..f7e80a273 --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/SystemProxy.hpp @@ -0,0 +1,48 @@ +// SystemProxy.h - xmlrpc-c C++ proxy class +// Auto-generated by xml-rpc-api2cpp. + +#ifndef _SystemProxy_H_ +#define _SystemProxy_H_ 1 + +#include + +#include "xmlrpc-c/oldcppwrapper.hpp" + +class SystemProxy { + XmlRpcClient mClient; + +public: + SystemProxy (const XmlRpcClient& client) + : mClient(client) {} + SystemProxy (const std::string& server_url) + : mClient(XmlRpcClient(server_url)) {} + SystemProxy (const SystemProxy& o) + : mClient(o.mClient) {} + + SystemProxy& operator= (const SystemProxy& o) { + if (this != &o) mClient = o.mClient; + return *this; + } + + /* Return an array of all available XML-RPC methods on this server. */ + XmlRpcValue /*array*/ listMethods (); + + /* Given the name of a method, return an array of legal + signatures. Each signature is an array of strings. The first item of + each signature is the return type, and any others items are + parameter types. */ + XmlRpcValue /*array*/ methodSignature (std::string string1); + + /* Given the name of a method, return a help string. */ + std::string methodHelp (std::string string1); + + /* Process an array of calls, and return an array of results. Calls + should be structs of the form {'methodName': string, 'params': + array}. Each result will either be a single-item array containg the + result value, or a struct of the form {'faultCode': int, + 'faultString': string}. This is useful when you need to make lots of + small calls without lots of round trips. */ + XmlRpcValue /*array*/ multicall (XmlRpcValue /*array*/ array1); +}; + +#endif /* _SystemProxy_H_ */ diff --git a/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.cpp b/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.cpp new file mode 100644 index 000000000..2678560ff --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.cpp @@ -0,0 +1,84 @@ +#include +#include +#include + +using namespace std; + +#include "xmlrpc-c/oldcppwrapper.hpp" + +#include "DataType.hpp" +#include "XmlRpcFunction.hpp" +#include "XmlRpcClass.hpp" + + +XmlRpcClass::XmlRpcClass(string const& className) : + mClassName(className) {} + + + +XmlRpcClass::XmlRpcClass(XmlRpcClass const& c) : + mClassName(c.mClassName), + mFunctions(c.mFunctions) {} + + + +XmlRpcClass& +XmlRpcClass::operator= (XmlRpcClass const& c) { + + if (this != &c) { + this->mClassName = c.mClassName; + this->mFunctions = c.mFunctions; + } + return *this; +} + + + +void +XmlRpcClass::addFunction(XmlRpcFunction const& function) { + + mFunctions.push_back(function); +} + + + +void +XmlRpcClass::printDeclaration(ostream & out) const { + + out << "class " << mClassName << " {" << endl; + out << " XmlRpcClient mClient;" << endl; + out << endl; + out << "public:" << endl; + out << " " << mClassName << " (const XmlRpcClient& client)" << endl; + out << " : mClient(client) {}" << endl; + out << " " << mClassName << " (const std::string& server_url)" << endl; + out << " : mClient(XmlRpcClient(server_url)) {}" << endl; + out << " " << mClassName << " (const " << mClassName << "& o)" << endl; + out << " : mClient(o.mClient) {}" << endl; + out << endl; + out << " " << mClassName << "& operator= (const " + << mClassName << "& o) {" << endl; + out << " if (this != &o) mClient = o.mClient;" << endl; + out << " return *this;" << endl; + out << " }" << endl; + + vector::const_iterator f; + for (f = mFunctions.begin(); f < mFunctions.end(); ++f) { + f->printDeclarations(out); + } + + out << "};" << endl; +} + + + +void +XmlRpcClass::printDefinition(ostream & out) const { + + vector::const_iterator f; + + for (f = mFunctions.begin(); f < mFunctions.end(); ++f) { + f->printDefinitions(out, mClassName); + } +} + diff --git a/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.hpp b/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.hpp new file mode 100644 index 000000000..e13c96fc4 --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/XmlRpcClass.hpp @@ -0,0 +1,22 @@ +#include + +class XmlRpcClass { + // An object of this class contains information about a proxy + // class, and knows how to generate code. + + std::string mClassName; + std::vector mFunctions; + + +public: + XmlRpcClass (std::string const& className); + XmlRpcClass(XmlRpcClass const&); + XmlRpcClass& operator= (XmlRpcClass const&); + + std::string className () const { return mClassName; } + + void addFunction (const XmlRpcFunction& function); + + void printDeclaration (ostream& out) const; + void printDefinition (ostream& out) const; +}; diff --git a/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.cpp b/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.cpp new file mode 100644 index 000000000..85751a515 --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.cpp @@ -0,0 +1,216 @@ +#include +#include +#include + +#include "xmlrpc-c/oldcppwrapper.hpp" +#include "DataType.hpp" +#include "XmlRpcFunction.hpp" + +using namespace std; + + +XmlRpcFunction::XmlRpcFunction(string const& functionName, + string const& methodName, + string const& help, + XmlRpcValue const signatureList) : + mFunctionName(functionName), + mMethodName(methodName), + mHelp(help), + mSynopsis(signatureList) {} + + + +XmlRpcFunction::XmlRpcFunction(XmlRpcFunction const& f) : + mFunctionName(f.mFunctionName), + mMethodName(f.mMethodName), + mHelp(f.mHelp), + mSynopsis(f.mSynopsis) {} + + + +XmlRpcFunction& +XmlRpcFunction::operator= (XmlRpcFunction const& f) { + + if (this != &f) { + this->mFunctionName = f.mFunctionName; + this->mMethodName = f.mMethodName; + this->mHelp = f.mHelp; + this->mSynopsis = f.mSynopsis; + } + return *this; +} + + + +void +XmlRpcFunction::printDeclarations(ostream & out) const { + + try { + // Print the method help as a comment + + out << endl << " /* " << mHelp << " */" << endl; + + size_t end; + + try { + end = mSynopsis.arraySize(); + } catch (XmlRpcFault const& fault) { + throw(logic_error("Failed to get size of signature array for " + "method " + this->mFunctionName + ". " + + fault.getFaultString())); + } + // Print the declarations for all the signatures of this + // XML-RPC method. + + for (size_t i = 0; i < end; ++i) + printDeclaration(out, i); + + } catch (exception const& e) { + throw(logic_error("Failed to generate declarations for method " + + this->mFunctionName + ". " + e.what())); + } +} + + + +void +XmlRpcFunction::printDefinitions(ostream & out, + string const& className) const { + + try { + size_t const end(mSynopsis.arraySize()); + + for (size_t i = 0; i < end; ++i) { + out << endl; + printDefinition(out, className, i); + } + } catch (XmlRpcFault const& fault) { + throw(logic_error("Failed to generate definitions for class " + + this->mFunctionName + ". " + + fault.getFaultString())); + } +} + + + +void +XmlRpcFunction::printParameters(ostream & out, + size_t const synopsisIndex) const { +/*---------------------------------------------------------------------------- + Print the parameter declarations. +-----------------------------------------------------------------------------*/ + size_t const end(parameterCount(synopsisIndex)); + + bool first; + + first = true; + + for (size_t i = 0; i < end; ++i) { + if (!first) + out << ", "; + + DataType const& ptype(parameterType(synopsisIndex, i)); + string const basename(ptype.defaultParameterBaseName(i + 1)); + out << ptype.parameterFragment(basename); + + first = false; + } +} + + + +void +XmlRpcFunction::printDeclaration(ostream & out, + size_t const synopsisIndex) const { + + try { + DataType const& rtype(returnType(synopsisIndex)); + + out << " " << rtype.returnTypeFragment() << " " + << mFunctionName << " ("; + + printParameters(out, synopsisIndex); + + out << ");" << endl; + } catch (XmlRpcFault const& fault) { + ostringstream msg; + + msg << "Failed to generate header for signature " + << synopsisIndex + << " . " + << fault.getFaultString(); + + throw(logic_error(msg.str())); + } +} + + + +void +XmlRpcFunction::printDefinition(ostream & out, + string const& className, + size_t const synopsisIndex) const { + + DataType const& rtype(returnType(synopsisIndex)); + + out << rtype.returnTypeFragment() << " " + << className << "::" << mFunctionName << " ("; + + printParameters(out, synopsisIndex); + + out << ") {" << endl; + out << " XmlRpcValue params(XmlRpcValue::makeArray());" << endl; + + /* Emit code to convert the parameters into an array of XML-RPC objects. */ + size_t const end(parameterCount(synopsisIndex)); + for (size_t i = 0; i < end; ++i) { + DataType const& ptype(parameterType(synopsisIndex, i)); + string const basename(ptype.defaultParameterBaseName(i + 1)); + out << " params.arrayAppendItem(" + << ptype.inputConversionFragment(basename) << ");" << endl; + } + + /* Emit the function call.*/ + out << " XmlRpcValue result(this->mClient.call(\"" + << mMethodName << "\", params));" << endl; + + /* Emit the return statement. */ + out << " return " << rtype.outputConversionFragment("result") + << ";" << endl; + out << "}" << endl; +} + + + +const DataType& +XmlRpcFunction::returnType(size_t const synopsisIndex) const { + + XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex)); + + return findDataType(funcSynop.arrayGetItem(0).getString()); +} + + + +size_t +XmlRpcFunction::parameterCount(size_t const synopsisIndex) const { + + XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex)); + size_t const size(funcSynop.arraySize()); + + if (size < 1) + throw domain_error("Synopsis contained no items"); + return size - 1; +} + + + +DataType const& +XmlRpcFunction::parameterType(size_t const synopsisIndex, + size_t const parameterIndex) const { + + XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex)); + XmlRpcValue const param(funcSynop.arrayGetItem(parameterIndex + 1)); + + return findDataType(param.getString()); +} diff --git a/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.hpp b/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.hpp new file mode 100644 index 000000000..bdef5b0e3 --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/XmlRpcFunction.hpp @@ -0,0 +1,39 @@ +#include +#include + +using std::string; +using std::ostream; + +class XmlRpcFunction { + // An object of this class contains everything we know about a + // given XML-RPC method, and knows how to print local bindings. + + string mFunctionName; + string mMethodName; + string mHelp; + XmlRpcValue mSynopsis; + +public: + XmlRpcFunction(const string& function_name, + const string& method_name, + const string& help, + XmlRpcValue synopsis); + + XmlRpcFunction (const XmlRpcFunction&); + XmlRpcFunction& operator= (const XmlRpcFunction&); + + void printDeclarations (ostream& out) const; + void printDefinitions (ostream& out, const string& className) const; + +private: + void printParameters (ostream& out, size_t synopsis_index) const; + void printDeclaration (ostream& out, size_t synopsis_index) const; + void printDefinition (ostream& out, + const string& className, + size_t synopsis_index) const; + + const DataType& returnType (size_t synopsis_index) const; + size_t parameterCount (size_t synopsis_index) const; + const DataType& parameterType (size_t synopsis_index, + size_t parameter_index) const; +}; diff --git a/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1 b/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1 new file mode 100644 index 000000000..a1c8b8068 --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1 @@ -0,0 +1,62 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH XML-RPC-API2CPP 1 "June 27, 2001" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +xml-rpc-api2cpp \- Make a C++ wrapper class for an XML-RPC API +.SH SYNOPSIS +.B xml-rpc-api2cpp +\fIserver-url\fR \fIremote-method-prefix\fR \fIc++-class-name\fR +.SH DESCRIPTION +xml-rpc-api2cpp queries an XML-RPC server using the XML-RPC +Instrospection API designed by Edd Dumbill. It then prints a C++ +wrapper class to standard output. This class can be used with +xmlrpc-c's C++ API. +.PP +You can find a list of supported XML-RPC server libraries (and patches +for many others) at \fBhttp://xmlrpc-c.sourceforge.net/hacks.php\fR. +.SH OPTIONS +.TP +.I server-url +The name of the server to query. Try +\fBhttp://xmlrpc-c.sourceforge.net/cgi-bin/interop.cgi\fR. +.TP +.I remote-method-prefix +The prefix of the methods to wrap. For example, to wrap all the +system.* calls, you could specify "system". +.TP +.I c++-class-name +The name of the C++ class to generate. Try "SystemProxy". +.SH BUGS +xml-rpc-api2cpp can't talk to certain PHP servers based on Edd +Dumbill's PHP library, because the trailing bytes of the XML-RPC +message get truncated in HTTP pipelining mode. It's not clear whether +this is a PHP, Apache or w3c-libwww bug. +.PP +xml-rpc-api2cpp assumes that method descriptions are ASCII text, not +HTML as specified in the standard. (In practice, both conventions are +often seen.) It may also get unhappy if method descriptions contain +"*/". +.PP +In general, error messages and diagnostics are still fairly poor. +.SH SEE ALSO +.BR xmlrpc-c (7), +.BR xml-rpc-api2txt (1). +.PP +This program is part of xmlrpc-c. +.SH AUTHOR +This manual page was written by Eric Kidd . +It may be distributed under the same terms as the rest of xmlrpc-c. diff --git a/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp b/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp new file mode 100644 index 000000000..adb63057d --- /dev/null +++ b/trunk/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp @@ -0,0 +1,212 @@ +#include +#include + +#include "xmlrpc-c/oldcppwrapper.hpp" + +#include "DataType.hpp" +#include "XmlRpcFunction.hpp" +#include "XmlRpcClass.hpp" +#include "SystemProxy.hpp" + +using namespace std; + +#define NAME "xml-rpc-api2cpp" +#define VERSION "0.1" + + +/*---------------------------------------------------------------------------- + Command line +-----------------------------------------------------------------------------*/ + +class cmdlineInfo { +public: + string serverUrl; + string methodPrefix; + string localClass; + + cmdlineInfo(int const argc, + const char ** const argv); + +private: + cmdlineInfo(); +}; + + + +cmdlineInfo::cmdlineInfo(int const argc, + const char ** const argv) { + + if (argc-1 != 3) { + cerr << argv[0] << ": Usage:" << endl + << " xml-rpc-api2cpp " + << endl << endl + << "Sample arguments:" << endl + << " server_url = http://localhost/RPC2" << endl + << " method_prefix = system" << endl + << " local_class = SystemProxy" << endl; + exit(1); + } + this->serverUrl = string(argv[1]); + this->methodPrefix = string(argv[2]); + this->localClass = string(argv[3]); +} + + + +static XmlRpcClass +getClassInfo(string const& serverUrl, + string const& classPrefix, + string const& className) { +/*---------------------------------------------------------------------------- + Connect to a remote server and extract the information we'll need to + build a proxy class. +-----------------------------------------------------------------------------*/ + XmlRpcClass info(className); + + SystemProxy system(serverUrl); + + XmlRpcValue const methods(system.listMethods()); + + size_t const end = methods.arraySize(); + + for (size_t i = 0; i < end; ++i) { + + // Break the method name into two pieces. + string const methodName(methods.arrayGetItem(i).getString()); + size_t const lastDot(methodName.rfind('.')); + + string methodPrefix; + string functionName; + + if (lastDot == string::npos) { + methodPrefix = ""; + functionName = methodName; + } else { + methodPrefix = string(methodName, 0, lastDot); + functionName = string(methodName, lastDot + 1); + } + + if (methodPrefix == classPrefix) { + // It's a method User cares about + + string const help(system.methodHelp(methodName)); + XmlRpcValue const signatureList( + system.methodSignature(methodName)); + + if (signatureList.getType() != XMLRPC_TYPE_ARRAY) { + // It must be the string "undef", meaning the server + // won't tell us any signatures. + cerr << "Skipping method " << methodName << " " + << "because server does not report any signatures " + << "for it (via system.methodSignature method)" + << endl; + } else { + // Add this function to our class information. + XmlRpcFunction const method(functionName, + methodName, + help, + signatureList); + info.addFunction(method); + } + } + } + return info; +} + + + +static void +printHeader(ostream & out, + XmlRpcClass const& classInfo) { +/*---------------------------------------------------------------------------- + Print a complete header for the specified class. +-----------------------------------------------------------------------------*/ + string const className(classInfo.className()); + + try { + out << "// " << className << ".h - xmlrpc-c C++ proxy class" << endl; + out << "// Auto-generated by xml-rpc-api2cpp." << endl; + out << endl; + + string const headerSymbol("_" + className + "_H_"); + + out << "#ifndef " << headerSymbol << endl; + out << "#define " << headerSymbol << " 1" << endl; + out << endl; + out << "#include " << endl; + out << endl; + + classInfo.printDeclaration(cout); + + out << endl; + out << "#endif /* " << headerSymbol << " */" << endl; + } catch (exception const& e) { + throw(logic_error("Failed to generate header for class " + + className + ". " + e.what())); + } +} + + + +static void +printCppFile(ostream & out, + XmlRpcClass const& classInfo) { +/*---------------------------------------------------------------------------- + Print a complete definition for the specified class. +-----------------------------------------------------------------------------*/ + string const className(classInfo.className()); + + try { + out << "// " << className << ".cc - xmlrpc-c C++ proxy class" << endl; + out << "// Auto-generated by xml-rpc-api2cpp." << endl; + out << endl; + + out << "#include " << endl; + out << "#include \"" << className << ".h\"" << endl; + + classInfo.printDefinition(cout); + } catch (XmlRpcFault const& fault) { + throw(logic_error("Failed to generate definition for class " + + className + ". " + fault.getFaultString())); + } +} + + + +int +main(int const argc, + const char ** const argv) { + + string const progName(argv[0]); + + cmdlineInfo const cmdline(argc, argv); + + int retval; + + XmlRpcClient::Initialize(NAME, VERSION); + + try { + XmlRpcClass system = getClassInfo(cmdline.serverUrl, + cmdline.methodPrefix, + cmdline.localClass); + printHeader(cout, system); + cout << endl; + printCppFile(cout, system); + retval = 0; + } catch (XmlRpcFault& fault) { + cerr << progName << ": XML-RPC fault #" << fault.getFaultCode() + << ": " << fault.getFaultString() << endl; + retval = 1; + } catch (logic_error& err) { + cerr << progName << ": " << err.what() << endl; + retval = 1; + } catch (...) { + cerr << progName << ": Unknown exception" << endl; + retval = 1; + } + + XmlRpcClient::Terminate(); + + return retval; +} + diff --git a/trunk/tools/xml-rpc-api2txt/Makefile b/trunk/tools/xml-rpc-api2txt/Makefile new file mode 100644 index 000000000..b4dd64678 --- /dev/null +++ b/trunk/tools/xml-rpc-api2txt/Makefile @@ -0,0 +1,42 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/xml-rpc-api2txt + +default: all + +include $(BLDDIR)/config.mk + +PROGS := +PROGRAMS_TO_INSTALL := xml-rpc-api2txt +MAN_FILES_TO_INSTALL := xml-rpc-api2txt.1 + +all: $(PROGS) + +include $(SRCDIR)/tools/common.mk + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean +clean: clean-common + rm -f $(PROGS) + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: dep +dep: dep-common diff --git a/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt b/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt new file mode 100644 index 000000000..e771463bd --- /dev/null +++ b/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt @@ -0,0 +1,147 @@ +#!/usr/bin/perl -w +# +# A handy little program to get the documentation of the available +# methods from an XML-RPC service (via XML-RPC Introspection) and +# print it out nicely formatted. +# +# (I wrote this in Perl because of all the spiffy report-generation +# features.) +# +# You'll need to get Ken MacLeod's Frontier::RPC2 module from CPAN to use +# this. +# +# Eric Kidd +# +# This script is part of xmlrpc-c, and may be used and distributed under +# the same terms as the rest of the package. + +use strict; + +# One global variable for use with Perl's format routines, and one for +# use inside an 'exec' block. +use vars qw/$helptext $method_list/; + +# Try to load our Perl XML-RPC bindings, but fail gracefully. +eval { + require Frontier::Client; +}; +if ($@) { + print STDERR <<"EOD"; +This script requires Ken MacLeod\'s Frontier::RPC2 module. You can get this +from CPAN or from his website at http://bitsko.slc.ut.us/~ken/xml-rpc/ . + +For installation instructions, see the XML-RPC HOWTO at: + http://www.linuxdoc.org/HOWTO/XML-RPC-HOWTO/index.html + +EOD + exit 1; +} + +# Parse our command-line arguments. +if (@ARGV != 1 || $ARGV[0] eq "--help") { + print STDERR "Usage: xml-rpc-api2txt serverURL\n"; + exit 1; +} + +my $server = Frontier::Client->new(url => $ARGV[0]); + +# Try (very carefully) to get our a list of methods from the server. +local $method_list; +eval { + $method_list = $server->call('system.listMethods'); +}; +if ($@) { + print STDERR <<"EOD"; +An error occurred while trying to talk to the XML-RPC server: + + $@ + +This may have been caused by several things--the server might not support +introspection, it might not be an XML-RPC server, or your network might be +down. Try the following: + + xml-rpc-api2txt http://xmlrpc-c.sourceforge.net/api/sample.php + +EOD + exit 1; +} + +# Enter the methods into a hashtable. +my @methods = sort @$method_list; +my %method_table; +foreach my $method (@methods) { + $method_table{$method} = {}; +} + +# Get more information for the hash table. Since we need to make lots and +# lots of very small XML-RPC calls, we'd like to use system.multicall to +# reduce the latency. +if (defined $method_table{'system.multicall'}) { + + # This is messy but fast. Everybody hates HTTP round-trip lag, right? + my @call; + foreach my $method (@methods) { + push @call, {methodName => 'system.methodSignature', + params => [$method]}; + push @call, {methodName => 'system.methodHelp', + params => [$method]}; + } + my @result = @{$server->call('system.multicall', \@call)}; + for (my $i = 0; $i < @methods; $i++) { + my $method = $methods[$i]; + $method_table{$method}->{'signatures'} = $result[2*$i]->[0]; + $method_table{$method}->{'help'} = $result[2*$i+1]->[0]; + } +} else { + + # This is easy but slow (especially over backbone links). + foreach my $method (@methods) { + my $signature = $server->call('system.methodSignature', $method); + my $help = $server->call('system.methodHelp', $method); + $method_table{$method}->{'signatures'} = $signature; + $method_table{$method}->{'help'} = $help; + } +} + +# Now, we need to dump the API. +print <<"EOD"; +XML-RPC API for $ARGV[0] + +See http://www.linuxdoc.org/HOWTO/XML-RPC-HOWTO/index.html for instructions +on using XML-RPC with Perl, Python, Java, C, C++, PHP, etc. +EOD +foreach my $method (@methods) { + print "\n"; + + # Print a synopsis of the function. + if ($method_table{$method}->{'signatures'} eq 'undef') { + # No documentation. Bad server. No biscuit. + print "unknown $method (...)\n"; + } else { + for my $signature (@{$method_table{$method}->{'signatures'}}) { + my $return_type = shift @$signature; + my $arguments = join(", ", @$signature); + print "$return_type $method ($arguments)\n"; + } + } + print "\n"; + + my $help = $method_table{$method}->{'help'}; + if ($help =~ /\n/) { + # Text has already been broken into lines by the server, so just + # indent it by two spaces and hope for the best. + my @lines = split(/\n/, $help); + my $help = " " . join("\n ", @lines); + print "$help\n"; + } else { + # Print our help text in a nicely-wrapped fashion using Perl's + # formatting routines. + $helptext = $method_table{$method}->{'help'}; + write; + } +} + +format STDOUT = + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~ + $helptext +. diff --git a/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt.1 b/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt.1 new file mode 100644 index 000000000..a9e1ee322 --- /dev/null +++ b/trunk/tools/xml-rpc-api2txt/xml-rpc-api2txt.1 @@ -0,0 +1,47 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH XML-RPC-API2TXT 1 "June 27, 2001" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +xml-rpc-api2txt \- Print out a description of an XML-RPC API as text +.SH SYNOPSIS +.B xml-rpc-api2txt +\fIserver-url\fR +.SH DESCRIPTION +xml-rpc-api2txt queries an XML-RPC server using the XML-RPC +Instrospection API designed by Edd Dumbill. It then prints the +results to standard output in a nicely formatted form, suitable for +sending via e-mail. +.PP +You can find a list of supported XML-RPC server libraries (and patches +for many others) at \fBhttp://xmlrpc-c.sourceforge.net/hacks.php\fR. +.SH OPTIONS +.TP +.I server-url +The name of the server to query. Try +\fBhttp://xmlrpc-c.sourceforge.net/cgi-bin/interop.cgi\fR. +.SH BUGS +xml-rpc-api2txt assumes that method descriptions are ASCII text, not +HTML as specified in the standard. (In practice, both conventions are +often seen.) +.SH SEE ALSO +.BR xmlrpc-c (7), +.BR xml-rpc-api2cpp (1). +.PP +This program is part of xmlrpc-c. +.SH AUTHOR +This manual page was written by Eric Kidd . +It may be distributed under the same terms as the rest of xmlrpc-c. diff --git a/trunk/tools/xml/Makefile b/trunk/tools/xml/Makefile new file mode 100644 index 000000000..70e05e8a3 --- /dev/null +++ b/trunk/tools/xml/Makefile @@ -0,0 +1,68 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/xml + +default: all + +include $(BLDDIR)/config.mk + +PROGS := xmlrpc_parsecall + +PROGRAMS_TO_INSTALL = $(PROGS) + +include $(SRCDIR)/tools/common.mk + +INCLUDES = \ + -I../lib/include \ + -Iblddir \ + -Iblddir/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include + +all: $(PROGS) + +UTIL_OBJS = \ + casprintf.o \ + +UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) + +DUMPVALUE = blddir/tools/lib/dumpvalue.o + +# Can we just use $(LIBS) in the link? + +LIBS = $(LIBXMLRPC) $(LIBXMLRPC_XML) $(LIBXMLRPC_UTIL) + +PARSECALL_OBJS = xmlrpc_parsecall.o $(DUMPVALUE) + +xmlrpc_parsecall: $(PARSECALL_OBJS) $(LIBS) $(UTILS) + $(CCLD) -o $@ $(LDFLAGS_ALL) $^ + +%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h + $(CC) -c $(CFLAGS_ALL) $< + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: dep +dep: dep-common + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean +clean: clean-common + rm -f $(PROGS) + +.PHONY: distclean +distclean: clean distclean-common diff --git a/trunk/tools/xml/xmlrpc_parsecall.c b/trunk/tools/xml/xmlrpc_parsecall.c new file mode 100644 index 000000000..ac576f212 --- /dev/null +++ b/trunk/tools/xml/xmlrpc_parsecall.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include + +#include +#include + +#include "casprintf.h" +#include "dumpvalue.h" + + +static void +die_if_fault_occurred (xmlrpc_env * const envP) { + if (envP->fault_occurred) { + fprintf(stderr, "Error: %s (%d)\n", + envP->fault_string, envP->fault_code); + exit(1); + } +} + + + +static void +readFile(xmlrpc_env * const envP, + FILE * const ifP, + xmlrpc_mem_block ** const fileContentsPP) { + + xmlrpc_mem_block * fileContentsP; + + fileContentsP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + + while (!envP->fault_occurred && !feof(ifP)) { + char buffer[4096]; + size_t bytesRead; + + bytesRead = fread(buffer, 1, sizeof(buffer), ifP); + XMLRPC_MEMBLOCK_APPEND(char, envP, + fileContentsP, buffer, bytesRead); + } + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, fileContentsP); + + *fileContentsPP = fileContentsP; +} + + + +int +main(int argc, const char ** argv) { + + xmlrpc_env env; + const char * methodName; + xmlrpc_value * paramArrayP; + xmlrpc_mem_block * callXmlP; + + if (argc-1 > 0) { + fprintf(stderr, "No arguments. Input is from Standard Input\n"); + if (argv){} /* defeat compiler warning */ + exit(99); + } + + xmlrpc_env_init(&env); + + fprintf(stderr, "Reading call data from Standard Input...\n"); + + readFile(&env, stdin, &callXmlP); + die_if_fault_occurred(&env); + + xmlrpc_parse_call(&env, + XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP), + XMLRPC_MEMBLOCK_SIZE(char, callXmlP), + &methodName, + ¶mArrayP); + + if (env.fault_occurred) + printf("Invalid call. %s\n", env.fault_string); + else { + printf("Parsed successfully as XML-RPC call.\n"); + + printf("Method name: '%s'\n", methodName); + + printf("Parameter array:\n"); + + dumpValue(" ", paramArrayP); + + strfree(methodName); + xmlrpc_DECREF(paramArrayP); + } + XMLRPC_MEMBLOCK_FREE(char, callXmlP); + + xmlrpc_env_clean(&env); + + return 0; +} diff --git a/trunk/tools/xmlrpc/Makefile b/trunk/tools/xmlrpc/Makefile new file mode 100644 index 000000000..3e322ce66 --- /dev/null +++ b/trunk/tools/xmlrpc/Makefile @@ -0,0 +1,68 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/xmlrpc + +default: all + +include $(BLDDIR)/config.mk + +PROGRAMS_TO_INSTALL = xmlrpc + +include $(SRCDIR)/tools/common.mk + +INCLUDES = \ + -I../lib/include \ + -Iblddir \ + -Iblddir/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include + +all: xmlrpc + +UTIL_OBJS = \ + casprintf.o \ + cmdline_parser.o \ + getoptx.o \ + stripcaseeq.o \ + string_parser.o \ + +UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) + +DUMPVALUE = blddir/tools/lib/dumpvalue.o + +XMLRPC_OBJS = xmlrpc.o $(DUMPVALUE) + +CLIENT_LDLIBS += $(SOCKETLIBOPT) $(THREAD_LIBS) + +xmlrpc: $(XMLRPC_OBJS) $(CLIENT_LIBS_DEP) $(UTILS) + $(CCLD) -o $@ $(LDFLAGS_ALL) $(XMLRPC_OBJS) $(UTILS) $(CLIENT_LDLIBS) + +%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h + $(CC) -c $(CFLAGS_ALL) $< + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: dep +dep: dep-common + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean +clean: clean-common + rm -f xmlrpc + +.PHONY: distclean +distclean: clean distclean-common diff --git a/trunk/tools/xmlrpc/xmlrpc.c b/trunk/tools/xmlrpc/xmlrpc.c new file mode 100644 index 000000000..8d45bdb98 --- /dev/null +++ b/trunk/tools/xmlrpc/xmlrpc.c @@ -0,0 +1,945 @@ +/* Make an XML-RPC call. + + User specifies details of the call on the command line. + + We print the result on Standard Output. + + Example: + + $ xmlrpc http://localhost:8080/RPC2 sample.add i/3 i/5 + Result: + Integer: 8 + + $ xmlrpc localhost:8080 sample.add i/3 i/5 + Result: + Integer: 8 +*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" /* information about this build environment */ +#include "bool.h" +#include "int.h" +#include "mallocvar.h" +#include "girstring.h" +#include "casprintf.h" +#include "string_parser.h" +#include "cmdline_parser.h" +#include "dumpvalue.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/client.h" +#include "xmlrpc-c/string_int.h" + +#define NAME "xmlrpc command line program" +#define VERSION "1.0" + +struct cmdlineInfo { + const char * url; + const char * username; + const char * password; + const char * methodName; + unsigned int paramCount; + const char ** params; + /* Array of parameters, in order. Has 'paramCount' entries. */ + const char * transport; + /* Name of XML transport he wants to use. NULL if he has no + preference. + */ + const char * curlinterface; + /* "network interface" parameter for the Curl transport. (Not + valid if 'transport' names a non-Curl transport). + */ + xmlrpc_bool curlnoverifypeer; + xmlrpc_bool curlnoverifyhost; + const char * curluseragent; + bool xmlsizelimitSpec; + unsigned int xmlsizelimit; +}; + + + +static void +die_if_fault_occurred (xmlrpc_env * const envP) { + if (envP->fault_occurred) { + fprintf(stderr, "Failed. %s\n", envP->fault_string); + exit(1); + } +} + + + +static void GNU_PRINTF_ATTR(2,3) +setError(xmlrpc_env * const envP, const char format[], ...) { + va_list args; + const char * faultString; + + va_start(args, format); + + cvasprintf(&faultString, format, args); + va_end(args); + + xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, faultString); + + strfree(faultString); +} + + + +static void +processArguments(xmlrpc_env * const envP, + cmdlineParser const cp, + struct cmdlineInfo * const cmdlineP) { + + if (cmd_argumentCount(cp) < 2) + setError(envP, "Not enough arguments. Need at least a URL and " + "method name."); + else { + unsigned int i; + + cmdlineP->url = cmd_getArgument(cp, 0); + cmdlineP->methodName = cmd_getArgument(cp, 1); + cmdlineP->paramCount = cmd_argumentCount(cp) - 2; + MALLOCARRAY_NOFAIL(cmdlineP->params, cmdlineP->paramCount); + for (i = 0; i < cmdlineP->paramCount; ++i) + cmdlineP->params[i] = cmd_getArgument(cp, i+2); + } +} + + + +static void +chooseTransport(xmlrpc_env * const envP ATTR_UNUSED, + cmdlineParser const cp, + const char ** const transportPP) { + + const char * transportOpt = cmd_getOptionValueString(cp, "transport"); + + if (transportOpt) { + *transportPP = transportOpt; + } else { + if (cmd_optionIsPresent(cp, "curlinterface") || + cmd_optionIsPresent(cp, "curlnoverifypeer") || + cmd_optionIsPresent(cp, "curlnoverifyhost") || + cmd_optionIsPresent(cp, "curluseragent")) + + *transportPP = strdup("curl"); + else + *transportPP = NULL; + } +} + + + +static void +parseCommandLine(xmlrpc_env * const envP, + int const argc, + const char ** const argv, + struct cmdlineInfo * const cmdlineP) { + + cmdlineParser const cp = cmd_createOptionParser(); + + const char * error; + + cmd_defineOption(cp, "transport", OPTTYPE_STRING); + cmd_defineOption(cp, "username", OPTTYPE_STRING); + cmd_defineOption(cp, "password", OPTTYPE_STRING); + cmd_defineOption(cp, "curlinterface", OPTTYPE_STRING); + cmd_defineOption(cp, "curlnoverifypeer", OPTTYPE_STRING); + cmd_defineOption(cp, "curlnoverifyhost", OPTTYPE_STRING); + cmd_defineOption(cp, "curluseragent", OPTTYPE_STRING); + cmd_defineOption(cp, "xmlsizelimit", OPTTYPE_BINUINT); + + cmd_processOptions(cp, argc, argv, &error); + + if (error) { + setError(envP, "Command syntax error. %s", error); + strfree(error); + } else { + if (cmd_optionIsPresent(cp, "xmlsizelimit")) { + cmdlineP->xmlsizelimitSpec = true; + cmdlineP->xmlsizelimit = + cmd_getOptionValueUint(cp, "xmlsizelimit"); + } else + cmdlineP->xmlsizelimitSpec = false; + + cmdlineP->username = cmd_getOptionValueString(cp, "username"); + cmdlineP->password = cmd_getOptionValueString(cp, "password"); + + if (cmdlineP->username && !cmdlineP->password) + setError(envP, "When you specify -username, you must also " + "specify -password."); + else { + chooseTransport(envP, cp, &cmdlineP->transport); + + cmdlineP->curlinterface = + cmd_getOptionValueString(cp, "curlinterface"); + cmdlineP->curlnoverifypeer = + cmd_optionIsPresent(cp, "curlnoverifypeer"); + cmdlineP->curlnoverifyhost = + cmd_optionIsPresent(cp, "curlnoverifyhost"); + cmdlineP->curluseragent = + cmd_getOptionValueString(cp, "curluseragent"); + + if ((!cmdlineP->transport || + !streq(cmdlineP->transport, "curl")) + && + (cmdlineP->curlinterface || + cmdlineP->curlnoverifypeer || + cmdlineP->curlnoverifyhost || + cmdlineP->curluseragent)) + setError(envP, "You may not specify a Curl transport " + "option unless you also specify -transport=curl"); + + processArguments(envP, cp, cmdlineP); + } + } + cmd_destroyOptionParser(cp); +} + + + +static void +freeCmdline(struct cmdlineInfo const cmdline) { + + unsigned int i; + + strfree(cmdline.url); + strfree(cmdline.methodName); + if (cmdline.transport) + strfree(cmdline.transport); + if (cmdline.curlinterface) + strfree(cmdline.curlinterface); + if (cmdline.curluseragent) + strfree(cmdline.curluseragent); + if (cmdline.username) + strfree(cmdline.username); + if (cmdline.password) + strfree(cmdline.password); + for (i = 0; i < cmdline.paramCount; ++i) + strfree(cmdline.params[i]); +} + + + +static void +computeUrl(const char * const urlArg, + const char ** const urlP) { + + if (strstr(urlArg, "://") != 0) + casprintf(urlP, "%s", urlArg); + else + casprintf(urlP, "http://%s/RPC2", urlArg); +} + + +enum TokenType {COMMA, COLON, LEFTPAREN, RIGHTPAREN, + LEFTBRACE, RIGHTBRACE, END}; + +static const char * +tokenTypeName(enum TokenType const type) { + + switch (type) { + case COMMA: return "comma"; + case COLON: return "colon"; + case LEFTPAREN: return "left parenthesis"; + case RIGHTPAREN: return "right parenthesis"; + case LEFTBRACE: return "left brace"; + case RIGHTBRACE: return "right brace"; + case END: return "end of string"; + } + return NULL; /* defeat bogus compiler warning */ +} + + + +static void +getDelimiter(xmlrpc_env * const envP, + const char ** const cursorP, + enum TokenType * const typeP) { + + const char * cursor; + enum TokenType tokenType; + + cursor = *cursorP; + + switch (*cursor) { + case ',': tokenType = COMMA; break; + case ':': tokenType = COLON; break; + case '(': tokenType = LEFTPAREN; break; + case ')': tokenType = RIGHTPAREN; break; + case '{': tokenType = LEFTBRACE; break; + case '}': tokenType = RIGHTBRACE; break; + case '\0': tokenType = END; break; + default: + setError(envP, "Unrecognized delimiter character '%c'", *cursor); + } + + if (!envP->fault_occurred && tokenType != END) + ++cursor; + + *cursorP = cursor; + *typeP = tokenType; +} + + + +static void +getCdata(xmlrpc_env * const envP, + const char ** const cursorP, + const char ** const cdataP) { + + size_t const cdataSizeBound = strlen(*cursorP) + 1; + + char * text; + + MALLOCARRAY(text, cdataSizeBound); + + if (text == NULL) + setError(envP, "Failed to allocate a buffer of size %u " + "to compute cdata", (unsigned)cdataSizeBound); + else { + unsigned int textCursor; + bool end; + const char * cursor; + + cursor = *cursorP; /* initial value */ + + for (textCursor = 0, end = false; !end; ) { + switch (*cursor) { + case ',': + case ':': + case '(': + case ')': + case '{': + case '}': + case '\0': + end = true; + break; + case '\\': { + ++cursor; // skip backslash escape character + if (!*cursor) + setError(envP, "Nothing after escape character ('\\')"); + else + text[textCursor++] = *cursor++; + }; break; + default: + text[textCursor++]= *cursor++; + } + assert(textCursor <= cdataSizeBound); + } + text[textCursor++] = '\0'; + + assert(textCursor <= cdataSizeBound); + + *cdataP = text; + *cursorP = cursor; + } +} + + + +static void +buildValue(xmlrpc_env * const envP, + const char ** const cursorP, + xmlrpc_value ** const valuePP); // for recursion + + +static void +buildString(xmlrpc_env * const envP, + const char * const valueString, + xmlrpc_value ** const paramPP) { + + *paramPP = xmlrpc_string_new(envP, valueString); +} + + + +static void +interpretHex(xmlrpc_env * const envP, + const char * const valueString, + size_t const valueStringSize, + unsigned char * const byteString) { + + size_t bsCursor; + size_t strCursor; + + for (strCursor = 0, bsCursor = 0; + strCursor < valueStringSize && !envP->fault_occurred; + ) { + int rc; + + rc = sscanf(&valueString[strCursor], "%2hhx", + &byteString[bsCursor++]); + + if (rc != 1) + xmlrpc_faultf(envP, "Invalid hex data '%s'", + &valueString[strCursor]); + else + strCursor += 2; + } +} + + + +static void +buildBytestring(xmlrpc_env * const envP, + const char * const valueString, + xmlrpc_value ** const paramPP) { + + size_t const valueStringSize = strlen(valueString); + + if (valueStringSize / 2 * 2 != valueStringSize) + xmlrpc_faultf(envP, "Hexadecimal text is not an even " + "number of characters (it is %u characters)", + (unsigned)strlen(valueString)); + else { + size_t const byteStringSize = strlen(valueString)/2; + + unsigned char * byteString; + + MALLOCARRAY(byteString, byteStringSize); + + if (byteString == NULL) + xmlrpc_faultf(envP, "Failed to allocate %u-byte buffer", + (unsigned)byteStringSize); + else { + interpretHex(envP, valueString, valueStringSize, byteString); + + if (!envP->fault_occurred) + *paramPP = xmlrpc_base64_new(envP, byteStringSize, byteString); + + free(byteString); + } + } +} + + + +static void +buildInt(xmlrpc_env * const envP, + const char * const valueString, + xmlrpc_value ** const paramPP) { + + if (strlen(valueString) < 1) + setError(envP, "Integer argument has nothing after the 'i/'"); + else { + int value; + const char * error; + + interpretInt(valueString, &value, &error); + + if (error) { + setError(envP, "'%s' is not a valid 32-bit integer. %s", + valueString, error); + strfree(error); + } else + *paramPP = xmlrpc_int_new(envP, value); + } +} + + + +static void +buildBool(xmlrpc_env * const envP, + const char * const valueString, + xmlrpc_value ** const paramPP) { + + if (streq(valueString, "t") || streq(valueString, "true")) + *paramPP = xmlrpc_bool_new(envP, true); + else if (streq(valueString, "f") || streq(valueString, "false")) + *paramPP = xmlrpc_bool_new(envP, false); + else + setError(envP, "Boolean argument has unrecognized value '%s'. " + "recognized values are 't', 'f', 'true', and 'false'.", + valueString); +} + + + +static void +buildDouble(xmlrpc_env * const envP, + const char * const valueString, + xmlrpc_value ** const paramPP) { + + if (strlen(valueString) < 1) + setError(envP, "\"Double\" argument has nothing after the 'd/'"); + else { + double value; + char * tailptr; + + value = strtod(valueString, &tailptr); + + if (*tailptr != '\0') + setError(envP, + "\"Double\" argument has non-decimal crap in it: '%s'", + tailptr); + else + *paramPP = xmlrpc_double_new(envP, value); + } +} + + + +static void +buildNil(xmlrpc_env * const envP, + const char * const valueString, + xmlrpc_value ** const paramPP) { + + if (strlen(valueString) > 0) + setError(envP, "Nil argument has something after the 'n/'"); + else { + *paramPP = xmlrpc_nil_new(envP); + } +} + + + +static void +buildI8(xmlrpc_env * const envP, + const char * const valueString, + xmlrpc_value ** const paramPP) { + + if (strlen(valueString) < 1) + setError(envP, "Integer argument has nothing after the 'I/'"); + else { + int64_t value; + const char * error; + + interpretLl(valueString, &value, &error); + + if (error) { + setError(envP, "'%s' is not a valid 64-bit integer. %s", + valueString, error); + strfree(error); + } else + *paramPP = xmlrpc_i8_new(envP, value); + } +} + + + +static void +addArrayItem(xmlrpc_env * const envP, + const char ** const cursorP, + xmlrpc_value * const arrayP, + bool * const endP) { + + xmlrpc_value * itemP; + + buildValue(envP, cursorP, &itemP); + + if (!envP->fault_occurred) { + xmlrpc_array_append_item(envP, arrayP, itemP); + + if (!envP->fault_occurred) { + enum TokenType delim; + + getDelimiter(envP, cursorP, &delim); + + if (!envP->fault_occurred) { + switch (delim) { + case COMMA: break; + case RIGHTPAREN: *endP = true; break; + default: + setError(envP, "Array specifier has garbage where " + "there should be a comma " + "(element separator) " + "or close parenthesis " + "(marking the end of the element list)"); + } + } + } + xmlrpc_DECREF(itemP); + } +} + + + +static void +buildArray(xmlrpc_env * const envP, + const char ** const cursorP, + xmlrpc_value ** const valuePP) { + + enum TokenType tokenType; + + getDelimiter(envP, cursorP, &tokenType); + + if (!envP->fault_occurred) { + if (tokenType != LEFTPAREN) + setError(envP, "Array specifier value starts with %s instead of " + "left parenthesis", tokenTypeName(tokenType)); + else { + xmlrpc_value * const arrayP = xmlrpc_array_new(envP); + + if (!envP->fault_occurred) { + bool end; /* We've reached the end of the array elements */ + for (end = false; !end && !envP->fault_occurred; ) + addArrayItem(envP, cursorP, arrayP, &end); + + if (envP->fault_occurred) + xmlrpc_DECREF(arrayP); + else + *valuePP = arrayP; + } + } + } +} + + + +static void +addStructMember(xmlrpc_env * const envP, + const char ** const cursorP, + xmlrpc_value * const structP, + bool * const endP) { + + const char * key; + + getCdata(envP, cursorP, &key); + + if (!envP->fault_occurred) { + enum TokenType delim; + + getDelimiter(envP, cursorP, &delim); + + if (!envP->fault_occurred) { + if (delim != COLON) + setError(envP, "Something other than a colon follows the " + "key value '%s' in a structure member.", key); + else { + xmlrpc_value * valueP; + + buildValue(envP, cursorP, &valueP); + + if (!envP->fault_occurred) { + xmlrpc_struct_set_value(envP, structP, key, valueP); + + if (!envP->fault_occurred) { + enum TokenType delim; + + getDelimiter(envP, cursorP, &delim); + + if (!envP->fault_occurred) { + switch (delim) { + case COMMA: break; + case RIGHTBRACE: *endP = true; break; + default: + setError(envP, "Struct specifier " + "has garbage where " + "there should be a comma " + "(member separator) " + "or close brace " + "(marking the end of the " + "member list)"); + } + } + } + xmlrpc_DECREF(valueP); + } + } + } + strfree(key); + } +} + + + + +static void +buildStruct(xmlrpc_env * const envP, + const char ** const cursorP, + xmlrpc_value ** const valuePP) { + + enum TokenType tokenType; + + getDelimiter(envP, cursorP, &tokenType); + + if (!envP->fault_occurred) { + if (tokenType != LEFTBRACE) + setError(envP, "Struct specifier value starts with %s instead of " + "left brace", tokenTypeName(tokenType)); + else { + xmlrpc_value * const structP = xmlrpc_struct_new(envP); + + if (!envP->fault_occurred) { + bool end; /* We've reached the end of the struct members */ + for (end = false; !end && !envP->fault_occurred; ) + addStructMember(envP, cursorP, structP, &end); + + if (envP->fault_occurred) + xmlrpc_DECREF(structP); + else + *valuePP = structP; + } + } + } +} + + + +static void +buildValue(xmlrpc_env * const envP, + const char ** const cursorP, + xmlrpc_value ** const valuePP) { +/*---------------------------------------------------------------------------- + Parse the text at *cursorP as a specification of an XML-RPC value + (e.g. "i/4" or "array/(i/0,i/2,i/2)") + + Stop parsing at the end of the specification of one value. Advance + *cursorP to that spot. +-----------------------------------------------------------------------------*/ + const char * cdata; + + getCdata(envP, cursorP, &cdata); + /* This should get e.g. "i/492" or "hello" or "array/" */ + + if (!envP->fault_occurred) { + if (strlen(cdata) == 0) + setError(envP, "Expected value type specifier such as 'i/' or " + "'array/' but found '%s'", *cursorP); + + if (xmlrpc_strneq(cdata, "s/", 2)) + buildString(envP, &cdata[2], valuePP); + else if (xmlrpc_strneq(cdata, "h/", 2)) + buildBytestring(envP, &cdata[2], valuePP); + else if (xmlrpc_strneq(cdata, "i/", 2)) + buildInt(envP, &cdata[2], valuePP); + else if (xmlrpc_strneq(cdata, "I/", 2)) + buildI8(envP, &cdata[2], valuePP); + else if (xmlrpc_strneq(cdata, "d/", 2)) + buildDouble(envP, &cdata[2], valuePP); + else if (xmlrpc_strneq(cdata, "b/", 2)) + buildBool(envP, &cdata[2], valuePP); + else if (xmlrpc_strneq(cdata, "n/", 2)) + buildNil(envP, &cdata[2], valuePP); + else if (xmlrpc_strneq(cdata, "array/", 6)) { + if (cdata[6] != '\0') + setError(envP, "Junk after 'array/' instead of " + "left parenthesis: '%s'", &cdata[6]); + else + buildArray(envP, cursorP, valuePP); + } else if (xmlrpc_strneq(cdata, "struct/", 7)) { + if (cdata[7] != '\0') + setError(envP, "Junk after 'struct/' instead of " + "left brace: '%s'", &cdata[7]); + else + buildStruct(envP, cursorP, valuePP); + } else { + /* It's not in normal type/value format, so we take it to be + the shortcut string notation + */ + buildString(envP, cdata, valuePP); + } + strfree(cdata); + } +} + + + +static void +computeParam(xmlrpc_env * const envP, + const char * const paramArg, + xmlrpc_value ** const paramPP) { + + const char * cursor; + + cursor = ¶mArg[0]; + + buildValue(envP, &cursor, paramPP); + + if (!envP->fault_occurred) { + if (*cursor != '\0') + setError(envP, "Junk after parameter specification: '%s'", cursor); + } +} + + + +static void +computeParamArray(xmlrpc_env * const envP, + unsigned int const paramCount, + const char ** const params, + xmlrpc_value ** const paramArrayPP) { + + unsigned int i; + + xmlrpc_value * paramArrayP; + + paramArrayP = xmlrpc_array_new(envP); + + for (i = 0; i < paramCount && !envP->fault_occurred; ++i) { + xmlrpc_value * paramP; + xmlrpc_env paramEnv; + + xmlrpc_env_init(¶mEnv); + + computeParam(¶mEnv, params[i], ¶mP); + + if (!paramEnv.fault_occurred) { + xmlrpc_array_append_item(¶mEnv, paramArrayP, paramP); + + xmlrpc_DECREF(paramP); + } + if (paramEnv.fault_occurred) + setError(envP, "Invalid specification of parameter %u " + "(starting at zero). %s", i, paramEnv.fault_string); + + xmlrpc_env_clean(¶mEnv); + } + *paramArrayPP = paramArrayP; +} + + + +static void +dumpResult(xmlrpc_value * const resultP) { + + printf("Result:\n\n"); + + dumpValue("", resultP); +} + + + +static void +callWithClient(xmlrpc_env * const envP, + const xmlrpc_server_info * const serverInfoP, + const char * const methodName, + xmlrpc_value * const paramArrayP, + xmlrpc_value ** const resultPP) { + + xmlrpc_env env; + xmlrpc_env_init(&env); + *resultPP = xmlrpc_client_call_server_params( + &env, serverInfoP, methodName, paramArrayP); + + if (env.fault_occurred) + xmlrpc_faultf(envP, "Call failed. %s. (XML-RPC fault code %d)", + env.fault_string, env.fault_code); + xmlrpc_env_clean(&env); +} + + + +static void +doCall(xmlrpc_env * const envP, + const char * const transport, + const char * const curlinterface, + xmlrpc_bool const curlnoverifypeer, + xmlrpc_bool const curlnoverifyhost, + const char * const curluseragent, + const xmlrpc_server_info * const serverInfoP, + const char * const methodName, + xmlrpc_value * const paramArrayP, + xmlrpc_value ** const resultPP) { + + struct xmlrpc_clientparms clientparms; + + XMLRPC_ASSERT(xmlrpc_value_type(paramArrayP) == XMLRPC_TYPE_ARRAY); + + clientparms.transport = transport; + + if (transport && streq(transport, "curl")) { + struct xmlrpc_curl_xportparms * curlXportParmsP; + MALLOCVAR(curlXportParmsP); + + curlXportParmsP->network_interface = curlinterface; + curlXportParmsP->no_ssl_verifypeer = curlnoverifypeer; + curlXportParmsP->no_ssl_verifyhost = curlnoverifyhost; + curlXportParmsP->user_agent = curluseragent; + + clientparms.transportparmsP = curlXportParmsP; + clientparms.transportparm_size = XMLRPC_CXPSIZE(user_agent); + } else { + clientparms.transportparmsP = NULL; + clientparms.transportparm_size = 0; + } + xmlrpc_client_init2(envP, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, + &clientparms, XMLRPC_CPSIZE(transportparm_size)); + if (!envP->fault_occurred) { + callWithClient(envP, serverInfoP, methodName, paramArrayP, resultPP); + + xmlrpc_client_cleanup(); + } + if (clientparms.transportparmsP) + free((void*)clientparms.transportparmsP); +} + + + +static void +createServerInfo(xmlrpc_env * const envP, + const char * const serverUrl, + const char * const userName, + const char * const password, + xmlrpc_server_info ** const serverInfoPP) { + + xmlrpc_server_info * serverInfoP; + + serverInfoP = xmlrpc_server_info_new(envP, serverUrl); + if (!envP->fault_occurred) { + if (userName) { + xmlrpc_server_info_set_basic_auth( + envP, serverInfoP, userName, password); + } + } + *serverInfoPP = serverInfoP; +} + + + +int +main(int const argc, + const char ** const argv) { + + struct cmdlineInfo cmdline; + xmlrpc_env env; + xmlrpc_value * paramArrayP; + xmlrpc_value * resultP; + const char * url; + xmlrpc_server_info * serverInfoP; + + xmlrpc_env_init(&env); + + parseCommandLine(&env, argc, argv, &cmdline); + die_if_fault_occurred(&env); + + if (cmdline.xmlsizelimitSpec) + xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, cmdline.xmlsizelimit); + + computeUrl(cmdline.url, &url); + + computeParamArray(&env, cmdline.paramCount, cmdline.params, ¶mArrayP); + die_if_fault_occurred(&env); + + createServerInfo(&env, url, cmdline.username, cmdline.password, + &serverInfoP); + die_if_fault_occurred(&env); + + doCall(&env, cmdline.transport, cmdline.curlinterface, + cmdline.curlnoverifypeer, cmdline.curlnoverifyhost, + cmdline.curluseragent, + serverInfoP, + cmdline.methodName, paramArrayP, + &resultP); + die_if_fault_occurred(&env); + + dumpResult(resultP); + + strfree(url); + + xmlrpc_DECREF(resultP); + + freeCmdline(cmdline); + + xmlrpc_env_clean(&env); + + return 0; +} diff --git a/trunk/tools/xmlrpc_cpp_proxy/Makefile b/trunk/tools/xmlrpc_cpp_proxy/Makefile new file mode 100644 index 000000000..8bf1f7f23 --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/Makefile @@ -0,0 +1,70 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/xmlrpc_cpp_proxy + +default: all + +include $(BLDDIR)/config.mk + +PROGRAMS_TO_INSTALL = xmlrpc_cpp_proxy + +include $(SRCDIR)/tools/common.mk + +# in Glibc 2.2 has a bug that results in inlining failure, +# so we disable warnings for that: +CFLAGS_LOCAL = $(CFLAGS_NO_INLINE_WARNING) + +INCLUDES = -I$(BLDDIR) -I$(BLDDIR)/include -Isrcdir/include + +all: xmlrpc_cpp_proxy + +OBJECTS = \ + xmlrpc_cpp_proxy.o \ + xmlrpcMethod.o \ + xmlrpcType.o \ + proxyClass.o \ + systemProxy.o \ + +LIBS = \ + $(LIBXMLRPC_CLIENTPP) \ + $(LIBXMLRPCPP) \ + $(CLIENT_LIBS_DEP) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_XML) \ + $(LIBXMLRPC_UTILPP) \ + $(LIBXMLRPC_UTIL) \ + +LDLIBS = $(CLIENTPP_LDLIBS) $(CLIENT_LDLIBS) $(SOCKETLIBOPT) $(THREAD_LIBS) + +xmlrpc_cpp_proxy: $(OBJECTS) $(LIBS) + $(CXXLD) -o $@ $(LDFLAGS_ALL) $(OBJECTS) $(LDLIBS) $(LADD) + +%.o:%.cpp $(BLDDIR)/include/xmlrpc-c/config.h + $(CXX) -c $(CXXFLAGS_ALL) $< + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean +clean: clean-common + rm -f xmlrpc_cpp_proxy + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: dep +dep: dep-common diff --git a/trunk/tools/xmlrpc_cpp_proxy/proxyClass.cpp b/trunk/tools/xmlrpc_cpp_proxy/proxyClass.cpp new file mode 100644 index 000000000..295b4824f --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/proxyClass.cpp @@ -0,0 +1,85 @@ +#include +#include +#include + +using namespace std; + +#include "xmlrpc-c/client_simple.hpp" + +#include "xmlrpcType.hpp" +#include "xmlrpcMethod.hpp" + +#include "proxyClass.hpp" + + +proxyClass::proxyClass(string const& className) : + _className(className) {} + + + +proxyClass::proxyClass(proxyClass const& c) : + _className(c._className), + functions(c.functions) {} + + + +string +proxyClass::className() const { + + return this->_className; +} + + + +void +proxyClass::addFunction(xmlrpcMethod const& function) { + + functions.push_back(function); +} + + + +void +proxyClass::printDeclaration(ostream & out) const { + + out << "class " << this->_className << " {" << endl; + out << endl; + out << "public:" << endl; + + // emit the constructor prototype: + out << " " << this->_className << "(std::string const& serverUrl) " + << endl + << " : serverUrl(serverUrl) {}" + << endl; + + // emit the XML-RPC method method prototypes: + vector::const_iterator f; + for (f = this->functions.begin(); f < this->functions.end(); ++f) { + f->printDeclarations(out); + } + + // emit the private data: + + out << "private:" << endl; + + out << " xmlrpc_c::clientSimple client;" << endl; + + out << " std::string const serverUrl;" << endl; + out << " // The URL for the server for which we are proxy" << endl; + + // emit the class closing: + out << "};" << endl; +} + + + +void +proxyClass::printDefinition(ostream & out) const { + + vector::const_iterator f; + + for (f = this->functions.begin(); f < this->functions.end(); ++f) { + f->printDefinitions(out, this->_className); + } +} + diff --git a/trunk/tools/xmlrpc_cpp_proxy/proxyClass.hpp b/trunk/tools/xmlrpc_cpp_proxy/proxyClass.hpp new file mode 100644 index 000000000..572f44451 --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/proxyClass.hpp @@ -0,0 +1,32 @@ +#include +#include + +#include "xmlrpcMethod.hpp" + +class proxyClass { + // An object of this class contains information about a proxy + // class, and knows how to generate code. + +public: + proxyClass(std::string const& className); + + proxyClass(proxyClass const&); + + std::string + className() const; + + void + addFunction(xmlrpcMethod const& function); + + void + printDeclaration(std::ostream& out) const; + + void + printDefinition(std::ostream& out) const; + +private: + + std::string const _className; + + std::vector functions; +}; diff --git a/trunk/tools/xmlrpc_cpp_proxy/systemProxy.cpp b/trunk/tools/xmlrpc_cpp_proxy/systemProxy.cpp new file mode 100644 index 000000000..51556873b --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/systemProxy.cpp @@ -0,0 +1,57 @@ +/*============================================================================= + systemProxy +=============================================================================== + + This is a proxy class for the introspection system methods of the server. + + Note that you can use 'xmlrpc_cpp_proxy' itself to generate this + file, but we hand-edit it to make it easier to read. + +=============================================================================*/ + +#include "systemProxy.hpp" + +using namespace std; + +xmlrpc_c::value // array +systemProxy::listMethods(string const& serverUrl) { + + xmlrpc_c::paramList params; + xmlrpc_c::value result; + + this->call(serverUrl, "system.listMethods", &result); + + return result; +} + + + +xmlrpc_c::value // array +systemProxy::methodSignature(string const& serverUrl, + string const& methodName) { + + xmlrpc_c::paramList params; + params.add(xmlrpc_c::value_string(methodName)); + + xmlrpc_c::value result; + + this->call(serverUrl, "system.methodSignature", params, &result); + + return result; +} + + + +string +systemProxy::methodHelp(string const& serverUrl, + string const& methodName) { + + xmlrpc_c::paramList params; + params.add(xmlrpc_c::value_string(methodName)); + + xmlrpc_c::value result; + + this->call(serverUrl, "system.methodHelp", params, &result); + + return xmlrpc_c::value_string(result); +} diff --git a/trunk/tools/xmlrpc_cpp_proxy/systemProxy.hpp b/trunk/tools/xmlrpc_cpp_proxy/systemProxy.hpp new file mode 100644 index 000000000..db4808b12 --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/systemProxy.hpp @@ -0,0 +1,25 @@ +#ifndef SYSTEMPROXY_HPP_INCLUDED +#define SYSTEMPROXY_HPP_INCLUDED + +#include +#include + +class systemProxy : public xmlrpc_c::clientSimple { + +public: + systemProxy() {} + + xmlrpc_c::value /*array*/ + listMethods(std::string const& serverUrl); + + xmlrpc_c::value /*array*/ + methodSignature(std::string const& serverUrl, + std::string const& methodName); + + std::string + methodHelp(std::string const& serverUrl, + std::string const& methodName); +}; + +#endif + diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp new file mode 100644 index 000000000..544648b65 --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp @@ -0,0 +1,240 @@ +#include +#include +#include + +#include "xmlrpcType.hpp" + +#include "xmlrpcMethod.hpp" + +using namespace std; + + +xmlrpcMethod::xmlrpcMethod(string const& functionName, + string const& methodName, + string const& help, + xmlrpc_c::value_array const& signatureList) : + mFunctionName(functionName), + mMethodName(methodName), + mHelp(help), + mSynopsis(signatureList) {} + + + +xmlrpcMethod::xmlrpcMethod(xmlrpcMethod const& f) : + mFunctionName(f.mFunctionName), + mMethodName(f.mMethodName), + mHelp(f.mHelp), + mSynopsis(f.mSynopsis) {} + + + +xmlrpcMethod& +xmlrpcMethod::operator= (xmlrpcMethod const& f) { + + if (this != &f) { + this->mFunctionName = f.mFunctionName; + this->mMethodName = f.mMethodName; + this->mHelp = f.mHelp; + this->mSynopsis = f.mSynopsis; + } + return *this; +} + + + + + + +size_t +xmlrpcMethod::parameterCount(size_t const synopsisIndex) const { + + xmlrpc_c::value_array const funcSynop( + mSynopsis.vectorValueValue()[synopsisIndex]); + size_t const size(funcSynop.size()); + + if (size < 1) + throw domain_error("Synopsis contains no items"); + + return size - 1; +} + + + +xmlrpcType const& +xmlrpcMethod::parameterType(size_t const synopsisIndex, + size_t const parameterIndex) const { + + xmlrpc_c::value_array const funcSynop( + mSynopsis.vectorValueValue()[synopsisIndex]); + xmlrpc_c::value_string const param( + funcSynop.vectorValueValue()[parameterIndex + 1]); + + return findXmlrpcType(static_cast(param)); +} + + + +const xmlrpcType& +xmlrpcMethod::returnType(size_t const synopsisIndex) const { + + xmlrpc_c::value_array const funcSynop( + mSynopsis.vectorValueValue()[synopsisIndex]); + + xmlrpc_c::value_string datatype(funcSynop.vectorValueValue()[0]); + return findXmlrpcType(static_cast(datatype)); +} + + + +void +xmlrpcMethod::printParameters(ostream & out, + size_t const synopsisIndex) const { +/*---------------------------------------------------------------------------- + Print the parameter declarations. +-----------------------------------------------------------------------------*/ + size_t const end(parameterCount(synopsisIndex)); + + bool first; + + first = true; + + for (size_t i = 0; i < end; ++i) { + if (!first) + out << ", "; + + xmlrpcType const& ptype(parameterType(synopsisIndex, i)); + + string const localName(ptype.defaultParameterBaseName(i + 1)); + out << ptype.parameterFragment(localName); + + first = false; + } +} + + + +void +xmlrpcMethod::printDeclaration(ostream & out, + size_t const synopsisIndex) const { + + try { + xmlrpcType const& rtype(returnType(synopsisIndex)); + + out << " " << rtype.returnTypeFragment() << " " + << mFunctionName << " ("; + + printParameters(out, synopsisIndex); + + out << ");" << endl; + } catch (xmlrpc_c::fault const& f) { + ostringstream msg; + + msg << "Failed to generate header for signature " + << synopsisIndex + << " . " + << f.getDescription(); + + throw(logic_error(msg.str())); + } +} + + + +void +xmlrpcMethod::printDeclarations(ostream & out) const { + + try { + // Print the method help as a comment + + out << endl << " /* " << mHelp << " */" << endl; + + size_t end; + + try { + end = mSynopsis.size(); + } catch (xmlrpc_c::fault const& f) { + throw(logic_error("Failed to get size of signature array for " + "method " + this->mFunctionName + ". " + + f.getDescription())); + } + // Print the declarations for all the signatures of this + // XML-RPC method. + + for (size_t i = 0; i < end; ++i) + printDeclaration(out, i); + + } catch (exception const& e) { + throw(logic_error("Failed to generate declarations for method " + + this->mFunctionName + ". " + e.what())); + } +} + + + +void +xmlrpcMethod::printDefinition(ostream & out, + string const& className, + size_t const synopsisIndex) const { + + xmlrpcType const& rtype(returnType(synopsisIndex)); + + out << rtype.returnTypeFragment() << " " + << className << "::" << mFunctionName << " ("; + + printParameters(out, synopsisIndex); + + out << ") {" << endl; + + size_t const end(parameterCount(synopsisIndex)); + if (end > 0){ + // Emit code to generate the parameter list object + out << " xmlrpc_c::paramList params;" << endl; + for (size_t i = 0; i < end; ++i) { + xmlrpcType const& ptype(parameterType(synopsisIndex, i)); + string const basename(ptype.defaultParameterBaseName(i + 1)); + out << " params.add(" + << ptype.inputConversionFragment(basename) << ");" << endl; + } + } + + // Emit result holder declaration. + out << " xmlrpc_c::value result;" << endl; + + // Emit the call to the XML-RPC call method + out << " this->client.call(" + << "this->serverUrl, " + << "\"" << mMethodName << "\", "; + + if (end > 0) + out << "params, "; + + out << "&result);" << endl; + + // Emit the return statement. + out << " return " << rtype.outputConversionFragment("result") + << ";" << endl; + out << "}" << endl; +} + + + +void +xmlrpcMethod::printDefinitions(ostream & out, + string const& className) const { + + try { + size_t const end(mSynopsis.size()); + + for (size_t i = 0; i < end; ++i) { + out << endl; + printDefinition(out, className, i); + } + } catch (xmlrpc_c::fault const& f) { + throw(logic_error("Failed to generate definitions for class " + + this->mFunctionName + ". " + + f.getDescription())); + } +} + + + diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp new file mode 100644 index 000000000..276899703 --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp @@ -0,0 +1,59 @@ +#ifndef XMLRPCMETHOD_HPP +#define XMLRPCMETHOD_HPP + +#include +#include +#include + +class xmlrpcMethod { + // An object of this class contains everything we know about a + // given XML-RPC method, and knows how to print local bindings. + + std::string mFunctionName; + std::string mMethodName; + std::string mHelp; + xmlrpc_c::value_array mSynopsis; + +public: + xmlrpcMethod(std::string const& function_name, + std::string const& method_name, + std::string const& help, + xmlrpc_c::value_array const& signatureList); + + xmlrpcMethod(xmlrpcMethod const& f); + + xmlrpcMethod& operator= (xmlrpcMethod const& f); + + void + printDeclarations(std::ostream& out) const; + + void + printDefinitions(std::ostream & out, + std::string const& className) const; + +private: + void + printParameters(std::ostream & out, + size_t const synopsis_index) const; + + void + printDeclaration(std::ostream & out, + size_t const synopsis_index) const; + + void + printDefinition(std::ostream & out, + std::string const& className, + size_t const synopsis_index) const; + + const xmlrpcType& + returnType(size_t const synopsis_index) const; + + size_t + parameterCount(size_t const synopsis_index) const; + + const xmlrpcType& + parameterType(size_t const synopsis_index, + size_t const parameter_index) const; +}; + +#endif diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp new file mode 100644 index 000000000..f884ee419 --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp @@ -0,0 +1,270 @@ +#include +#include +#include +#include +#include + +#include + +#include "xmlrpcType.hpp" + +using namespace std; + + + +//========================================================================= +// abstract class xmlrpcType +//========================================================================= +// Instances of xmlrpcType know how generate code fragments for manipulating +// a specific XML-RPC data type. + +string +xmlrpcType::defaultParameterBaseName(unsigned int const position) const { + + ostringstream nameStream; + + nameStream << typeName() << position; + + return nameStream.str(); +} + + + +class rawXmlrpcType : public xmlrpcType { +public: + rawXmlrpcType(string const& typeName) : xmlrpcType(typeName) {} + + virtual string + parameterFragment(string const& baseName) const; + + virtual string + inputConversionFragment(string const& baseName) const; + + virtual string + returnTypeFragment() const; + + virtual string + outputConversionFragment(string const& varName) const; +}; + + + +string +rawXmlrpcType::parameterFragment(string const& baseName) const { + return "xmlrpc_c::value /*" + typeName() + "*/ " + baseName; +} + + + +string +rawXmlrpcType::inputConversionFragment(string const& baseName) const { + + return baseName; +} + + + +string +rawXmlrpcType::returnTypeFragment() const { + return "xmlrpc_c::value /*" + typeName() + "*/"; +} + + + +string +rawXmlrpcType::outputConversionFragment(string const& varName) const { + + return varName; +} + + + +class simpleXmlrpcType : public xmlrpcType { + + string mNativeType; + string mMakerFunc; + string mGetterFunc; + +public: + simpleXmlrpcType(string const& typeName, + string const& nativeType, + string const& makerFunc, + string const& getterFunc); + + virtual string + parameterFragment(string const& baseName) const; + + virtual string + inputConversionFragment(string const& baseName) const; + + virtual string + returnTypeFragment() const; + + virtual string + outputConversionFragment(string const& varName) const; +}; + + + +simpleXmlrpcType::simpleXmlrpcType(string const& typeName, + string const& nativeType, + string const& makerFunc, + string const& getterFunc) + : xmlrpcType(typeName), + mNativeType(nativeType), + mMakerFunc(makerFunc), + mGetterFunc(getterFunc) { +} + + + +string +simpleXmlrpcType::parameterFragment(string const& baseName) const { + + return mNativeType + " const " + baseName; +} + + + +string +simpleXmlrpcType::inputConversionFragment(string const& baseName) const { + + return mMakerFunc + "(" + baseName + ")"; +} + + + +string +simpleXmlrpcType::returnTypeFragment() const { + + return mNativeType; +} + + + +string +simpleXmlrpcType::outputConversionFragment(string const& varName) const { + return mMakerFunc + "(" + varName + ")"; +} + + + +class voidXmlrpcType : public xmlrpcType { +public: + voidXmlrpcType() : xmlrpcType("void") {} + + virtual string + parameterFragment(string const& baseName) const; + + virtual string + inputConversionFragment(string const& baseName) const; + + virtual string + returnTypeFragment() const; + + virtual string + outputConversionFragment(string const& varName) const; +}; + + + +string +voidXmlrpcType::parameterFragment(string const&) const { + + throw domain_error("Can't handle functions with 'void' arguments'"); +} + + + +string +voidXmlrpcType::inputConversionFragment(string const&) const { + + throw domain_error("Can't handle functions with 'void' arguments'"); +} + + + +string +voidXmlrpcType::returnTypeFragment () const { + + return "void"; +} + + + +string +voidXmlrpcType::outputConversionFragment(string const&) const { + return "/* Return value ignored. */"; +} + + + +static simpleXmlrpcType const intType ("int", "int", + "xmlrpc_c::value_int", + "getInt"); +static simpleXmlrpcType const boolType ("bool", "bool", + "xmlrpc_c::value_boolean", + "getBool"); +static simpleXmlrpcType const doubleType ("double", "double", + "xmlrpc_c::value_double", + "getDouble"); +static simpleXmlrpcType const stringType ("string", "std::string", + "xmlrpc_c::value_string", + "getString"); + +static rawXmlrpcType const dateTimeType ("dateTime"); +static rawXmlrpcType const base64Type ("base64"); +static rawXmlrpcType const structType ("struct"); +static rawXmlrpcType const arrayType ("array"); + +static voidXmlrpcType const voidType; + + + +const xmlrpcType& +findXmlrpcType(string const& name) { +/*---------------------------------------------------------------------------- + Given the name of an XML-RPC data type, try to find a corresponding + xmlrpcType object. +-----------------------------------------------------------------------------*/ + if (name == "int" || name == "i4") + return intType; + else if (name == "boolean") + return boolType; + else if (name == "double") + return doubleType; + else if (name == "string") + return stringType; + else if (name == "dateTime.iso8601") + return dateTimeType; + else if (name == "base64") + return base64Type; + else if (name == "struct") + return structType; + else if (name == "array") + return arrayType; + else if (name == "void") + return voidType; + else if (name == "INT") + return intType; + else if (name == "BOOLEAN") + return boolType; + else if (name == "DOUBLE") + return doubleType; + else if (name == "STRING") + return stringType; + else if (name == "DATETIME.ISO8601") + return dateTimeType; + else if (name == "BASE64") + return base64Type; + else if (name == "STRUCT") + return structType; + else if (name == "ARRAY") + return arrayType; + else if (name == "VOID") + return voidType; + else if (name == "NIL") + return voidType; + else + throw domain_error("Unknown XML-RPC type name '" + name + "'"); +} diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp new file mode 100644 index 000000000..2b026f153 --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp @@ -0,0 +1,43 @@ +#include +#include + +class xmlrpcType { + std::string mTypeName; + + xmlrpcType(xmlrpcType const&) { assert(false); } + + xmlrpcType& operator= (xmlrpcType const&) { + assert(false); + return *this; + } + +public: + xmlrpcType(const std::string& type_name) : mTypeName(type_name) {} + + virtual ~xmlrpcType () {} + + // Return the name for this XML-RPC type. + virtual std::string + typeName() const { return mTypeName; } + + // Given a parameter position, calculate a unique base name for all + // parameter-related variables. + virtual std::string + defaultParameterBaseName(unsigned int const position) const; + + // Virtual functions for processing parameters. + virtual std::string + parameterFragment(std::string const& base_name) const = 0; + + virtual std::string + inputConversionFragment(std::string const& base_name) const = 0; + + // Virtual functions for processing return values. + virtual std::string + returnTypeFragment () const = 0; + + virtual std::string + outputConversionFragment(std::string const& var_name) const = 0; +}; + +const xmlrpcType& findXmlrpcType(const std::string& name); diff --git a/trunk/tools/xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp b/trunk/tools/xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp new file mode 100644 index 000000000..7ec8a477f --- /dev/null +++ b/trunk/tools/xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp @@ -0,0 +1,208 @@ +#include +#include +#include + +#include "xmlrpcType.hpp" +#include "xmlrpcMethod.hpp" +#include "proxyClass.hpp" +#include "systemProxy.hpp" + +using namespace std; + + +/*---------------------------------------------------------------------------- + Command line +-----------------------------------------------------------------------------*/ + +class cmdlineInfo { +public: + string serverUrl; + string methodPrefix; + string localClass; + + cmdlineInfo(int const argc, + const char ** const argv); + +private: + cmdlineInfo(); +}; + + + +cmdlineInfo::cmdlineInfo(int const argc, + const char ** const argv) { + + if (argc-1 != 3) { + cerr << "There are 3 arguments: server URL, " + << "prefix for the methods to include (null to include all), " + << "and name to give the generated proxy class. " + << "You specified " << argc-1 << " arguments." + << endl + << "Example: " + << "xmlrpc_cpp_proxy http://localhost/RPC2 system systemProxy" + << endl; + exit(1); + } + this->serverUrl = string(argv[1]); + this->methodPrefix = string(argv[2]); + this->localClass = string(argv[3]); +} + + + +static proxyClass +getClassInfo(string const& serverUrl, + string const& classPrefix, + string const& className) { +/*---------------------------------------------------------------------------- + Connect to a remote server and extract the information we'll need to + build a proxy class. +-----------------------------------------------------------------------------*/ + proxyClass theClass(className); + + systemProxy system; + + xmlrpc_c::value_array methods(system.listMethods(serverUrl)); + + unsigned int arraySize = methods.size(); + + for (size_t i = 0; i < arraySize; ++i) { + + // Break the method name into two pieces. + xmlrpc_c::value_string val = (methods.vectorValueValue())[i]; + string const methodName(static_cast(val)); + size_t const lastDot(methodName.rfind('.')); + + string methodPrefix; + string functionName; + + if (lastDot == string::npos) { + methodPrefix = ""; + functionName = methodName; + } else { + methodPrefix = string(methodName, 0, lastDot); + functionName = string(methodName, lastDot + 1); + } + + if (methodPrefix == classPrefix) { + // It's a method User cares about + + string const help(system.methodHelp(serverUrl, methodName)); + xmlrpc_c::value const signatureList( + system.methodSignature(serverUrl, methodName)); + + if (signatureList.type() != xmlrpc_c::value::TYPE_ARRAY) { + // It must be the string "undef", meaning the server + // won't tell us any signatures. + cerr << "Skipping method " << methodName << " " + << "because server does not report any signatures " + << "for it (via system.methodSignature method)" + << endl; + } else { + // Add this function to our class information. + xmlrpcMethod const method( + functionName, + methodName, + help, + xmlrpc_c::value_array(signatureList)); + theClass.addFunction(method); + } + } + } + return theClass; +} + + + +static void +printHeader(ostream & out, + proxyClass const& classInfo) { +/*---------------------------------------------------------------------------- + Print a complete header for the specified class. +-----------------------------------------------------------------------------*/ + string const className(classInfo.className()); + + try { + out << "// Interface definition for " << className << " class, " + << "an XML-RPC FOR C/C++ proxy class" << endl; + out << "// Generated by 'xmlrpc_cpp_proxy'" << endl; + out << endl; + + string const headerSymbol("_" + className + "_H_"); + + out << "#ifndef " << headerSymbol << endl; + out << "#define " << headerSymbol << " 1" << endl; + out << endl; + out << "#include " << endl; + out << "#include " << endl; + out << endl; + + classInfo.printDeclaration(cout); + + out << endl; + out << "#endif /* " << headerSymbol << " */" << endl; + } catch (exception const& e) { + throw(logic_error("Failed to generate header for class " + + className + ". " + e.what())); + } +} + + + +static void +printCppFile(ostream & out, + proxyClass const& classInfo) { +/*---------------------------------------------------------------------------- + Print a complete definition for the specified class. +-----------------------------------------------------------------------------*/ + string const className(classInfo.className()); + + try { + out << "// " << className << " - " + << "an XML-RPC FOR C/C++ proxy class" << endl; + out << "// Generated by 'xmlrpc_cpp_proxy'" << endl; + out << endl; + + out << "#include \"" << className << ".h\"" << endl; + + classInfo.printDefinition(cout); + } catch (xmlrpc_c::fault const& f) { + throw(logic_error("Failed to generate definition for class " + + className + ". " + f.getDescription())); + } +} + + + +int +main(int const argc, + const char ** const argv) { + + string const myName(argv[0]); + + cmdlineInfo const cmdline(argc, argv); + + int retval; + + try { + proxyClass system(getClassInfo(cmdline.serverUrl, + cmdline.methodPrefix, + cmdline.localClass)); + printHeader(cout, system); + cout << endl; + printCppFile(cout, system); + retval = 0; + } catch (xmlrpc_c::fault& f) { + cerr << myName << ": XML-RPC fault #" << f.getCode() + << ": " << f.getDescription() << endl; + retval = 1; + } catch (exception const& e) { + cerr << myName << ": " << e.what() << endl; + retval = 1; + } catch (...) { + cerr << myName << ": Unknown exception" << endl; + retval = 1; + } + + return retval; +} diff --git a/trunk/tools/xmlrpc_dumpserver/Makefile b/trunk/tools/xmlrpc_dumpserver/Makefile new file mode 100644 index 000000000..c5cbf0098 --- /dev/null +++ b/trunk/tools/xmlrpc_dumpserver/Makefile @@ -0,0 +1,72 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/xmlrpc_dumpserver + +default: all + +include $(BLDDIR)/config.mk + +PROGS := xmlrpc_dumpserver + +PROGRAMS_TO_INSTALL = $(PROGS) + +include $(SRCDIR)/tools/common.mk + +INCLUDES = \ + -I../lib/include \ + -Iblddir \ + -Iblddir/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include + +all: xmlrpc_dumpserver + +# cmdline.parser.o references getoptx.o and string_parser.o. +# string_parser.o references stripcaseeq.o + +UTIL_OBJS = \ + casprintf.o \ + cmdline_parser.o \ + getoptx.o \ + string_parser.o \ + stripcaseeq.o \ + +UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) + +DUMPVALUE = blddir/tools/lib/dumpvalue.o + +XMLRPC_OBJS = xmlrpc_dumpserver.o $(DUMPVALUE) + +xmlrpc_dumpserver: $(XMLRPC_OBJS) $(SERVER_ABYSS_LIBS_DEP) $(UTILS) + $(CCLD) -o $@ $(LDFLAGS_ALL) $(XMLRPC_OBJS) $(UTILS) \ + $(SERVER_ABYSS_LDLIBS) + +%.o:%.c $(BLDDIR)/include/xmlrpc-c/config.h + $(CC) -c $(CFLAGS_ALL) $< + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: dep +dep: dep-common + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean +clean: clean-common + rm -f $(PROGS) + +.PHONY: distclean +distclean: clean distclean-common diff --git a/trunk/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c b/trunk/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c new file mode 100644 index 000000000..562fd3e93 --- /dev/null +++ b/trunk/tools/xmlrpc_dumpserver/xmlrpc_dumpserver.c @@ -0,0 +1,269 @@ +/*============================================================================= + xmlrpc_dumpserver +=============================================================================== + + This program runs an XML-RPC server that does nothing but print to Standard + Output the contents of every call it receives, and send a failure response. + + You use this to test a client or to learn about XML-RPC. + + Example: + + $ xmlrpc_dumpserver -port=8080 & + + $ xmlrpc localhost:8080 dummymethod s/hello i/5 + +=============================================================================*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include +#include +#include + +#include "xmlrpc_config.h" /* information about this build environment */ +#include "bool.h" +#include "int.h" +#include "mallocvar.h" +#include "girstring.h" +#include "casprintf.h" +#include "cmdline_parser.h" +#include "dumpvalue.h" + +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/server_abyss.h" + +#define NAME "xmlrpc command line program" +#define VERSION "1.0" + +struct CmdlineInfo { + unsigned int port; +}; + + + +static void +parseCommandLine(int const argc, + const char ** const argv, + struct CmdlineInfo * const cmdlineP, + const char ** const errorP) { + + cmdlineParser const cp = cmd_createOptionParser(); + + const char * error; + + cmd_defineOption(cp, "port", OPTTYPE_UINT); + + cmd_processOptions(cp, argc, argv, &error); + + if (error) { + casprintf(errorP, "Command syntax error. %s", error); + strfree(error); + } else { + *errorP = NULL; /* initial assumption */ + + if (cmd_argumentCount(cp) > 0) + casprintf(errorP, "No non-option arguments are possible. " + "You specified %u", cmd_argumentCount(cp)); + + if (!*errorP) { + if (cmd_optionIsPresent(cp, "port")) { + cmdlineP->port = cmd_getOptionValueUint(cp, "port"); + } else { + casprintf(errorP, "You must specify the TCP port number " + "on which to listen for XML-RPC calls with -port"); + } + } + } + cmd_destroyOptionParser(cp); +} + + + +static void +freeCmdline(struct CmdlineInfo const cmdline ATTR_UNUSED) { + +} + + + +static void +dumpParameters(xmlrpc_value * const paramArrayP) { + + xmlrpc_env env; + int arraySize; + unsigned int paramSeq; + + xmlrpc_env_init(&env); + + arraySize = xmlrpc_array_size(&env, paramArrayP); + + assert(!env.fault_occurred); + assert(arraySize >= 0); + + { + unsigned int const paramCt = arraySize; + + printf("Number of parameters: %u\n", paramCt); + + printf("\n"); + + for (paramSeq = 0; paramSeq < paramCt; ++paramSeq) { + + xmlrpc_value * paramValueP; + + xmlrpc_array_read_item(&env, paramArrayP, paramSeq, ¶mValueP); + + assert(!env.fault_occurred); + + printf("Parameter %u:\n", paramSeq); + printf("\n"); + + dumpValue(" ", paramValueP); + + xmlrpc_DECREF(paramValueP); + + printf("\n"); + } + } + xmlrpc_env_clean(&env); +} + + + +static xmlrpc_value * +defaultMethod(xmlrpc_env * const envP, + const char * const callInfoP ATTR_UNUSED, + const char * const methodName, + xmlrpc_value * const paramArrayP, + void * const serverInfo ATTR_UNUSED) { +/*---------------------------------------------------------------------------- + This is a *xmlrpc_default_method, i.e. a default method for an Xmlrpc-c + registry, which is meant to be called by an XML-RPC server when it receives + a call for a method that is not registered by name. +-----------------------------------------------------------------------------*/ + printf("Server has received a call of method '%s'\n", methodName); + + printf("\n"); + + assert(xmlrpc_value_type(paramArrayP) == XMLRPC_TYPE_ARRAY); + + dumpParameters(paramArrayP); + + xmlrpc_faultf(envP, + "This XML-RPC server is a test server that fails all " + "RPCs. But the fact that it failed this way tells you that " + "the call _was_ valid in XML-RPC terms. The server " + "printed to Standard Output a description of the valid " + "call."); + + /* Return value is irrelevant because we failed the RPC, but to prevent + a compiler warning: + */ + return NULL; +} + + + +static void +setServerParm(xmlrpc_server_abyss_parms * const serverparmP, + xmlrpc_registry * const registryP, + unsigned int const portNum, + size_t * const lengthP) { + + serverparmP->config_file_name = NULL; + serverparmP->registryP = registryP; + serverparmP->port_number = portNum; + serverparmP->log_file_name = NULL; + serverparmP->keepalive_timeout = 0; + serverparmP->keepalive_max_conn = 0; + serverparmP->timeout = 0; + serverparmP->dont_advertise = false; + serverparmP->socket_bound = false; + serverparmP->uri_path = NULL; + serverparmP->chunk_response = false; + serverparmP->enable_shutdown = true; + + *lengthP = XMLRPC_APSIZE(enable_shutdown); +} + + + +static void +runServer(unsigned int const portNum, + const char ** const errorP) { + + xmlrpc_registry * registryP; + xmlrpc_env env; + + xmlrpc_env_init(&env); + + registryP = xmlrpc_registry_new(&env); + if (env.fault_occurred) + casprintf(errorP, "xmlrpc_registry_new() failed. %s", + env.fault_string); + else { + xmlrpc_registry_set_default_method(&env, registryP, + &defaultMethod, NULL); + + if (env.fault_occurred) + casprintf(errorP, "xmlrpc_registry_add_method3() failed. %s", + env.fault_string); + else { + xmlrpc_server_abyss_parms serverparm; + size_t parmLength; + + setServerParm(&serverparm, registryP, portNum, &parmLength); + + printf("Running XML-RPC server on TCP Port %u...\n", portNum); + + xmlrpc_server_abyss(&env, &serverparm, parmLength); + + if (env.fault_occurred) + casprintf(errorP, "xmlrpc_server_abyss() failed. %s", + env.fault_string); + + /* xmlrpc_server_abyss() never returns unless it fails */ + *errorP = NULL; + } + } +} + + + +int +main(int const argc, + const char ** const argv) { + + int exitCode; + struct CmdlineInfo cmdline; + const char * error; + + parseCommandLine(argc, argv, &cmdline, &error); + + if (error) { + fprintf(stderr, "Command syntax error. %s\n", error); + strfree(error); + exitCode = 10; + } else { + const char * error; + + runServer(cmdline.port, &error); + + if (error) { + fprintf(stderr, "Server on port %u failed. %s\n", + cmdline.port, error); + strfree(error); + exitCode = 1; + } else + exitCode = 0; + + freeCmdline(cmdline); + } + return exitCode; +} + + + diff --git a/trunk/tools/xmlrpc_pstream/Makefile b/trunk/tools/xmlrpc_pstream/Makefile new file mode 100644 index 000000000..869a7f6b9 --- /dev/null +++ b/trunk/tools/xmlrpc_pstream/Makefile @@ -0,0 +1,79 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/xmlrpc_pstream + +READLINE_LDLIBS = -lreadline -lncurses + +default: all + +include $(BLDDIR)/config.mk + +PROGRAMS_TO_INSTALL = xmlrpc_pstream + +include $(SRCDIR)/tools/common.mk + +INCLUDES = \ + -I../lib/include \ + -Isrcdir/lib/util/include \ + -Iblddir \ + -Iblddir/include \ + -Isrcdir/include \ + +all: xmlrpc_pstream + +OBJECTS = \ + xmlrpc_pstream.o \ + blddir/tools/lib/dumpvalue.o \ + +LIBS = \ + $(LIBXMLRPC_CLIENTPP) \ + $(LIBXMLRPCPP) \ + $(CLIENT_LIBS_DEP) \ + $(LIBXMLRPC) \ + $(LIBXMLRPC_XML) \ + $(LIBXMLRPC_UTIL) \ + +LDLIBS = $(CLIENTPP_LDLIBS) $(CLIENT_LDLIBS) $(READLINE_LDLIBS) + +UTIL_OBJS = \ + casprintf.o \ + cmdline_parser_cpp.o \ + cmdline_parser.o \ + getoptx.o \ + string_parser.o \ + stripcaseeq.o \ + +UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) + +xmlrpc_pstream: $(OBJECTS) $(LIBS) $(UTILS) + $(CXXLD) -o $@ $(LDFLAGS_ALL) $(OBJECTS) $(UTILS) $(LDLIBS) $(LADD) + +%.o:%.cpp blddir/include/xmlrpc-c/config.h + $(CXX) -c $(CXXFLAGS_ALL) $< + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: clean +clean: clean-common + rm -f xmlrpc_pstream + +.PHONY: distclean +distclean: clean distclean-common + +.PHONY: dep +dep: dep-common diff --git a/trunk/tools/xmlrpc_pstream/test b/trunk/tools/xmlrpc_pstream/test new file mode 100755 index 000000000..e618a19d0 --- /dev/null +++ b/trunk/tools/xmlrpc_pstream/test @@ -0,0 +1,28 @@ +#! /bin/sh + +# This is for testing and playing with Xmlrpc_pstream. + +# To use, first start a packet stream XML-RPC server. The +# 'pstream_inetd_server' program from examples/cpp is good: +# +# $ socketexec -accept -local_port=8080 -- pstream_inetd_server +# +# Then (in another shell), run this program: +# +# $ ./test +# > sample.add i/3 i/5 +# +# Result: +# Integer: 8 +# +# > [ctl-D] +# $ +# +# OR: +# +# $ ./test sample.add i/3 i/5 +# $ + +socketexec -connect -remote_host=localhost -remote_port=8080 --filedes=3 -- \ + ./xmlrpc_pstream $* + diff --git a/trunk/tools/xmlrpc_pstream/xmlrpc_pstream.cpp b/trunk/tools/xmlrpc_pstream/xmlrpc_pstream.cpp new file mode 100644 index 000000000..d7a7097c9 --- /dev/null +++ b/trunk/tools/xmlrpc_pstream/xmlrpc_pstream.cpp @@ -0,0 +1,507 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cmdline_parser.hpp" +#include "xmlrpc-c/girerr.hpp" +using girerr::throwf; + +#ifdef __cplusplus +extern "C" { +#endif + +#include "dumpvalue.h" /* An internal Xmlrpc-c header file ! */ + +#ifdef __cplusplus +} +#endif + +#include +#include +#include + +using namespace std; +using namespace xmlrpc_c; + +/*---------------------------------------------------------------------------- + Command line +-----------------------------------------------------------------------------*/ + +class cmdlineInfo { +public: + int serverfd; + bool interactive; + + // Valid only if !interactive: + string methodName; + vector params; + + cmdlineInfo(int const argc, + const char ** const argv); + +private: + cmdlineInfo(); +}; + + + +static void +parseCommandLine(cmdlineInfo * const cmdlineP, + int const argc, + const char ** const argv) { + + CmdlineParser cp; + + cp.defineOption("serverfd", CmdlineParser::UINT); + + try { + cp.processOptions(argc, argv); + } catch (exception const& e) { + throwf("Command syntax error. %s", e.what()); + } + + if (cp.optionIsPresent("serverfd")) { + cmdlineP->serverfd = cp.getOptionValueUint("serverfd"); + } else + cmdlineP->serverfd = 3; + + if (cp.argumentCount() < 1) + cmdlineP->interactive = true; + else { + cmdlineP->interactive = false; + cmdlineP->methodName = cp.getArgument(0); + for (uint argI = 1; argI < cp.argumentCount(); ++argI) + cmdlineP->params.push_back(cp.getArgument(argI)); + } +} + + + +cmdlineInfo:: +cmdlineInfo(int const argc, + const char ** const argv) { + + try { + parseCommandLine(this, argc, argv); + } catch (exception const& e) { + throwf("Command syntax error. %s", e.what()); + } +} + + + +static value +bytestringValFromParm(string const& valueString) { + + value retval; + + if (valueString.length() / 2 * 2 != valueString.length()) + throwf("Hexadecimal text is not an even " + "number of characters (it is %u characters)", + (unsigned)valueString.length()); + else { + vector byteString(valueString.length() / 2); + size_t strCursor; + + strCursor = 0; + + while (strCursor < valueString.length()) { + string const hexByte(valueString.substr(strCursor, 2)); + + unsigned char byte; + int rc; + + rc = sscanf(hexByte.c_str(), "%2hhx", &byte); + + byteString.push_back(byte); + + if (rc != 1) + throwf("Invalid hex data '%s'", hexByte.c_str()); + else + strCursor += 2; + } + retval = value_bytestring(byteString); + } + return retval; +} + + + +static value +intValFromParm(string const& valueString) { + + value retval; + + if (valueString.length() < 1) + throwf("Integer argument has nothing after the 'i/'"); + else { + long longValue; + char * tailptr; + + errno = 0; + + longValue = strtol(valueString.c_str(), &tailptr, 10); + + if (errno == ERANGE) + throwf("'%s' is out of range for a 32 bit integer", + valueString.c_str()); + else if (errno != 0) + throwf("Mysterious failure of strtol(), errno=%d (%s)", + errno, strerror(errno)); + else { + if (*tailptr != '\0') + throwf("Integer argument has non-digit crap in it: '%s'", + tailptr); + else + retval = value_int(longValue); + } + } + return retval; +} + + + +static value +boolValFromParm(string const& valueString) { + + value retval; + + if (valueString == "t" || valueString == "true") + retval = value_boolean(true); + else if (valueString == "f" || valueString == "false") + retval = value_boolean(false); + else + throwf("Boolean argument has unrecognized value '%s'. " + "recognized values are 't', 'f', 'true', and 'false'.", + valueString.c_str()); + + return retval; +} + + + +static value +doubleValFromParm(string const& valueString) { + + value retval; + + if (valueString.length() < 1) + throwf("\"Double\" argument has nothing after the 'd/'"); + else { + double value; + char * tailptr; + + value = strtod(valueString.c_str(), &tailptr); + + if (*tailptr != '\0') + throwf("\"Double\" argument has non-decimal crap in it: '%s'", + tailptr); + else + retval = value_double(value); + } + return retval; +} + + + +static value +nilValFromParm(string const& valueString) { + + value retval; + + if (valueString.length() > 0) + throwf("Nil argument has something after the 'n/'"); + else + retval = value_nil(); + + return retval; +} + + + +static value +i8ValFromParm(string const& valueString) { + + value retval; + + if (valueString.length() < 1) + throwf("Integer argument has nothing after the 'I/'"); + else { + long long value; + char * tailptr; + + errno = 0; + + value = strtoll(valueString.c_str(), &tailptr, 10); + + if (errno == ERANGE) + throwf("'%s' is out of range for a 64 bit integer", + valueString.c_str()); + else if (errno != 0) + throwf("Mysterious failure of strtoll(), errno=%d (%s)", + errno, strerror(errno)); + else { + if (*tailptr != '\0') + throwf("64 bit integer argument has non-digit crap " + "in it: '%s'", + tailptr); + else + retval = value_i8(value); + } + } + return retval; +} + + + +static value +parameterFromArg(string const& paramArg) { + + value param; + + try { + if (paramArg.substr(0, 2) == "s/") + param = value_string(paramArg.substr(2)); + else if (paramArg.substr(0, 2) == "h/") + param = bytestringValFromParm(paramArg.substr(2)); + else if (paramArg.substr(0, 2) == "i/") + param = intValFromParm(paramArg.substr(2)); + else if (paramArg.substr(0, 2) == "I/") + param = i8ValFromParm(paramArg.substr(2)); + else if (paramArg.substr(0, 2) == "d/") + param = doubleValFromParm(paramArg.substr(2)); + else if (paramArg.substr(0, 2) == "b/") + param = boolValFromParm(paramArg.substr(2)); + else if (paramArg.substr(0, 2) == "n/") + param = nilValFromParm(paramArg.substr(2)); + else { + /* It's not in normal type/value format, so we take it to be + the shortcut string notation + */ + param = value_string(paramArg); + } + } catch (exception const& e) { + throwf("Failed to interpret parameter argument '%s'. %s", + paramArg.c_str(), e.what()); + } + return param; +} + + + +static paramList +paramListFromParamArgs(vector const& params) { + + paramList paramList; + + for (vector::const_iterator p = params.begin(); + p != params.end(); ++p) + paramList.add(parameterFromArg(*p)); + + return paramList; +} + + + +static void +callWithClient(client * const clientP, + string const& methodName, + paramList const& paramList, + value * const resultP) { + + rpcPtr myRpcP(methodName, paramList); + + carriageParm_pstream myCarriageParm; // Empty - no parm needed + + try { + myRpcP->call(clientP, &myCarriageParm); + } catch (exception const& e) { + throwf("RPC failed. %s", e.what()); + } + *resultP = myRpcP->getResult(); +} + + + +static void +dumpResult(value const& result) { + + cout << "Result:" << endl << endl; + + /* Here we borrow code from inside Xmlrpc-c, and also use an + internal interface of xmlrpc_c::value. This sliminess is one + reason that this is Bryan's private code instead of part of the + Xmlrpc-c package. + + Note that you must link with the dumpvalue.o object module from + inside an Xmlrpc-c build tree. + */ + + dumpValue("", result.cValueP); +} + + + +static list +parseWordList(string const& wordString) { + + list retval; + + unsigned int pos; + + pos = 0; + + while (pos < wordString.length()) { + pos = wordString.find_first_not_of(' ', pos); + + if (pos < wordString.length()) { + unsigned int const end = wordString.find_first_of(' ', pos); + + retval.push_back(wordString.substr(pos, end - pos)); + + pos = end; + } + } + return retval; +} + + + +static void +parseCommand(string const& cmd, + string * const methodNameP, + vector * const paramListP) { + + list const wordList(parseWordList(cmd)); + + list::const_iterator cmdWordP; + + cmdWordP = wordList.begin(); + + if (cmdWordP == wordList.end()) + throwf("Command '%s' does not have a method name", cmd.c_str()); + else { + *methodNameP = *cmdWordP++; + + *paramListP = vector(); // Start empty + + while (cmdWordP != wordList.end()) + paramListP->push_back(*cmdWordP++); + } +} + + + +static void +doCommand(client_xml * const clientP, + string const& methodName, + vector const& paramArgs) { + + value result; + + callWithClient(clientP, methodName, paramListFromParamArgs(paramArgs), + &result); + + try { + dumpResult(result); + } catch(exception const& e) { + throwf("Error showing result after RPC completed normally. %s", + e.what()); + } +} + + + +static void +getCommand(string * const cmdP, + bool* const eofP) { + + const char * cmd; + + cmd = readline(">"); + + *eofP = (cmd == NULL); + + if (cmd != NULL) { + *cmdP = string(cmd); + + free(const_cast(cmd)); + } +} + + + +static void +doInteractive(client_xml * const clientP) { + + bool quitRequested; + + quitRequested = false; + + while (!quitRequested) { + string cmd; + bool eof; + + getCommand(&cmd, &eof); + + if (eof) { + quitRequested = true; + cout << endl; + } else { + try { + string methodName; + vector paramArgs; + + parseCommand(cmd, &methodName, ¶mArgs); + + doCommand(clientP, methodName, paramArgs); + } catch (exception const& e) { + cout << "Command failed. " << e.what() << endl; + } + } + } +} + + + +int +main(int const argc, + const char ** const argv) { + + try { + cmdlineInfo cmdline(argc, argv); + + signal(SIGPIPE, SIG_IGN); + + clientXmlTransport_pstream myTransport( + clientXmlTransport_pstream::constrOpt() + .fd(cmdline.serverfd)); + + client_xml myClient(&myTransport); + + if (cmdline.interactive) { + if (cmdline.serverfd == STDIN_FILENO || + cmdline.serverfd == STDOUT_FILENO) + throwf("Can't use Stdin or Stdout for the server fd when " + "running interactively."); + doInteractive(&myClient); + } else + doCommand(&myClient, cmdline.methodName, cmdline.params); + + } catch (exception const& e) { + cerr << "Failed. " << e.what() << endl; + } catch (...) { + cerr << "Code threw unrecognized exception" << endl; + abort(); + } + return 0; +} diff --git a/trunk/tools/xmlrpc_transport/Makefile b/trunk/tools/xmlrpc_transport/Makefile new file mode 100644 index 000000000..59c56b691 --- /dev/null +++ b/trunk/tools/xmlrpc_transport/Makefile @@ -0,0 +1,63 @@ +ifeq ($(SRCDIR),) + updir = $(shell echo $(dir $(1)) | sed 's/.$$//') + TOOLSDIR := $(call updir,$(CURDIR)) + SRCDIR := $(call updir,$(TOOLSDIR)) + BLDDIR := $(SRCDIR) +endif +SUBDIR := tools/xmlrpc_transport + +default: all + +include $(BLDDIR)/config.mk + +PROGRAMS_TO_INSTALL = xmlrpc_transport + +include $(SRCDIR)/tools/common.mk + +INCLUDES = \ + -I$(BLDDIR) \ + -I$(BLDDIR)/include \ + -Isrcdir/include \ + -Isrcdir/lib/util/include + +all: xmlrpc_transport + +CLIENT_LDLIBS += $(SOCKETLIBOPT) $(THREAD_LIBS) + +UTIL_OBJS = \ + casprintf.o \ + cmdline_parser.o \ + getoptx.o \ + stripcaseeq.o \ + string_parser.o \ + +UTILS = $(UTIL_OBJS:%=$(UTIL_DIR)/%) + +xmlrpc_transport:%:%.o $(CLIENT_LIBS_DEP) $(UTILS) + $(CCLD) -o $@ $(LDFLAGS_ALL) $< $(CLIENT_LDLIBS) $(UTILS) + +%.o:%.c + $(CC) -c $(CFLAGS_ALL) $< + +# This common.mk dependency makes sure the symlinks get built before +# this make file is used for anything. + +$(SRCDIR)/tools/common.mk: srcdir blddir + +include depend.mk + +.PHONY: install +install: install-common + +.PHONY: uninstall +uninstall: uninstall-common + +.PHONY: dep +dep: dep-common + +.PHONY: clean +clean: clean-common + rm -f xmlrpc_transport config.h + +.PHONY: distclean +distclean: clean distclean-common diff --git a/trunk/tools/xmlrpc_transport/xmlrpc_transport.c b/trunk/tools/xmlrpc_transport/xmlrpc_transport.c new file mode 100644 index 000000000..80770e905 --- /dev/null +++ b/trunk/tools/xmlrpc_transport/xmlrpc_transport.c @@ -0,0 +1,290 @@ +/* Transport some XML to a server and get the response back, as if doing + an XML-RPC call. +*/ + +#define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ + +#include +#include +#include + +#include "xmlrpc_config.h" /* information about this build environment */ +#include "casprintf.h" +#include "mallocvar.h" +#include "cmdline_parser.h" + +#include "xmlrpc-c/util_int.h" +#include "xmlrpc-c/base.h" +#include "xmlrpc-c/client.h" + +#define NAME "xmlrpc_transport command line program" +#define VERSION "1.0" + +struct cmdlineInfo { + const char * url; + const char * username; + const char * password; + const char * transport; + /* Name of XML transport he wants to use. NULL if he has no + preference. + */ +}; + + + +static void +die_if_fault_occurred (xmlrpc_env * const envP) { + if (envP->fault_occurred) { + fprintf(stderr, "Error: %s (%d)\n", + envP->fault_string, envP->fault_code); + exit(1); + } +} + + + +static void GNU_PRINTF_ATTR(2,3) +setError(xmlrpc_env * const envP, const char format[], ...) { + va_list args; + const char * faultString; + + va_start(args, format); + + cvasprintf(&faultString, format, args); + va_end(args); + + xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, faultString); + + strfree(faultString); +} + + + +static void +processArguments(xmlrpc_env * const envP, + cmdlineParser const cp, + struct cmdlineInfo * const cmdlineP) { + + if (cmd_argumentCount(cp) < 1) + setError(envP, "Not enough arguments. Need a URL."); + else { + cmdlineP->url = cmd_getArgument(cp, 0); + } +} + + + +static void +parseCommandLine(xmlrpc_env * const envP, + int const argc, + const char ** const argv, + struct cmdlineInfo * const cmdlineP) { + + cmdlineParser const cp = cmd_createOptionParser(); + + const char * error; + + cmd_defineOption(cp, "transport", OPTTYPE_STRING); + cmd_defineOption(cp, "username", OPTTYPE_STRING); + cmd_defineOption(cp, "password", OPTTYPE_STRING); + + cmd_processOptions(cp, argc, argv, &error); + + if (error) { + setError(envP, "Command syntax error. %s", error); + strfree(error); + } else { + cmdlineP->username = cmd_getOptionValueString(cp, "username"); + cmdlineP->password = cmd_getOptionValueString(cp, "password"); + + if (cmdlineP->username && !cmdlineP->password) + setError(envP, "When you specify -username, you must also " + "specify -password."); + else { + cmdlineP->transport = cmd_getOptionValueString(cp, "transport"); + + processArguments(envP, cp, cmdlineP); + } + } + cmd_destroyOptionParser(cp); +} + + + +static void +freeCmdline(struct cmdlineInfo const cmdline) { + + strfree(cmdline.url); + if (cmdline.username) + strfree(cmdline.username); + if (cmdline.password) + strfree(cmdline.password); + if (cmdline.transport) + strfree(cmdline.transport); +} + + + +static void +computeUrl(const char * const urlArg, + const char ** const urlP) { + + if (strstr(urlArg, "://") != 0) { + *urlP = strdup(urlArg); + } else { + casprintf(urlP, "http://%s/RPC2", urlArg); + } +} + + + +static void +doCall(xmlrpc_env * const envP, + const char * const transport, + const xmlrpc_server_info * const serverInfoP, + xmlrpc_mem_block * const callXmlP, + xmlrpc_mem_block ** const respXmlPP) { + + struct xmlrpc_clientparms clientparms; + + clientparms.transport = transport; + + clientparms.transportparmsP = NULL; + clientparms.transportparm_size = 0; + + xmlrpc_client_init2(envP, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, + &clientparms, XMLRPC_CPSIZE(transportparm_size)); + if (!envP->fault_occurred) { + xmlrpc_client_transport_call(envP, NULL, serverInfoP, + callXmlP, respXmlPP); + + xmlrpc_client_cleanup(); + } +} + + + +static void +createServerInfo(xmlrpc_env * const envP, + const char * const serverUrl, + const char * const userName, + const char * const password, + xmlrpc_server_info ** const serverInfoPP) { + + xmlrpc_server_info * serverInfoP; + + serverInfoP = xmlrpc_server_info_new(envP, serverUrl); + if (!envP->fault_occurred) { + if (userName) { + xmlrpc_server_info_set_basic_auth( + envP, serverInfoP, userName, password); + } + } + *serverInfoPP = serverInfoP; +} + + + +static void +readFile(xmlrpc_env * const envP, + FILE * const ifP, + xmlrpc_mem_block ** const fileContentsPP) { + + xmlrpc_mem_block * fileContentsP; + + fileContentsP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); + + while (!envP->fault_occurred && !feof(ifP)) { + char buffer[4096]; + size_t bytesRead; + + bytesRead = fread(buffer, 1, sizeof(buffer), ifP); + XMLRPC_MEMBLOCK_APPEND(char, envP, + fileContentsP, buffer, bytesRead); + } + if (envP->fault_occurred) + XMLRPC_MEMBLOCK_FREE(char, fileContentsP); + + *fileContentsPP = fileContentsP; +} + + + +static void +writeFile(xmlrpc_env * const envP, + FILE * const ofP, + xmlrpc_mem_block * const fileContentsP) { + + size_t totalWritten; + + totalWritten = 0; + + while (!envP->fault_occurred && + totalWritten < XMLRPC_MEMBLOCK_SIZE(char, fileContentsP)) { + size_t bytesWritten; + + bytesWritten = fwrite( + XMLRPC_MEMBLOCK_CONTENTS(char, fileContentsP) + totalWritten, + 1, + XMLRPC_MEMBLOCK_SIZE(char, fileContentsP) - totalWritten, + ofP); + + if (bytesWritten < 1) + xmlrpc_env_set_fault_formatted( + envP, XMLRPC_INTERNAL_ERROR, + "Error writing output"); + + totalWritten -= bytesWritten; + } +} + + + +int +main(int const argc, + const char ** const argv) { + + struct cmdlineInfo cmdline; + xmlrpc_env env; + xmlrpc_mem_block * callXmlP; + xmlrpc_mem_block * respXmlP; + const char * url; + xmlrpc_server_info * serverInfoP; + + xmlrpc_env_init(&env); + + parseCommandLine(&env, argc, argv, &cmdline); + die_if_fault_occurred(&env); + + computeUrl(cmdline.url, &url); + + createServerInfo(&env, url, cmdline.username, cmdline.password, + &serverInfoP); + die_if_fault_occurred(&env); + + fprintf(stderr, "Reading call data from Standard Input...\n"); + + readFile(&env, stdin, &callXmlP); + die_if_fault_occurred(&env); + + fprintf(stderr, "Making call...\n"); + + doCall(&env, cmdline.transport, serverInfoP, callXmlP, + &respXmlP); + die_if_fault_occurred(&env); + + fprintf(stderr, "Writing response data to Standard Output\n"); + writeFile(&env, stdout, respXmlP); + die_if_fault_occurred(&env); + + XMLRPC_MEMBLOCK_FREE(char, callXmlP); + XMLRPC_MEMBLOCK_FREE(char, respXmlP); + + strfree(url); + + freeCmdline(cmdline); + + xmlrpc_env_clean(&env); + + return 0; +} diff --git a/trunk/tools/xmlrpc_transport/xmlrpc_transport.html b/trunk/tools/xmlrpc_transport/xmlrpc_transport.html new file mode 100644 index 000000000..f244408d6 --- /dev/null +++ b/trunk/tools/xmlrpc_transport/xmlrpc_transport.html @@ -0,0 +1,93 @@ + +Xmlrpc_transport User Manual + + +

xmlrpc_transport transports data to a server as if to make an +XML-RPC remote procedure call and displays the response from the server. + +

You supply the call in XML form on Standard Input and get the response +in XML form on Standard Output. xmlrpc_transport doesn't really know +anything about XML; it sends the characters you supply and displays the +characters it gets back. + +

xmlrpc_transport uses the lower levels of the XML-RPC For C/C++ +client libraries. + +

This program is mainly useful for debugging and learning about +XML-RPC servers and the XML-RPC For C/C++ client XML transports. + + +

Examples

+ +
+
+     $ xmlrpc_transport http://localhost:8080/RPC2 <<EOF
+        <?xml version="1.0" encoding="UTF-8"?>
+        <methodCall>
+        <methodName>sample.add</methodName>
+        <params>
+        <param><value><i4>5</i4></value></param>
+        <param><value><i4>7</i4></value></param>
+        </params>
+        </methodCall>
+        EOF
+     <?xml version="1.0" encoding="UTF-8"?>
+     <methodResponse>
+     <params>
+     <param><value><i4>12</i4></value></param>
+     </params>
+     </methodResponse>
+
+
+ +

Overview

+

+xmlrpc_transport +url +[-transport=transportname] +[-username=username -password=password] + +

Minimum unique abbreviation of option is acceptable. You may use double +hyphens instead of single hyphen to denote options. You may use white +space in place of the equals sign to separate an option name from its value. + + +

Arguments

+ +
+
url + +
This is the URL of the XML-RPC server. As XML-RPC uses HTTP, this +must be an HTTP url. However, if you don't specify a type ("http:") +in the URL, xmlrpc_transport assumes an "http://" prefix and a +"/RPC2" suffix. RPC2 is the conventional file name for +an XML-RPC responder. + +
+ + +

Options

+ +
+
-transport=transportname + +
This selects the XML transport facility (e.g. libwww) that +xmlrpc_transport uses to perform the RPC. + +

The name transportname is one that the Xmlrpc-c programming +library recognizes. This is typically libwww, curl, and +wininet. + +

By default, xmlrpc_transport lets the Xmlrpc-c library choose. + +

-username=username +
-password=password + +
These options, which must be used together, cause the client to +authenticate itself to the server, if the server requires it, using +HTTP Basic Authentication and the specified username and password. + +
+ + + diff --git a/trunk/transport_config.mk b/trunk/transport_config.mk new file mode 100644 index 000000000..5791af6f8 --- /dev/null +++ b/trunk/transport_config.mk @@ -0,0 +1,39 @@ +# -*-makefile-*- <-- an Emacs control + + +# The make variables herein come from config.mk, which is included +# by the make file that includes us. + +transport_config.h: $(BLDDIR)/config.mk + rm -f $@ + echo '/* This file was generated by a make rule */' >>$@ +ifeq ($(MUST_BUILD_WININET_CLIENT),yes) + echo '#define MUST_BUILD_WININET_CLIENT 1' >>$@ +else + echo '#define MUST_BUILD_WININET_CLIENT 0' >>$@ +endif +ifeq ($(MUST_BUILD_CURL_CLIENT),yes) + echo '#define MUST_BUILD_CURL_CLIENT 1' >>$@ +else + echo '#define MUST_BUILD_CURL_CLIENT 0' >>$@ +endif +ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) + echo '#define MUST_BUILD_LIBWWW_CLIENT 1' >>$@ +else + echo '#define MUST_BUILD_LIBWWW_CLIENT 0' >>$@ +endif + echo "static const char * const XMLRPC_DEFAULT_TRANSPORT =" >>$@ +ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) + echo '"libwww";' >>$@ +else + ifeq ($(MUST_BUILD_CURL_CLIENT),yes) + echo '"curl";' >>$@ + else + ifeq ($(MUST_BUILD_WININET_CLIENT),yes) + echo '"wininet";' >>$@ + else + @echo 'ERROR: no client XML transport configured'; rm $@; false + endif + endif +endif + diff --git a/trunk/unix-common.mk b/trunk/unix-common.mk new file mode 100644 index 000000000..6954faf52 --- /dev/null +++ b/trunk/unix-common.mk @@ -0,0 +1,104 @@ +# -*-makefile-*- <-- an Emacs control + +# The including make file must define these make variables: +# +# SHARED_LIBS_TO_BUILD: List of the shared libraries that need to be +# built -- just the basic library names. E.g. "libfoo libbar" +# +# SHARED_LIBS_TO_INSTALL: List of the shared libraries that need to be +# installed -- just the basic library names. E.g. "libfoo libbar" +# +# SHLIB_SUFFIX: Shared library filename suffix, e.g. "so". +# +# MAJ: Library major version number, e.g. "3" in file name "libfoo.3.1" +# +# MIN: Library minor version number, e.g. "1" in file name "libfoo.3.1" +# +# LDFLAGS_SHLIB: linker (Ld) flags needed to link object files together into +# a shared library. May use $(SONAME) for the soname of the library. +# Include -lc if appropriate. +# +# LADD: Additional linker flags (normally set on the make command line). +# +# INSTALL_DATA: beginning of shell command to install a library file. +# +# DESTDIR: main installation directory +# +# LIBINST_DIR: directory in which to install libraries, relative to DESTDIR. +# +# LN_S: beginning of shell command to make symbolic link (e.g. "ln -s"). +# +# CXXLD: beginning of shell command to link, e.g. "g++". + +# This make file defines these make variables that the including make file +# can use: +# +# SHLIB_CMD: a command to build a shared library for C linkage +# You can use this in a rule to build a shared library +# SHLIBPP_CMD: Same, but for C++ linkage + +# Including make file must contain a rule to build each library file +# (e.g. libfoo.3.1) + +# This make file provides these rules: +# +# install-shared-libraries: install all shared libraries and the necessary +# symbolic links. + +# uninstall-shared-libraries: remove what would be installed by +# install-shared-libraries + +# SONAME is to be referenced by $(LDFLAGS_SHLIB) in the rule to make +# a shared library (in common.mk). I.e. $@ is the name of the shared +# library file. + +# SONAME is the name of the library file being built, with the minor +# version number cut off. E.g. if we're building libfoo.so.1.2, SONAME +# is libfoo.so.1 . +SONAME = $(@:%.$(MIN)=%) + +SHLIB_CMD = $(CCLD) $(LADD) $(LDFLAGS_SHLIB) -o $@ $^ + +SHLIB_LE_TARGETS = $(call shliblefn, $(SHARED_LIBS_TO_BUILD)) + +$(SHLIB_LE_TARGETS):%:%.$(MAJ) + rm -f $@ + $(LN_S) $< $@ + +SONAME_TARGETS = $(SHLIB_LE_TARGETS:%=%.$(MAJ)) + +$(SONAME_TARGETS):%:%.$(MIN) + rm -f $@ + $(LN_S) $< $@ + +.PHONY: $(SHLIB_INSTALL_TARGETS) +.PHONY: install-shared-libraries + +SHLIB_INSTALL_TARGETS = $(SHARED_LIBS_TO_INSTALL:%=%/install) + +#SHLIB_INSTALL_TARGETS is like "libfoo/install libbar/install" + +install-shared-libraries: $(SHLIB_INSTALL_TARGETS) + +LIBDESTDIR = $(DESTDIR)$(LIBINST_DIR) + +$(SHLIB_INSTALL_TARGETS):%/install:%.$(SHLIB_SUFFIX).$(MAJ).$(MIN) +# $< is a library file name, e.g. libfoo.so.3.1 . + $(INSTALL_SHLIB) $< $(LIBDESTDIR)/$< + cd $(LIBDESTDIR); \ + rm -f $(<:%.$(MIN)=%); \ + $(LN_S) $< $(<:%.$(MIN)=%) + cd $(LIBDESTDIR); \ + rm -f $(<:%.$(MAJ).$(MIN)=%); \ + $(LN_S) $(<:%.$(MIN)=%) $(<:%.$(MAJ).$(MIN)=%) + +.PHONY: uninstall-shared-libraries +uninstall-shared-libraries: + @list='$(SHARED_LIBS_TO_INSTALL)'; \ + for p in $$list; do \ + echo "Uninstalling $$p shared library"; \ + cd $(LIBDESTDIR); \ + rm -f $$p.$(SHLIB_SUFFIX); \ + rm -f $$p.$(SHLIB_SUFFIX).$(MAJ); \ + rm -f $$p.$(SHLIB_SUFFIX).$(MAJ).$(MIN); \ + done diff --git a/trunk/version.mk b/trunk/version.mk new file mode 100644 index 000000000..31e61d2e3 --- /dev/null +++ b/trunk/version.mk @@ -0,0 +1,11 @@ +############################################################################### +# This is not only a make file inclusion, but a source file for the program +# 'mkvers' in the Windows build system. The latter is very particular about +# the format of this file. Do not change white space, add comment lines, or +# anything! +# +# +############################################################################### +XMLRPC_MAJOR_RELEASE = 1 +XMLRPC_MINOR_RELEASE = 55 +XMLRPC_POINT_RELEASE = 0 diff --git a/trunk/xmlrpc-c-config.main b/trunk/xmlrpc-c-config.main new file mode 100644 index 000000000..d37be4eaf --- /dev/null +++ b/trunk/xmlrpc-c-config.main @@ -0,0 +1,207 @@ +usage="Usage: xmlrpc-c-config ...
"); -} +} @@ -482,7 +482,7 @@ formatValueContent(xmlrpc_env * const envP, if (!envP->fault_occurred) addString(envP, outputP, ""); } - } break; + } break; case XMLRPC_TYPE_ARRAY: serializeArray(envP, outputP, valueP, dialect); @@ -513,7 +513,7 @@ formatValueContent(xmlrpc_env * const envP, -void +void xmlrpc_serialize_value2(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const valueP, @@ -539,7 +539,7 @@ xmlrpc_serialize_value2(xmlrpc_env * const envP, -void +void xmlrpc_serialize_value(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const valueP) { @@ -549,7 +549,7 @@ xmlrpc_serialize_value(xmlrpc_env * const envP, -void +void xmlrpc_serialize_params2(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const paramArrayP, @@ -591,7 +591,7 @@ xmlrpc_serialize_params2(xmlrpc_env * const envP, -void +void xmlrpc_serialize_params(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const paramArrayP) { @@ -608,9 +608,9 @@ xmlrpc_serialize_params(xmlrpc_env * const envP, ** xmlrpc_serialize_call **========================================================================= ** Serialize an XML-RPC call. -*/ +*/ -void +void xmlrpc_serialize_call2(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, const char * const methodName, @@ -626,7 +626,7 @@ xmlrpc_serialize_call2(xmlrpc_env * const envP, XMLRPC_ASSERT(outputP != NULL); XMLRPC_ASSERT(methodName != NULL); XMLRPC_ASSERT_VALUE_OK(paramArrayP); - + addString(envP, outputP, XML_PROLOGUE); if (!envP->fault_occurred) { const char * const xmlns = @@ -657,7 +657,7 @@ xmlrpc_serialize_call2(xmlrpc_env * const envP, -void +void xmlrpc_serialize_call(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, const char * const methodName, @@ -669,7 +669,7 @@ xmlrpc_serialize_call(xmlrpc_env * const envP, -void +void xmlrpc_serialize_response2(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const valueP, @@ -699,12 +699,12 @@ xmlrpc_serialize_response2(xmlrpc_env * const envP, ""CRLF); } } - } + } } -void +void xmlrpc_serialize_response(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const valueP) { @@ -714,7 +714,7 @@ xmlrpc_serialize_response(xmlrpc_env * const envP, -void +void xmlrpc_serialize_fault(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, const xmlrpc_env * const faultP) { @@ -765,8 +765,8 @@ xmlrpc_serialize_fault(xmlrpc_env * const envP, ** 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. -** +** 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 From 00d35ba450cbf71728bc2b4649636469cb8ac316 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 7 Jun 2020 21:33:24 +0000 Subject: [PATCH 128/154] silence compiler warning git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3113 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/src/xmlrpc_serialize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/src/xmlrpc_serialize.c b/trunk/src/xmlrpc_serialize.c index 1def1ca96..d42f7d2e1 100644 --- a/trunk/src/xmlrpc_serialize.c +++ b/trunk/src/xmlrpc_serialize.c @@ -306,7 +306,7 @@ serializeDatetime(xmlrpc_env * const envP, valueP->_value.dt.s); if (valueP->_value.dt.u != 0) { - char usecString[64]; + char usecString[32]; assert(valueP->_value.dt.u < 1000000); XMLRPC_SNPRINTF(usecString, sizeof(usecString), ".%06u", valueP->_value.dt.u); From fa9787ea333160fe9f6bea08dcefa83dbab35849 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 7 Jun 2020 21:35:55 +0000 Subject: [PATCH 129/154] Silence compiler warnings git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3114 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/expat/xmltok/xmlrole.c | 1 + trunk/lib/expat/xmltok/xmltok_impl.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/trunk/lib/expat/xmltok/xmlrole.c b/trunk/lib/expat/xmltok/xmlrole.c index 821971343..9fcfb2bd3 100644 --- a/trunk/lib/expat/xmltok/xmlrole.c +++ b/trunk/lib/expat/xmltok/xmlrole.c @@ -92,6 +92,7 @@ int prolog0(PROLOG_STATE *state, return XML_ROLE_NONE; case XML_TOK_COMMENT: state->handler = prolog1; + return XML_ROLE_NONE; case XML_TOK_BOM: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: diff --git a/trunk/lib/expat/xmltok/xmltok_impl.c b/trunk/lib/expat/xmltok/xmltok_impl.c index cf0091d1d..2e4e42de7 100644 --- a/trunk/lib/expat/xmltok/xmltok_impl.c +++ b/trunk/lib/expat/xmltok/xmltok_impl.c @@ -14,6 +14,9 @@ Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd See the file copying.txt for copying permission. */ +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" + #ifndef IS_INVALID_CHAR #define IS_INVALID_CHAR(enc, ptr, n) (0) #endif From eaab0fc22c8cb0c2917e505609e9e0cfff7c7520 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 14 Jun 2020 00:27:20 +0000 Subject: [PATCH 130/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3115 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/abyss/src/sockutil.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/trunk/lib/abyss/src/sockutil.c b/trunk/lib/abyss/src/sockutil.c index bd991998b..9a2278779 100644 --- a/trunk/lib/abyss/src/sockutil.c +++ b/trunk/lib/abyss/src/sockutil.c @@ -120,7 +120,7 @@ sockutil_getSockName(int const sockFd, socklen_t nameSize; nameSize = sizeof(struct sockaddr) + 1; - + sockName = malloc(nameSize); if (sockName == NULL) @@ -164,7 +164,7 @@ sockutil_getPeerName(int const sockFd, socklen_t nameSize; nameSize = sizeof(struct sockaddr) + 1; - + peerName = malloc(nameSize); if (peerName == NULL) @@ -263,9 +263,9 @@ sockutil_formatPeerInfo(int const sockFd, int rc; sockaddrLen = sizeof(sockaddr); - + rc = getpeername(sockFd, &sockaddr, &sockaddrLen); - + if (rc < 0) xmlrpc_asprintf(peerStringP, "?? getpeername() failed. errno=%d (%s)", errno, strerror(errno)); @@ -341,7 +341,7 @@ sockutil_waitForConnection(int const listenSockFd, pollfds[1].fd = interruptPipe.interrupteeFd; pollfds[1].events = POLLIN; - + rc = poll(pollfds, ARRAY_SIZE(pollfds), -1); if (rc < 0) { @@ -418,7 +418,7 @@ sockutil_bindSocketToPort(int const fd, const struct sockaddr * const sockAddrP, socklen_t const sockAddrLen, const char ** const errorP) { - + int rc; rc = bind(fd, sockAddrP, sockAddrLen); @@ -442,7 +442,7 @@ void sockutil_bindSocketToPortInet(int const fd, uint16_t const portNumber, const char ** const errorP) { - + struct sockaddr_in name; int rc; From 146e9bf7f8933c3baec871dfc2365e471171ddf4 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 27 Jun 2020 16:59:57 +0000 Subject: [PATCH 131/154] Release 1.58.01 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3116 98333e67-4a24-44d7-a75c-e53540dd3050 --- advanced/lib/abyss/src/server.c | 3 +- advanced/lib/abyss/src/sessionReadRequest.c | 2 +- advanced/lib/abyss/src/socket_unix.c | 22 +++---- advanced/lib/abyss/src/sockutil.c | 14 ++--- advanced/lib/curl_transport/curltransaction.c | 2 +- advanced/lib/expat/xmlparse/xmlparse.c | 2 + advanced/lib/expat/xmltok/xmlrole.c | 1 + advanced/lib/expat/xmltok/xmltok_impl.c | 3 + advanced/src/abyss_handler.c | 42 ++++++------- advanced/src/json.c | 2 +- advanced/src/xmlrpc_data.c | 1 + advanced/src/xmlrpc_datetime.c | 46 +++++++------- advanced/src/xmlrpc_serialize.c | 62 +++++++++---------- advanced/version.mk | 2 +- 14 files changed, 106 insertions(+), 98 deletions(-) diff --git a/advanced/lib/abyss/src/server.c b/advanced/lib/abyss/src/server.c index e681b494c..bfb3f2f1b 100644 --- a/advanced/lib/abyss/src/server.c +++ b/advanced/lib/abyss/src/server.c @@ -1486,7 +1486,7 @@ ServerRunOnce(TServer * const serverP) { Accept a connection from the channel switch and do the HTTP transaction that comes over it. - If no connection is presently waiting at the switch, wait for one. But + If no connection is currently waiting at the switch, wait for one. But return immediately if we receive a signal during the wait. -----------------------------------------------------------------------------*/ struct _TServer * const srvP = serverP->srvP; @@ -1592,6 +1592,7 @@ ServerDaemonize(TServer * const serverP) { break; case -1: TraceExit("Unable to become a daemon"); + break; default: /* We are the parent */ exit(0); diff --git a/advanced/lib/abyss/src/sessionReadRequest.c b/advanced/lib/abyss/src/sessionReadRequest.c index 4f38e0c54..4d0e4f1d8 100644 --- a/advanced/lib/abyss/src/sessionReadRequest.c +++ b/advanced/lib/abyss/src/sessionReadRequest.c @@ -379,7 +379,7 @@ readRequestField(TSession * const sessionP, through the session's internal buffer; i.e. we may get data that was previously read from the network, or we may read more from the network. - We assume the connection is presently positioned to the beginning of + We assume the connection is currently positioned to the beginning of the HTTP document. We leave it positioned after the request field. We ignore any empty lines at the beginning of the stream, per diff --git a/advanced/lib/abyss/src/socket_unix.c b/advanced/lib/abyss/src/socket_unix.c index 1848f6ac3..c21001af4 100644 --- a/advanced/lib/abyss/src/socket_unix.c +++ b/advanced/lib/abyss/src/socket_unix.c @@ -127,7 +127,7 @@ channelWrite(TChannel * const channelP, // MSG_NOSIGNAL is not standard enough. An SO_NOSIGPIPE socket // option is another way, but even less standard. So instead, the // thread simply must be set to ignore SIGPIPE. - + rc = send(socketUnixP->fd, &buffer[len-bytesLeft], MIN(maxSend, bytesLeft), 0); @@ -160,8 +160,8 @@ channelWrite(TChannel * const channelP, static ChannelReadImpl channelRead; static void -channelRead(TChannel * const channelP, - unsigned char * const buffer, +channelRead(TChannel * const channelP, + unsigned char * const buffer, uint32_t const bufferSize, uint32_t * const bytesReceivedP, bool * const failedP) { @@ -253,7 +253,7 @@ channelWait(TChannel * const channelP, pollfds[1].fd = socketUnixP->interruptPipe.interrupteeFd; pollfds[1].events = POLLIN; - + rc = poll(pollfds, ARRAY_SIZE(pollfds), timeoutMs == TIME_INFINITE ? -1 : (int)timeoutMs); @@ -347,13 +347,13 @@ makeChannelInfo(struct abyss_unix_chaninfo ** const channelInfoPP, struct abyss_unix_chaninfo * channelInfoP; MALLOCVAR(channelInfoP); - + if (channelInfoP == NULL) xmlrpc_asprintf(errorP, "Unable to allocate memory"); else { channelInfoP->peerAddrLen = peerAddrLen; channelInfoP->peerAddr = peerAddr; - + *errorP = NULL; } *channelInfoPP = channelInfoP; @@ -369,13 +369,13 @@ makeChannelFromFd(int const fd, struct socketUnix * socketUnixP; MALLOCVAR(socketUnixP); - + if (socketUnixP == NULL) xmlrpc_asprintf(errorP, "Unable to allocate memory for Unix " "channel descriptor"); else { TChannel * channelP; - + socketUnixP->fd = fd; socketUnixP->userSuppliedFd = true; @@ -383,7 +383,7 @@ makeChannelFromFd(int const fd, if (!*errorP) { ChannelCreate(&channelVtbl, socketUnixP, &channelP); - + if (channelP == NULL) xmlrpc_asprintf(errorP, "Unable to allocate memory for " "channel descriptor."); @@ -655,7 +655,7 @@ createChanSwitch(int const fd, socketUnixP->fd = fd; socketUnixP->userSuppliedFd = userSuppliedFd; socketUnixP->isListening = false; - + sockutil_interruptPipeInit(&socketUnixP->interruptPipe, errorP); if (!*errorP) { @@ -828,7 +828,7 @@ ChanSwitchUnixGetListenName(TChanSwitch * const chanSwitchP, case, this is the only way the user can find out what port the OS picked. -----------------------------------------------------------------------------*/ struct socketUnix * const socketUnixP = chanSwitchP->implP; - + if (!socketUnixP->isListening) xmlrpc_asprintf(errorP, "Channel Switch is not listening"); else diff --git a/advanced/lib/abyss/src/sockutil.c b/advanced/lib/abyss/src/sockutil.c index bd991998b..9a2278779 100644 --- a/advanced/lib/abyss/src/sockutil.c +++ b/advanced/lib/abyss/src/sockutil.c @@ -120,7 +120,7 @@ sockutil_getSockName(int const sockFd, socklen_t nameSize; nameSize = sizeof(struct sockaddr) + 1; - + sockName = malloc(nameSize); if (sockName == NULL) @@ -164,7 +164,7 @@ sockutil_getPeerName(int const sockFd, socklen_t nameSize; nameSize = sizeof(struct sockaddr) + 1; - + peerName = malloc(nameSize); if (peerName == NULL) @@ -263,9 +263,9 @@ sockutil_formatPeerInfo(int const sockFd, int rc; sockaddrLen = sizeof(sockaddr); - + rc = getpeername(sockFd, &sockaddr, &sockaddrLen); - + if (rc < 0) xmlrpc_asprintf(peerStringP, "?? getpeername() failed. errno=%d (%s)", errno, strerror(errno)); @@ -341,7 +341,7 @@ sockutil_waitForConnection(int const listenSockFd, pollfds[1].fd = interruptPipe.interrupteeFd; pollfds[1].events = POLLIN; - + rc = poll(pollfds, ARRAY_SIZE(pollfds), -1); if (rc < 0) { @@ -418,7 +418,7 @@ sockutil_bindSocketToPort(int const fd, const struct sockaddr * const sockAddrP, socklen_t const sockAddrLen, const char ** const errorP) { - + int rc; rc = bind(fd, sockAddrP, sockAddrLen); @@ -442,7 +442,7 @@ void sockutil_bindSocketToPortInet(int const fd, uint16_t const portNumber, const char ** const errorP) { - + struct sockaddr_in name; int rc; diff --git a/advanced/lib/curl_transport/curltransaction.c b/advanced/lib/curl_transport/curltransaction.c index 62f5bae90..6952e0844 100644 --- a/advanced/lib/curl_transport/curltransaction.c +++ b/advanced/lib/curl_transport/curltransaction.c @@ -688,7 +688,7 @@ setupCurlSession(xmlrpc_env * const envP, /* A Curl session is serial -- it processes zero or one transaction at a time. We use the "private" attribute of the Curl session to - indicate which transaction it is presently processing. This is + indicate which transaction it is currently processing. This is important when the transaction finishes, because libcurl will just tell us that something finished on a particular session, not that a particular transaction finished. diff --git a/advanced/lib/expat/xmlparse/xmlparse.c b/advanced/lib/expat/xmlparse/xmlparse.c index 48adfb33c..8087360f9 100644 --- a/advanced/lib/expat/xmlparse/xmlparse.c +++ b/advanced/lib/expat/xmlparse/xmlparse.c @@ -3929,8 +3929,10 @@ doProlog(XML_Parser const xmlParserP, switch (tok) { case XML_TOK_PARAM_ENTITY_REF: *errorCodeP = XML_ERROR_PARAM_ENTITY_REF; + break; case XML_TOK_XML_DECL: *errorCodeP = XML_ERROR_MISPLACED_XML_PI; + break; default: *errorCodeP = XML_ERROR_SYNTAX; } diff --git a/advanced/lib/expat/xmltok/xmlrole.c b/advanced/lib/expat/xmltok/xmlrole.c index 821971343..9fcfb2bd3 100644 --- a/advanced/lib/expat/xmltok/xmlrole.c +++ b/advanced/lib/expat/xmltok/xmlrole.c @@ -92,6 +92,7 @@ int prolog0(PROLOG_STATE *state, return XML_ROLE_NONE; case XML_TOK_COMMENT: state->handler = prolog1; + return XML_ROLE_NONE; case XML_TOK_BOM: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: diff --git a/advanced/lib/expat/xmltok/xmltok_impl.c b/advanced/lib/expat/xmltok/xmltok_impl.c index cf0091d1d..2e4e42de7 100644 --- a/advanced/lib/expat/xmltok/xmltok_impl.c +++ b/advanced/lib/expat/xmltok/xmltok_impl.c @@ -14,6 +14,9 @@ Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd See the file copying.txt for copying permission. */ +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" + #ifndef IS_INVALID_CHAR #define IS_INVALID_CHAR(enc, ptr, n) (0) #endif diff --git a/advanced/src/abyss_handler.c b/advanced/src/abyss_handler.c index 7698703bb..bd2873fff 100644 --- a/advanced/src/abyss_handler.c +++ b/advanced/src/abyss_handler.c @@ -41,25 +41,25 @@ addAuthCookie(xmlrpc_env * const envP, const char * const authCookie) { const char * cookieResponse; - + xmlrpc_asprintf(&cookieResponse, "auth=%s", authCookie); - + if (xmlrpc_strnomem(cookieResponse)) xmlrpc_faultf(envP, "Insufficient memory to generate cookie " "response header."); else { ResponseAddField(abyssSessionP, "Set-Cookie", cookieResponse); - + xmlrpc_strfree(cookieResponse); } -} - +} + -static void +static void sendResponse(xmlrpc_env * const envP, - TSession * const abyssSessionP, - const char * const body, + TSession * const abyssSessionP, + const char * const body, size_t const len, bool const chunked, ResponseAccessCtl const accessControl) { @@ -107,7 +107,7 @@ sendResponse(xmlrpc_env * const envP, ResponseContentType(abyssSessionP, "text/xml; charset=utf-8"); ResponseContentLength(abyssSessionP, abyssLen); ResponseAccessControl(abyssSessionP, accessControl); - + ResponseWriteStart(abyssSessionP); ResponseWriteBody(abyssSessionP, body, abyssLen); ResponseWriteEnd(abyssSessionP); @@ -134,7 +134,7 @@ sendResponse(xmlrpc_env * const envP, static void -sendError(TSession * const abyssSessionP, +sendError(TSession * const abyssSessionP, unsigned int const status, const char * const explanation) { /*---------------------------------------------------------------------------- @@ -207,7 +207,7 @@ getBody(xmlrpc_env * const envP, const char * chunkPtr; size_t chunkLen; - SessionGetReadData(abyssSessionP, contentSize - bytesRead, + SessionGetReadData(abyssSessionP, contentSize - bytesRead, &chunkPtr, &chunkLen); bytesRead += chunkLen; @@ -234,7 +234,7 @@ storeCookies(TSession * const httpRequestP, -----------------------------------------------------------------------------*/ const char * const cookie = RequestHeaderValue(httpRequestP, "cookie"); if (cookie) { - /* + /* Setting the value in an environment variable doesn't make any sense. So for now, cookie code is disabled. -Bryan 04.10.03. @@ -261,7 +261,7 @@ processContentLength(TSession * const httpRequestP, don't want to figure out how to safely handle HTTP < 1.1 requests without it. -----------------------------------------------------------------------------*/ - const char * const content_length = + const char * const content_length = RequestHeaderValue(httpRequestP, "content-length"); if (content_length == NULL) { @@ -276,9 +276,9 @@ processContentLength(TSession * const httpRequestP, else { unsigned long contentLengthValue; char * tail; - + contentLengthValue = strtoul(content_length, &tail, 10); - + if (*tail != '\0') xmlrpc_asprintf(errorP, "There's non-numeric crap in " "the value of your content-length " @@ -287,7 +287,7 @@ processContentLength(TSession * const httpRequestP, xmlrpc_asprintf(errorP, "According to your content-length " "HTTP header, your request is empty (zero " "length)"); - else if ((unsigned long)(size_t)contentLengthValue + else if ((unsigned long)(size_t)contentLengthValue != contentLengthValue) xmlrpc_asprintf(errorP, "According to your content-length " "HTTP header, your request is too big to " @@ -305,7 +305,7 @@ processContentLength(TSession * const httpRequestP, static void traceHandlerCalled(TSession * const abyssSessionP) { - + const char * methodDesc; const TRequestInfo * requestInfoP; @@ -395,11 +395,11 @@ processCall(TSession * const abyssSessionP, &output); if (!env.fault_occurred) { /* Send out the result. */ - sendResponse(&env, abyssSessionP, + sendResponse(&env, abyssSessionP, XMLRPC_MEMBLOCK_CONTENTS(char, output), XMLRPC_MEMBLOCK_SIZE(char, output), wantChunk, accessControl); - + XMLRPC_MEMBLOCK_FREE(char, output); } XMLRPC_MEMBLOCK_FREE(char, body); @@ -498,7 +498,7 @@ handleXmlRpcCallReq(TSession * const abyssSessionP, bool missing; size_t contentSize; - processContentLength(abyssSessionP, + processContentLength(abyssSessionP, &contentSize, &missing, &error); if (error) { sendError(abyssSessionP, 400, error); @@ -524,7 +524,7 @@ handleXmlRpcOptionsReq(TSession * const abyssSessionP, ResponseAccessCtl const accessControl) { ResponseAddField(abyssSessionP, "Allow", "POST"); - + ResponseAccessControl(abyssSessionP, accessControl); ResponseContentLength(abyssSessionP, 0); ResponseStatus(abyssSessionP, 200); diff --git a/advanced/src/json.c b/advanced/src/json.c index be0257722..cfffb53e4 100644 --- a/advanced/src/json.c +++ b/advanced/src/json.c @@ -829,7 +829,7 @@ parseObjectMember(xmlrpc_env * const envP, xmlrpc_env_init(&env); /* The current token is the string which is the member name: */ - assert(tokP->type = typeString); + assert(tokP->type == typeString); assert(tokP->end >= tokP->begin + 2); assert(*tokP->begin == '"'); assert(*(tokP->end-1) == '"'); diff --git a/advanced/src/xmlrpc_data.c b/advanced/src/xmlrpc_data.c index 605cac1eb..bc554ae18 100644 --- a/advanced/src/xmlrpc_data.c +++ b/advanced/src/xmlrpc_data.c @@ -95,6 +95,7 @@ destroyValue(xmlrpc_value * const valueP) { case XMLRPC_TYPE_DEAD: XMLRPC_ASSERT(false); /* Can't happen, per entry conditions */ + break; default: XMLRPC_ASSERT(false); /* There are no other possible values */ diff --git a/advanced/src/xmlrpc_datetime.c b/advanced/src/xmlrpc_datetime.c index 117f5297c..d5f252d1c 100644 --- a/advanced/src/xmlrpc_datetime.c +++ b/advanced/src/xmlrpc_datetime.c @@ -60,14 +60,14 @@ UnixTimeToSystemTime(time_t const t, static void UnixTimeFromFileTime(xmlrpc_env * const envP, LPFILETIME const pft, - time_t * const timeValueP) { + time_t * const timeValueP) { int64_t const WinEpoch100Ns = ((int64_t)pft->dwHighDateTime << 32) + pft->dwLowDateTime; int64_t const unixEpoch100Ns = WinEpoch100Ns - (SECS_BETWEEN_EPOCHS * SECS_TO_100NS); int64_t const unixEpochSeconds = - unixEpoch100Ns / SECS_TO_100NS; + unixEpoch100Ns / SECS_TO_100NS; if ((time_t)unixEpochSeconds != unixEpochSeconds) { /* Value is too big for a time_t; fail. */ @@ -85,8 +85,8 @@ UnixTimeFromSystemTime(xmlrpc_env * const envP, time_t * const timeValueP) { FILETIME filetime; - SystemTimeToFileTime(pst, &filetime); - UnixTimeFromFileTime(envP, &filetime, timeValueP); + SystemTimeToFileTime(pst, &filetime); + UnixTimeFromFileTime(envP, &filetime, timeValueP); } #endif /* MSVCRT */ @@ -100,8 +100,8 @@ validateDatetimeType(xmlrpc_env * const envP, if (valueP->_type != XMLRPC_TYPE_DATETIME) { xmlrpc_env_set_fault_formatted( envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " - "type %s was expected.", - xmlrpc_type_name(valueP->_type), + "type %s was expected.", + xmlrpc_type_name(valueP->_type), xmlrpc_type_name(XMLRPC_TYPE_DATETIME)); } } @@ -153,11 +153,11 @@ xmlrpc_read_datetime_str(xmlrpc_env * const envP, /* Note that this format is NOT ISO 8601 -- it's a bizarre hybrid of two ISO 8601 formats. */ - strftime(dtString, sizeof(dtString), "%Y%m%dT%H:%M:%S", + strftime(dtString, sizeof(dtString), "%Y%m%dT%H:%M:%S", &brokenTime); if (usecs != 0) { - char usecString[64]; + char usecString[32]; assert(usecs < 1000000); XMLRPC_SNPRINTF(usecString, sizeof(usecString), ".%06u", usecs); @@ -180,7 +180,7 @@ xmlrpc_read_datetime_str_old(xmlrpc_env * const envP, const char ** const stringValueP) { assert(valueP->_cache); - + validateDatetimeType(envP, valueP); if (!envP->fault_occurred) { const char ** const readBufferP = valueP->_cache; @@ -200,7 +200,7 @@ xmlrpc_read_datetime_usec(xmlrpc_env * const envP, const xmlrpc_value * const valueP, time_t * const secsP, unsigned int * const usecsP) { - + validateDatetimeType(envP, valueP); if (!envP->fault_occurred) { @@ -211,14 +211,14 @@ xmlrpc_read_datetime_usec(xmlrpc_env * const envP, else { struct tm brokenTime; const char * error; - + brokenTime.tm_sec = valueP->_value.dt.s; brokenTime.tm_min = valueP->_value.dt.m; brokenTime.tm_hour = valueP->_value.dt.h; brokenTime.tm_mday = valueP->_value.dt.D; brokenTime.tm_mon = valueP->_value.dt.M - 1; brokenTime.tm_year = valueP->_value.dt.Y - 1900; - + xmlrpc_timegm(&brokenTime, secsP, &error); if (error) { @@ -251,7 +251,7 @@ void xmlrpc_read_datetime_sec(xmlrpc_env * const envP, const xmlrpc_value * const valueP, time_t * const timeValueP) { - + unsigned int usecs; xmlrpc_read_datetime_usec(envP, valueP, timeValueP, &usecs); @@ -265,7 +265,7 @@ void xmlrpc_read_datetime_timeval(xmlrpc_env * const envP, const xmlrpc_value * const valueP, struct timeval * const timeValueP) { - + time_t secs; unsigned int usecs; @@ -284,7 +284,7 @@ void xmlrpc_read_datetime_timespec(xmlrpc_env * const envP, const xmlrpc_value * const valueP, struct timespec * const timeValueP) { - + time_t secs; unsigned int usecs; @@ -334,7 +334,7 @@ xmlrpc_read_datetime_8601(xmlrpc_env * const envP, xmlrpc_faultf(envP, "Unable to allocate memory " "for datetime string"); - + if (envP->fault_occurred) xmlrpc_strfree(*iso8601ValueP); } @@ -345,13 +345,13 @@ xmlrpc_read_datetime_8601(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_datetime_new(xmlrpc_env * const envP, +xmlrpc_datetime_new(xmlrpc_env * const envP, xmlrpc_datetime const dt) { xmlrpc_value * valP; const char ** readBufferP; - + MALLOCVAR(readBufferP); if (!readBufferP) @@ -365,7 +365,7 @@ xmlrpc_datetime_new(xmlrpc_env * const envP, if (!envP->fault_occurred) { valP->_type = XMLRPC_TYPE_DATETIME; - + valP->_value.dt = dt; valP->_cache = readBufferP; @@ -540,7 +540,7 @@ validateFormat(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_datetime_new_str(xmlrpc_env * const envP, +xmlrpc_datetime_new_str(xmlrpc_env * const envP, const char * const datetimeString) { /*---------------------------------------------------------------------------- This exists only for backward compatibility. Originally, this was the @@ -609,7 +609,7 @@ xmlrpc_datetime_new_usec(xmlrpc_env * const envP, xmlrpc_value * -xmlrpc_datetime_new_sec(xmlrpc_env * const envP, +xmlrpc_datetime_new_sec(xmlrpc_env * const envP, time_t const value) { return xmlrpc_datetime_new_usec(envP, value, 0); @@ -620,7 +620,7 @@ xmlrpc_datetime_new_sec(xmlrpc_env * const envP, #if XMLRPC_HAVE_TIMEVAL xmlrpc_value * -xmlrpc_datetime_new_timeval(xmlrpc_env * const envP, +xmlrpc_datetime_new_timeval(xmlrpc_env * const envP, struct timeval const value) { return xmlrpc_datetime_new_usec(envP, value.tv_sec, value.tv_usec); @@ -632,7 +632,7 @@ xmlrpc_datetime_new_timeval(xmlrpc_env * const envP, #if XMLRPC_HAVE_TIMESPEC xmlrpc_value * -xmlrpc_datetime_new_timespec(xmlrpc_env * const envP, +xmlrpc_datetime_new_timespec(xmlrpc_env * const envP, struct timespec const value) { return xmlrpc_datetime_new_usec(envP, value.tv_sec, value.tv_nsec/1000); diff --git a/advanced/src/xmlrpc_serialize.c b/advanced/src/xmlrpc_serialize.c index f1679a07b..d42f7d2e1 100644 --- a/advanced/src/xmlrpc_serialize.c +++ b/advanced/src/xmlrpc_serialize.c @@ -41,7 +41,7 @@ addString(xmlrpc_env * const envP, -static void +static void formatOut(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, const char * const formatString, @@ -85,7 +85,7 @@ formatOut(xmlrpc_env * const envP, -static void +static void assertValidUtf8(const char * const str ATTR_UNUSED, size_t const len ATTR_UNUSED) { /*---------------------------------------------------------------------------- @@ -112,7 +112,7 @@ assertValidUtf8(const char * const str ATTR_UNUSED, static size_t escapedSize(const char * const chars, size_t const len) { - + size_t size; size_t i; @@ -135,7 +135,7 @@ escapedSize(const char * const chars, static void -escapeForXml(xmlrpc_env * const envP, +escapeForXml(xmlrpc_env * const envP, const char * const chars, size_t const len, xmlrpc_mem_block ** const outputPP) { @@ -148,7 +148,7 @@ escapeForXml(xmlrpc_env * const envP, symmetry. < etc. are known in XML as "entity references." - + Also Escape CR as . While raw CR _is_ allowed in the content of an XML element, it has a special meaning -- it means line ending. Our input uses LF for for line endings. Since it also means line ending @@ -214,7 +214,7 @@ escapeForXml(xmlrpc_env * const envP, -static void +static void serializeUtf8MemBlock(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_mem_block * const inputP) { @@ -247,7 +247,7 @@ serializeUtf8MemBlock(xmlrpc_env * const envP, const char * const contents = XMLRPC_MEMBLOCK_CONTENTS(const char, escapedP); size_t const size = XMLRPC_MEMBLOCK_SIZE(char, escapedP); - + XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, contents, size); XMLRPC_MEMBLOCK_FREE(const char, escapedP); @@ -256,10 +256,10 @@ serializeUtf8MemBlock(xmlrpc_env * const envP, -static void +static void xmlrpc_serialize_base64_data(xmlrpc_env * const envP, xmlrpc_mem_block * const output, - unsigned char * const data, + unsigned char * const data, size_t const len) { /*---------------------------------------------------------------------------- Encode the 'len' bytes at 'data' in base64 ASCII and append the result to @@ -271,11 +271,11 @@ xmlrpc_serialize_base64_data(xmlrpc_env * const envP, if (!envP->fault_occurred) { unsigned char * const contents = XMLRPC_MEMBLOCK_CONTENTS(unsigned char, encoded); - size_t const size = + size_t const size = XMLRPC_MEMBLOCK_SIZE(unsigned char, encoded); - + XMLRPC_MEMBLOCK_APPEND(char, envP, output, contents, size); - + XMLRPC_MEMBLOCK_FREE(char, encoded); } } @@ -306,7 +306,7 @@ serializeDatetime(xmlrpc_env * const envP, valueP->_value.dt.s); if (valueP->_value.dt.u != 0) { - char usecString[64]; + char usecString[32]; assert(valueP->_value.dt.u < 1000000); XMLRPC_SNPRINTF(usecString, sizeof(usecString), ".%06u", valueP->_value.dt.u); @@ -328,7 +328,7 @@ serializeStructMember(xmlrpc_env * const envP, xmlrpc_value * const memberKeyP, xmlrpc_value * const memberValueP, xmlrpc_dialect const dialect) { - + addString(envP, outputP, ""); if (!envP->fault_occurred) { @@ -350,7 +350,7 @@ serializeStructMember(xmlrpc_env * const envP, -static void +static void serializeStruct(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const structP, @@ -412,7 +412,7 @@ serializeArray(xmlrpc_env * const envP, } if (!envP->fault_occurred) addString(envP, outputP, "
"); -} +} @@ -482,7 +482,7 @@ formatValueContent(xmlrpc_env * const envP, if (!envP->fault_occurred) addString(envP, outputP, ""); } - } break; + } break; case XMLRPC_TYPE_ARRAY: serializeArray(envP, outputP, valueP, dialect); @@ -513,7 +513,7 @@ formatValueContent(xmlrpc_env * const envP, -void +void xmlrpc_serialize_value2(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const valueP, @@ -539,7 +539,7 @@ xmlrpc_serialize_value2(xmlrpc_env * const envP, -void +void xmlrpc_serialize_value(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const valueP) { @@ -549,7 +549,7 @@ xmlrpc_serialize_value(xmlrpc_env * const envP, -void +void xmlrpc_serialize_params2(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const paramArrayP, @@ -591,7 +591,7 @@ xmlrpc_serialize_params2(xmlrpc_env * const envP, -void +void xmlrpc_serialize_params(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const paramArrayP) { @@ -608,9 +608,9 @@ xmlrpc_serialize_params(xmlrpc_env * const envP, ** xmlrpc_serialize_call **========================================================================= ** Serialize an XML-RPC call. -*/ +*/ -void +void xmlrpc_serialize_call2(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, const char * const methodName, @@ -626,7 +626,7 @@ xmlrpc_serialize_call2(xmlrpc_env * const envP, XMLRPC_ASSERT(outputP != NULL); XMLRPC_ASSERT(methodName != NULL); XMLRPC_ASSERT_VALUE_OK(paramArrayP); - + addString(envP, outputP, XML_PROLOGUE); if (!envP->fault_occurred) { const char * const xmlns = @@ -657,7 +657,7 @@ xmlrpc_serialize_call2(xmlrpc_env * const envP, -void +void xmlrpc_serialize_call(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, const char * const methodName, @@ -669,7 +669,7 @@ xmlrpc_serialize_call(xmlrpc_env * const envP, -void +void xmlrpc_serialize_response2(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const valueP, @@ -699,12 +699,12 @@ xmlrpc_serialize_response2(xmlrpc_env * const envP, ""CRLF); } } - } + } } -void +void xmlrpc_serialize_response(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, xmlrpc_value * const valueP) { @@ -714,7 +714,7 @@ xmlrpc_serialize_response(xmlrpc_env * const envP, -void +void xmlrpc_serialize_fault(xmlrpc_env * const envP, xmlrpc_mem_block * const outputP, const xmlrpc_env * const faultP) { @@ -765,8 +765,8 @@ xmlrpc_serialize_fault(xmlrpc_env * const envP, ** 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. -** +** 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 diff --git a/advanced/version.mk b/advanced/version.mk index 56a05de60..07ff23fb3 100644 --- a/advanced/version.mk +++ b/advanced/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 58 -XMLRPC_POINT_RELEASE = 0 +XMLRPC_POINT_RELEASE = 1 From d81a9498d84b3b89040ee4864bf6a2c24f5401d9 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 26 Sep 2020 16:26:59 +0000 Subject: [PATCH 132/154] miscellaneous update git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3117 98333e67-4a24-44d7-a75c-e53540dd3050 From 31d24bb9131ca995d831251d14b5787d4c181a13 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 20 Feb 2021 05:14:41 +0000 Subject: [PATCH 133/154] Fix bug - *errorP not set when sessionReadRequest times out git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3118 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/abyss/src/sessionReadRequest.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/trunk/lib/abyss/src/sessionReadRequest.c b/trunk/lib/abyss/src/sessionReadRequest.c index 4d0e4f1d8..4206a5a17 100644 --- a/trunk/lib/abyss/src/sessionReadRequest.c +++ b/trunk/lib/abyss/src/sessionReadRequest.c @@ -389,22 +389,31 @@ readRequestField(TSession * const sessionP, Return as *requestLineP the request field read. This ASCIIZ string is in the session's internal buffer. + + If we fail to get a field and fail to time out, we return as *errorP + a text description of the failure in newly malloced storage. Otherwise, + we return *errorP == NULL. -----------------------------------------------------------------------------*/ char * line; bool endOfHeader; + bool timedOut; const char * skipError; - skipToNonemptyLine(sessionP->connP, deadline, timedOutP, &skipError); + skipToNonemptyLine(sessionP->connP, deadline, &timedOut, &skipError); if (skipError) { xmlrpc_asprintf(errorP, "Failed to find the request field, " "i.e. a non-empty line. %s", skipError); xmlrpc_strfree(skipError); - } else if (!*timedOutP) { + } else if (timedOut) { + *errorP = NULL; + *timedOutP = true; + } else { const char * error; + bool timedOut; readField(sessionP->connP, deadline, &endOfHeader, &line, - timedOutP, &error); + &timedOut, &error); if (error) { xmlrpc_asprintf(errorP, "Got beginning of the request field, " @@ -413,13 +422,16 @@ readRequestField(TSession * const sessionP, } else { *errorP = NULL; - if (!*timedOutP) { + if (timedOut) + *timedOutP = true; + else { /* End of header is delimited by an empty line, and we skipped all the empty lines above, so readField() could not have encountered EOH: */ assert(!endOfHeader); + *timedOutP = false; *requestLineP = line; } } @@ -1146,6 +1158,9 @@ SessionReadRequest(TSession * const sessionP, to be read by an HTTP request handler (via SessionRefillBuffer() and SessionGetReadData()). + We wait no longer than 'timeout' seconds from the time we are called for + the complete header to arrive. + If we are unable to read the header, we return a text description as *errorP and a suitable HTTP status code as *httpErrorCodeP. From 74f51cf0ce36e7a9068562c84f5b2d8d1beceb69 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 20 Feb 2021 22:06:05 +0000 Subject: [PATCH 134/154] Release 1.58.02 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3119 98333e67-4a24-44d7-a75c-e53540dd3050 --- advanced/lib/abyss/src/sessionReadRequest.c | 3 ++- advanced/version.mk | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/advanced/lib/abyss/src/sessionReadRequest.c b/advanced/lib/abyss/src/sessionReadRequest.c index 4d0e4f1d8..d02977d25 100644 --- a/advanced/lib/abyss/src/sessionReadRequest.c +++ b/advanced/lib/abyss/src/sessionReadRequest.c @@ -423,7 +423,8 @@ readRequestField(TSession * const sessionP, *requestLineP = line; } } - } + } else + *errorP = NULL; } diff --git a/advanced/version.mk b/advanced/version.mk index 07ff23fb3..0d56afb68 100644 --- a/advanced/version.mk +++ b/advanced/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 58 -XMLRPC_POINT_RELEASE = 1 +XMLRPC_POINT_RELEASE = 2 From 969d5e99b7e3d79879e9d931a3234a1d9d8afcef Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 20 Feb 2021 22:06:24 +0000 Subject: [PATCH 135/154] Release 1.54.03 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3120 98333e67-4a24-44d7-a75c-e53540dd3050 --- stable/lib/abyss/src/sessionReadRequest.c | 3 ++- stable/version.mk | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/stable/lib/abyss/src/sessionReadRequest.c b/stable/lib/abyss/src/sessionReadRequest.c index bad3f06f8..08feeb9da 100644 --- a/stable/lib/abyss/src/sessionReadRequest.c +++ b/stable/lib/abyss/src/sessionReadRequest.c @@ -422,7 +422,8 @@ readRequestField(TSession * const sessionP, *requestLineP = line; } } - } + } else + *errorP = NULL; } diff --git a/stable/version.mk b/stable/version.mk index 51f42045f..fb598282a 100644 --- a/stable/version.mk +++ b/stable/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 54 -XMLRPC_POINT_RELEASE = 2 +XMLRPC_POINT_RELEASE = 3 From 43ddc2b28df539872271f408a7be6ad0eec1d533 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 20 Feb 2021 22:18:09 +0000 Subject: [PATCH 136/154] Release 1.51.07 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3121 98333e67-4a24-44d7-a75c-e53540dd3050 From 602eb6ecfa5830a9c0e9f3adaa2445ba5e0b1b19 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 28 Mar 2021 17:37:18 +0000 Subject: [PATCH 137/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3122 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/xmlrpc_config.h.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trunk/xmlrpc_config.h.in b/trunk/xmlrpc_config.h.in index 968c27396..5234b43f3 100644 --- a/trunk/xmlrpc_config.h.in +++ b/trunk/xmlrpc_config.h.in @@ -7,7 +7,7 @@ A major goal of this file is to reduce conditional compilation in the other source files as much as possible. Even more, we want to avoid having to generate source code particular to a build environment - except in this file. + except in this file. This file is NOT meant to be used by any code outside of the Xmlrpc-c source tree. There is a similar file that gets installed @@ -73,7 +73,7 @@ #if (!defined(__inline__)) #if (defined(__sgi) || defined(_AIX) || defined(_MSC_VER)) #define __inline__ __inline - #else + #else #define __inline__ #endif #endif From 534da688aedc49b77e9b35613ad45edd4b8fd0f5 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Wed, 2 Jun 2021 03:17:23 +0000 Subject: [PATCH 138/154] miscellaneous update git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3123 98333e67-4a24-44d7-a75c-e53540dd3050 From 7bc29db89ae6179af0797d1cae588d1a8ef3430c Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 7 Aug 2021 15:51:15 +0000 Subject: [PATCH 139/154] Fix incorrect invocation of 'curl-config' git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3124 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/src/Makefile b/trunk/src/Makefile index 1cdf8b021..acd04dd82 100644 --- a/trunk/src/Makefile +++ b/trunk/src/Makefile @@ -57,7 +57,7 @@ ifeq ($(MUST_BUILD_CURL_CLIENT),yes) TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curltransaction TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curlmulti - TRANSPORT_LIBDEP += $(shell $CURL_CONFIG --libs) + TRANSPORT_LIBDEP += $(shell $(CURL_CONFIG) --libs) TRANSPORT_INCLUDES += -Isrcdir/lib/curl_transport endif ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) From bee8e29aaa0ef968b6ce045bae4305b7cf2516d2 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 7 Aug 2021 15:54:04 +0000 Subject: [PATCH 140/154] Release 1.58.03 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3125 98333e67-4a24-44d7-a75c-e53540dd3050 --- advanced/src/Makefile | 2 +- advanced/version.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/advanced/src/Makefile b/advanced/src/Makefile index 1cdf8b021..acd04dd82 100644 --- a/advanced/src/Makefile +++ b/advanced/src/Makefile @@ -57,7 +57,7 @@ ifeq ($(MUST_BUILD_CURL_CLIENT),yes) TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curltransaction TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curlmulti - TRANSPORT_LIBDEP += $(shell $CURL_CONFIG --libs) + TRANSPORT_LIBDEP += $(shell $(CURL_CONFIG) --libs) TRANSPORT_INCLUDES += -Isrcdir/lib/curl_transport endif ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) diff --git a/advanced/version.mk b/advanced/version.mk index 0d56afb68..be6ba46f1 100644 --- a/advanced/version.mk +++ b/advanced/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 58 -XMLRPC_POINT_RELEASE = 2 +XMLRPC_POINT_RELEASE = 3 From 148e64a5bb5588a89840ee498430332456c216f3 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 7 Aug 2021 15:54:59 +0000 Subject: [PATCH 141/154] Relase 1.54.04 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3126 98333e67-4a24-44d7-a75c-e53540dd3050 --- stable/src/Makefile | 2 +- stable/version.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stable/src/Makefile b/stable/src/Makefile index 1cdf8b021..acd04dd82 100644 --- a/stable/src/Makefile +++ b/stable/src/Makefile @@ -57,7 +57,7 @@ ifeq ($(MUST_BUILD_CURL_CLIENT),yes) TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/xmlrpc_curl_transport TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curltransaction TRANSPORT_MODS += $(BLDDIR)/lib/curl_transport/curlmulti - TRANSPORT_LIBDEP += $(shell $CURL_CONFIG --libs) + TRANSPORT_LIBDEP += $(shell $(CURL_CONFIG) --libs) TRANSPORT_INCLUDES += -Isrcdir/lib/curl_transport endif ifeq ($(MUST_BUILD_LIBWWW_CLIENT),yes) diff --git a/stable/version.mk b/stable/version.mk index fb598282a..8f503f967 100644 --- a/stable/version.mk +++ b/stable/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 54 -XMLRPC_POINT_RELEASE = 3 +XMLRPC_POINT_RELEASE = 4 From e5d2ceffe6bad909ea27945e99e8c34c2225456f Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 7 Aug 2021 15:58:31 +0000 Subject: [PATCH 142/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3127 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/examples/ssl_secure_server.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/trunk/examples/ssl_secure_server.c b/trunk/examples/ssl_secure_server.c index 0ef533cb8..da55dd880 100644 --- a/trunk/examples/ssl_secure_server.c +++ b/trunk/examples/ssl_secure_server.c @@ -24,16 +24,16 @@ You can drive the most difficult part of this example (initial SSL handshake) with the 'openssl' program that comes with OpenSSL, as follows. - + $ ./ssl_secure_server 8080 & - $ openssl -connect localhost:8080 -state + $ openssl -connect localhost:8080 -state The 'openssl' command connects and handshakes with the server, then waits for you to type stuff to send to the server. You would have to type a complete HTTP header followed by a valid XML-RPC call to complete the demonstration. - This uses the "provide your own Abyss server" mode of operation, + This uses the "provide your own Abyss server" mode of operation, as opposed to other Xmlrpc-c facilities that create an Abyss server under the covers, because this is the only way to get SSL. @@ -89,7 +89,7 @@ sslInfoCallback(const SSL * const sslP, SSL_alert_desc_string_long(ret)); } else if (where & SSL_CB_EXIT) { if (ret == 0) - fprintf(stderr, "%s:failed in %s\n", + fprintf(stderr, "%s:failed in %s\n", str, SSL_state_string_long(sslP)); else if (ret < 0) { fprintf(stderr, "%s:error in %s\n", @@ -130,7 +130,7 @@ shutdownAbyss(xmlrpc_env * const faultP, void * const context, const char * const comment, void * const callInfo) { - + TServer * const abyssServerP = context; xmlrpc_env_init(faultP); @@ -141,11 +141,11 @@ shutdownAbyss(xmlrpc_env * const faultP, static xmlrpc_value * -sample_add(xmlrpc_env * const envP, +sample_add(xmlrpc_env * const envP, xmlrpc_value * const paramArrayP, void * const serverInfo, void * const channelInfo) { - + xmlrpc_int x, y, z; printPeerIpAddr(channelInfo); @@ -164,8 +164,8 @@ sample_add(xmlrpc_env * const envP, -int -main(int const argc, +int +main(int const argc, const char ** const argv) { struct xmlrpc_method_info3 const methodInfo = { @@ -190,7 +190,7 @@ main(int const argc, } AbyssInit(&error); - + xmlrpc_env_init(&env); sslCtxP = SSL_CTX_new(SSLv23_server_method()); @@ -199,7 +199,7 @@ main(int const argc, SSL_CTX_use_certificate_chain_file(sslCtxP, "/tmp/ssltest/certificate.pem"); - + SSL_CTX_use_PrivateKey_file(sslCtxP, "/tmp/ssltest/dsakey.pem", SSL_FILETYPE_PEM); From 1c7c9c0e6af7d73c7ac55f578dcf4cb96b25a007 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Thu, 12 Aug 2021 19:42:22 +0000 Subject: [PATCH 143/154] Fix handling of error on interrupt pipe git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3128 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/abyss/src/sockutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/lib/abyss/src/sockutil.c b/trunk/lib/abyss/src/sockutil.c index 9a2278779..6700c7eac 100644 --- a/trunk/lib/abyss/src/sockutil.c +++ b/trunk/lib/abyss/src/sockutil.c @@ -360,7 +360,7 @@ sockutil_waitForConnection(int const listenSockFd, xmlrpc_asprintf(errorP, "INTERNAL ERROR: interrupt socket hung up"); } else if (pollfds[0].revents & POLLERR) { xmlrpc_asprintf(errorP, "listening socket is in POLLERR status"); - } else if (pollfds[1].revents & POLLHUP) { + } else if (pollfds[1].revents & POLLERR) { xmlrpc_asprintf(errorP, "interrupt socket is in POLLERR status"); } else { *errorP = NULL; From 453094f2a4963db0e0f44dc9d006fb89df096d90 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Thu, 12 Aug 2021 19:48:51 +0000 Subject: [PATCH 144/154] Release 1.58.04 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3129 98333e67-4a24-44d7-a75c-e53540dd3050 --- advanced/lib/abyss/src/sockutil.c | 2 +- advanced/version.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/advanced/lib/abyss/src/sockutil.c b/advanced/lib/abyss/src/sockutil.c index 9a2278779..6700c7eac 100644 --- a/advanced/lib/abyss/src/sockutil.c +++ b/advanced/lib/abyss/src/sockutil.c @@ -360,7 +360,7 @@ sockutil_waitForConnection(int const listenSockFd, xmlrpc_asprintf(errorP, "INTERNAL ERROR: interrupt socket hung up"); } else if (pollfds[0].revents & POLLERR) { xmlrpc_asprintf(errorP, "listening socket is in POLLERR status"); - } else if (pollfds[1].revents & POLLHUP) { + } else if (pollfds[1].revents & POLLERR) { xmlrpc_asprintf(errorP, "interrupt socket is in POLLERR status"); } else { *errorP = NULL; diff --git a/advanced/version.mk b/advanced/version.mk index be6ba46f1..5e3f430c0 100644 --- a/advanced/version.mk +++ b/advanced/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 58 -XMLRPC_POINT_RELEASE = 3 +XMLRPC_POINT_RELEASE = 4 From 51f74e2e461e281f87ee0257d38dc24ac79c0371 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Thu, 9 Sep 2021 04:29:50 +0000 Subject: [PATCH 145/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3130 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/curl_transport/curlmulti.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/trunk/lib/curl_transport/curlmulti.c b/trunk/lib/curl_transport/curlmulti.c index 47cbb128d..6adf4a509 100644 --- a/trunk/lib/curl_transport/curlmulti.c +++ b/trunk/lib/curl_transport/curlmulti.c @@ -107,7 +107,7 @@ void curlMulti_destroy(curlMulti * const curlMultiP) { curl_multi_cleanup(curlMultiP->curlMultiP); - + curlMultiP->lockP->destroy(curlMultiP->lockP); free(curlMultiP); @@ -153,7 +153,7 @@ curlMulti_perform(xmlrpc_env * const envP, xmlrpc_strfree(reason); } } -} +} @@ -167,7 +167,7 @@ curlMulti_addHandle(xmlrpc_env * const envP, curlMultiP->lockP->acquire(curlMultiP->lockP); rc = curl_multi_add_handle(curlMultiP->curlMultiP, curlSessionP); - + curlMultiP->lockP->release(curlMultiP->lockP); /* Old libcurl (e.g. 7.12) actually returns CURLM_CALL_MULTI_PERFORM @@ -193,7 +193,7 @@ curlMulti_removeHandle(curlMulti * const curlMultiP, curlMultiP->lockP->acquire(curlMultiP->lockP); curl_multi_remove_handle(curlMultiP->curlMultiP, curlSessionP); - + curlMultiP->lockP->release(curlMultiP->lockP); } @@ -218,16 +218,16 @@ curlMulti_getMessage(curlMulti * const curlMultiP, */ curlMultiP->lockP->acquire(curlMultiP->lockP); - + privateCurlMsgP = curl_multi_info_read(curlMultiP->curlMultiP, &remainingMsgCount); - + if (privateCurlMsgP == NULL) *endOfMessagesP = true; else { *endOfMessagesP = false; *curlMsgP = *privateCurlMsgP; - } + } curlMultiP->lockP->release(curlMultiP->lockP); } @@ -251,7 +251,7 @@ curlMulti_fdset(xmlrpc_env * const envP, for work with select(). -----------------------------------------------------------------------------*/ CURLMcode rc; - + curlMultiP->lockP->acquire(curlMultiP->lockP); /* curl_multi_fdset() doesn't _set_ the fdsets. It adds to existing @@ -316,5 +316,5 @@ curlMulti_updateFdSet(curlMulti * const curlMultiP, curlMultiP->exceptFdSet = exceptFdSet; } - + From b9643b19313ddc564ef5ea3b0557010960442b1b Mon Sep 17 00:00:00 2001 From: giraffedata Date: Thu, 9 Sep 2021 04:37:16 +0000 Subject: [PATCH 146/154] whitespace git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3131 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/libutil/select.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/trunk/lib/libutil/select.c b/trunk/lib/libutil/select.c index 01856adcb..0c042ab0d 100644 --- a/trunk/lib/libutil/select.c +++ b/trunk/lib/libutil/select.c @@ -14,7 +14,7 @@ #include #include /* For struct timespec on some systems */ #endif -#endif +#endif #include #include "xmlrpc-c/select_int.h" @@ -43,7 +43,7 @@ xmlrpc_pselect(int const n, #endif #else /* HAVE_PSELECT */ struct timeval timeout; - + timeout.tv_sec = timeoutP->tv_sec; timeout.tv_usec = timeoutP->tv_nsec/1000; #if MSVCRT @@ -60,3 +60,6 @@ xmlrpc_pselect(int const n, return retval; } + + + From 12b20bf1bc153028e756bf8df8a8e359a49bc1ed Mon Sep 17 00:00:00 2001 From: giraffedata Date: Wed, 15 Sep 2021 01:53:00 +0000 Subject: [PATCH 147/154] Add comments, setting of HAVE_CURL_MULTI_POLL for possible future use git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3132 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/lib/curl_transport/Makefile | 8 ++++++++ trunk/lib/curl_transport/curlmulti.c | 20 +++++++++++++++++++ .../curl_transport/xmlrpc_curl_transport.c | 6 ++++++ 3 files changed, 34 insertions(+) diff --git a/trunk/lib/curl_transport/Makefile b/trunk/lib/curl_transport/Makefile index 03a1973c0..611d71d3c 100644 --- a/trunk/lib/curl_transport/Makefile +++ b/trunk/lib/curl_transport/Makefile @@ -43,6 +43,14 @@ ifeq ($(NEED_CURL_TYPES_H),Y) CFLAGS_LOCAL += -DNEED_CURL_TYPES_H endif +# 074100 means 7.65.0 +HAVE_CURL_MULTI_POLL := $(shell if test $(CURL_VERSION) '>' 074100; then echo Y; fi) + +ifeq ($(HAVE_CURL_MULTI_POLL),Y) + CFLAGS_LOCAL += -DHAVE_CURL_MULTI_POLL +endif + + CURL_INCLUDES := $(shell $(CURL_CONFIG) --cflags) # We expect that curl-config --cflags just gives us -I options, because # we need just the -I options for 'make dep'. Plus, it's scary to think diff --git a/trunk/lib/curl_transport/curlmulti.c b/trunk/lib/curl_transport/curlmulti.c index 6adf4a509..25788bbbd 100644 --- a/trunk/lib/curl_transport/curlmulti.c +++ b/trunk/lib/curl_transport/curlmulti.c @@ -9,6 +9,26 @@ requires the user to maintain them separately. =============================================================================*/ +/* Engineering note: Modern Curl has an easier interface for waiting for + there to be something for libcurl to do: 'curl_multi_poll'. Besides + being easier to code, it handles all file descriptors, whereas + the code here doesn't work for file descriptors > FD_SET (typically + 1023). For those, the user of this code ends up busywaiting for there + to be work to do on them. + + 'curl_multi_poll' is awkwardly nonmodular in the way it deals with programs + that need to wait simultaneously for libcurl to have work to do and for + other things, but our only user doesn't need to wait for anything but + libcurl to have work to do, so that is not a practical problem. + + One thing 'curl_multi_poll' lacks that the current implementation has is + the ability to reliably stop waiting when a signal is received. + I.e. 'curl_multi_poll' does 'poll', not 'ppoll'. + + But we ought to use 'curl_multi_poll' if we can. We could use + HAVE_CURL_MULTI_POLL (set in Makefile, but not used today) for that. +*/ + #define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ #include "xmlrpc_config.h" diff --git a/trunk/lib/curl_transport/xmlrpc_curl_transport.c b/trunk/lib/curl_transport/xmlrpc_curl_transport.c index 7537af632..f2c607e62 100644 --- a/trunk/lib/curl_transport/xmlrpc_curl_transport.c +++ b/trunk/lib/curl_transport/xmlrpc_curl_transport.c @@ -474,6 +474,12 @@ waitForWork(xmlrpc_env * const envP, /* There are no Curl file descriptors on which to wait. So either there's work to do right now or all transactions are already complete. + + It may also be the case that there are Curl file descriptors on + which Caller should wait, but they are too high (> FD_SETSIZE) + to use with 'pselect'. Libcurl doesn't provide a way to deal + with this case gracefully, so Caller will unfortunately end up + busywaiting for there to be work for libcurl to do. */ } else { xmlrpc_timespec const pselectTimeoutArg = From 06d12a1f066a0c0bfd3d8c2a2f3b2e6aac5bc5f2 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 26 Sep 2021 00:17:34 +0000 Subject: [PATCH 148/154] Release 1.51.08 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3133 98333e67-4a24-44d7-a75c-e53540dd3050 From 69dd1510acd6d1cd89683e273496d06cc80a8dd0 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 26 Sep 2021 00:21:33 +0000 Subject: [PATCH 149/154] Release 1.54.05 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3134 98333e67-4a24-44d7-a75c-e53540dd3050 --- stable/lib/abyss/src/sockutil.c | 2 +- stable/version.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stable/lib/abyss/src/sockutil.c b/stable/lib/abyss/src/sockutil.c index bd991998b..08cffc357 100644 --- a/stable/lib/abyss/src/sockutil.c +++ b/stable/lib/abyss/src/sockutil.c @@ -360,7 +360,7 @@ sockutil_waitForConnection(int const listenSockFd, xmlrpc_asprintf(errorP, "INTERNAL ERROR: interrupt socket hung up"); } else if (pollfds[0].revents & POLLERR) { xmlrpc_asprintf(errorP, "listening socket is in POLLERR status"); - } else if (pollfds[1].revents & POLLHUP) { + } else if (pollfds[1].revents & POLLERR) { xmlrpc_asprintf(errorP, "interrupt socket is in POLLERR status"); } else { *errorP = NULL; diff --git a/stable/version.mk b/stable/version.mk index 8f503f967..c1fcd7ebf 100644 --- a/stable/version.mk +++ b/stable/version.mk @@ -8,4 +8,4 @@ ############################################################################### XMLRPC_MAJOR_RELEASE = 1 XMLRPC_MINOR_RELEASE = 54 -XMLRPC_POINT_RELEASE = 4 +XMLRPC_POINT_RELEASE = 5 From 90978dfa964a57e6a31d76b128d0fa4ee9db574b Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 26 Sep 2021 00:24:05 +0000 Subject: [PATCH 150/154] Make release number 1.60.00 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3135 98333e67-4a24-44d7-a75c-e53540dd3050 --- trunk/version.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trunk/version.mk b/trunk/version.mk index ef0d7b9d4..f110b95e7 100644 --- a/trunk/version.mk +++ b/trunk/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 58 -XMLRPC_POINT_RELEASE = 99 +XMLRPC_MINOR_RELEASE = 59 +XMLRPC_POINT_RELEASE = 0 From 4a31c9a841dc16bae6800944d3953805ec9b5ca7 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 26 Sep 2021 00:24:41 +0000 Subject: [PATCH 151/154] Last 1.58 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3136 98333e67-4a24-44d7-a75c-e53540dd3050 From 12235c239e3e370cb6805d889a99f0751edc5eb7 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 26 Sep 2021 00:25:02 +0000 Subject: [PATCH 152/154] First 1.59 release git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3137 98333e67-4a24-44d7-a75c-e53540dd3050 From 6d361663c70e06155baac400ed31379a2a232bde Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 26 Sep 2021 00:28:25 +0000 Subject: [PATCH 153/154] Promote current Development release to Advanced 1.59.00 git-svn-id: http://svn.code.sf.net/p/xmlrpc-c/code@3138 98333e67-4a24-44d7-a75c-e53540dd3050 --- advanced/examples/ssl_secure_server.c | 22 +++++------ advanced/lib/abyss/src/sessionReadRequest.c | 26 ++++++++++--- advanced/lib/curl_transport/Makefile | 8 ++++ advanced/lib/curl_transport/curlmulti.c | 38 ++++++++++++++----- .../curl_transport/xmlrpc_curl_transport.c | 6 +++ advanced/lib/libutil/select.c | 7 +++- advanced/version.mk | 4 +- advanced/xmlrpc_config.h.in | 4 +- 8 files changed, 83 insertions(+), 32 deletions(-) diff --git a/advanced/examples/ssl_secure_server.c b/advanced/examples/ssl_secure_server.c index 0ef533cb8..da55dd880 100644 --- a/advanced/examples/ssl_secure_server.c +++ b/advanced/examples/ssl_secure_server.c @@ -24,16 +24,16 @@ You can drive the most difficult part of this example (initial SSL handshake) with the 'openssl' program that comes with OpenSSL, as follows. - + $ ./ssl_secure_server 8080 & - $ openssl -connect localhost:8080 -state + $ openssl -connect localhost:8080 -state The 'openssl' command connects and handshakes with the server, then waits for you to type stuff to send to the server. You would have to type a complete HTTP header followed by a valid XML-RPC call to complete the demonstration. - This uses the "provide your own Abyss server" mode of operation, + This uses the "provide your own Abyss server" mode of operation, as opposed to other Xmlrpc-c facilities that create an Abyss server under the covers, because this is the only way to get SSL. @@ -89,7 +89,7 @@ sslInfoCallback(const SSL * const sslP, SSL_alert_desc_string_long(ret)); } else if (where & SSL_CB_EXIT) { if (ret == 0) - fprintf(stderr, "%s:failed in %s\n", + fprintf(stderr, "%s:failed in %s\n", str, SSL_state_string_long(sslP)); else if (ret < 0) { fprintf(stderr, "%s:error in %s\n", @@ -130,7 +130,7 @@ shutdownAbyss(xmlrpc_env * const faultP, void * const context, const char * const comment, void * const callInfo) { - + TServer * const abyssServerP = context; xmlrpc_env_init(faultP); @@ -141,11 +141,11 @@ shutdownAbyss(xmlrpc_env * const faultP, static xmlrpc_value * -sample_add(xmlrpc_env * const envP, +sample_add(xmlrpc_env * const envP, xmlrpc_value * const paramArrayP, void * const serverInfo, void * const channelInfo) { - + xmlrpc_int x, y, z; printPeerIpAddr(channelInfo); @@ -164,8 +164,8 @@ sample_add(xmlrpc_env * const envP, -int -main(int const argc, +int +main(int const argc, const char ** const argv) { struct xmlrpc_method_info3 const methodInfo = { @@ -190,7 +190,7 @@ main(int const argc, } AbyssInit(&error); - + xmlrpc_env_init(&env); sslCtxP = SSL_CTX_new(SSLv23_server_method()); @@ -199,7 +199,7 @@ main(int const argc, SSL_CTX_use_certificate_chain_file(sslCtxP, "/tmp/ssltest/certificate.pem"); - + SSL_CTX_use_PrivateKey_file(sslCtxP, "/tmp/ssltest/dsakey.pem", SSL_FILETYPE_PEM); diff --git a/advanced/lib/abyss/src/sessionReadRequest.c b/advanced/lib/abyss/src/sessionReadRequest.c index d02977d25..4206a5a17 100644 --- a/advanced/lib/abyss/src/sessionReadRequest.c +++ b/advanced/lib/abyss/src/sessionReadRequest.c @@ -389,22 +389,31 @@ readRequestField(TSession * const sessionP, Return as *requestLineP the request field read. This ASCIIZ string is in the session's internal buffer. + + If we fail to get a field and fail to time out, we return as *errorP + a text description of the failure in newly malloced storage. Otherwise, + we return *errorP == NULL. -----------------------------------------------------------------------------*/ char * line; bool endOfHeader; + bool timedOut; const char * skipError; - skipToNonemptyLine(sessionP->connP, deadline, timedOutP, &skipError); + skipToNonemptyLine(sessionP->connP, deadline, &timedOut, &skipError); if (skipError) { xmlrpc_asprintf(errorP, "Failed to find the request field, " "i.e. a non-empty line. %s", skipError); xmlrpc_strfree(skipError); - } else if (!*timedOutP) { + } else if (timedOut) { + *errorP = NULL; + *timedOutP = true; + } else { const char * error; + bool timedOut; readField(sessionP->connP, deadline, &endOfHeader, &line, - timedOutP, &error); + &timedOut, &error); if (error) { xmlrpc_asprintf(errorP, "Got beginning of the request field, " @@ -413,18 +422,20 @@ readRequestField(TSession * const sessionP, } else { *errorP = NULL; - if (!*timedOutP) { + if (timedOut) + *timedOutP = true; + else { /* End of header is delimited by an empty line, and we skipped all the empty lines above, so readField() could not have encountered EOH: */ assert(!endOfHeader); + *timedOutP = false; *requestLineP = line; } } - } else - *errorP = NULL; + } } @@ -1147,6 +1158,9 @@ SessionReadRequest(TSession * const sessionP, to be read by an HTTP request handler (via SessionRefillBuffer() and SessionGetReadData()). + We wait no longer than 'timeout' seconds from the time we are called for + the complete header to arrive. + If we are unable to read the header, we return a text description as *errorP and a suitable HTTP status code as *httpErrorCodeP. diff --git a/advanced/lib/curl_transport/Makefile b/advanced/lib/curl_transport/Makefile index 03a1973c0..611d71d3c 100644 --- a/advanced/lib/curl_transport/Makefile +++ b/advanced/lib/curl_transport/Makefile @@ -43,6 +43,14 @@ ifeq ($(NEED_CURL_TYPES_H),Y) CFLAGS_LOCAL += -DNEED_CURL_TYPES_H endif +# 074100 means 7.65.0 +HAVE_CURL_MULTI_POLL := $(shell if test $(CURL_VERSION) '>' 074100; then echo Y; fi) + +ifeq ($(HAVE_CURL_MULTI_POLL),Y) + CFLAGS_LOCAL += -DHAVE_CURL_MULTI_POLL +endif + + CURL_INCLUDES := $(shell $(CURL_CONFIG) --cflags) # We expect that curl-config --cflags just gives us -I options, because # we need just the -I options for 'make dep'. Plus, it's scary to think diff --git a/advanced/lib/curl_transport/curlmulti.c b/advanced/lib/curl_transport/curlmulti.c index 47cbb128d..25788bbbd 100644 --- a/advanced/lib/curl_transport/curlmulti.c +++ b/advanced/lib/curl_transport/curlmulti.c @@ -9,6 +9,26 @@ requires the user to maintain them separately. =============================================================================*/ +/* Engineering note: Modern Curl has an easier interface for waiting for + there to be something for libcurl to do: 'curl_multi_poll'. Besides + being easier to code, it handles all file descriptors, whereas + the code here doesn't work for file descriptors > FD_SET (typically + 1023). For those, the user of this code ends up busywaiting for there + to be work to do on them. + + 'curl_multi_poll' is awkwardly nonmodular in the way it deals with programs + that need to wait simultaneously for libcurl to have work to do and for + other things, but our only user doesn't need to wait for anything but + libcurl to have work to do, so that is not a practical problem. + + One thing 'curl_multi_poll' lacks that the current implementation has is + the ability to reliably stop waiting when a signal is received. + I.e. 'curl_multi_poll' does 'poll', not 'ppoll'. + + But we ought to use 'curl_multi_poll' if we can. We could use + HAVE_CURL_MULTI_POLL (set in Makefile, but not used today) for that. +*/ + #define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ #include "xmlrpc_config.h" @@ -107,7 +127,7 @@ void curlMulti_destroy(curlMulti * const curlMultiP) { curl_multi_cleanup(curlMultiP->curlMultiP); - + curlMultiP->lockP->destroy(curlMultiP->lockP); free(curlMultiP); @@ -153,7 +173,7 @@ curlMulti_perform(xmlrpc_env * const envP, xmlrpc_strfree(reason); } } -} +} @@ -167,7 +187,7 @@ curlMulti_addHandle(xmlrpc_env * const envP, curlMultiP->lockP->acquire(curlMultiP->lockP); rc = curl_multi_add_handle(curlMultiP->curlMultiP, curlSessionP); - + curlMultiP->lockP->release(curlMultiP->lockP); /* Old libcurl (e.g. 7.12) actually returns CURLM_CALL_MULTI_PERFORM @@ -193,7 +213,7 @@ curlMulti_removeHandle(curlMulti * const curlMultiP, curlMultiP->lockP->acquire(curlMultiP->lockP); curl_multi_remove_handle(curlMultiP->curlMultiP, curlSessionP); - + curlMultiP->lockP->release(curlMultiP->lockP); } @@ -218,16 +238,16 @@ curlMulti_getMessage(curlMulti * const curlMultiP, */ curlMultiP->lockP->acquire(curlMultiP->lockP); - + privateCurlMsgP = curl_multi_info_read(curlMultiP->curlMultiP, &remainingMsgCount); - + if (privateCurlMsgP == NULL) *endOfMessagesP = true; else { *endOfMessagesP = false; *curlMsgP = *privateCurlMsgP; - } + } curlMultiP->lockP->release(curlMultiP->lockP); } @@ -251,7 +271,7 @@ curlMulti_fdset(xmlrpc_env * const envP, for work with select(). -----------------------------------------------------------------------------*/ CURLMcode rc; - + curlMultiP->lockP->acquire(curlMultiP->lockP); /* curl_multi_fdset() doesn't _set_ the fdsets. It adds to existing @@ -316,5 +336,5 @@ curlMulti_updateFdSet(curlMulti * const curlMultiP, curlMultiP->exceptFdSet = exceptFdSet; } - + diff --git a/advanced/lib/curl_transport/xmlrpc_curl_transport.c b/advanced/lib/curl_transport/xmlrpc_curl_transport.c index 7537af632..f2c607e62 100644 --- a/advanced/lib/curl_transport/xmlrpc_curl_transport.c +++ b/advanced/lib/curl_transport/xmlrpc_curl_transport.c @@ -474,6 +474,12 @@ waitForWork(xmlrpc_env * const envP, /* There are no Curl file descriptors on which to wait. So either there's work to do right now or all transactions are already complete. + + It may also be the case that there are Curl file descriptors on + which Caller should wait, but they are too high (> FD_SETSIZE) + to use with 'pselect'. Libcurl doesn't provide a way to deal + with this case gracefully, so Caller will unfortunately end up + busywaiting for there to be work for libcurl to do. */ } else { xmlrpc_timespec const pselectTimeoutArg = diff --git a/advanced/lib/libutil/select.c b/advanced/lib/libutil/select.c index 01856adcb..0c042ab0d 100644 --- a/advanced/lib/libutil/select.c +++ b/advanced/lib/libutil/select.c @@ -14,7 +14,7 @@ #include #include /* For struct timespec on some systems */ #endif -#endif +#endif #include #include "xmlrpc-c/select_int.h" @@ -43,7 +43,7 @@ xmlrpc_pselect(int const n, #endif #else /* HAVE_PSELECT */ struct timeval timeout; - + timeout.tv_sec = timeoutP->tv_sec; timeout.tv_usec = timeoutP->tv_nsec/1000; #if MSVCRT @@ -60,3 +60,6 @@ xmlrpc_pselect(int const n, return retval; } + + + diff --git a/advanced/version.mk b/advanced/version.mk index 5e3f430c0..f110b95e7 100644 --- a/advanced/version.mk +++ b/advanced/version.mk @@ -7,5 +7,5 @@ # ############################################################################### XMLRPC_MAJOR_RELEASE = 1 -XMLRPC_MINOR_RELEASE = 58 -XMLRPC_POINT_RELEASE = 4 +XMLRPC_MINOR_RELEASE = 59 +XMLRPC_POINT_RELEASE = 0 diff --git a/advanced/xmlrpc_config.h.in b/advanced/xmlrpc_config.h.in index 968c27396..5234b43f3 100644 --- a/advanced/xmlrpc_config.h.in +++ b/advanced/xmlrpc_config.h.in @@ -7,7 +7,7 @@ A major goal of this file is to reduce conditional compilation in the other source files as much as possible. Even more, we want to avoid having to generate source code particular to a build environment - except in this file. + except in this file. This file is NOT meant to be used by any code outside of the Xmlrpc-c source tree. There is a similar file that gets installed @@ -73,7 +73,7 @@ #if (!defined(__inline__)) #if (defined(__sgi) || defined(_AIX) || defined(_MSC_VER)) #define __inline__ __inline - #else + #else #define __inline__ #endif #endif From fb4f913791c3756f0ae0b86816fc729c93f9eb9e Mon Sep 17 00:00:00 2001 From: stickz Date: Thu, 30 Dec 2021 23:17:02 -0500 Subject: [PATCH 154/154] Implement curl_multi_wait --- advanced/lib/curl_transport/curlmulti.c | 168 ++---------- advanced/lib/curl_transport/curlmulti.h | 15 -- .../curl_transport/xmlrpc_curl_transport.c | 250 ++---------------- 3 files changed, 46 insertions(+), 387 deletions(-) diff --git a/advanced/lib/curl_transport/curlmulti.c b/advanced/lib/curl_transport/curlmulti.c index 25788bbbd..0c08f4ac4 100644 --- a/advanced/lib/curl_transport/curlmulti.c +++ b/advanced/lib/curl_transport/curlmulti.c @@ -9,26 +9,6 @@ requires the user to maintain them separately. =============================================================================*/ -/* Engineering note: Modern Curl has an easier interface for waiting for - there to be something for libcurl to do: 'curl_multi_poll'. Besides - being easier to code, it handles all file descriptors, whereas - the code here doesn't work for file descriptors > FD_SET (typically - 1023). For those, the user of this code ends up busywaiting for there - to be work to do on them. - - 'curl_multi_poll' is awkwardly nonmodular in the way it deals with programs - that need to wait simultaneously for libcurl to have work to do and for - other things, but our only user doesn't need to wait for anything but - libcurl to have work to do, so that is not a practical problem. - - One thing 'curl_multi_poll' lacks that the current implementation has is - the ability to reliably stop waiting when a signal is received. - I.e. 'curl_multi_poll' does 'poll', not 'ppoll'. - - But we ought to use 'curl_multi_poll' if we can. We could use - HAVE_CURL_MULTI_POLL (set in Makefile, but not used today) for that. -*/ - #define _XOPEN_SOURCE 600 /* Make sure strdup() is in */ #include "xmlrpc_config.h" @@ -77,15 +57,6 @@ struct curlMulti { using the multi manager whenever you're calling a Curl library multi manager function. */ - /* The following file descriptor sets are an integral part of the - CURLM object; Our curlMulti_fdset() routine binds them to the - CURLM object, and said object expects us to use them in a very - specific way, including doing a select() on them. It is very, - very messy. - */ - fd_set readFdSet; - fd_set writeFdSet; - fd_set exceptFdSet; }; @@ -138,41 +109,44 @@ curlMulti_destroy(curlMulti * const curlMultiP) { void curlMulti_perform(xmlrpc_env * const envP, curlMulti * const curlMultiP, - bool * const immediateWorkToDoP, int * const runningHandleCtP) { /*---------------------------------------------------------------------------- Do whatever work is ready to be done under the control of multi manager 'curlMultiP'. E.g. if HTTP response data has recently arrived from the network, process it as an HTTP response. - Iff this results in some work being finished from our point of view, - return *immediateWorkToDoP true. (Caller can query the multi manager for - messages and find out what it is). - Return as *runningHandleCtP the number of Curl easy handles under the multi manager's control that are still running -- yet to finish. -----------------------------------------------------------------------------*/ - CURLMcode rc; - - curlMultiP->lockP->acquire(curlMultiP->lockP); - - rc = curl_multi_perform(curlMultiP->curlMultiP, runningHandleCtP); - - curlMultiP->lockP->release(curlMultiP->lockP); - - if (rc == CURLM_CALL_MULTI_PERFORM) { - *immediateWorkToDoP = true; - } else { - *immediateWorkToDoP = false; - - if (rc != CURLM_OK) { - const char * reason; + do + { + CURLMcode rc; + int numfds; + + curlMultiP->lockP->acquire(curlMultiP->lockP); + + rc = curl_multi_perform(curlMultiP->curlMultiP, runningHandleCtP); + + curlMultiP->lockP->release(curlMultiP->lockP); + + if (rc == CURLM_OK) { + /* wait for activity, timeout or "nothing" */ + rc = curl_multi_wait(curlMultiP->curlMultiP, NULL, 0, 1000, numfds); + } + + if (rc != CURLM_OK) { + const char * reason; interpretCurlMultiError(&reason, rc); - xmlrpc_faultf(envP, "Impossible failure of curl_multi_perform(): " - "%s", reason); + xmlrpc_faultf(envP, "Failure of curl_multi_perform(): %s", reason); xmlrpc_strfree(reason); - } - } + break; + } + + // Wait 100ms after timeout or no file descriptors before trying again + if(!numfds) { + WAITMS(100); + } + } while (runningHandleCtP); } @@ -250,91 +224,3 @@ curlMulti_getMessage(curlMulti * const curlMultiP, } curlMultiP->lockP->release(curlMultiP->lockP); } - - - -void -curlMulti_fdset(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - fd_set * const readFdSetP, - fd_set * const writeFdSetP, - fd_set * const exceptFdSetP, - int * const maxFdP) { -/*---------------------------------------------------------------------------- - Set the CURLM object's file descriptor sets to those in the - curlMulti object, update those file descriptor sets with the - current needs of the multi manager, and return the resulting values - of the file descriptor sets. - - This is a bizarre operation, but is necessary because of the nonmodular - way in which the Curl multi interface works with respect to waiting - for work with select(). ------------------------------------------------------------------------------*/ - CURLMcode rc; - - curlMultiP->lockP->acquire(curlMultiP->lockP); - - /* curl_multi_fdset() doesn't _set_ the fdsets. It adds to existing - ones (so you can easily do a select() on other fds and Curl - fds at the same time). So we have to clear first: - */ - FD_ZERO(&curlMultiP->readFdSet); - FD_ZERO(&curlMultiP->writeFdSet); - FD_ZERO(&curlMultiP->exceptFdSet); - - /* WARNING: curl_multi_fdset() doesn't just update the fdsets pointed - to by its arguments. It makes the CURLM object remember those - pointers and refer back to them later! In fact, curl_multi_perform - expects its caller to have done a select() on those masks. No, - really. The man page even admits it. - - Inspection of the Libcurl code in March 2007 indicates that - this isn't actually true -- curl_multi_fdset() updates your - fdset and doesn't remember the pointer at all. I.e. it's just - what you would expect. The man pages still says it's as - described above. My guess is that Libcurl was fixed at some - time and the man page not updated. In any case, we have to - work with old Libcurl if at all possible, so we still maintain - these fdsets as if they belong to the CURLM object. - */ - - rc = curl_multi_fdset(curlMultiP->curlMultiP, - &curlMultiP->readFdSet, - &curlMultiP->writeFdSet, - &curlMultiP->exceptFdSet, - maxFdP); - - *readFdSetP = curlMultiP->readFdSet; - *writeFdSetP = curlMultiP->writeFdSet; - *exceptFdSetP = curlMultiP->exceptFdSet; - - curlMultiP->lockP->release(curlMultiP->lockP); - - if (rc != CURLM_OK) { - const char * reason; - interpretCurlMultiError(&reason, rc); - xmlrpc_faultf(envP, "Impossible failure of curl_multi_fdset(): %s", - reason); - xmlrpc_strfree(reason); - } -} - - - -void -curlMulti_updateFdSet(curlMulti * const curlMultiP, - fd_set const readFdSet, - fd_set const writeFdSet, - fd_set const exceptFdSet) { -/*---------------------------------------------------------------------------- - curl_multi_perform() expects the file descriptor sets, which were bound - to the CURLM object via a prior curlMulti_fdset(), to contain the results - of a recent select(). This subroutine provides you a way to supply those. ------------------------------------------------------------------------------*/ - curlMultiP->readFdSet = readFdSet; - curlMultiP->writeFdSet = writeFdSet; - curlMultiP->exceptFdSet = exceptFdSet; -} - - - diff --git a/advanced/lib/curl_transport/curlmulti.h b/advanced/lib/curl_transport/curlmulti.h index 265ed0c17..9c29a44e7 100644 --- a/advanced/lib/curl_transport/curlmulti.h +++ b/advanced/lib/curl_transport/curlmulti.h @@ -17,7 +17,6 @@ curlMulti_destroy(curlMulti * const curlMultiP); void curlMulti_perform(xmlrpc_env * const envP, curlMulti * const curlMultiP, - bool * const immediateWorkToDoP, int * const runningHandlesP); void @@ -34,18 +33,4 @@ curlMulti_getMessage(curlMulti * const curlMultiP, bool * const endOfMessagesP, CURLMsg * const curlMsgP); -void -curlMulti_fdset(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - fd_set * const readFdSetP, - fd_set * const writeFdSetP, - fd_set * const exceptFdSetP, - int * const maxFdP); - -void -curlMulti_updateFdSet(curlMulti * const curlMultiP, - fd_set const readFdSet, - fd_set const writeFdSet, - fd_set const exceptFdSet); - #endif diff --git a/advanced/lib/curl_transport/xmlrpc_curl_transport.c b/advanced/lib/curl_transport/xmlrpc_curl_transport.c index f2c607e62..710172335 100644 --- a/advanced/lib/curl_transport/xmlrpc_curl_transport.c +++ b/advanced/lib/curl_transport/xmlrpc_curl_transport.c @@ -366,46 +366,6 @@ curlHasNosignal(void) { -static xmlrpc_timespec -pselectTimeout(xmlrpc_timeoutType const timeoutType, - xmlrpc_timespec const timeoutDt) { -/*---------------------------------------------------------------------------- - Return the value that should be used in the select() call to wait for - there to be work for the Curl multi manager to do, given that the user - wants to timeout according to 'timeoutType' and 'timeoutDt'. ------------------------------------------------------------------------------*/ - unsigned int const million = 1000000; - unsigned int selectTimeoutMillisec; - xmlrpc_timespec retval; - - /* We assume there is work to do at least every 3 seconds, because - the Curl multi manager often has retries and other scheduled work - that doesn't involve file handles on which we can select(). - One thing that might cause work to do without any file handle becoming - ready is Curl timing out a request. - */ - switch (timeoutType) { - case timeout_no: - selectTimeoutMillisec = 3000; - break; - case timeout_yes: { - xmlrpc_timespec nowTime; - int timeLeft; - - xmlrpc_gettimeofday(&nowTime); - timeLeft = timeDiffMillisec(timeoutDt, nowTime); - - selectTimeoutMillisec = MIN(3000, MAX(0, timeLeft)); - } break; - } - retval.tv_sec = selectTimeoutMillisec / 1000; - retval.tv_nsec = (uint32_t)((selectTimeoutMillisec % 1000) * million); - - return retval; -} - - - static void processCurlMessages(xmlrpc_env * const envP, curlMulti * const curlMultiP) { @@ -435,121 +395,6 @@ processCurlMessages(xmlrpc_env * const envP, -static void -waitForWork(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - xmlrpc_timeoutType const timeoutType, - xmlrpc_timespec const deadline, - sigset_t * const sigmaskP) { -/*---------------------------------------------------------------------------- - Wait for the Curl multi manager to have work to do, time to run out, - or a signal to be received (and caught), whichever comes first. - - Update the Curl multi manager's file descriptor sets to indicate what - work we found for it to do. - - Wait under signal mask *sigmaskP. The point of this is that Caller can - make sure that arrival of a signal of a certain class interrupts our wait, - even if the signal arrives shortly before we begin waiting. Caller blocks - that signal class, then checks whether a signal of that class has already - been received. If not, he calls us with *sigmaskP indicating that class - NOT blocked. Thus, if a signal of that class arrived any time after Caller - checked, we will return immediately and if it arrives while we're waiting, - we will return then. Note that we can provide this service only because - pselect() has the same atomic unblock/wait feature. - - If sigmaskP is NULL, wait under whatever the current signal mask is. ------------------------------------------------------------------------------*/ - fd_set readFdSet; - fd_set writeFdSet; - fd_set exceptFdSet; - int maxFd; - - trace("Waiting for work"); - - curlMulti_fdset(envP, curlMultiP, - &readFdSet, &writeFdSet, &exceptFdSet, &maxFd); - if (!envP->fault_occurred) { - if (maxFd == -1) { - /* There are no Curl file descriptors on which to wait. - So either there's work to do right now or all transactions - are already complete. - - It may also be the case that there are Curl file descriptors on - which Caller should wait, but they are too high (> FD_SETSIZE) - to use with 'pselect'. Libcurl doesn't provide a way to deal - with this case gracefully, so Caller will unfortunately end up - busywaiting for there to be work for libcurl to do. - */ - } else { - xmlrpc_timespec const pselectTimeoutArg = - pselectTimeout(timeoutType, deadline); - - int rc; - - trace("No work available; waiting for a Curl file descriptor to " - "be ready or %u.%03u sec", - pselectTimeoutArg.tv_sec, pselectTimeoutArg.tv_nsec/1000000); - - rc = xmlrpc_pselect(maxFd+1, &readFdSet, &writeFdSet, &exceptFdSet, - &pselectTimeoutArg, sigmaskP); - - if (rc < 0 && errno != EINTR) - xmlrpc_faultf(envP, "Impossible failure of pselect() " - "with errno %d (%s)", - errno, strerror(errno)); - else { - /* Believe it or not, the Curl multi manager needs the - results of our pselect(). So hand them over: - */ - curlMulti_updateFdSet(curlMultiP, - readFdSet, writeFdSet, exceptFdSet); - } - } - trace("Wait is over"); - } -} - - - -static void -waitForWorkInt(xmlrpc_env * const envP, - curlMulti * const curlMultiP, - xmlrpc_timeoutType const timeoutType, - xmlrpc_timespec const deadline, - int * const interruptP) { -/*---------------------------------------------------------------------------- - Same as waitForWork(), except we guarantee to return if a signal handler - sets or has set *interruptP, whereas waitForWork() can miss a signal - that happens before or just after it starts. - - We mess with global state -- the signal mask -- so we might mess up - a multithreaded program. Therefore, don't call this if - waitForWork() will suffice. ------------------------------------------------------------------------------*/ - sigset_t callerBlockSet; -#if MSVCRT - waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); -#else - sigset_t allSignals; - - assert(interruptP != NULL); - - sigfillset(&allSignals); - - sigprocmask(SIG_BLOCK, &allSignals, &callerBlockSet); - - if (*interruptP == 0) - waitForWork(envP, curlMultiP, timeoutType, deadline, &callerBlockSet); - else - trace("Not waiting because interrupt flag is set\n"); - - sigprocmask(SIG_SETMASK, &callerBlockSet, NULL); -#endif -} - - - static void doCurlWork(xmlrpc_env * const envP, curlMulti * const curlMultiP, @@ -567,17 +412,11 @@ doCurlWork(xmlrpc_env * const envP, manager's transactions so that there is no reason to call us ever again. -----------------------------------------------------------------------------*/ - bool immediateWorkToDo; int runningHandleCt; trace("Calling libcurl to perform all immediate work"); - - immediateWorkToDo = true; /* initial assumption */ - - while (immediateWorkToDo && !envP->fault_occurred) { - curlMulti_perform(envP, curlMultiP, - &immediateWorkToDo, &runningHandleCt); - } + + curlMulti_perform(envP, curlMultiP, &runningHandleCt); /* We either did all the work that's ready to do or hit an error. */ @@ -615,62 +454,27 @@ finishCurlMulti(xmlrpc_env * const envP, if 'interruptP' is non-null, it points to a value which is normally zero, but is nonzero when Caller wants us to abort all the transactions and return ASAP. - - The *interruptP flag alone will not interrupt us. We will wait in - spite of it for all Curl transactions to complete. *interruptP - just gives us a hint that the Curl transactions are being - interrupted, so we know there is work to do for them. (The way it - works is Caller sets up a "progress" function that checks the same - interrupt flag and reports "kill me." When we see the interrupt - flag, we tell libcurl to do whatever work there is to do, and as part of - that, libcurl calls the progress function, gets the "kill me" message, - and passes that on to us). -----------------------------------------------------------------------------*/ - /* For integrity, we make sure we don't let *interruptP interrupt our - wait for work more than once. That way, if for any reason libcurl - fails to call the progress function, or the progress function fails - to notice the interrupt flag and tell libcurl to abort, or libcurl - does abort as told, we don't have a busy loop of calls to - doCurlWork(). - - 'curlCalledSinceInterrupt' is part of this logic. - */ - - bool rpcStillRunning; - bool timedOut; - bool curlCalledSinceInterrupt; - rpcStillRunning = true; /* initial assumption */ - timedOut = false; - curlCalledSinceInterrupt = false; + bool rpcStillRunning = true; + bool timedOut = false; + + do + { + xmlrpc_timespec nowTime; - while (rpcStillRunning && !timedOut && !envP->fault_occurred) { + doCurlWork(envP, curlMultiP, &rpcStillRunning); - if (interruptP && !curlCalledSinceInterrupt) { - waitForWorkInt(envP, curlMultiP, timeoutType, deadline, - interruptP); - } else - waitForWork(envP, curlMultiP, timeoutType, deadline, NULL); - - if (!envP->fault_occurred) { - xmlrpc_timespec nowTime; - - /* doCurlWork() (among other things) finds Curl transactions that - user wants to abort and finishes them. (This is by virtue - of libcurl calling its progress function when we tell it to do - all available work). - */ - if (interruptP && *interruptP) - curlCalledSinceInterrupt = true; - - doCurlWork(envP, curlMultiP, &rpcStillRunning); - - xmlrpc_gettimeofday(&nowTime); + xmlrpc_gettimeofday(&nowTime); - timedOut = (timeoutType == timeout_yes && - timeIsAfter(nowTime, deadline)); - } - } + timedOut = (timeoutType == timeout_yes && + timeIsAfter(nowTime, deadline)); + + /* Abort all transactions and exit ASAP if interrupt is sent */ + if (interruptP && *interruptP) { + break; + } + } while (rpcStillRunning && !timedOut && !envP->fault_occurred); } @@ -947,20 +751,6 @@ getXportParms(xmlrpc_env * const envP, getConnectTimeoutParm(envP, curlXportParmsP, parmSize, &curlSetupP->connectTimeout); - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(tcp_keepalive)) - curlSetupP->tcpKeepalive = false; - else - curlSetupP->tcpKeepalive = curlXportParmsP->tcp_keepalive; - - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(tcp_keepidle_sec)) - curlSetupP->tcpKeepidle = 0; - else - curlSetupP->tcpKeepidle = curlXportParmsP->tcp_keepidle_sec; - if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(tcp_keepintvl_sec)) - curlSetupP->tcpKeepintvl = 0; - else - curlSetupP->tcpKeepintvl = curlXportParmsP->tcp_keepintvl_sec; } @@ -1165,18 +955,16 @@ static void assertNoOutstandingCurlWork(curlMulti * const curlMultiP) { xmlrpc_env env; - bool immediateWorkToDo; int runningHandles; xmlrpc_env_init(&env); - curlMulti_perform(&env, curlMultiP, &immediateWorkToDo, &runningHandles); + curlMulti_perform(&env, curlMultiP, &runningHandles); /* We know the above was a no-op, since we're asserting that there is no outstanding work. */ XMLRPC_ASSERT(!env.fault_occurred); - XMLRPC_ASSERT(!immediateWorkToDo); XMLRPC_ASSERT(runningHandles == 0); xmlrpc_env_clean(&env); }